LuxBlend_0.1.py
author David Bucciarelli <dade@ngi.it>
Wed Dec 16 15:08:36 2009 +0100 (2009-12-16)
branchv06x
changeset 447 4b8109987265
parent 445 2ce148c6a8b6
child 448 97106ada6b4e
permissions -rw-r--r--
Backported the fix for max. value of network_interval
lordcrc@384
     1
#!BPY
lordcrc@384
     2
# -*- coding: utf-8 -*-
lordcrc@384
     3
# coding=utf-8
lordcrc@384
     4
"""Registration info for Blender menus:
jeanphi@441
     5
Name: 'LuxBlend v0.6.1 Exporter'
lordcrc@384
     6
Blender: 248
lordcrc@384
     7
Group: 'Render'
jeanphi@441
     8
Tooltip: 'Export/Render to LuxRender v0.6.1 scene format (.lxs)'
lordcrc@384
     9
"""
lordcrc@384
    10
lordcrc@384
    11
__author__ = "radiance, zuegs, ideasman42, luxblender, dougal2"
jeanphi@441
    12
__version__ = "0.6.1"
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
# --------------------------------------------------------------------------
jeanphi@441
    37
# LuxBlend v0.6.1 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):
dade@424
   350
        print("    exporting mesh")
lordcrc@384
   351
        if mats == []:
lordcrc@384
   352
            mats = [dummyMat]
dade@424
   353
        usedmats = [f.mat for f in mesh.faces]
lordcrc@384
   354
        for matIndex in range(len(mats)):
dade@424
   355
            if not matIndex in usedmats:
dade@424
   356
                continue
dade@424
   357
            if not(portal):
dade@424
   358
                mat = mats[matIndex]
dade@424
   359
                if not mat:
dade@424
   360
                   mat = dummyMat
dade@424
   361
                self.exportMaterialLink(file, mat)
dade@424
   362
            mesh_str = self.getMeshType(len(mesh.verts), mats[matIndex])
dade@424
   363
            if not(portal):
dade@424
   364
                file.write("\tShape %s \"integer indices\" [\n"% mesh_str)
dade@424
   365
            else:
dade@424
   366
                self.exportMaterialLink(file, mats[matIndex])
dade@424
   367
                file.write("\tPortalShape %s \"integer indices\" [\n"% mesh_str)
dade@424
   368
            index = 0
dade@424
   369
            ffaces = [f for f in mesh.faces if f.mat == matIndex]
dade@424
   370
            for face in ffaces:
dade@424
   371
                file.write("%d %d %d\n"%(index, index+1, index+2))
dade@424
   372
                if (len(face)==4):
dade@424
   373
                    file.write("%d %d %d\n"%(index, index+2, index+3))
dade@424
   374
                index += len(face.verts)
dade@424
   375
            file.write("\t] \"point P\" [\n")
dade@424
   376
            for face in ffaces:
dade@424
   377
                for vertex in face:
dade@424
   378
                    file.write("%f %f %f\n"% tuple(vertex.co))
dade@424
   379
            file.write("\t] \"normal N\" [\n")
dade@424
   380
            for face in ffaces:
dade@424
   381
                normal = face.no
dade@424
   382
                for vertex in face:
dade@424
   383
                    if (face.smooth):
dade@424
   384
                        normal = vertex.no
dade@424
   385
                    file.write("%f %f %f\n"% tuple(normal))
dade@424
   386
            if (mesh.faceUV):
dade@424
   387
                file.write("\t] \"float uv\" [\n")
lordcrc@384
   388
                for face in ffaces:
dade@424
   389
                    for uv in face.uv:
dade@424
   390
                        file.write("%f %f\n"% tuple(uv))
dade@424
   391
            file.write("\t]\n")
lordcrc@384
   392
lordcrc@384
   393
    #-------------------------------------------------
lordcrc@384
   394
    # exportMeshOpt(self, file, mesh, mats, name, portal, optNormals)
lordcrc@384
   395
    # exports mesh to the file with optimization.
lordcrc@384
   396
    # portal: export without normals and UVs
lordcrc@384
   397
    # optNormals: speed and filesize optimization, flat faces get exported without normals
lordcrc@384
   398
    #-------------------------------------------------
lordcrc@384
   399
    def exportMeshOpt(self, file, mesh, mats, name, portal=False, optNormals=True):
dade@424
   400
        print("    exporting optimized mesh")
lordcrc@384
   401
        shapeList, smoothFltr, shapeText = [0], [[0,1]], [""]
lordcrc@384
   402
        if portal:
lordcrc@384
   403
            normalFltr, uvFltr, shapeText = [0], [0], ["portal"] # portal, no normals, no UVs
lordcrc@384
   404
        else:
lordcrc@384
   405
            uvFltr, normalFltr, shapeText = [1], [1], ["mixed with normals"] # normals and UVs
lordcrc@384
   406
            if optNormals: # one pass for flat faces without normals and another pass for smoothed faces with normals, all with UVs
lordcrc@384
   407
                shapeList, smoothFltr, normalFltr, uvFltr, shapeText = [0,1], [[0],[1]], [0,1], [1,1], ["flat w/o normals", "smoothed with normals"]
lordcrc@384
   408
        if mats == []:
lordcrc@384
   409
            mats = [dummyMat]
tom@406
   410
        usedmats = [f.mat for f in mesh.faces]
lordcrc@384
   411
        for matIndex in range(len(mats)):
tom@406
   412
            if not matIndex in usedmats:
tom@406
   413
                continue
tom@406
   414
            if not(portal):
tom@406
   415
                mat = mats[matIndex]
tom@406
   416
                if not mat:
tom@406
   417
                   mat = dummyMat
tom@406
   418
                self.exportMaterialLink(file, mat)
tom@406
   419
            for shape in shapeList:
tom@406
   420
                blenderExportVertexMap = []
tom@406
   421
                exportVerts = []
tom@406
   422
                exportFaces = []
tom@406
   423
                ffaces = [f for f in mesh.faces if (f.mat == matIndex) and (f.smooth in smoothFltr[shape])]
tom@406
   424
                for face in ffaces:
tom@406
   425
                    exportVIndices = []
tom@406
   426
                    index = 0
tom@406
   427
                    for vertex in face:
lordcrc@384
   428
#                            v = [vertex.co[0], vertex.co[1], vertex.co[2]]
tom@406
   429
                        v = [vertex.co]
tom@406
   430
                        if normalFltr[shape]:
tom@406
   431
                            if (face.smooth):
lordcrc@384
   432
#                                    v.extend(vertex.no)
tom@406
   433
                                v.append(vertex.no)
tom@406
   434
                            else:
lordcrc@384
   435
#                                    v.extend(face.no)
tom@406
   436
                                v.append(face.no)
tom@406
   437
                        if (uvFltr[shape]) and (mesh.faceUV):
lordcrc@384
   438
#                                v.extend(face.uv[index])
tom@406
   439
                            v.append(face.uv[index])
tom@406
   440
                        blenderVIndex = vertex.index
tom@406
   441
                        newExportVIndex = -1
tom@406
   442
                        length = len(v)
tom@406
   443
                        if (blenderVIndex < len(blenderExportVertexMap)):
tom@406
   444
                            for exportVIndex in blenderExportVertexMap[blenderVIndex]:
tom@406
   445
                                v2 = exportVerts[exportVIndex]
tom@406
   446
                                if (length==len(v2)) and (v == v2):
tom@406
   447
                                    newExportVIndex = exportVIndex
tom@406
   448
                                    break
tom@406
   449
                        if (newExportVIndex < 0):
tom@406
   450
                            newExportVIndex = len(exportVerts)
tom@406
   451
                            exportVerts.append(v)
tom@406
   452
                            while blenderVIndex >= len(blenderExportVertexMap):
tom@406
   453
                                blenderExportVertexMap.append([])
tom@406
   454
                            blenderExportVertexMap[blenderVIndex].append(newExportVIndex)
tom@406
   455
                        exportVIndices.append(newExportVIndex)
tom@406
   456
                        index += 1
tom@406
   457
                    exportFaces.append(exportVIndices)
tom@406
   458
                if (len(exportVerts)>0):
tom@406
   459
                    mesh_str = self.getMeshType(len(exportVerts), mats[matIndex])
dade@424
   460
                    if portal:
tom@406
   461
                        file.write("\tPortalShape %s \"integer indices\" [\n"% mesh_str)
tom@406
   462
                    else:
tom@406
   463
                        file.write("\tShape %s \"integer indices\" [\n"% mesh_str)
tom@406
   464
                    for face in exportFaces:
tom@406
   465
                        file.write("%d %d %d\n"%(face[0], face[1], face[2]))
tom@406
   466
                        if (len(face)==4):
tom@406
   467
                            file.write("%d %d %d\n"%(face[0], face[2], face[3]))
tom@406
   468
                    file.write("\t] \"point P\" [\n")
lordcrc@384
   469
#                        for vertex in exportVerts:
lordcrc@384
   470
#                            file.write("%f %f %f\n"%(vertex[0], vertex[1], vertex[2]))
tom@406
   471
                    file.write("".join(["%f %f %f\n"%tuple(vertex[0]) for vertex in exportVerts]))
tom@406
   472
                    if normalFltr[shape]:
tom@406
   473
                        file.write("\t] \"normal N\" [\n")
lordcrc@384
   474
#                            for vertex in exportVerts:
lordcrc@384
   475
#                                file.write("%f %f %f\n"%(vertex[3], vertex[4], vertex[5]))
tom@406
   476
                        file.write("".join(["%f %f %f\n"%tuple(vertex[1]) for vertex in exportVerts])) 
tom@406
   477
                        if (uvFltr[shape]) and (mesh.faceUV):
tom@406
   478
                            file.write("\t] \"float uv\" [\n")
lordcrc@384
   479
#                                for vertex in exportVerts:
lordcrc@384
   480
#                                    file.write("%f %f\n"%(vertex[6], vertex[7]))
tom@406
   481
                            file.write("".join(["%f %f\n"%tuple(vertex[2]) for vertex in exportVerts])) 
tom@406
   482
                    else:            
tom@406
   483
                        if (uvFltr[shape]) and (mesh.faceUV):
tom@406
   484
                            file.write("\t] \"float uv\" [\n")
lordcrc@384
   485
#                                for vertex in exportVerts:
lordcrc@384
   486
#                                    file.write("%f %f\n"%(vertex[3], vertex[4]))
tom@406
   487
                            file.write("".join(["%f %f\n"%tuple(vertex[1]) for vertex in exportVerts])) 
tom@406
   488
                    file.write("\t]\n")
tom@406
   489
                    print("  shape(%s): %d vertices, %d faces"%(shapeText[shape], len(exportVerts), len(exportFaces)))
lordcrc@384
   490
    
lordcrc@384
   491
    #-------------------------------------------------
lordcrc@384
   492
    # exportMeshes(self, file)
lordcrc@384
   493
    # exports meshes that uses instancing (meshes that are used by at least "instancing_threshold" objects)
lordcrc@384
   494
    #-------------------------------------------------
lordcrc@384
   495
    def exportMeshes(self, file):
lordcrc@384
   496
        scn = Scene.GetCurrent()
lordcrc@384
   497
        instancing_threshold = luxProp(scn, "instancing_threshold", 2).get()
dade@424
   498
        mesh_optimizing = luxProp(scn, "mesh_optimizing", "true")
lordcrc@384
   499
        mesh = Mesh.New('')
lordcrc@384
   500
        for (mesh_name, objs) in self.meshes.items():
lordcrc@384
   501
            allow_instancing = True
lordcrc@384
   502
            mats = getMaterials(objs[0]) # mats = obj.getData().getMaterials()
lordcrc@384
   503
            for mat in mats: # don't instance if one of the materials is emissive
lordcrc@384
   504
                if (mat!=None) and (luxProp(mat, "type", "").get()=="light"):
lordcrc@384
   505
                    allow_instancing = False
lordcrc@384
   506
            for obj in objs: # don't instance if the objects with same mesh uses different materials
lordcrc@384
   507
                ms = getMaterials(obj)
lordcrc@384
   508
                if ms != mats:
lordcrc@384
   509
                    allow_instancing = False
lordcrc@384
   510
            if obj.modifiers.__len__() > 0:
lordcrc@384
   511
                allow_instancing = False
lordcrc@384
   512
            if allow_instancing and (len(objs) > instancing_threshold):
lordcrc@384
   513
                del self.meshes[mesh_name]
lordcrc@384
   514
                mesh.getFromObject(objs[0], 0, 1)
lordcrc@384
   515
                print("blender-mesh: %s (%d vertices, %d faces)"%(mesh_name, len(mesh.verts), len(mesh.faces)))
lordcrc@384
   516
                file.write("ObjectBegin \"%s\"\n"%mesh_name)
tom@406
   517
dade@424
   518
                if (mesh_optimizing.get() == "true"):
lordcrc@384
   519
                    self.exportMeshOpt(file, mesh, mats, mesh_name)
lordcrc@384
   520
                else:
lordcrc@384
   521
                    self.exportMesh(file, mesh, mats, mesh_name)
lordcrc@384
   522
                file.write("ObjectEnd # %s\n\n"%mesh_name)
lordcrc@384
   523
        mesh.verts = None
lordcrc@384
   524
lordcrc@384
   525
    #-------------------------------------------------
lordcrc@384
   526
    # exportObjects(self, file)
lordcrc@384
   527
    # exports objects to the file
lordcrc@384
   528
    #-------------------------------------------------
lordcrc@384
   529
    def exportObjects(self, file):
lordcrc@384
   530
        scn = Scene.GetCurrent()
lordcrc@384
   531
        cam = scn.getCurrentCamera().data
lordcrc@384
   532
        objectmblur = luxProp(cam, "objectmblur", "true")
lordcrc@384
   533
        usemblur = luxProp(cam, "usemblur", "false")
dade@424
   534
        mesh_optimizing = luxProp(scn, "mesh_optimizing", "true")
lordcrc@384
   535
        mesh = Mesh.New('')
lordcrc@384
   536
        for [obj, matrix] in self.objects:
lordcrc@384
   537
            print("object: %s"%(obj.getName()))
lordcrc@384
   538
            mesh_name = obj.getData(name_only=True)
lordcrc@384
   539
lordcrc@384
   540
            motion = None
lordcrc@384
   541
            if(objectmblur.get() == "true" and usemblur.get() == "true"):
lordcrc@384
   542
                # motion blur
lordcrc@384
   543
                frame = Blender.Get('curframe')
lordcrc@384
   544
                Blender.Set('curframe', frame+1)
lordcrc@384
   545
                m1 = 1.0*matrix # multiply by 1.0 to get a copy of orignal matrix (will be frame-independant) 
lordcrc@384
   546
                Blender.Set('curframe', frame)
lordcrc@384
   547
                if m1 != matrix:
lordcrc@384
   548
                    print("  motion blur")
lordcrc@384
   549
                    motion = m1
lordcrc@384
   550
    
lordcrc@384
   551
            if motion: # motion-blur only works with instances, so ensure mesh is exported as instance first
lordcrc@384
   552
                if mesh_name in self.meshes:
lordcrc@384
   553
                    del self.meshes[mesh_name]
lordcrc@384
   554
                    mesh.getFromObject(obj, 0, 1)
lordcrc@384
   555
                    mats = getMaterials(obj)
lordcrc@384
   556
                    print("  blender-mesh: %s (%d vertices, %d faces)"%(mesh_name, len(mesh.verts), len(mesh.faces)))
lordcrc@384
   557
                    file.write("ObjectBegin \"%s\"\n"%mesh_name)
dade@424
   558
                    if (mesh_optimizing.get() == "true"):
lordcrc@384
   559
                        self.exportMeshOpt(file, mesh, mats, mesh_name)
lordcrc@384
   560
                    else:
lordcrc@384
   561
                        self.exportMesh(file, mesh, mats, mesh_name)
lordcrc@384
   562
                    file.write("ObjectEnd # %s\n\n"%mesh_name)
lordcrc@384
   563
lordcrc@384
   564
            file.write("AttributeBegin # %s\n"%obj.getName())
lordcrc@384
   565
            file.write("\tTransform [%s %s %s %s  %s %s %s %s  %s %s %s %s  %s %s %s %s]\n"\
lordcrc@384
   566
                %(matrix[0][0], matrix[0][1], matrix[0][2], matrix[0][3],\
lordcrc@384
   567
                  matrix[1][0], matrix[1][1], matrix[1][2], matrix[1][3],\
lordcrc@384
   568
                  matrix[2][0], matrix[2][1], matrix[2][2], matrix[2][3],\
lordcrc@384
   569
                    matrix[3][0], matrix[3][1], matrix[3][2], matrix[3][3]))
lordcrc@384
   570
            if motion:
lordcrc@384
   571
                file.write("\tTransformBegin\n")
lordcrc@384
   572
                file.write("\t\tIdentity\n")
lordcrc@384
   573
                file.write("\t\tTransform [%s %s %s %s  %s %s %s %s  %s %s %s %s  %s %s %s %s]\n"\
lordcrc@384
   574
                    %(motion[0][0], motion[0][1], motion[0][2], motion[0][3],\
lordcrc@384
   575
                      motion[1][0], motion[1][1], motion[1][2], motion[1][3],\
lordcrc@384
   576
                      motion[2][0], motion[2][1], motion[2][2], motion[2][3],\
lordcrc@384
   577
                        motion[3][0], motion[3][1], motion[3][2], motion[3][3]))
lordcrc@384
   578
                file.write("\t\tCoordinateSystem \"%s\"\n"%(obj.getName()+"_motion"))
lordcrc@384
   579
                file.write("\tTransformEnd\n")
lordcrc@384
   580
            if mesh_name in self.meshes:
lordcrc@384
   581
                mesh.getFromObject(obj, 0, 1)
lordcrc@384
   582
                mats = getMaterials(obj)
lordcrc@384
   583
                print("  blender-mesh: %s (%d vertices, %d faces)"%(mesh_name, len(mesh.verts), len(mesh.faces)))
dade@424
   584
                if (mesh_optimizing.get() == "true"):
lordcrc@384
   585
                    self.exportMeshOpt(file, mesh, mats, mesh_name)
lordcrc@384
   586
                else:
lordcrc@384
   587
                    self.exportMesh(file, mesh, mats, mesh_name)
lordcrc@384
   588
            else:
lordcrc@384
   589
                print("  instance %s"%(mesh_name))
lordcrc@384
   590
                if motion:
lordcrc@384
   591
                    file.write("\tMotionInstance \"%s\" 0.0 1.0 \"%s\"\n"%(mesh_name, obj.getName()+"_motion"))
lordcrc@384
   592
                else:
lordcrc@384
   593
                    file.write("\tObjectInstance \"%s\"\n"%mesh_name)
lordcrc@384
   594
            file.write("AttributeEnd\n\n")
lordcrc@384
   595
        mesh.verts = None
lordcrc@384
   596
lordcrc@384
   597
    #-------------------------------------------------
lordcrc@384
   598
    # exportPortals(self, file)
lordcrc@384
   599
    # exports portals objects to the file
lordcrc@384
   600
    #-------------------------------------------------
lordcrc@384
   601
    def exportPortals(self, file):
lordcrc@384
   602
        scn = Scene.GetCurrent()
dade@424
   603
        mesh_optimizing = luxProp(scn, "mesh_optimizing", "true")
lordcrc@384
   604
        mesh = Mesh.New('')
lordcrc@384
   605
        for [obj, matrix] in self.portals:
lordcrc@384
   606
            print("portal: %s"%(obj.getName()))
lordcrc@384
   607
            file.write("\tTransform [%s %s %s %s  %s %s %s %s  %s %s %s %s  %s %s %s %s]\n"\
lordcrc@384
   608
                %(matrix[0][0], matrix[0][1], matrix[0][2], matrix[0][3],\
lordcrc@384
   609
                  matrix[1][0], matrix[1][1], matrix[1][2], matrix[1][3],\
lordcrc@384
   610
                  matrix[2][0], matrix[2][1], matrix[2][2], matrix[2][3],\
lordcrc@384
   611
                    matrix[3][0], matrix[3][1], matrix[3][2], matrix[3][3]))
lordcrc@384
   612
            mesh_name = obj.getData(name_only=True)
lordcrc@384
   613
            mesh.getFromObject(obj, 0, 1)
lordcrc@384
   614
            mats = getMaterials(obj) # mats = obj.getData().getMaterials()
dade@424
   615
            if (mesh_optimizing.get() == "true"):
lordcrc@384
   616
                self.exportMeshOpt(file, mesh, mats, mesh_name, True)
lordcrc@384
   617
            else:
lordcrc@384
   618
                self.exportMesh(file, mesh, mats, mesh_name, True)
lordcrc@384
   619
        mesh.verts = None
lordcrc@384
   620
lordcrc@384
   621
    #-------------------------------------------------
lordcrc@384
   622
    # exportLights(self, file)
lordcrc@384
   623
    # exports lights to the file
lordcrc@384
   624
    #-------------------------------------------------
lordcrc@384
   625
    def exportLights(self, file):
lordcrc@384
   626
        for [obj, matrix] in self.lights:
lordcrc@384
   627
            ltype = obj.getData(mesh=1).getType() # data
lordcrc@384
   628
            if (ltype == Lamp.Types["Lamp"]) or (ltype == Lamp.Types["Spot"]) or (ltype == Lamp.Types["Area"]):
lordcrc@384
   629
                print("light: %s"%(obj.getName()))
lordcrc@384
   630
                if ltype == Lamp.Types["Area"]:
lordcrc@384
   631
                    (str, link) = luxLight("", "", obj, None, 0)
lordcrc@384
   632
                    file.write(str)
lordcrc@384
   633
                if ltype == Lamp.Types["Area"]: file.write("AttributeBegin # %s\n"%obj.getName())
lordcrc@384
   634
                else: file.write("TransformBegin # %s\n"%obj.getName())
lordcrc@384
   635
                file.write("\tTransform [%s %s %s %s  %s %s %s %s  %s %s %s %s  %s %s %s %s]\n"\
lordcrc@384
   636
                    %(matrix[0][0], matrix[0][1], matrix[0][2], matrix[0][3],\
lordcrc@384
   637
                      matrix[1][0], matrix[1][1], matrix[1][2], matrix[1][3],\
lordcrc@384
   638
                      matrix[2][0], matrix[2][1], matrix[2][2], matrix[2][3],\
lordcrc@384
   639
                        matrix[3][0], matrix[3][1], matrix[3][2], matrix[3][3]))
lordcrc@384
   640
                col = obj.getData(mesh=1).col # data
lordcrc@384
   641
                energy = obj.getData(mesh=1).energy # data
lordcrc@384
   642
                if ltype == Lamp.Types["Lamp"]:
lordcrc@384
   643
                    lightgroup = luxProp(obj, "light.lightgroup", "default")
lordcrc@384
   644
                    if luxProp(Scene.GetCurrent(), "nolg", "false").get()!="true":
lordcrc@384
   645
                        file.write("LightGroup \"%s\"\n"%lightgroup.get())
lordcrc@384
   646
                    (str, link) = luxLamp("", "", obj, None, 0)
lordcrc@384
   647
                    file.write(str+"LightSource \"point\""+link+"\n")
lordcrc@384
   648
                if ltype == Lamp.Types["Spot"]:
lordcrc@384
   649
                    (str, link) = luxSpot("", "", obj, None, 0)
lordcrc@384
   650
                    file.write(str)
lordcrc@384
   651
                    proj = luxProp(obj, "light.usetexproj", "false")
lordcrc@384
   652
                    if luxProp(Scene.GetCurrent(), "nolg", "false").get()!="true":
lordcrc@384
   653
                        lightgroup = luxProp(obj, "light.lightgroup", "default")
lordcrc@384
   654
                        file.write("LightGroup \"%s\"\n"%lightgroup.get())
lordcrc@384
   655
                    if(proj.get() == "true"):
lordcrc@384
   656
                        file.write("Rotate 180 0 1 0\n")
lordcrc@384
   657
                        file.write("LightSource \"projection\" \"float fov\" [%f]"%(obj.getData(mesh=1).spotSize))
lordcrc@384
   658
                    else:
lordcrc@384
   659
                        file.write("LightSource \"spot\" \"point from\" [0 0 0] \"point to\" [0 0 -1] \"float coneangle\" [%f] \"float conedeltaangle\" [%f]"\
lordcrc@384
   660
                            %(obj.getData(mesh=1).spotSize*0.5, obj.getData(mesh=1).spotSize*0.5*obj.getData(mesh=1).spotBlend)) # data
lordcrc@384
   661
                    file.write(link+"\n")
lordcrc@384
   662
                if ltype == Lamp.Types["Area"]:
lordcrc@384
   663
                    lightgroup = luxProp(obj, "light.lightgroup", "default")
lordcrc@384
   664
                    if luxProp(Scene.GetCurrent(), "nolg", "false").get()!="true":
lordcrc@384
   665
                        file.write("LightGroup \"%s\"\n"%lightgroup.get())
lordcrc@384
   666
                    file.write("\tAreaLightSource \"area\"")
lordcrc@384
   667
                    file.write(link)
lordcrc@384
   668
#                    file.write(luxLight("", "", obj, None, 0))
lordcrc@384
   669
                    file.write("\n")
lordcrc@384
   670
                    areax = obj.getData(mesh=1).getAreaSizeX()
lordcrc@384
   671
                    # lamps "getAreaShape()" not implemented yet - so we can't detect shape! Using square as default
lordcrc@384
   672
                    # todo: ideasman42
lordcrc@384
   673
                    if (True): areay = areax
lordcrc@384
   674
                    else: areay = obj.getData(mesh=1).getAreaSizeY()
lordcrc@384
   675
                    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
   676
                if ltype == Lamp.Types["Area"]: file.write("AttributeEnd # %s\n"%obj.getName())
lordcrc@384
   677
                else: file.write("TransformEnd # %s\n"%obj.getName())
lordcrc@384
   678
                file.write("\n")
lordcrc@384
   679
lordcrc@384
   680
lordcrc@384
   681
    #-------------------------------------------------
lordcrc@384
   682
    # exportVolumes(self, file)
lordcrc@384
   683
    # exports volumes to the file
lordcrc@384
   684
    #-------------------------------------------------
lordcrc@384
   685
    def exportVolumes(self, file):
lordcrc@384
   686
        for [obj, matrix] in self.volumes:
lordcrc@384
   687
            print("volume: %s"%(obj.getName()))
lordcrc@384
   688
            file.write("# Volume: %s\n"%(obj.getName()))
lordcrc@384
   689
lordcrc@384
   690
            # trickery to obtain objectspace boundingbox AABB
lordcrc@384
   691
            mat = obj.matrixWorld.copy().invert()
lordcrc@384
   692
            bb = [vec * mat for vec in obj.getBoundBox()]
lordcrc@384
   693
            minx = miny = minz = 100000000000000.0
lordcrc@384
   694
            maxx = maxy = maxz = -100000000000000.0
lordcrc@384
   695
            for vec in bb:
lordcrc@384
   696
                if (vec[0] < minx): minx = vec[0]
lordcrc@384
   697
                if (vec[1] < miny): miny = vec[1]
lordcrc@384
   698
                if (vec[2] < minz): minz = vec[2]
lordcrc@384
   699
                if (vec[0] > maxx): maxx = vec[0]
lordcrc@384
   700
                if (vec[1] > maxy): maxy = vec[1]
lordcrc@384
   701
                if (vec[2] > maxz): maxz = vec[2]
lordcrc@384
   702
lordcrc@384
   703
            file.write("Transform [%s %s %s %s  %s %s %s %s  %s %s %s %s  %s %s %s %s]\n"\
lordcrc@384
   704
                %(matrix[0][0], matrix[0][1], matrix[0][2], matrix[0][3],\
lordcrc@384
   705
                  matrix[1][0], matrix[1][1], matrix[1][2], matrix[1][3],\
lordcrc@384
   706
                  matrix[2][0], matrix[2][1], matrix[2][2], matrix[2][3],\
lordcrc@384
   707
                    matrix[3][0], matrix[3][1], matrix[3][2], matrix[3][3]))
lordcrc@384
   708
lordcrc@384
   709
            str_opt = (" \"point p0\" [%f %f %f] \"point p1\" [%f %f %f]"%(minx, miny, minz, maxx, maxy, maxz))
lordcrc@384
   710
            mats = getMaterials(obj)
lordcrc@384
   711
            if (len(mats)>0) and (mats[0]!=None) and (luxProp(mats[0], "type", "").get()=="boundvolume"):
lordcrc@384
   712
                mat = mats[0]
lordcrc@384
   713
                (str, link) = luxMaterialBlock("", "", "", mat, None, 0, str_opt)
lordcrc@384
   714
                file.write("%s"%link)
lordcrc@384
   715
                file.write("\n\n")
lordcrc@384
   716
lordcrc@384
   717
lordcrc@384
   718
# Note - radiance - this is a work in progress
lordcrc@384
   719
def luxFlashBlock(camObj):
lordcrc@384
   720
    str = ""
lordcrc@384
   721
    str += "CoordSysTransform \"camera\"\n"
lordcrc@384
   722
lordcrc@384
   723
    str += "Texture \"camflashtex\" \"color\" \"blackbody\" \"float temperature\" [5500.0]"
lordcrc@384
   724
    str += "AreaLightSource \"area\" \"texture L\" [\"camflashtex\"] \"float power\" [100.000000] \"float efficacy\" [17.000000] \"float gain\" [1.000000]\n"
lordcrc@384
   725
lordcrc@384
   726
    up = 10.0
lordcrc@384
   727
lordcrc@384
   728
    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
   729
lordcrc@384
   730
    return str
lordcrc@384
   731
lordcrc@384
   732
lordcrc@384
   733
######################################################
lordcrc@384
   734
# EXPORT
lordcrc@384
   735
######################################################
lordcrc@384
   736
lordcrc@384
   737
def save_lux(filename, unindexedname):
lordcrc@384
   738
    
lordcrc@384
   739
    export_total_steps = 12.0
lordcrc@384
   740
    
lordcrc@384
   741
    global meshlist, matnames, lxs_filename, geom_filename, geom_pfilename, mat_filename, mat_pfilename, vol_filename, vol_pfilename, LuxIsGUI
lordcrc@384
   742
lordcrc@384
   743
    global render_status_text
lordcrc@384
   744
    global render_status
lordcrc@384
   745
    render_status_text = 'Exporting...'
lordcrc@384
   746
    render_status = True
lordcrc@384
   747
lordcrc@384
   748
    print("Lux Render Export started...\n")
lordcrc@384
   749
    time1 = Blender.sys.time()
lordcrc@384
   750
    scn = Scene.GetCurrent()
lordcrc@384
   751
lordcrc@384
   752
    filepath = os.path.dirname(filename)
lordcrc@384
   753
    filebase = os.path.splitext(os.path.basename(filename))[0]
lordcrc@384
   754
lordcrc@384
   755
    lxs_filename = filename
lordcrc@384
   756
lordcrc@384
   757
    geom_filename = os.path.join(filepath, filebase + "-geom.lxo")
lordcrc@384
   758
    geom_pfilename = filebase + "-geom.lxo"
lordcrc@384
   759
lordcrc@384
   760
    mat_filename = os.path.join(filepath, filebase + "-mat.lxm")
lordcrc@384
   761
    mat_pfilename = filebase + "-mat.lxm"
lordcrc@384
   762
    
lordcrc@384
   763
    vol_filename = os.path.join(filepath, filebase + "-vol.lxv")
lordcrc@384
   764
    vol_pfilename = filebase + "-vol.lxv"
lordcrc@384
   765
lordcrc@384
   766
    ### Zuegs: initialization for export class
lordcrc@384
   767
    export = luxExport(Blender.Scene.GetCurrent())
lordcrc@384
   768
lordcrc@384
   769
    # check if a light is present
lordcrc@384
   770
    envtype = luxProp(scn, "env.type", "infinite").get()
lordcrc@384
   771
    if envtype == "sunsky":
lordcrc@384
   772
        sun = None
lordcrc@384
   773
        for obj in scn.objects:
lordcrc@384
   774
            if (obj.getType() == "Lamp") and ((obj.Layers & scn.Layers) > 0):
lordcrc@384
   775
                if obj.getData(mesh=1).getType() == 1: # sun object # data
lordcrc@384
   776
                    sun = obj
lordcrc@384
   777
    if not(export.analyseScene()) and not(envtype == "infinite") and not((envtype == "sunsky") and (sun != None)):
lordcrc@384
   778
        print("ERROR: No light source found")
lordcrc@384
   779
        Draw.PupMenu("ERROR: No light source found%t|OK%x1")
jeanphi@391
   780
        render_status_text = ''
jeanphi@391
   781
        render_status = False
jeanphi@391
   782
        Blender.Window.QRedrawAll()
jeanphi@391
   783
        del export
lordcrc@384
   784
        return False
lordcrc@384
   785
lordcrc@384
   786
    if LuxIsGUI: DrawProgressBar(0.0/export_total_steps,'Setting up Scene file')
lordcrc@384
   787
    
lordcrc@384
   788
    class output_proxy():
lordcrc@384
   789
        load_result = False
lordcrc@384
   790
        combine_all_output = False
lordcrc@384
   791
        f = None
lordcrc@384
   792
        def close(self):
lordcrc@384
   793
            if self.f is not None: self.f.close()
lordcrc@384
   794
        def write(self, str):
lordcrc@384
   795
            if self.f is not None:
lordcrc@384
   796
                self.f.write(str)
lordcrc@384
   797
                self.f.flush()
lordcrc@384
   798
            
lordcrc@384
   799
    class file_output(output_proxy):
lordcrc@384
   800
        def __init__(self,filename):
lordcrc@384
   801
            self.f = open(filename, "w")
lordcrc@384
   802
            
lordcrc@384
   803
    from threading import Thread
lordcrc@384
   804
    class pipe_output(output_proxy, Thread):
lordcrc@384
   805
        combine_all_output = True
lordcrc@384
   806
        
dade@435
   807
        def __init__(self, xr,yr, haltspp, halttime, filename):
lordcrc@384
   808
            Thread.__init__(self)
lordcrc@384
   809
            
lordcrc@384
   810
            self.filename = filename
lordcrc@384
   811
            self.haltspp = haltspp
dade@435
   812
            self.halttime = halttime
lordcrc@384
   813
            self.xr = xr
lordcrc@384
   814
            self.yr = yr
lordcrc@384
   815
            
dade@435
   816
            if self.haltspp > 0 or self.halttime > 0:
lordcrc@384
   817
                bintype = "luxconsole"
lordcrc@384
   818
                self.load_result = True
lordcrc@384
   819
            else:
lordcrc@384
   820
                bintype = "luxrender"
lordcrc@384
   821
               
lordcrc@384
   822
            print("pipe: using %s" % bintype)
lordcrc@384
   823
                
lordcrc@384
   824
            self.p = get_lux_pipe(scn, 1, bintype)
lordcrc@384
   825
            self.f = self.p.stdin
lordcrc@384
   826
        def close(self):
lordcrc@384
   827
            global render_status_text
lordcrc@384
   828
            global render_status
lordcrc@384
   829
            render_status = True
lordcrc@384
   830
            render_status_text = "Rendering ..."
lordcrc@384
   831
            Blender.Window.QRedrawAll()
lordcrc@384
   832
            self.start()
lordcrc@384
   833
        
lordcrc@384
   834
        def run(self):
lordcrc@384
   835
            if self.load_result: self.data = self.p.communicate()[0]
lordcrc@384
   836
            self.f.close()
tom@397
   837
            if self.load_result: # self.load_image()
tom@397
   838
                self.load_data()
lordcrc@384
   839
            print("LuxRender process finished")
lordcrc@384
   840
            self.update_status()
lordcrc@384
   841
            
lordcrc@384
   842
        def load_image(self):
lordcrc@384
   843
            i = Blender.Image.Load(self.filename)
lordcrc@384
   844
            i.makeCurrent()
lordcrc@384
   845
            i.reload()
lordcrc@384
   846
           
lordcrc@384
   847
        def load_data(self):
lordcrc@384
   848
            print("processing %i image bytes" % len(self.data))
lordcrc@384
   849
            i = Blender.Image.New('luxrender', self.xr, self.yr, 32)
lordcrc@384
   850
            raw_image = []
lordcrc@384
   851
            for j in self.data:
lordcrc@384
   852
                raw_image.append(ord(j))
lordcrc@384
   853
            del self.data
lordcrc@384
   854
            bi = 0
lordcrc@384
   855
            for y in range(self.yr-1, -1, -1):
lordcrc@384
   856
                for x in range(0, self.xr):
lordcrc@384
   857
                    i.setPixelI(x,y, raw_image[bi:bi+3]+[0])
lordcrc@384
   858
                    bi+=3
lordcrc@384
   859
            i.makeCurrent()
lordcrc@384
   860
            
lordcrc@384
   861
        def update_status(self):
lordcrc@384
   862
            global render_status_text
lordcrc@384
   863
            global render_status
lordcrc@384
   864
            render_status = False
lordcrc@384
   865
            render_status_text = "Rendering complete"
dade@435
   866
            if self.haltspp > 0 or self.halttime > 0: render_status_text += ", check Image Editor window"
lordcrc@384
   867
            Blender.Window.QRedrawAll()
lordcrc@384
   868
            
lordcrc@384
   869
    use_pipe_output = luxProp(scn, "pipe", "false").get() == "true" and luxProp(scn, "run", "true").get() == "true"
lordcrc@384
   870
    
lordcrc@384
   871
    file = output_proxy()
lordcrc@384
   872
    
lordcrc@384
   873
    if luxProp(scn, "lxs", "true").get()=="true" or use_pipe_output:
lordcrc@384
   874
        ##### Determine/open files
lordcrc@384
   875
        if use_pipe_output:
lordcrc@384
   876
            print("using pipe output")
lordcrc@384
   877
            print("Exporting scene to pipe")
lordcrc@384
   878
            xr,yr = get_render_resolution(scn)
lordcrc@384
   879
            file = pipe_output(xr, yr,
lordcrc@384
   880
                luxProp(scn, "haltspp", 0).get(),
dade@435
   881
                luxProp(scn, "halttime", 0).get(),
lordcrc@384
   882
                os.path.join(filepath, filebase + ".png")
lordcrc@384
   883
            )
lordcrc@384
   884
        else:
lordcrc@384
   885
            print("using file output")
lordcrc@384
   886
            print("Exporting scene to '" + filename + "'...\n")
lordcrc@384
   887
            file = file_output(filename)
lordcrc@384
   888
lordcrc@384
   889
        ##### Write Header ######
dade@423
   890
        file.write("# Lux Render v%s Scene File\n"%__version__)
lordcrc@384
   891
        file.write("# Exported by LuxBlend Blender Exporter\n")
lordcrc@384
   892
        file.write("\n")
lordcrc@384
   893
    
lordcrc@384
   894
        ##### Write camera ######
lordcrc@384
   895
        camObj = scn.getCurrentCamera()
lordcrc@384
   896
lordcrc@384
   897
        if LuxIsGUI: DrawProgressBar(1.0/export_total_steps,'Exporting Camera')
lordcrc@384
   898
        if camObj:
lordcrc@384
   899
            print("processing Camera...")
lordcrc@384
   900
            cam = camObj.data
lordcrc@384
   901
            cammblur = luxProp(cam, "cammblur", "true")
lordcrc@384
   902
            usemblur = luxProp(cam, "usemblur", "false")
lordcrc@384
   903
lordcrc@384
   904
            matrix = camObj.getMatrix()
lordcrc@384
   905
lordcrc@384
   906
            motion = None
lordcrc@384
   907
            if(cammblur.get() == "true" and usemblur.get() == "true"):
lordcrc@384
   908
                # motion blur
lordcrc@384
   909
                frame = Blender.Get('curframe')
lordcrc@384
   910
                Blender.Set('curframe', frame+1)
lordcrc@384
   911
                m1 = 1.0*matrix # multiply by 1.0 to get a copy of original matrix (will be frame-independant) 
lordcrc@384
   912
                Blender.Set('curframe', frame)
lordcrc@384
   913
                if m1 != matrix:
lordcrc@384
   914
                    # Motion detected, write endtransform
lordcrc@384
   915
                    print("  motion blur")
lordcrc@384
   916
                    motion = m1
lordcrc@384
   917
                    pos = m1[3]
lordcrc@384
   918
                    forwards = -m1[2]
lordcrc@384
   919
                    target = pos + forwards
lordcrc@384
   920
                    up = m1[1]
lordcrc@384
   921
                    file.write("TransformBegin\n")
lordcrc@384
   922
                    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
   923
                    file.write("   CoordinateSystem \"CameraEndTransform\"\n")
lordcrc@384
   924
                    file.write("TransformEnd\n\n")
lordcrc@384
   925
lordcrc@384
   926
            # Write original lookat transform
lordcrc@384
   927
            pos = matrix[3]
lordcrc@384
   928
            forwards = -matrix[2]
lordcrc@384
   929
            target = pos + forwards
lordcrc@384
   930
            up = matrix[1]
lordcrc@384
   931
            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
   932
            file.write(luxCamera(camObj.data, scn.getRenderingContext()))
lordcrc@384
   933
            if motion:
lordcrc@384
   934
                file.write("\n   \"string endtransform\" [\"CameraEndTransform\"]")
lordcrc@384
   935
            file.write("\n")
lordcrc@384
   936
        file.write("\n")
lordcrc@384
   937
    
lordcrc@384
   938
        if LuxIsGUI: DrawProgressBar(2.0/export_total_steps,'Exporting Film Settings')
lordcrc@384
   939
        ##### Write film ######
lordcrc@384
   940
        file.write(luxFilm(scn))
lordcrc@384
   941
        file.write("\n")
lordcrc@384
   942
lordcrc@384
   943
        if LuxIsGUI: DrawProgressBar(3.0/export_total_steps,'Exporting Pixel Filter')
lordcrc@384
   944
        ##### Write Pixel Filter ######
lordcrc@384
   945
        file.write(luxPixelFilter(scn))
lordcrc@384
   946
        file.write("\n")
lordcrc@384
   947
    
lordcrc@384
   948
        if LuxIsGUI: DrawProgressBar(4.0/export_total_steps,'Exporting Sampler')
lordcrc@384
   949
        ##### Write Sampler ######
lordcrc@384
   950
        file.write(luxSampler(scn))
lordcrc@384
   951
        file.write("\n")
lordcrc@384
   952
    
lordcrc@384
   953
        if LuxIsGUI: DrawProgressBar(5.0/export_total_steps,'Exporting Surface Integrator')
lordcrc@384
   954
        ##### Write Surface Integrator ######
lordcrc@384
   955
        file.write(luxSurfaceIntegrator(scn))
lordcrc@384
   956
        file.write("\n")
lordcrc@384
   957
        
lordcrc@384
   958
        if LuxIsGUI: DrawProgressBar(6.0/export_total_steps,'Exporting Volume Integrator')
lordcrc@384
   959
        ##### Write Volume Integrator ######
lordcrc@384
   960
        file.write(luxVolumeIntegrator(scn))
lordcrc@384
   961
        file.write("\n")
lordcrc@384
   962
        
lordcrc@384
   963
        if LuxIsGUI: DrawProgressBar(7.0/export_total_steps,'Exporting Accelerator')
lordcrc@384
   964
        ##### Write Acceleration ######
lordcrc@384
   965
        file.write(luxAccelerator(scn))
lordcrc@384
   966
        file.write("\n")    
lordcrc@384
   967
    
lordcrc@384
   968
        ########## BEGIN World
lordcrc@384
   969
        file.write("\n")
lordcrc@384
   970
        file.write("WorldBegin\n")
lordcrc@384
   971
        file.write("\n")
lordcrc@384
   972
lordcrc@384
   973
        ########## World scale
lordcrc@384
   974
        #scale = luxProp(scn, "global.scale", 1.0).get()
lordcrc@384
   975
        #if scale != 1.0:
lordcrc@384
   976
        #    # TODO: not working yet !!!
lordcrc@384
   977
        #    # TODO: propabily scale needs to be applyed on camera coords too 
lordcrc@384
   978
        #    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
   979
        #    file.write("\n")
lordcrc@384
   980
        
lordcrc@384
   981
        if LuxIsGUI: DrawProgressBar(8.0/export_total_steps,'Exporting Environment')
lordcrc@384
   982
        ##### Write World Background, Sunsky or Env map ######
lordcrc@384
   983
        env = luxEnvironment(scn)
lordcrc@384
   984
        if env != "":
lordcrc@384
   985
            file.write("AttributeBegin\n")
lordcrc@384
   986
            file.write(env)
lordcrc@384
   987
            export.exportPortals(file)
lordcrc@384
   988
            file.write("AttributeEnd\n")
lordcrc@384
   989
            file.write("\n")    
lordcrc@384
   990
lordcrc@384
   991
    # Note - radiance - this is a work in progress
lordcrc@384
   992
#        flash = luxFlashBlock(camObj)
lordcrc@384
   993
#        if flash != "":
lordcrc@384
   994
#            file.write("# Camera flash lamp\n")
lordcrc@384
   995
#            file.write("AttributeBegin\n")
lordcrc@384
   996
#            #file.write("CoordSysTransform \"camera\"\n")
lordcrc@384
   997
#            file.write(flash)
lordcrc@384
   998
#            file.write("AttributeEnd\n\n")
lordcrc@384
   999
lordcrc@384
  1000
        #### Write material & geometry file includes in scene file
lordcrc@384
  1001
        if not file.combine_all_output: file.write("Include \"%s\"\n\n" %(mat_pfilename))
lordcrc@384
  1002
        if not file.combine_all_output: file.write("Include \"%s\"\n\n" %(geom_pfilename))
lordcrc@384
  1003
        if not file.combine_all_output: file.write("Include \"%s\"\n\n" %(vol_pfilename))
lordcrc@384
  1004
        
lordcrc@384
  1005
    if luxProp(scn, "lxm", "true").get()=="true" or use_pipe_output:
lordcrc@384
  1006
        if LuxIsGUI: DrawProgressBar(9.0/export_total_steps,'Exporting Materials')
lordcrc@384
  1007
        ##### Write Material file #####
lordcrc@384
  1008
        if not file.combine_all_output: print("Exporting materials to '" + mat_filename + "'...\n")
lordcrc@384
  1009
        mat_file = open(mat_filename, 'w') if not file.combine_all_output else file
lordcrc@384
  1010
        mat_file.write("")
lordcrc@384
  1011
        export.exportMaterials(mat_file)
lordcrc@384
  1012
        mat_file.write("")
lordcrc@384
  1013
        if not file.combine_all_output: mat_file.close()
lordcrc@384
  1014
    
lordcrc@384
  1015
    if luxProp(scn, "lxo", "true").get()=="true" or use_pipe_output:
lordcrc@384
  1016
        if LuxIsGUI: DrawProgressBar(10.0/export_total_steps,'Exporting Geometry')
lordcrc@384
  1017
        ##### Write Geometry file #####
lordcrc@384
  1018
        if not file.combine_all_output: print("Exporting geometry to '" + geom_filename + "'...\n")
lordcrc@384
  1019
        geom_file = open(geom_filename, 'w') if not file.combine_all_output else file
lordcrc@384
  1020
        meshlist = []
lordcrc@384
  1021
        geom_file.write("")
lordcrc@384
  1022
        export.exportLights(geom_file)
lordcrc@384
  1023
        export.exportMeshes(geom_file)
lordcrc@384
  1024
        export.exportObjects(geom_file)
lordcrc@384
  1025
        geom_file.write("")
lordcrc@384
  1026
        if not file.combine_all_output: geom_file.close()
lordcrc@384
  1027
lordcrc@384
  1028
    if luxProp(scn, "lxv", "true").get()=="true" or use_pipe_output:
lordcrc@384
  1029
        if LuxIsGUI: DrawProgressBar(11.0/export_total_steps,'Exporting Volumes')
lordcrc@384
  1030
        ##### Write Volume file #####
lordcrc@384
  1031
        if not file.combine_all_output: print("Exporting volumes to '" + vol_filename + "'...\n")
lordcrc@384
  1032
        vol_file = open(vol_filename, 'w') if not file.combine_all_output else file
lordcrc@384
  1033
        meshlist = []
lordcrc@384
  1034
        vol_file.write("")
lordcrc@384
  1035
        export.exportVolumes(vol_file)
lordcrc@384
  1036
        vol_file.write("")
lordcrc@384
  1037
        if not file.combine_all_output: vol_file.close()
lordcrc@384
  1038
lordcrc@384
  1039
    render_status_text = ''
lordcrc@384
  1040
    render_status = False
lordcrc@384
  1041
    Blender.Window.QRedrawAll()
lordcrc@384
  1042
lordcrc@384
  1043
    if luxProp(scn, "lxs", "true").get()=="true" or use_pipe_output:
lordcrc@384
  1044
        #### Write End Tag
lordcrc@384
  1045
        file.write("WorldEnd\n\n")
lordcrc@384
  1046
        file.close()
lordcrc@384
  1047
lordcrc@384
  1048
    if LuxIsGUI: DrawProgressBar(12.0/export_total_steps,'Export Finished')
lordcrc@384
  1049
    print("Finished.\n")
lordcrc@384
  1050
    del export
lordcrc@384
  1051
    
lordcrc@384
  1052
    time2 = Blender.sys.time()
lordcrc@384
  1053
    print("Processing time: %f\n" %(time2-time1))
tom@397
  1054
tom@397
  1055
    if use_pipe_output:
doug@403
  1056
        #if luxProp(scn, "haltspp", 0).get() > 0:
tom@397
  1057
            # Wait for piped luxconsole render thread to end
doug@403
  1058
        file.join()
tom@397
  1059
tom@397
  1060
        # Don't launch it again as a piped scene is started implicitly
tom@397
  1061
        return False
tom@397
  1062
lordcrc@384
  1063
    return True
lordcrc@384
  1064
lordcrc@384
  1065
########################################################################
lordcrc@384
  1066
####  Construct server string argument
lordcrc@384
  1067
########################################################################
lordcrc@384
  1068
lordcrc@384
  1069
def networkstring(scn):
lordcrc@384
  1070
    servers_string = ""
lordcrc@384
  1071
    if  (luxProp(scn,"network","false").get() == "true"):
lordcrc@384
  1072
        if (luxProp(scn,"network_use_file","false").get() == "true"):
lordcrc@384
  1073
            print("read network servers from file: "+ luxProp(scn,"network_file_path","false").get())
lordcrc@384
  1074
            f = open(luxProp(scn,"network_file_path","false").get())
lordcrc@384
  1075
            for s in f:
lordcrc@384
  1076
                s = s.strip("\n")
lordcrc@384
  1077
                print("add server :" + s)
lordcrc@384
  1078
                servers_string=servers_string+" -u "+ s
lordcrc@384
  1079
            f.close
lordcrc@384
  1080
        else : 
lordcrc@384
  1081
             if  luxProp(scn,"network_servers","").get():
lordcrc@384
  1082
                 for server in luxProp(scn,"network_servers","").get().split(","):
lordcrc@384
  1083
                    servers_string=servers_string+" -u "+ server
lordcrc@384
  1084
    return servers_string
lordcrc@384
  1085
lordcrc@384
  1086
lordcrc@384
  1087
#########################################################################
lordcrc@384
  1088
###     LAUNCH LuxRender AND RENDER CURRENT SCENE
lordcrc@384
  1089
#########################################################################
lordcrc@384
  1090
lordcrc@384
  1091
def get_lux_exec(scn, type="luxrender"):
lordcrc@384
  1092
    
lordcrc@384
  1093
    #get blenders 'bpydata' directory
lordcrc@384
  1094
    datadir=Blender.Get("datadir")
lordcrc@384
  1095
    
lordcrc@384
  1096
    ic = luxProp(scn, "lux", "").get()
lordcrc@384
  1097
    ic = Blender.sys.dirname(ic) + os.sep + type
lordcrc@384
  1098
    
lordcrc@384
  1099
    if osys.platform == "win32": ic = ic + ".exe"
lordcrc@384
  1100
    
lordcrc@384
  1101
    if type=="luxrender" and osys.platform == "darwin": ic = ic + ".app/Contents/MacOS/luxrender"
lordcrc@384
  1102
    
lordcrc@384
  1103
    return ic
lordcrc@384
  1104
    
tom@396
  1105
def get_lux_args(filename, extra_args=[], anim=False):
lordcrc@384
  1106
    ostype = osys.platform
lordcrc@384
  1107
    scn = Scene.GetCurrent()
tom@396
  1108
    
tom@396
  1109
    ic = get_lux_exec(scn, type=(anim and 'luxconsole' or 'luxrender'))
lordcrc@384
  1110
    
lordcrc@384
  1111
    servers_string = networkstring(scn)
lordcrc@384
  1112
    update_int=luxProp(scn,"newtork_interval",180).get()
lordcrc@384
  1113
    
lordcrc@384
  1114
    checkluxpath = luxProp(scn, "checkluxpath", True).get()
lordcrc@384
  1115
    if checkluxpath:
lordcrc@384
  1116
        if sys.exists(ic) != 1:
lordcrc@384
  1117
            Draw.PupMenu("Error: Lux renderer not found. Please set path on System page.%t|OK")
lordcrc@384
  1118
            return
lordcrc@384
  1119
    autothreads = luxProp(scn, "autothreads", "true").get()
lordcrc@384
  1120
    threads = luxProp(scn, "threads", 1).get()
lordcrc@384
  1121
    luxnice = luxProp(scn, "luxnice", 0).get()
lordcrc@384
  1122
    noopengl = luxProp(scn, "noopengl", "false").get()
lordcrc@384
  1123
    
jeanphi@439
  1124
    if noopengl == "true" and not anim:
lordcrc@384
  1125
        extra_args.append("--noopengl")
lordcrc@384
  1126
    
lordcrc@384
  1127
    lux_args = "\"%s\" " % ic
lordcrc@384
  1128
    
lordcrc@384
  1129
    extra_args.append('%s'%servers_string)
lordcrc@384
  1130
    extra_args.append("-i %d " % update_int)
lordcrc@384
  1131
    
lordcrc@384
  1132
    if autothreads != "true":
lordcrc@384
  1133
        extra_args.append("--threads=%d " % threads)
lordcrc@384
  1134
    
lordcrc@384
  1135
    lux_args2 = ' '.join(extra_args)
lordcrc@384
  1136
    
lordcrc@384
  1137
    if filename == '-':
lordcrc@384
  1138
        lux_args2 = " - " + lux_args2
lordcrc@384
  1139
    else:
lordcrc@384
  1140
        filename = "\"%s\"" % filename
lordcrc@384
  1141
        lux_args2 = lux_args2 + filename
lordcrc@384
  1142
        
lordcrc@384
  1143
    lux_args += lux_args2
lordcrc@384
  1144
    
lordcrc@384
  1145
    if ostype == "win32":
lordcrc@384
  1146
        prio = ""
lordcrc@384
  1147
        if luxnice > 15: prio = "/low"
lordcrc@384
  1148
        elif luxnice > 5: prio = "/belownormal"
lordcrc@384
  1149
        elif luxnice > -5: prio = "/normal"
lordcrc@384
  1150
        elif luxnice > -15: prio = "/abovenormal"
lordcrc@384
  1151
        else: prio = "/high"
lordcrc@384
  1152
        
doug@401
  1153
        if not anim:
doug@401
  1154
            cmd = "start /b %s \"\" %s" % (prio, lux_args)
doug@401
  1155
        else:
doug@401
  1156
            cmd = "start /WAIT %s \"\" %s" % (prio, lux_args)
lordcrc@384
  1157
        
jensverwiebe@394
  1158
#    if ostype == "linux2" or ostype == "darwin":
jensverwiebe@394
  1159
    else:
tom@396
  1160
        if not anim:
tom@396
  1161
            cmd = "(nice -n %d %s)&"%(luxnice, lux_args)
tom@396
  1162
        else:
tom@396
  1163
            cmd = "(nice -n %d %s)"%(luxnice, lux_args)
lordcrc@384
  1164
    
lordcrc@384
  1165
    return cmd, lux_args2
lordcrc@384
  1166
lordcrc@384
  1167
def get_lux_pipe(scn, buf = 1024, type="luxconsole"):
lordcrc@384
  1168
    bin = "\"%s\"" % get_lux_exec(scn, type)
lordcrc@384
  1169
    
lordcrc@384
  1170
    print("piping to lux binary: " + bin)
lordcrc@384
  1171
    
lordcrc@384
  1172
    PIPE = subprocess.PIPE
lordcrc@384
  1173
    
lordcrc@384
  1174
    cmd, raw_args = get_lux_args('-',
lordcrc@384
  1175
        extra_args=['-b'] if type=="luxconsole" else []
lordcrc@384
  1176
    )
lordcrc@384
  1177
    
jeanphi@439
  1178
    # dirty hack to filter "noopengl" option from luxconsole args
jeanphi@439
  1179
    raw_args = raw_args.replace('--noopengl', '')
jeanphi@439
  1180
lordcrc@384
  1181
    return subprocess.Popen(bin + raw_args, shell=True, bufsize=buf, stdin=PIPE, stdout=PIPE, stderr=PIPE)
lordcrc@384
  1182
lordcrc@384
  1183
def launchLux(filename):
lordcrc@384
  1184
    cmd, raw_args = get_lux_args(filename, extra_args=[])
lordcrc@384
  1185
    print("Running Luxrender:\n"+cmd)
lordcrc@384
  1186
    os.system(cmd)
lordcrc@384
  1187
tom@396
  1188
def launchLuxWait(filename, anim=False):
jensverwiebe@393
  1189
    ostype = osys.platform
tom@396
  1190
    cmd, raw_args = get_lux_args(filename, extra_args=[], anim=anim)
lordcrc@384
  1191
    
lordcrc@384
  1192
    if ostype == "win32":
lordcrc@384
  1193
        os.system(cmd)
lordcrc@384
  1194
    
jensverwiebe@394
  1195
#    if ostype == "linux2" or ostype == "darwin":
jensverwiebe@394
  1196
    else:
lordcrc@384
  1197
        subprocess.call(cmd,shell=True)
lordcrc@384
  1198
doug@402
  1199
#### SAVE ANIMATION ####
doug@402
  1200
doug@402
  1201
doug@404
  1202
#def save_anim(filename):
doug@404
  1203
#    global LuxIsGUI
doug@404
  1204
#    scn = Scene.GetCurrent()
doug@404
  1205
#    to = luxProp(scn, 'export.threaded', 'true').get()
doug@404
  1206
#    run = luxProp(scn, "run", "true").get()
doug@404
  1207
#    deflt = luxProp(scn, "default", "true").get()
doug@404
  1208
#    if to == 'true' and run == 'true' and deflt == 'false':
doug@404
  1209
#        import threading
doug@404
  1210
#        anim_thread = threading.Thread(target=save_anim_real, args=(filename,True))
doug@404
  1211
#        anim_thread.start()
doug@404
  1212
#    else:
doug@404
  1213
#        save_anim_real(filename)
doug@404
  1214
doug@404
  1215
def save_anim(filename, as_thread=False):
doug@403
  1216
    if as_thread: print('SAR thread started')
doug@403
  1217
    global MatSaved, LuxIsGUI
lordcrc@384
  1218
    
lordcrc@384
  1219
    MatSaved = 0
lordcrc@384
  1220
    startF = Blender.Get('staframe')
lordcrc@384
  1221
    endF = Blender.Get('endframe')
lordcrc@384
  1222
    scn = Scene.GetCurrent()
lordcrc@384
  1223
lordcrc@384
  1224
    Run = luxProp(scn, "run", "true").get()
lordcrc@384
  1225
tom@397
  1226
    if Run == "true":
tom@397
  1227
        haltspp = luxProp(scn, "haltspp", 0).get()
dade@435
  1228
        halttime = luxProp(scn, "halttime", 0).get()
dade@435
  1229
        if haltspp == 0 and halttime == 0:
dade@435
  1230
            Draw.PupMenu("ERROR: You must set a limit for spp (Output->halt) or for time (Output->time) when doing animation and the 'run' flag is switched on")
tom@397
  1231
            if LuxIsGUI:
tom@397
  1232
                Draw.Redraw()
tom@397
  1233
            return
tom@397
  1234
lordcrc@384
  1235
    print("\n\nRendering animation (frame %i to %i)\n\n"%(startF, endF))
lordcrc@384
  1236
doug@403
  1237
    v_frame = Blender.Get('curframe')
doug@403
  1238
lordcrc@384
  1239
    for i in range (startF, endF+1):
doug@403
  1240
        # Seems to get stuck unless we redraw the UI
doug@404
  1241
#        if LuxIsGUI:
doug@404
  1242
#            Window.QRedrawAll()
lordcrc@384
  1243
        Blender.Set('curframe', i)
lordcrc@384
  1244
        print("Rendering frame %i"%(i))
lordcrc@384
  1245
        Blender.Redraw()
lordcrc@384
  1246
        frameindex = ("-%05d" % (i)) + ".lxs"
lordcrc@384
  1247
        indexedname = sys.makename(filename, frameindex)
lordcrc@384
  1248
        unindexedname = filename
lordcrc@384
  1249
        luxProp(scn, "filename", Blender.Get("filename")).set(sys.makename(filename, "-%05d" %  (Blender.Get('curframe'))))
lordcrc@384
  1250
lordcrc@384
  1251
        if Run == "true":
lordcrc@384
  1252
            if save_lux(filename, unindexedname):
tom@396
  1253
                launchLuxWait(filename, anim=True)
lordcrc@384
  1254
        else:
lordcrc@384
  1255
            save_lux(indexedname, unindexedname)
lordcrc@384
  1256
lordcrc@384
  1257
        MatSaved = 1
doug@403
  1258
        # Seems to get stuck unless we redraw the UI
doug@404
  1259
#        if LuxIsGUI:
doug@404
  1260
#            Window.QRedrawAll()
doug@403
  1261
            
doug@403
  1262
    Blender.Set('curframe', v_frame)
lordcrc@384
  1263
lordcrc@384
  1264
    print("\n\nFinished Rendering animation\n")
doug@403
  1265
    if as_thread: print('SAR thread finished')
lordcrc@384
  1266
lordcrc@384
  1267
#### SAVE STILL (hackish...) ####
doug@402
  1268
doug@404
  1269
#import threading
doug@404
  1270
#def save_still(filename):
doug@404
  1271
#    global LuxIsGUI
doug@404
  1272
#    scn = Scene.GetCurrent()
doug@404
  1273
#    to = luxProp(scn, 'export.threaded', 'true').get()
doug@404
  1274
#    if to == 'true' and luxProp(scn, "run", "true").get() == "true":
doug@404
  1275
#        import threading
doug@404
  1276
#        still_thread = threading.Thread(target=save_still_real, args=(filename,))
doug@404
  1277
#        still_thread.start()
doug@404
  1278
#    else:
doug@404
  1279
#        save_still_real(filename)
doug@404
  1280
lordcrc@384
  1281
def save_still(filename):
doug@403
  1282
    global MatSaved, runRenderAfterExport
lordcrc@384
  1283
    scn = Scene.GetCurrent()
lordcrc@384
  1284
    luxProp(scn, "filename", Blender.Get("filename")).set(sys.makename(filename, ""))
lordcrc@384
  1285
    MatSaved = 0
lordcrc@384
  1286
    unindexedname = filename
doug@403
  1287
    # Seems to get stuck unless we redraw the UI
doug@404
  1288
#    if LuxIsGUI:
doug@404
  1289
#        Window.QRedrawAll()
lordcrc@384
  1290
    if save_lux(filename, unindexedname):
lordcrc@384
  1291
        if runRenderAfterExport and luxProp(scn, "pipe", "false").get() == "false": #(run == None and luxProp(scn, "run", "true").get() == "true") or run:
lordcrc@384
  1292
            launchLux(filename)
doug@403
  1293
            
doug@403
  1294
    # Seems to get stuck unless we redraw the UI
doug@404
  1295
#    if LuxIsGUI:
doug@404
  1296
#        Window.QRedrawAll()
lordcrc@384
  1297
lordcrc@384
  1298
lordcrc@384
  1299
######################################################
lordcrc@384
  1300
# Icons
lordcrc@384
  1301
######################################################
lordcrc@384
  1302
lordcrc@384
  1303
def base64value(char):
lordcrc@384
  1304
    if 64 < ord(char) < 91: return ord(char)-65
lordcrc@384
  1305
    if 96 < ord(char) < 123: return ord(char)-97+26
lordcrc@384
  1306
    if 47 < ord(char) < 58: return ord(char)-48+52
lordcrc@384
  1307
    if char == '+': return 62
lordcrc@384
  1308
    return 63
lordcrc@384
  1309
lordcrc@384
  1310
def decodeIconStr(s):
lordcrc@384
  1311
    buf = BGL.Buffer(BGL.GL_BYTE, [16,16,4])
lordcrc@384
  1312
    offset = 0
lordcrc@384
  1313
    for y in range(16):
lordcrc@384
  1314
        for x in range(16):
lordcrc@384
  1315
            for c in range(4):
lordcrc@384
  1316
                buf[y][x][c] = int(base64value(s[offset])*4.048)
lordcrc@384
  1317
                offset += 1
lordcrc@384
  1318
    return buf
lordcrc@384
  1319
lordcrc@384
  1320
def decodeLogoStr(s):
lordcrc@384
  1321
    buf = BGL.Buffer(BGL.GL_BYTE, [18,118,4])
lordcrc@384
  1322
    offset = 0
lordcrc@384
  1323
    for y in range(18):
lordcrc@384
  1324
        for x in range(118):
lordcrc@384
  1325
            for c in range(4):
lordcrc@384
  1326
                buf[y][x][c] = int(base64value(s[offset])*4.048)
lordcrc@384
  1327
                offset += 1
lordcrc@384
  1328
    return buf
lordcrc@384
  1329
lordcrc@384
  1330
def decodeArrowStr(s):
lordcrc@384
  1331
    buf = BGL.Buffer(BGL.GL_BYTE, [22,22,4])
lordcrc@384
  1332
    offset = 0
lordcrc@384
  1333
    for y in range(22):
lordcrc@384
  1334
        for x in range(22):
lordcrc@384
  1335
            for c in range(4):
lordcrc@384
  1336
                buf[y][x][c] = int(base64value(s[offset])*4.048)
lordcrc@384
  1337
                offset += 1
lordcrc@384
  1338
    return buf
lordcrc@384
  1339
lordcrc@384
  1340
def decodeBarStr(s):
lordcrc@384
  1341
    buf = BGL.Buffer(BGL.GL_BYTE, [17,138,4])
lordcrc@384
  1342
    offset = 0
lordcrc@384
  1343
    for y in range(17):
lordcrc@384
  1344
        for x in range(138):
lordcrc@384
  1345
            for c in range(4):
lordcrc@384
  1346
                buf[y][x][c] = int(base64value(s[offset])*4.048)
lordcrc@384
  1347
                offset += 1
lordcrc@384
  1348
    return buf
lordcrc@384
  1349
lordcrc@384
  1350
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
  1351
lordcrc@384
  1352
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
  1353
lordcrc@384
  1354
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
  1355
lordcrc@384
  1356
lordcrc@384
  1357
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
  1358
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
  1359
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
  1360
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
  1361
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
  1362
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
  1363
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
  1364
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
  1365
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
  1366
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
  1367
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
  1368
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
  1369
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
  1370
lordcrc@384
  1371
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
  1372
lordcrc@384
  1373
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
  1374
lordcrc@384
  1375
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
  1376
lordcrc@384
  1377
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
  1378
lordcrc@384
  1379
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
  1380
lordcrc@384
  1381
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
  1382
lordcrc@384
  1383
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
  1384
lordcrc@384
  1385
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
  1386
lordcrc@384
  1387
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
  1388
lordcrc@384
  1389
lordcrc@384
  1390
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
  1391
lordcrc@384
  1392
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
  1393
lordcrc@384
  1394
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
  1395
lordcrc@384
  1396
def drawIcon(icon, x, y):
lordcrc@384
  1397
    BGL.glEnable(BGL.GL_BLEND)
lordcrc@384
  1398
    BGL.glBlendFunc(BGL.GL_SRC_ALPHA, BGL.GL_ONE_MINUS_SRC_ALPHA) 
lordcrc@384
  1399
    BGL.glRasterPos2f(int(x)+0.5, int(y)+0.5)
lordcrc@384
  1400
    BGL.glDrawPixels(16, 16, BGL.GL_RGBA, BGL.GL_UNSIGNED_BYTE, icon)
lordcrc@384
  1401
    BGL.glDisable(BGL.GL_BLEND)
lordcrc@384
  1402
lordcrc@384
  1403
def drawArrow(icon, x, y):
lordcrc@384
  1404
    BGL.glEnable(BGL.GL_BLEND)
lordcrc@384
  1405
    BGL.glBlendFunc(BGL.GL_SRC_ALPHA, BGL.GL_ONE_MINUS_SRC_ALPHA) 
lordcrc@384
  1406
    BGL.glRasterPos2f(int(x)+0.5, int(y)+0.5)
lordcrc@384
  1407
    BGL.glDrawPixels(22, 22, BGL.GL_RGBA, BGL.GL_UNSIGNED_BYTE, icon)
lordcrc@384
  1408
    BGL.glDisable(BGL.GL_BLEND)
lordcrc@384
  1409
lordcrc@384
  1410
def drawLogo(icon, x, y):
lordcrc@384
  1411
    BGL.glEnable(BGL.GL_BLEND)
lordcrc@384
  1412
    BGL.glBlendFunc(BGL.GL_SRC_ALPHA, BGL.GL_ONE_MINUS_SRC_ALPHA) 
lordcrc@384
  1413
    BGL.glRasterPos2f(int(x)+0.5, int(y)+0.5)
lordcrc@384
  1414
    BGL.glDrawPixels(118, 18, BGL.GL_RGBA, BGL.GL_UNSIGNED_BYTE, icon)
lordcrc@384
  1415
    BGL.glDisable(BGL.GL_BLEND)
lordcrc@384
  1416
lordcrc@384
  1417
def drawBar(icon, x, y):
lordcrc@384
  1418
    BGL.glEnable(BGL.GL_BLEND)
lordcrc@384
  1419
    BGL.glBlendFunc(BGL.GL_SRC_ALPHA, BGL.GL_ONE_MINUS_SRC_ALPHA) 
lordcrc@384
  1420
    BGL.glRasterPos2f(int(x)+0.5, int(y)+0.5)
lordcrc@384
  1421
    BGL.glDrawPixels(138, 17, BGL.GL_RGBA, BGL.GL_UNSIGNED_BYTE, icon)
lordcrc@384
  1422
    BGL.glDisable(BGL.GL_BLEND)
lordcrc@384
  1423
lordcrc@384
  1424
lordcrc@384
  1425
lordcrc@384
  1426
#-------------------------------------------------
lordcrc@384
  1427
# luxImage()
lordcrc@384
  1428
# helper class to handle images and icons for the GUI
lordcrc@384
  1429
#-------------------------------------------------
lordcrc@384
  1430
lordcrc@384
  1431
class luxImage:
lordcrc@384
  1432
    def resize(self, width, height):
lordcrc@384
  1433
        self.width = width
lordcrc@384
  1434
        self.height = height
lordcrc@384
  1435
        self.buf = BGL.Buffer(BGL.GL_BYTE, [width,height,4]) # GL buffer
lordcrc@384
  1436
    def __init__(self, width=0, height=0):
lordcrc@384
  1437
        self.resize(width, height)
lordcrc@384
  1438
    def draw(self, x, y):
lordcrc@384
  1439
        BGL.glEnable(BGL.GL_BLEND)
lordcrc@384
  1440
        BGL.glBlendFunc(BGL.GL_SRC_ALPHA, BGL.GL_ONE_MINUS_SRC_ALPHA) 
lordcrc@384
  1441
        BGL.glRasterPos2f(int(x)+0.5, int(y)+0.5)
lordcrc@384
  1442
        BGL.glDrawPixels(self.width, self.height, BGL.GL_RGBA, BGL.GL_UNSIGNED_BYTE, self.buf)
lordcrc@384
  1443
        BGL.glDisable(BGL.GL_BLEND)        
lordcrc@384
  1444
    def decodeStr(self, width, height, s):
lordcrc@384
  1445
        self.resize(width, height)
lordcrc@384
  1446
        offset = 0
lordcrc@384
  1447
        for y in range(self.height):
lordcrc@384
  1448
            for x in range(self.width):
lordcrc@384
  1449
                for c in range(4):
lordcrc@384
  1450
                    self.buf[y][x][c] = int(base64value(s[offset])*4.048)
lordcrc@384
  1451
                    offset += 1
lordcrc@384
  1452
lordcrc@384
  1453
    def decodeLuxConsole(self, width, height, data):
lordcrc@384
  1454
        self.resize(width, height)
lordcrc@384
  1455
        offset = 0
lordcrc@384
  1456
        for y in range(self.height-1,-1,-1):
lordcrc@384
  1457
            for x in range(self.width):
lordcrc@384
  1458
                for c in range(3):
lordcrc@384
  1459
                    self.buf[y][x][c] = ord(data[offset])
lordcrc@384
  1460
                    offset += 1
lordcrc@384
  1461
                self.buf[y][x][3] = 255
lordcrc@384
  1462
lordcrc@384
  1463
lordcrc@384
  1464
previewCache = {}  # dictionary that will hold all preview images
lordcrc@384
  1465
lordcrc@384
  1466
lordcrc@384
  1467
######################################################
lordcrc@384
  1468
# New GUI by Zuegs
lordcrc@384
  1469
######################################################
lordcrc@384
  1470
lordcrc@384
  1471
from types import *
lordcrc@384
  1472
lordcrc@384
  1473
evtLuxGui = 99
lordcrc@384
  1474
evtSavePreset = 98
lordcrc@384
  1475
evtDeletePreset = 97
lordcrc@384
  1476
evtSaveMaterial = 96
lordcrc@384
  1477
evtLoadMaterial = 95
lordcrc@384
  1478
evtDeleteMaterial = 94
lordcrc@384
  1479
evtConvertMaterial = 92
lordcrc@384
  1480
evtSaveMaterial2 = 91
lordcrc@384
  1481
evtLoadMaterial2 = 90
lordcrc@384
  1482
lordcrc@384
  1483
lordcrc@384
  1484
# default settings
lordcrc@384
  1485
defaultsExclude = ['preset','filename','page','link']
lordcrc@384
  1486
try:
lordcrc@384
  1487
    luxdefaults = Blender.Registry.GetKey('luxblend', True)
lordcrc@384
  1488
    if not(type(luxdefaults) is DictType):
lordcrc@384
  1489
        luxdefaults = {}
lordcrc@384
  1490
except:
lordcrc@384
  1491
    luxdefaults = {}
lordcrc@384
  1492
newluxdefaults = luxdefaults.copy()
lordcrc@384
  1493
lordcrc@384
  1494
lordcrc@384
  1495
def saveluxdefaults():
lordcrc@384
  1496
    try: del newluxdefaults['page']
lordcrc@384
  1497
    except: pass
lordcrc@384
  1498
    try: Blender.Registry.SetKey('luxblend', newluxdefaults, True)
lordcrc@384
  1499
    except: pass
lordcrc@384
  1500
lordcrc@384
  1501
lordcrc@384
  1502
lordcrc@384
  1503
lordcrc@384
  1504
lordcrc@384
  1505
# *** PRESETS **************************************
lordcrc@384
  1506
presetsExclude = ['preset','lux','datadir','threads','filename','page','RGC','film.gamma','colorclamp','link']
lordcrc@384
  1507
def getPresets(key):
lordcrc@384
  1508
    presets = Blender.Registry.GetKey(key, True)
lordcrc@384
  1509
    if not(type(presets) is DictType):
lordcrc@384
  1510
        presets = {}
lordcrc@384
  1511
    return presets
lordcrc@384
  1512
def getScenePresets():
lordcrc@384
  1513
    presets = getPresets('luxblend_presets').copy()
lordcrc@384
  1514
lordcrc@384
  1515
    # radiance's hardcoded render presets:
lordcrc@384
  1516
jeanphi@443
  1517
    presets['0 Preview - Global Illumination'] = {
jeanphi@443
  1518
    'film.displayinterval': 4,
jeanphi@443
  1519
    'haltspp': 0,
jeanphi@443
  1520
    'halttime': 0,
jeanphi@443
  1521
    'useparamkeys': 'false',
jeanphi@443
  1522
    'sampler.showadvanced': 'false',
jeanphi@443
  1523
    'sintegrator.showadvanced': 'false',
jeanphi@443
  1524
    'pixelfilter.showadvanced': 'false',
jeanphi@443
  1525
jeanphi@443
  1526
    'sampler.type': 'lowdiscrepancy',
jeanphi@443
  1527
    'sampler.lowdisc.pixelsamples': 1,
jeanphi@443
  1528
    'sampler.lowdisc.pixelsampler': 'lowdiscrepancy',
jeanphi@443
  1529
jeanphi@443
  1530
    'sintegrator.type': 'distributedpath',
jeanphi@443
  1531
    'sintegrator.distributedpath.directsampleall': 'true',
jeanphi@443
  1532
    'sintegrator.distributedpath.directsamples': 1,
jeanphi@443
  1533
    'sintegrator.distributedpath.directdiffuse': 'true',
jeanphi@443
  1534
    'sintegrator.distributedpath.directglossy': 'true',
jeanphi@443
  1535
    'sintegrator.distributedpath.indirectsampleall': 'false',
jeanphi@443
  1536
    'sintegrator.distributedpath.indirectsamples': 1,
jeanphi@443
  1537
    'sintegrator.distributedpath.indirectdiffuse': 'true',
jeanphi@443
  1538
    'sintegrator.distributedpath.indirectglossy': 'true',
jeanphi@443
  1539
    'sintegrator.distributedpath.diffusereflectdepth': 1,
jeanphi@443
  1540
    'sintegrator.distributedpath.diffusereflectsamples': 4,
jeanphi@443
  1541
    'sintegrator.distributedpath.diffuserefractdepth': 4,
jeanphi@443
  1542
    'sintegrator.distributedpath.diffuserefractsamples': 1,
jeanphi@443
  1543
    'sintegrator.distributedpath.glossyreflectdepth': 1,
jeanphi@443
  1544
    'sintegrator.distributedpath.glossyreflectsamples': 2,
jeanphi@443
  1545
    'sintegrator.distributedpath.glossyrefractdepth': 4,
jeanphi@443
  1546
    'sintegrator.distributedpath.glossyrefractsamples': 1,
jeanphi@443
  1547
    'sintegrator.distributedpath.specularreflectdepth': 2,
jeanphi@443
  1548
    'sintegrator.distributedpath.specularrefractdepth': 4,
jeanphi@443
  1549
    'sintegrator.distributedpath.causticsonglossy': 'true',
jeanphi@443
  1550
    'sintegrator.distributedpath.causticsondiffuse': 'false',
jeanphi@443
  1551
    'sintegrator.distributedpath.strategy': 'auto',
jeanphi@443
  1552
jeanphi@443
  1553
    'pixelfilter.type': 'mitchell',
jeanphi@443
  1554
    'pixelfilter.mitchell.sharp': 0.250, 
jeanphi@443
  1555
    'pixelfilter.mitchell.xwidth': 2.0, 
jeanphi@443
  1556
    'pixelfilter.mitchell.ywidth': 2.0, 
jeanphi@443
  1557
    'pixelfilter.mitchell.optmode': "slider" }
jeanphi@443
  1558
jeanphi@443
  1559
    presets['0b Preview - Direct Lighting'] = {
lordcrc@384
  1560
    'film.displayinterval': 4,
lordcrc@384
  1561
    'haltspp': 0,
dade@435
  1562
    'halttime': 0,
lordcrc@384
  1563
    'useparamkeys': 'false',
lordcrc@384
  1564
    'sampler.showadvanced': 'false',
lordcrc@384
  1565
    'sintegrator.showadvanced': 'false',
lordcrc@384
  1566
    'pixelfilter.showadvanced': 'false',
lordcrc@384
  1567
lordcrc@384
  1568
    'sampler.type': 'lowdiscrepancy',
lordcrc@384
  1569
    'sampler.lowdisc.pixelsamples': 1,
lordcrc@384
  1570
    'sampler.lowdisc.pixelsampler': 'lowdiscrepancy',
lordcrc@384
  1571
lordcrc@384
  1572
    'sintegrator.type': 'directlighting',
lordcrc@384
  1573
    'sintegrator.dlighting.maxdepth': 5,
lordcrc@384
  1574
lordcrc@384
  1575
    'pixelfilter.type': 'mitchell',
lordcrc@384
  1576
    'pixelfilter.mitchell.sharp': 0.250, 
lordcrc@384
  1577
    'pixelfilter.mitchell.xwidth': 2.0, 
lordcrc@384
  1578
    'pixelfilter.mitchell.ywidth': 2.0, 
lordcrc@384
  1579
    'pixelfilter.mitchell.optmode': "slider" }
lordcrc@384
  1580
lordcrc@384
  1581
    presets['1 Final - MLT/Bidir Path Tracing (interior) (recommended)'] =  {
lordcrc@384
  1582
    'film.displayinterval': 8,
lordcrc@384
  1583
    'haltspp': 0,
dade@435
  1584
    'halttime': 0,
lordcrc@384
  1585
    'useparamkeys': 'false',
lordcrc@384
  1586
    'sampler.showadvanced': 'false',
lordcrc@384
  1587
    'sintegrator.showadvanced': 'false',
lordcrc@384
  1588
    'pixelfilter.showadvanced': 'false',
lordcrc@384
  1589
lordcrc@384
  1590
    'sampler.type': 'metropolis',
lordcrc@384
  1591
    'sampler.metro.strength': 0.6,
lordcrc@384
  1592
    'sampler.metro.lmprob': 0.4,
lordcrc@384
  1593
    'sampler.metro.maxrejects': 512,
lordcrc@384
  1594
    #'sampler.metro.initsamples': 262144,
lordcrc@384
  1595
    'sampler.metro.usevariance': "false",
lordcrc@384
  1596
lordcrc@384
  1597
    'sintegrator.type': 'bidirectional',
lordcrc@384
  1598
    'sintegrator.bidir.bounces': 16,
lordcrc@384
  1599
    'sintegrator.bidir.eyedepth': 16,
lordcrc@384
  1600
    'sintegrator.bidir.lightdepth': 16,
lordcrc@384
  1601
lordcrc@384
  1602
    'pixelfilter.type': 'mitchell',
lordcrc@384
  1603
    'pixelfilter.mitchell.sharp': 0.250, 
lordcrc@384
  1604
    'pixelfilter.mitchell.xwidth': 2.0, 
lordcrc@384
  1605
    'pixelfilter.mitchell.ywidth': 2.0, 
lordcrc@384
  1606
    'pixelfilter.mitchell.optmode': "slider" }
lordcrc@384
  1607
lordcrc@384
  1608
    presets['2 Final - MLT/Path Tracing (exterior)'] =  {
lordcrc@384
  1609
    'film.displayinterval': 8,
lordcrc@384
  1610
    'haltspp': 0,
dade@435
  1611
    'halttime': 0,
lordcrc@384
  1612
    'useparamkeys': 'false',
lordcrc@384
  1613
    'sampler.showadvanced': 'false',
lordcrc@384
  1614
    'sintegrator.showadvanced': 'false',
lordcrc@384
  1615
    'pixelfilter.showadvanced': 'false',
lordcrc@384
  1616
lordcrc@384
  1617
    'sampler.type': 'metropolis',
lordcrc@384
  1618
    'sampler.metro.strength': 0.6,
lordcrc@384
  1619
    'sampler.metro.lmprob': 0.4,
lordcrc@384
  1620
    'sampler.metro.maxrejects': 512,
lordcrc@384
  1621
    #'sampler.metro.initsamples': 262144,
lordcrc@384
  1622
    'sampler.metro.usevariance': "false",
lordcrc@384
  1623
lordcrc@384
  1624
    'sintegrator.type': 'path',
lordcrc@384
  1625
    'sintegrator.bidir.bounces': 10,
lordcrc@384
  1626
    'sintegrator.bidir.maxdepth': 10,
lordcrc@384
  1627
lordcrc@384
  1628
    'pixelfilter.type': 'mitchell',
lordcrc@384
  1629
    'pixelfilter.mitchell.sharp': 0.250, 
lordcrc@384
  1630
    'pixelfilter.mitchell.xwidth': 2.0, 
lordcrc@384
  1631
    'pixelfilter.mitchell.ywidth': 2.0, 
lordcrc@384
  1632
    'pixelfilter.mitchell.optmode': "slider" }
lordcrc@384
  1633
    
lordcrc@384
  1634
    presets['4 '] = { }
lordcrc@384
  1635
lordcrc@384
  1636
    presets['5 Progressive - Bidir Path Tracing (interior)'] =  {
lordcrc@384
  1637
    'film.displayinterval': 8,
lordcrc@384
  1638
    'haltspp': 0,
dade@435
  1639
    'halttime': 0,
lordcrc@384
  1640
    'useparamkeys': 'false',
lordcrc@384
  1641
    'sampler.showadvanced': 'false',
lordcrc@384
  1642
    'sintegrator.showadvanced': 'false',
lordcrc@384
  1643
    'pixelfilter.showadvanced': 'false',
lordcrc@384
  1644
lordcrc@384
  1645
    'sampler.type': 'lowdiscrepancy',
lordcrc@384
  1646
    'sampler.lowdisc.pixelsamples': 1,
lordcrc@384
  1647
    'sampler.lowdisc.pixelsampler': 'lowdiscrepancy',
lordcrc@384
  1648
lordcrc@384
  1649
    'sintegrator.type': 'bidirectional',
lordcrc@384
  1650
    'sintegrator.bidir.bounces': 16,
lordcrc@384
  1651
    'sintegrator.bidir.eyedepth': 16,
lordcrc@384
  1652
    'sintegrator.bidir.lightdepth': 16,
lordcrc@384
  1653
lordcrc@384
  1654
    'pixelfilter.type': 'mitchell',
lordcrc@384
  1655
    'pixelfilter.mitchell.sharp': 0.250, 
lordcrc@384
  1656
    'pixelfilter.mitchell.xwidth': 2.0, 
lordcrc@384
  1657
    'pixelfilter.mitchell.ywidth': 2.0, 
lordcrc@384
  1658
    'pixelfilter.mitchell.optmode': "slider" }
lordcrc@384
  1659
lordcrc@384
  1660
    presets['6 Progressive - Path Tracing (exterior)'] =  {
lordcrc@384
  1661
    'film.displayinterval': 8,
lordcrc@384
  1662
    'haltspp': 0,
dade@435
  1663
    'halttime': 0,
lordcrc@384
  1664
    'useparamkeys': 'false',
lordcrc@384
  1665
    'sampler.showadvanced': 'false',
lordcrc@384
  1666
    'sintegrator.showadvanced': 'false',
lordcrc@384
  1667
    'pixelfilter.showadvanced': 'false',
lordcrc@384
  1668
lordcrc@384
  1669
    'sampler.type': 'lowdiscrepancy',
lordcrc@384
  1670
    'sampler.lowdisc.pixelsamples': 1,
lordcrc@384
  1671
    'sampler.lowdisc.pixelsampler': 'lowdiscrepancy',
lordcrc@384
  1672
lordcrc@384
  1673
    'sintegrator.type': 'path',
lordcrc@384
  1674
    'sintegrator.bidir.bounces': 10,
lordcrc@384
  1675
    'sintegrator.bidir.maxdepth': 10,
lordcrc@384
  1676
lordcrc@384
  1677
    'pixelfilter.type': 'mitchell',
lordcrc@384
  1678
    'pixelfilter.mitchell.sharp': 0.250, 
lordcrc@384
  1679
    'pixelfilter.mitchell.xwidth': 2.0, 
lordcrc@384
  1680
    'pixelfilter.mitchell.ywidth': 2.0, 
lordcrc@384
  1681
    'pixelfilter.mitchell.optmode': "slider" }
lordcrc@384
  1682
lordcrc@384
  1683
    presets['7 '] = { }
lordcrc@384
  1684
lordcrc@384
  1685
    presets['8 Bucket - Bidir Path Tracing (interior)'] =  {
lordcrc@384
  1686
    'film.displayinterval': 8,
lordcrc@384
  1687
    'haltspp': 0,
dade@435
  1688
    'halttime': 0,
lordcrc@384
  1689
    'useparamkeys': 'false',
lordcrc@384
  1690
    'sampler.showadvanced': 'false',
lordcrc@384
  1691
    'sintegrator.showadvanced': 'false',
lordcrc@384
  1692
    'pixelfilter.showadvanced': 'false',
lordcrc@384
  1693
lordcrc@384
  1694
    'sampler.type': 'lowdiscrepancy',
lordcrc@384
  1695
    'sampler.lowdisc.pixelsamples': 64,
lordcrc@384
  1696
    'sampler.lowdisc.pixelsampler': 'hilbert',
lordcrc@384
  1697
lordcrc@384
  1698
    'sintegrator.type': 'bidirectional',
lordcrc@384
  1699
    'sintegrator.bidir.bounces': 8,
lordcrc@384
  1700
    'sintegrator.bidir.eyedepth': 8,
lordcrc@384
  1701
    'sintegrator.bidir.lightdepth': 10,
lordcrc@384
  1702
lordcrc@384
  1703
    'pixelfilter.type': 'mitchell',
lordcrc@384
  1704
    'pixelfilter.mitchell.sharp': 0.250, 
lordcrc@384
  1705
    'pixelfilter.mitchell.xwidth': 2.0, 
lordcrc@384
  1706
    'pixelfilter.mitchell.ywidth': 2.0, 
lordcrc@384
  1707
    'pixelfilter.mitchell.optmode': "slider" }
lordcrc@384
  1708
lordcrc@384
  1709
    presets['9 Bucket - Path Tracing (exterior)'] =  {
lordcrc@384
  1710
    'film.displayinterval': 8,
lordcrc@384
  1711
    'haltspp': 0,
dade@435
  1712
    'halttime': 0,
lordcrc@384
  1713
    'useparamkeys': 'false',
lordcrc@384
  1714
    'sampler.showadvanced': 'false',
lordcrc@384
  1715
    'sintegrator.showadvanced': 'false',
lordcrc@384
  1716
    'pixelfilter.showadvanced': 'false',
lordcrc@384
  1717
lordcrc@384
  1718
    'sampler.type': 'lowdiscrepancy',
lordcrc@384
  1719
    'sampler.lowdisc.pixelsamples': 64,
lordcrc@384
  1720
    'sampler.lowdisc.pixelsampler': 'hilbert',
lordcrc@384
  1721
lordcrc@384
  1722
    'sintegrator.type': 'path',
lordcrc@384
  1723
    'sintegrator.bidir.bounces': 8,
lordcrc@384
  1724
    'sintegrator.bidir.maxdepth': 8,
lordcrc@384
  1725
lordcrc@384
  1726
    'pixelfilter.type': 'mitchell',
lordcrc@384
  1727
    'pixelfilter.mitchell.sharp': 0.333, 
lordcrc@384
  1728
    'pixelfilter.mitchell.xwidth': 2.0, 
lordcrc@384
  1729
    'pixelfilter.mitchell.ywidth': 2.0, 
lordcrc@384
  1730
    'pixelfilter.mitchell.optmode': "slider" }
lordcrc@384
  1731
lordcrc@384
  1732
    presets['A '] = { }
lordcrc@384
  1733
lordcrc@384
  1734
    presets['B Anim - Distributed/GI low Q'] =  {
lordcrc@384
  1735
    'film.displayinterval': 8,
lordcrc@384
  1736
    'haltspp': 1,
dade@435
  1737
    'halttime': 0,
lordcrc@384
  1738
    'useparamkeys': 'false',
lordcrc@384
  1739
    'sampler.showadvanced': 'false',
lordcrc@384
  1740
    'sintegrator.showadvanced': 'false',
lordcrc@384
  1741
    'pixelfilter.showadvanced': 'false',
lordcrc@384
  1742
lordcrc@384
  1743
    'sampler.type': 'lowdiscrepancy',
lordcrc@384
  1744
    'sampler.lowdisc.pixelsamples': 16,
lordcrc@384
  1745
    'sampler.lowdisc.pixelsampler': 'hilbert',
lordcrc@384
  1746
lordcrc@384
  1747
    'sintegrator.type': 'distributedpath',
lordcrc@384
  1748
    'sintegrator.distributedpath.causticsonglossy': 'true',
lordcrc@384
  1749
    'sintegrator.distributedpath.diffuserefractdepth': 5,
lordcrc@384
  1750
    'sintegrator.distributedpath.indirectglossy': 'true',
lordcrc@384
  1751
    'sintegrator.distributedpath.directsamples': 1,
lordcrc@384
  1752
    'sintegrator.distributedpath.diffuserefractsamples': 1,
lordcrc@384
  1753
    'sintegrator.distributedpath.glossyreflectdepth': 2,
lordcrc@384
  1754
    'sintegrator.distributedpath.causticsondiffuse': 'false',
lordcrc@384
  1755
    'sintegrator.distributedpath.directsampleall': 'true',
lordcrc@384
  1756
    'sintegrator.distributedpath.indirectdiffuse': 'true',
lordcrc@384
  1757
    'sintegrator.distributedpath.specularreflectdepth': 3,
lordcrc@384
  1758
    'sintegrator.distributedpath.diffusereflectsamples': 1,
lordcrc@384
  1759
    'sintegrator.distributedpath.glossyreflectsamples': 1,
lordcrc@384
  1760
    'sintegrator.distributedpath.glossyrefractdepth': 5,
lordcrc@384
  1761
    'sintegrator.distributedpath.diffusereflectdepth': '2',
lordcrc@384
  1762
    'sintegrator.distributedpath.indirectsamples': 1,
lordcrc@384
  1763
    'sintegrator.distributedpath.indirectsampleall': 'false',
lordcrc@384
  1764
    'sintegrator.distributedpath.glossyrefractsamples': 1,
lordcrc@384
  1765
    'sintegrator.distributedpath.directdiffuse': 'true',
lordcrc@384
  1766
    'sintegrator.distributedpath.directglossy': 'true',
lordcrc@384
  1767
    'sintegrator.distributedpath.strategy': 'auto',
lordcrc@384
  1768
    'sintegrator.distributedpath.specularrefractdepth': 5,
lordcrc@384
  1769
lordcrc@384
  1770
    'pixelfilter.type': 'mitchell',
lordcrc@384
  1771
    'pixelfilter.mitchell.sharp': 0.333, 
lordcrc@384
  1772
    'pixelfilter.mitchell.xwidth': 2.0, 
lordcrc@384
  1773
    'pixelfilter.mitchell.ywidth': 2.0, 
lordcrc@384
  1774
    'pixelfilter.mitchell.optmode': "slider" }
lordcrc@384
  1775
lordcrc@384
  1776
    presets['C Anim - Distributed/GI medium Q'] =  {
lordcrc@384
  1777
    'film.displayinterval': 8,
lordcrc@384
  1778
    'haltspp': 1,
dade@435
  1779
    'halttime': 0,
lordcrc@384
  1780
    'useparamkeys': 'false',
lordcrc@384
  1781
    'sampler.showadvanced': 'false',
lordcrc@384
  1782
    'sintegrator.showadvanced': 'false',
lordcrc@384
  1783
    'pixelfilter.showadvanced': 'false',
lordcrc@384
  1784
lordcrc@384
  1785
    'sampler.type': 'lowdiscrepancy',
lordcrc@384
  1786
    'sampler.lowdisc.pixelsamples': 64,
lordcrc@384
  1787
    'sampler.lowdisc.pixelsampler': 'hilbert',
lordcrc@384
  1788
lordcrc@384
  1789
    'sintegrator.type': 'distributedpath',
lordcrc@384
  1790
    'sintegrator.distributedpath.causticsonglossy': 'true',
lordcrc@384
  1791
    'sintegrator.distributedpath.diffuserefractdepth': 5,
lordcrc@384
  1792
    'sintegrator.distributedpath.indirectglossy': 'true',
lordcrc@384
  1793
    'sintegrator.distributedpath.directsamples': 1,
lordcrc@384
  1794
    'sintegrator.distributedpath.diffuserefractsamples': 1,
lordcrc@384
  1795
    'sintegrator.distributedpath.glossyreflectdepth': 2,
lordcrc@384
  1796
    'sintegrator.distributedpath.causticsondiffuse': 'false',
lordcrc@384
  1797
    'sintegrator.distributedpath.directsampleall': 'true',
lordcrc@384
  1798
    'sintegrator.distributedpath.indirectdiffuse': 'true',
lordcrc@384
  1799
    'sintegrator.distributedpath.specularreflectdepth': 3,
lordcrc@384
  1800
    'sintegrator.distributedpath.diffusereflectsamples': 1,
lordcrc@384
  1801
    'sintegrator.distributedpath.glossyreflectsamples': 1,
lordcrc@384
  1802
    'sintegrator.distributedpath.glossyrefractdepth': 5,
lordcrc@384
  1803
    'sintegrator.distributedpath.diffusereflectdepth': '2',
lordcrc@384
  1804
    'sintegrator.distributedpath.indirectsamples': 1,
lordcrc@384
  1805
    'sintegrator.distributedpath.indirectsampleall': 'false',
lordcrc@384
  1806
    'sintegrator.distributedpath.glossyrefractsamples': 1,
lordcrc@384
  1807
    'sintegrator.distributedpath.directdiffuse': 'true',
lordcrc@384
  1808
    'sintegrator.distributedpath.directglossy': 'true',
lordcrc@384
  1809
    'sintegrator.distributedpath.strategy': 'auto',
lordcrc@384
  1810
    'sintegrator.distributedpath.specularrefractdepth': 5,
lordcrc@384
  1811
lordcrc@384
  1812
    'pixelfilter.type': 'mitchell',
lordcrc@384
  1813
    'pixelfilter.mitchell.sharp': 0.333, 
lordcrc@384
  1814
    'pixelfilter.mitchell.xwidth': 2.0, 
lordcrc@384
  1815
    'pixelfilter.mitchell.ywidth': 2.0, 
lordcrc@384
  1816
    'pixelfilter.mitchell.optmode': "slider" }
lordcrc@384
  1817
    
lordcrc@384
  1818
    presets['D Anim - Distributed/GI high Q'] =  {
lordcrc@384
  1819
    'film.displayinterval': 8,
lordcrc@384
  1820
    'haltspp': 1,
dade@435
  1821
    'halttime': 0,
lordcrc@384
  1822
    'useparamkeys': 'false',
lordcrc@384
  1823
    'sampler.showadvanced': 'false',
lordcrc@384
  1824
    'sintegrator.showadvanced': 'false',
lordcrc@384
  1825
    'pixelfilter.showadvanced': 'false',
lordcrc@384
  1826
lordcrc@384
  1827
    'sampler.type': 'lowdiscrepancy',
lordcrc@384
  1828
    'sampler.lowdisc.pixelsamples': 256,
lordcrc@384
  1829
    'sampler.lowdisc.pixelsampler': 'hilbert',
lordcrc@384
  1830
lordcrc@384
  1831
    'sintegrator.type': 'distributedpath',
lordcrc@384
  1832
    'sintegrator.distributedpath.causticsonglossy': 'true',
lordcrc@384
  1833
    'sintegrator.distributedpath.diffuserefractdepth': 5,
lordcrc@384
  1834
    'sintegrator.distributedpath.indirectglossy': 'true',
lordcrc@384
  1835
    'sintegrator.distributedpath.directsamples': 1,
lordcrc@384
  1836
    'sintegrator.distributedpath.diffuserefractsamples': 1,
lordcrc@384
  1837
    'sintegrator.distributedpath.glossyreflectdepth': 2,
lordcrc@384
  1838
    'sintegrator.distributedpath.causticsondiffuse': 'false',
lordcrc@384
  1839
    'sintegrator.distributedpath.directsampleall': 'true',
lordcrc@384
  1840
    'sintegrator.distributedpath.indirectdiffuse': 'true',
lordcrc@384
  1841
    'sintegrator.distributedpath.specularreflectdepth': 3,
lordcrc@384
  1842
    'sintegrator.distributedpath.diffusereflectsamples': 1,
lordcrc@384
  1843
    'sintegrator.distributedpath.glossyreflectsamples': 1,
lordcrc@384
  1844
    'sintegrator.distributedpath.glossyrefractdepth': 5,
lordcrc@384
  1845
    'sintegrator.distributedpath.diffusereflectdepth': '2',
lordcrc@384
  1846
    'sintegrator.distributedpath.indirectsamples': 1,
lordcrc@384
  1847
    'sintegrator.distributedpath.indirectsampleall': 'false',
lordcrc@384
  1848
    'sintegrator.distributedpath.glossyrefractsamples': 1,
lordcrc@384
  1849
    'sintegrator.distributedpath.directdiffuse': 'true',
lordcrc@384
  1850
    'sintegrator.distributedpath.directglossy': 'true',
lordcrc@384
  1851
    'sintegrator.distributedpath.strategy': 'auto',
lordcrc@384
  1852
    'sintegrator.distributedpath.specularrefractdepth': 5,
lordcrc@384
  1853
lordcrc@384
  1854
    'pixelfilter.type': 'mitchell',
lordcrc@384
  1855
    'pixelfilter.mitchell.sharp': 0.333, 
lordcrc@384
  1856
    'pixelfilter.mitchell.xwidth': 2.0, 
lordcrc@384
  1857
    'pixelfilter.mitchell.ywidth': 2.0, 
lordcrc@384
  1858
    'pixelfilter.mitchell.optmode': "slider" }
lordcrc@384
  1859
lordcrc@384
  1860
    presets['E Anim - Distributed/GI very high Q'] =  {
lordcrc@384
  1861
    'film.displayinterval': 8,
lordcrc@384
  1862
    'haltspp': 1,
dade@435
  1863
    'halttime': 0,
lordcrc@384
  1864
    'useparamkeys': 'false',
lordcrc@384
  1865
    'sampler.showadvanced': 'false',
lordcrc@384
  1866
    'sintegrator.showadvanced': 'false',
lordcrc@384
  1867
    'pixelfilter.showadvanced': 'false',
lordcrc@384
  1868
lordcrc@384
  1869
    'sampler.type': 'lowdiscrepancy',
lordcrc@384
  1870
    'sampler.lowdisc.pixelsamples': 512,
lordcrc@384
  1871
    'sampler.lowdisc.pixelsampler': 'hilbert',
lordcrc@384
  1872
lordcrc@384
  1873
    'sintegrator.type': 'distributedpath',
lordcrc@384
  1874
    'sintegrator.distributedpath.causticsonglossy': 'true',
lordcrc@384
  1875
    'sintegrator.distributedpath.diffuserefractdepth': 5,
lordcrc@384
  1876
    'sintegrator.distributedpath.indirectglossy': 'true',
lordcrc@384
  1877
    'sintegrator.distributedpath.directsamples': 1,
lordcrc@384
  1878
    'sintegrator.distributedpath.diffuserefractsamples': 1,
lordcrc@384
  1879
    'sintegrator.distributedpath.glossyreflectdepth': 2,
lordcrc@384
  1880
    'sintegrator.distributedpath.causticsondiffuse': 'false',
lordcrc@384
  1881
    'sintegrator.distributedpath.directsampleall': 'true',
lordcrc@384
  1882
    'sintegrator.distributedpath.indirectdiffuse': 'true',
lordcrc@384
  1883
    'sintegrator.distributedpath.specularreflectdepth': 3,
lordcrc@384
  1884
    'sintegrator.distributedpath.diffusereflectsamples': 1,
lordcrc@384
  1885
    'sintegrator.distributedpath.glossyreflectsamples': 1,
lordcrc@384
  1886
    'sintegrator.distributedpath.glossyrefractdepth': 5,
lordcrc@384
  1887
    'sintegrator.distributedpath.diffusereflectdepth': '2',
lordcrc@384
  1888
    'sintegrator.distributedpath.indirectsamples': 1,
lordcrc@384
  1889
    'sintegrator.distributedpath.indirectsampleall': 'false',
lordcrc@384
  1890
    'sintegrator.distributedpath.glossyrefractsamples': 1,
lordcrc@384
  1891
    'sintegrator.distributedpath.directdiffuse': 'true',
lordcrc@384
  1892
    'sintegrator.distributedpath.directglossy': 'true',
lordcrc@384
  1893
    'sintegrator.distributedpath.strategy': 'auto',
lordcrc@384
  1894
    'sintegrator.distributedpath.specularrefractdepth': 5,
lordcrc@384
  1895
lordcrc@384
  1896
    'pixelfilter.type': 'mitchell',
lordcrc@384
  1897
    'pixelfilter.mitchell.sharp': 0.333, 
lordcrc@384
  1898
    'pixelfilter.mitchell.xwidth': 2.0, 
lordcrc@384
  1899
    'pixelfilter.mitchell.ywidth': 2.0, 
lordcrc@384
  1900
    'pixelfilter.mitchell.optmode': "slider" }
lordcrc@384
  1901
lordcrc@384
  1902
    return presets
lordcrc@384
  1903
lordcrc@384
  1904
def getMaterialPresets():
lordcrc@384
  1905
    return getPresets('luxblend_materials')
lordcrc@384
  1906
lordcrc@384
  1907
def savePreset(key, name, d):
lordcrc@384
  1908
    try:
lordcrc@384
  1909
        presets = getPresets(key)
lordcrc@384
  1910
        if d:
lordcrc@384
  1911
            presets[name] = d.copy()
lordcrc@384
  1912
        else:
lordcrc@384
  1913
            del presets[name]
lordcrc@384
  1914
        Blender.Registry.SetKey(key, presets, True)
lordcrc@384
  1915
    except: pass    
lordcrc@384
  1916
def saveScenePreset(name, d):
lordcrc@384
  1917
    try:
lordcrc@384
  1918
        for n in presetsExclude:
lordcrc@384
  1919
            try: del d[n]
lordcrc@384
  1920
            except: pass
lordcrc@384
  1921
        savePreset('luxblend_presets', name, d)
lordcrc@384
  1922
    except: pass
lordcrc@384
  1923
def saveMaterialPreset(name, d):
lordcrc@384
  1924
    try:
lordcrc@384
  1925
        for n in presetsExclude:
lordcrc@384
  1926
            try: del d[n]
lordcrc@384
  1927
            except: pass
lordcrc@384
  1928
        savePreset('luxblend_materials', name, d)
lordcrc@384
  1929
    except: pass
lordcrc@384
  1930
lordcrc@384
  1931
lordcrc@384
  1932
# **************************************************
lordcrc@384
  1933
lordcrc@384
  1934
lordcrc@384
  1935
lordcrc@384
  1936
lordcrc@384
  1937
lordcrc@384
  1938
usedproperties = {} # global variable to collect used properties for storing presets
lordcrc@384
  1939
usedpropertiesfilterobj = None # assign a object to only collect the properties that are assigned to this object
lordcrc@384
  1940
lordcrc@384
  1941
# class to access properties (for lux settings)
lordcrc@384
  1942
class luxProp:
lordcrc@384
  1943
    def __init__(self, obj, name, default):
lordcrc@384
  1944
        self.obj = obj
lordcrc@384
  1945
        self.name = name
lordcrc@384
  1946
#        if len(name)>31: print("Warning: property-name \"%s\" has more than 31 chars."%(name))
lordcrc@384
  1947
        self.hashmode = len(name)>31   # activate hash mode for keynames longer 31 chars (limited by blenders ID-prop)
lordcrc@384
  1948
        self.hashname = "__hash:%x"%(name.__hash__())
lordcrc@384
  1949
        self.default = default
lordcrc@384
  1950
    def parseassignment(self, s, name):
lordcrc@384
  1951
        l = s.split(" = ")
lordcrc@384
  1952
        if l[0] != name: print("Warning: property-name \"%s\" has hash-collide with \"%s\"."%(name, l[0]))
lordcrc@384
  1953
        return l[1]
lordcrc@384
  1954
    def createassignment(self, name, value):
lordcrc@384
  1955
        return "%s = %s"%(name, value)
lordcrc@384
  1956
    def get(self):
lordcrc@384
  1957
        global usedproperties, usedpropertiesfilterobj, luxdefaults
lordcrc@384
  1958
        if self.obj:
lordcrc@384
  1959
            try:
lordcrc@384
  1960
                value = self.obj.properties['luxblend'][self.name]
lordcrc@384
  1961
                if not(usedpropertiesfilterobj) or (usedpropertiesfilterobj == self.obj):
lordcrc@384
  1962
                    usedproperties[self.name] = value
lordcrc@384
  1963
                return value
lordcrc@384
  1964
            except KeyError:
lordcrc@384
  1965
                try:
lordcrc@384
  1966
                    value = self.parseassignment(self.obj.properties['luxblend'][self.hashname], self.name)
lordcrc@384
  1967
                    if not(usedpropertiesfilterobj) or (usedpropertiesfilterobj == self.obj):
lordcrc@384
  1968
                        usedproperties[self.name] = value
lordcrc@384
  1969
                    return value
lordcrc@384
  1970
                except KeyError:
lordcrc@384
  1971
                    if self.obj.__class__.__name__ == "Scene": # luxdefaults only for global setting
lordcrc@384
  1972
                        try:
lordcrc@384
  1973
                            value = luxdefaults[self.name]
lordcrc@384
  1974
                            if not(usedpropertiesfilterobj) or (usedpropertiesfilterobj == self.obj):
lordcrc@384
  1975
                                usedproperties[self.name] = value
lordcrc@384
  1976
                            return value
lordcrc@384
  1977
                        except KeyError:
lordcrc@384
  1978
                            if not(usedpropertiesfilterobj) or (usedpropertiesfilterobj == self.obj):
lordcrc@384
  1979
                                usedproperties[self.name] = self.default
lordcrc@384
  1980
                            return self.default
lordcrc@384
  1981
                    if not(usedpropertiesfilterobj) or (usedpropertiesfilterobj == self.obj):
lordcrc@384
  1982
                        usedproperties[self.name] = self.default
lordcrc@384
  1983
                    return self.default
lordcrc@384
  1984
        return None
lordcrc@384
  1985
    def getobj(self):
lordcrc@384
  1986
        if self.obj:
lordcrc@384
  1987
            return self.obj
lordcrc@384
  1988
        else:
lordcrc@384
  1989
            return None
lordcrc@384
  1990
    def getname(self):
lordcrc@384
  1991
        if self.name:
lordcrc@384
  1992
            return self.name
lordcrc@384
  1993
        else:
lordcrc@384
  1994
            return None
lordcrc@384
  1995
    def set(self, value):
lordcrc@384
  1996
        global newluxdefaults
lordcrc@384
  1997
        if self.obj:
lordcrc@384
  1998
            if self.hashmode: n, v = self.hashname, self.createassignment(self.name, value)
lordcrc@384
  1999
            else: n, v = self.name, value
lordcrc@384
  2000
            if value is not None:
lordcrc@384
  2001
                try: self.obj.properties['luxblend'][n] = v
lordcrc@384
  2002
                except (KeyError, TypeError):
lordcrc@384
  2003
                    self.obj.properties['luxblend'] = {}
lordcrc@384
  2004
                    self.obj.properties['luxblend'][n] = v
lordcrc@384
  2005
            else:
lordcrc@384
  2006
                try: del self.obj.properties['luxblend'][n]
lordcrc@384
  2007
                except:    pass
lordcrc@384
  2008
            if self.obj.__class__.__name__ == "Scene": # luxdefaults only for global setting
lordcrc@384
  2009
                # value has changed, so this are user settings, remove preset reference
lordcrc@384
  2010
                if not(self.name in defaultsExclude):
lordcrc@384
  2011
                    newluxdefaults[self.name] = value
lordcrc@384
  2012
                    try: self.obj.properties['luxblend']['preset']=""
lordcrc@384
  2013
                    except: pass
lordcrc@384
  2014
    def delete(self):
lordcrc@384
  2015
        if self.obj:
lordcrc@384
  2016
            try: del self.obj.properties['luxblend'][self.name]
lordcrc@384
  2017
            except:    pass
lordcrc@384
  2018
            try: del self.obj.properties['luxblend'][self.hashname]
lordcrc@384
  2019
            except:    pass
lordcrc@384
  2020
    def getFloat(self):
lordcrc@384
  2021
        v = self.get()
lordcrc@384
  2022
        if type(v) == types.FloatType: return float(v)
lordcrc@384
  2023
        try:
lordcrc@384
  2024
            if type(v) == types.StringType: return float(v.split(" ")[0])
lordcrc@384
  2025
        except: pass
lordcrc@384
  2026
        v = self.default
lordcrc@384
  2027
        if type(v) == types.FloatType: return float(v)
lordcrc@384
  2028
        try:
lordcrc@384
  2029
            if type(v) == types.StringType: return float(v.split(" ")[0])
lordcrc@384
  2030
        except: pass
lordcrc@384
  2031
        return 0.0
lordcrc@384
  2032
    def getInt(self):
lordcrc@384
  2033
        try: return int(self.get())
lordcrc@384
  2034
        except: return int(self.default)
lordcrc@384
  2035
    def getRGB(self):
lordcrc@384
  2036
        return self.getVector()
lordcrc@384
  2037
    def getVector(self):
lordcrc@384
  2038
        v = self.get()
lordcrc@384
  2039
        if type(v) in [types.FloatType, types.IntType]: return (float(v), float(v), float(v))
lordcrc@384
  2040
        l = None
lordcrc@384
  2041
        try:
lordcrc@384
  2042
            if type(v) == types.StringType: l = self.get().split(" ")
lordcrc@384
  2043
        except: pass
lordcrc@384
  2044
        try:
lordcrc@384
  2045
            if (l==None) or (len(l) != 3): l = self.default.split(" ")
lordcrc@384
  2046
            return (float(l[0]), float(l[1]), float(l[2]))
lordcrc@384
  2047
        except AttributeError:
lordcrc@384
  2048
            return (float(l[0]), float(l[0]), float(l[0]))
lordcrc@384
  2049
        
lordcrc@384
  2050
    def getVectorStr(self):
lordcrc@384
  2051
        return "%f %f %f"%self.getVector()
lordcrc@384
  2052
    def isFloat(self):
lordcrc@384
  2053
        return type(self.get()) == types.FloatType
lordcrc@384
  2054
    def getRGC(self):
lordcrc@384
  2055
        col = self.getRGB()
lordcrc@384
  2056
        return "%f %f %f"%(rg(col[0]), rg(col[1]),rg(col[2]))
lordcrc@384
  2057
    def setRGB(self, value):
lordcrc@384
  2058
        self.set("%f %f %f"%(value[0], value[1], value[2]))
lordcrc@384
  2059
    def setVector(self, value):
lordcrc@384
  2060
        self.set("%f %f %f"%(value[0], value[1], value[2]))
lordcrc@384
  2061
lordcrc@384
  2062
lordcrc@384
  2063
# class to access blender attributes (for lux settings)
lordcrc@384
  2064
class luxAttr:
lordcrc@384
  2065
    def __init__(self, obj, name):
lordcrc@384
  2066
        self.obj = obj
lordcrc@384
  2067
        self.name = name
lordcrc@384
  2068
    def get(self):
lordcrc@384
  2069
        if self.obj:
lordcrc@384
  2070
            return getattr(self.obj, self.name)
lordcrc@384
  2071
        else:
lordcrc@384
  2072
            return None
lordcrc@384
  2073
    def getFloat(self):
lordcrc@384
  2074
        return float(self.get())
lordcrc@384
  2075
    def getInt(self):
lordcrc@384
  2076
        return int(self.get())
lordcrc@384
  2077
    def getobj(self):
lordcrc@384
  2078
        if self.obj:
lordcrc@384
  2079
            return self.obj
lordcrc@384
  2080
        else:
lordcrc@384
  2081
            return None
lordcrc@384
  2082
    def getname(self):
lordcrc@384
  2083
        if self.name:
lordcrc@384
  2084
            return self.name
lordcrc@384
  2085
        else:
lordcrc@384
  2086
            return None
lordcrc@384
  2087
    def set(self, value):
lordcrc@384
  2088
        if self.obj:
lordcrc@384
  2089
            setattr(self.obj, self.name, value)
lordcrc@384
  2090
            Window.QRedrawAll()
lordcrc@384
  2091
lordcrc@384
  2092
lordcrc@384
  2093
# class for dynamic gui
lordcrc@384
  2094
class luxGui:
lordcrc@384
  2095
    def __init__(self, y=200):
lordcrc@384
  2096
        self.x = 110 # left start position after captions
lordcrc@384
  2097
        self.xmax = 110+2*(140+4)
lordcrc@384
  2098
        self.y = y
lordcrc@384
  2099
        self.w = 140 # default element width in pixels
lordcrc@384
  2100
        self.h = 18  # default element height in pixels
lordcrc@384
  2101
        self.hmax = 0
lordcrc@384
  2102
        self.xgap = 4
lordcrc@384
  2103
        self.ygap = 4
lordcrc@384
  2104
        self.resethmax = False
lordcrc@384
  2105
    def getRect(self, wu, hu):
lordcrc@384
  2106
        w = int(self.w * wu + self.xgap * (wu-1))
lordcrc@384
  2107
        h = int(self.h * hu + self.ygap * (hu-1))
lordcrc@384
  2108
        if self.x + w > self.xmax: self.newline()
lordcrc@384
  2109
        if self.resethmax: self.hmax = 0; self.resethmax = False
lordcrc@384
  2110
        rect = [int(self.x), int(self.y-h), int(w), int(h)]
lordcrc@384
  2111
        self.x += int(w + self.xgap)
lordcrc@384
  2112
        if h+self.ygap > self.hmax: self.hmax = int(h+self.ygap)
lordcrc@384
  2113
        return rect
lordcrc@384
  2114
    def newline(self, title="", distance=0, level=0, icon=None, color=None):
lordcrc@384
  2115
        self.x = 110
lordcrc@384
  2116
        if not(self.resethmax): self.y -= int(self.hmax + distance)
lordcrc@384
  2117
        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
  2118
        if icon!=None: drawIcon(icon, 2+level*10, self.y-16)
lordcrc@384
  2119
        self.resethmax = True
lordcrc@384
  2120
        if title!="":
lordcrc@384
  2121
            self.getRect(0, 1)
lordcrc@384
  2122
            BGL.glColor3f(0.9,0.9,0.9); BGL.glRasterPos2i(20+level*10,self.y-self.h+5); Draw.Text(title)
lordcrc@384
  2123
    
lordcrc@384
  2124
def luxHelp(name, lux, caption, hint, gui, width=1.0):
lordcrc@384
  2125
    if gui:
lordcrc@384
  2126
        r = gui.getRect(width, 1)
lordcrc@384
  2127
        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
  2128
        drawIcon(icon_help, r[0], r[1])
lordcrc@384
  2129
lordcrc@384
  2130
    return "\n   \"bool %s\" [\"%s\"]"%(name, lux.get())
lordcrc@384
  2131
lordcrc@384
  2132
# lux parameter types
lordcrc@384
  2133
def luxOption(name, lux, options, caption, hint, gui, width=1.0):
lordcrc@384
  2134
    if gui:
lordcrc@384
  2135
        menustr = caption+": %t"
lordcrc@384
  2136
        for i, v in enumerate(options): menustr = "%s %%x%d|%s"%(v, i, menustr)
lordcrc@384
  2137
        try:
lordcrc@384
  2138
            i = options.index(lux.get())
lordcrc@384
  2139
        except ValueError:
lordcrc@384
  2140
            try:
lordcrc@384
  2141
                lux.set(lux.default) # not found, so try default value
lordcrc@384
  2142
                i = options.index(lux.get())
lordcrc@384
  2143
            except ValueError:
lordcrc@384
  2144
                print("value %s not found in options list"%(lux.get()))
lordcrc@384
  2145
                i = 0
lordcrc@384
  2146
        r = gui.getRect(width, 1)
lordcrc@384
  2147
        Draw.Menu(menustr, evtLuxGui, r[0], r[1], r[2], r[3], i, hint, lambda e,v: lux.set(options[v]))
lordcrc@384
  2148
    return "\n   \"string %s\" [\"%s\"]"%(name, lux.get())
lordcrc@384
  2149
lordcrc@384
  2150
def luxOptionRect(name, lux, options, caption, hint, gui, x, y, xx, yy):
lordcrc@384
  2151
    if gui:
lordcrc@384
  2152
        menustr = caption+": %t"
lordcrc@384
  2153
        for i, v in enumerate(options): menustr = "%s %%x%d|%s"%(v, i, menustr)
lordcrc@384
  2154
        try:
lordcrc@384
  2155
            i = options.index(lux.get())
lordcrc@384
  2156
        except ValueError:
lordcrc@384
  2157
            try:
lordcrc@384
  2158
                lux.set(lux.default) # not found, so try default value
lordcrc@384
  2159
                i = options.index(lux.get())
lordcrc@384
  2160
            except ValueError:
lordcrc@384
  2161
                print ("value %s not found in options list"%(lux.get()))
lordcrc@384
  2162
                i = 0
lordcrc@384
  2163
        Draw.Menu(menustr, evtLuxGui, x, y, xx, yy, i, hint, lambda e,v: lux.set(options[v]))
lordcrc@384
  2164
    return "\n   \"string %s\" [\"%s\"]"%(name, lux.get())
lordcrc@384
  2165
lordcrc@384
  2166
def luxIdentifier(name, lux, options, caption, hint, gui, icon=None, width=1.0):
lordcrc@384
  2167
    if gui: gui.newline(caption+":", 8, 0, icon, [0.75,0.5,0.25])
lordcrc@384
  2168
    luxOption(name, lux, options, caption, hint, gui, width)
lordcrc@384
  2169
    return "\n%s \"%s\""%(name, lux.get())
lordcrc@384
  2170
lordcrc@384
  2171
def luxFloat(name, lux, min, max, caption, hint, gui, width=1.0, useslider=0):
lordcrc@384
  2172
    if gui:
lordcrc@384
  2173
        if (luxProp(Scene.GetCurrent(), "useparamkeys", "false").get()=="true"):
lordcrc@384
  2174
            r = gui.getRect(width-0.12, 1)
lordcrc@384
  2175
        else:
lordcrc@384
  2176
            r = gui.getRect(width, 1)
lordcrc@384
  2177
lordcrc@384
  2178
        # Value
lordcrc@384
  2179
        if(useslider==1):
lordcrc@384
  2180
            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
  2181
        else:
lordcrc@384
  2182
            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
  2183
        if (luxProp(Scene.GetCurrent(), "useparamkeys", "false").get()=="true"):
lordcrc@384
  2184
            # IPO Curve
lordcrc@384
  2185
            obj = lux.getobj()
lordcrc@384
  2186
            keyname = lux.getname()
lordcrc@384
  2187
    
lordcrc@384
  2188
            useipo = luxProp(obj, keyname+".IPOuse", "false")
lordcrc@384
  2189
            i = gui.getRect(0.12, 1)
lordcrc@384
  2190
            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
  2191
            
lordcrc@384
  2192
            if useipo.get() == "true":
lordcrc@384
  2193
                if gui: gui.newline(caption+"IPO:", 8, 0, None, [0.5,0.45,0.35])
lordcrc@384
  2194
                curve = luxProp(obj, keyname+".IPOCurveName", "") 
lordcrc@384
  2195
                if curve.get() == "":
lordcrc@384
  2196
                    c = gui.getRect(2.0, 1)
lordcrc@384
  2197
                else:
lordcrc@384
  2198
                    c = gui.getRect(1.1, 1)
lordcrc@384
  2199
                
lordcrc@384
  2200
                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
  2201
                
lordcrc@384
  2202
                usemapping = luxProp(obj, keyname+".IPOmap", "false")
lordcrc@384
  2203
                icu_value = 0
lordcrc@384
  2204
    
lordcrc@384
  2205
                # Apply IPO to value
lordcrc@384
  2206
                if curve.get() != "":
lordcrc@384
  2207
                    try:
lordcrc@384
  2208
                        ipoob = Blender.Ipo.Get(curve.get())
lordcrc@384
  2209
                    except: 
lordcrc@384
  2210
                        curve.set("")
lordcrc@384
  2211
                    pass
lordcrc@384
  2212
                    if curve.get() != "":
lordcrc@384
  2213
                        names = list([x[0] for x in ipoob.curveConsts.items()])
lordcrc@384
  2214
                        ipotype = luxProp(obj, keyname+".IPOCurveType", "OB_LOCZ")
lordcrc@384
  2215
                        luxOption("ipocurve", ipotype, names, "IPO Curve", "Set IPO Curve", gui, 0.6)
lordcrc@384
  2216
    
lordcrc@384
  2217
                        icu = ipoob[eval("Blender.Ipo.%s" % (ipotype.get()))]
lordcrc@384
  2218
                        icu_value = icu[Blender.Get('curframe')]
lordcrc@384
  2219
                        if usemapping.get() == "false": # if true is set during mapping below
lordcrc@384
  2220
                            lux.set(icu_value)    
lordcrc@384
  2221
    
lordcrc@384
  2222
                        # Mapping options
lordcrc@384
  2223
                        m = gui.getRect(0.3, 1)
lordcrc@384
  2224
                        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
  2225
                        if usemapping.get() == "true":
lordcrc@384
  2226
                            if gui: gui.newline(caption+"IPO:", 8, 0, None, [0.5,0.45,0.35])
lordcrc@384
  2227
                            fmin = luxProp(obj, keyname+".IPOCurvefmin", 0.0)
lordcrc@384
  2228
                            luxFloatNoIPO("ipofmin", fmin, -100, 100, "fmin", "Map minimum value from Curve", gui, 0.5)
lordcrc@384
  2229
                            fmax = luxProp(obj, keyname+".IPOCurvefmax", 1.0)
lordcrc@384
  2230
                            luxFloatNoIPO("ipofmax", fmax, -100, 100, "fmax", "Map maximum value from Curve", gui, 0.5)
lordcrc@384
  2231
                            tmin = luxProp(obj, keyname+".IPOCurvetmin", min)
lordcrc@384
  2232
                            luxFloatNoIPO("ipotmin", tmin, min, max, "tmin", "Map miminum value to", gui, 0.5)
lordcrc@384
  2233
                            tmax = luxProp(obj, keyname+".IPOCurvetmax", max)
lordcrc@384
  2234
                            luxFloatNoIPO("ipotmax", tmax, min, max, "tmax", "Map maximum value to", gui, 0.5)
lordcrc@384
  2235
    
lordcrc@384
  2236
                            sval = (icu_value - fmin.getFloat()) / (fmax.getFloat() - fmin.getFloat())
lordcrc@384
  2237
                            lux.set(tmin.getFloat() + (sval * (tmax.getFloat() - tmin.getFloat())))
lordcrc@384
  2238
lordcrc@384
  2239
                            # invert
lordcrc@384
  2240
                            #v = gui.getRect(0.5, 1)
lordcrc@384
  2241
                            #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
  2242
    else:
lordcrc@384
  2243
        if (luxProp(Scene.GetCurrent(), "useparamkeys", "false").get()=="true"):
lordcrc@384
  2244
            obj = lux.getobj()
lordcrc@384
  2245
            keyname = lux.getname()
lordcrc@384
  2246
            useipo = luxProp(obj, keyname+".IPOuse", "false")
lordcrc@384
  2247
            if useipo.get() == "true":
lordcrc@384
  2248
                curve = luxProp(obj, keyname+".IPOCurveName", "") 
lordcrc@384
  2249
                try:
lordcrc@384
  2250
                    ipoob = Blender.Ipo.Get(curve.get())
lordcrc@384
  2251
                except: 
lordcrc@384
  2252
                    curve.set("")
lordcrc@384
  2253
                pass
lordcrc@384
  2254
                usemapping = luxProp(obj, keyname+".IPOmap", "false")
lordcrc@384
  2255
                icu_value = 0
lordcrc@384
  2256
                if curve.get() != "":
lordcrc@384
  2257
                    names = list([x[0] for x in ipoob.curveConsts.items()])
lordcrc@384
  2258
                    ipotype = luxProp(obj, keyname+".IPOCurveType", "OB_LOCZ")
lordcrc@384
  2259
    
lordcrc@384
  2260
                    icu = ipoob[eval("Blender.Ipo.%s" % (ipotype.get()))]
lordcrc@384
  2261
                    icu_value = icu[Blender.Get('curframe')]
lordcrc@384
  2262
                    if usemapping.get() == "false": # if true is set during mapping below
lordcrc@384
  2263
                        lux.set(icu_value)    
lordcrc@384
  2264
    
lordcrc@384
  2265
                if usemapping.get() == "true":
lordcrc@384
  2266
                    if gui: gui.newline(caption+"IPO:", 8, 0, None, [0.5,0.45,0.35])
lordcrc@384
  2267
                    fmin = luxProp(obj, keyname+".IPOCurvefmin", 0.0)
lordcrc@384
  2268
                    fmax = luxProp(obj, keyname+".IPOCurvefmax", 1.0)
lordcrc@384
  2269
                    tmin = luxProp(obj, keyname+".IPOCurvetmin", min)
lordcrc@384
  2270
                    tmax = luxProp(obj, keyname+".IPOCurvetmax", max)
lordcrc@384
  2271
                    sval = (icu_value - fmin.getFloat()) / (fmax.getFloat() - fmin.getFloat())
lordcrc@384
  2272
                    lux.set(tmin.getFloat() + (sval * (tmax.getFloat() - tmin.getFloat())))
lordcrc@384
  2273
lordcrc@384
  2274
    return "\n   \"float %s\" [%f]"%(name, lux.getFloat())
lordcrc@384
  2275
lordcrc@384
  2276
def luxFloatNoIPO(name, lux, min, max, caption, hint, gui, width=1.0, useslider=0):
lordcrc@384
  2277
    if gui:
lordcrc@384
  2278
        r = gui.getRect(width, 1)
lordcrc@384
  2279
        if(useslider==1):
lordcrc@384
  2280
            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
  2281
        else:
lordcrc@384
  2282
            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
  2283
    return "\n   \"float %s\" [%f]"%(name, lux.getFloat())
lordcrc@384
  2284
lordcrc@384
  2285
lordcrc@384
  2286
lordcrc@384
  2287
def luxInt(name, lux, min, max, caption, hint, gui, width=1.0):
lordcrc@384
  2288
    if gui:
lordcrc@384
  2289
        r = gui.getRect(width, 1)
lordcrc@384
  2290
        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
  2291
    return "\n   \"integer %s\" [%d]"%(name, lux.getInt())
lordcrc@384
  2292
lordcrc@384
  2293
def luxBool(name, lux, caption, hint, gui, width=1.0):
lordcrc@384
  2294
    if gui:
lordcrc@384
  2295
        r = gui.getRect(width, 1)
lordcrc@384
  2296
        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
  2297
    return "\n   \"bool %s\" [\"%s\"]"%(name, lux.get())
lordcrc@384
  2298
doug@387
  2299
def luxLabel(caption, gui):
doug@387
  2300
    if gui:
doug@387
  2301
        r = gui.getRect(2,1); BGL.glRasterPos2i(r[0],r[1]+5)
doug@387
  2302
        Draw.Text(caption)
doug@387
  2303
lordcrc@384
  2304
def luxCollapse(name, lux, caption, hint, gui, width=1.0):
lordcrc@384
  2305
    if gui:
lordcrc@384
  2306
        r = gui.getRect(width, 1)
lordcrc@384
  2307
        if lux.get() == "true":
lordcrc@384
  2308
            drawArrow(arrow_down, r[0]-22, r[1]-2)
lordcrc@384
  2309
        else:
lordcrc@384
  2310
            drawArrow(arrow_right, r[0]-22, r[1]-2)
lordcrc@384
  2311
        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
  2312
    return "\n   \"bool %s\" [\"%s\"]"%(name, lux.get())
lordcrc@384
  2313
lordcrc@384
  2314
def luxString(name, lux, caption, hint, gui, width=1.0):
lordcrc@384
  2315
    if gui:
lordcrc@384
  2316
        r = gui.getRect(width, 1)
lordcrc@384
  2317
        Draw.String(caption+": ", evtLuxGui, r[0], r[1], r[2], r[3], lux.get(), 250, hint, lambda e,v: lux.set(v))
lordcrc@384
  2318
    if lux.get()==lux.default: return ""
lordcrc@384
  2319
    else: return "\n   \"string %s\" [\"%s\"]"%(name, luxstr(lux.get()))
lordcrc@384
  2320
lordcrc@384
  2321
def luxFile(name, lux, caption, hint, gui, width=1.0):
lordcrc@384
  2322
    if gui:
lordcrc@384
  2323
        r = gui.getRect(width, 1)
lordcrc@384
  2324
        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
  2325
        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
  2326
    return "\n   \"string %s\" [\"%s\"]"%(name, luxstr(luxFilePath(lux.get())))
lordcrc@384
  2327
lordcrc@384
  2328
def luxPath(name, lux, caption, hint, gui, width=1.0):
lordcrc@384
  2329
    if gui:
lordcrc@384
  2330
        r = gui.getRect(width, 1)
lordcrc@384
  2331
        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
  2332
        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
  2333
    return "\n   \"string %s\" [\"%s\"]"%(name, luxstr(lux.get()))
lordcrc@384
  2334
lordcrc@384
  2335
def luxRGB(name, lux, max, caption, hint, gui, width=2.0):
lordcrc@384
  2336
    if gui:
lordcrc@384
  2337
        r = gui.getRect(width, 1)
lordcrc@384
  2338
        scale = 1.0
lordcrc@384
  2339
        rgb = lux.getRGB()
lordcrc@384
  2340
        if max > 1.0:
lordcrc@384
  2341
            for i in range(3):
lordcrc@384
  2342
                if rgb[i] > scale: scale = rgb[i]
lordcrc@384
  2343
            rgb = (rgb[0]/scale, rgb[1]/scale, rgb[2]/scale)
lordcrc@384
  2344
        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
  2345
        w = int((r[2]-r[3])/3); m = max
lordcrc@384
  2346
        if max > 1.0:
lordcrc@384
  2347
            w = int((r[2]-r[3])/4); m = 1.0
lordcrc@384
  2348
        drawR, drawG, drawB, drawS = Draw.Create(rgb[0]), Draw.Create(rgb[1]), Draw.Create(rgb[2]), Draw.Create(scale)
lordcrc@384
  2349
        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
  2350
        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
  2351
        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
  2352
        if max > 1.0:
lordcrc@384
  2353
            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
  2354
    if max <= 1.0:
lordcrc@384
  2355
        return "\n   \"color %s\" [%s]"%(name, lux.getRGC())
lordcrc@384
  2356
    return "\n   \"color %s\" [%s]"%(name, lux.get())
lordcrc@384
  2357
lordcrc@384
  2358
def luxVector(name, lux, min, max, caption, hint, gui, width=2.0):
lordcrc@384
  2359
    if gui:
lordcrc@384
  2360
        r = gui.getRect(width, 1)
lordcrc@384
  2361
        vec = lux.getVector()
lordcrc@384
  2362
        w = int(r[2]/3)
lordcrc@384
  2363
        drawX, drawY, drawZ = Draw.Create(vec[0]), Draw.Create(vec[1]), Draw.Create(vec[2])
lordcrc@384
  2364
        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
  2365
        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
  2366
        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
  2367
    return "\n   \"vector %s\" [%s]"%(name, lux.get())
lordcrc@384
  2368
lordcrc@384
  2369
def luxVectorUniform(name, lux, min, max, caption, hint, gui, width=2.0):
lordcrc@384
  2370
    def setUniform(lux, value):
lordcrc@384
  2371
        if value: lux.set(lux.getFloat())
lordcrc@384
  2372
        else: lux.setVector(lux.getVector())
lordcrc@384
  2373
    if gui:
lordcrc@384
  2374
        r = gui.getRect(width, 1)
lordcrc@384
  2375
        vec = lux.getVector()
lordcrc@384
  2376
        Draw.Toggle("U", evtLuxGui, r[0], r[1], gui.h, gui.h, lux.isFloat(), "uniform", lambda e,v: setUniform(lux, v))
lordcrc@384
  2377
        if lux.isFloat():
lordcrc@384
  2378
            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
  2379
        else:
lordcrc@384
  2380
            w = int((r[2]-gui.h)/3)
lordcrc@384
  2381
            drawX, drawY, drawZ = Draw.Create(vec[0]), Draw.Create(vec[1]), Draw.Create(vec[2])
lordcrc@384
  2382
            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
  2383
            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
  2384
            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
  2385
    return "\n   \"vector %s\" [%s]"%(name, lux.getVectorStr())
lordcrc@384
  2386
lordcrc@384
  2387
lordcrc@384
  2388
# lux individual identifiers
lordcrc@384
  2389
def luxCamera(cam, context, gui=None):
lordcrc@384
  2390
    global icon_c_camera
lordcrc@384
  2391
    str = ""
lordcrc@384
  2392
    if cam:
lordcrc@384
  2393
        camtype = luxProp(cam, "camera.type", "perspective")
lordcrc@384
  2394
        # Radiance - remarked 'realistic' for v0.6 release
lordcrc@384
  2395
        #str = luxIdentifier("Camera", camtype, ["perspective","orthographic","environment","realistic"], "CAMERA", "select camera type", gui, icon_c_camera)
lordcrc@384
  2396
        str = luxIdentifier("Camera", camtype, ["perspective","orthographic","environment"], "CAMERA", "select camera type", gui, icon_c_camera)
lordcrc@384
  2397
        scale = 1.0
lordcrc@384
  2398
        if camtype.get() == "perspective":
lordcrc@384
  2399
            if gui: gui.newline("  View:")
lordcrc@384
  2400
            str += luxFloat("fov", luxAttr(cam, "angle"), 8.0, 170.0, "fov", "camera field-of-view angle", gui)
lordcrc@384
  2401
            fl = luxAttr(cam, "lens")
lordcrc@384
  2402
            if gui:
lordcrc@384
  2403
                luxFloat("lens", fl, 1.0, 250.0, "focallength", "camera focal length", gui)
lordcrc@384
  2404
            
lordcrc@384
  2405
        if camtype.get() == "orthographic" :
lordcrc@384
  2406
            str += luxFloat("scale", luxAttr(cam, "scale"), 0.01, 1000.0, "scale", "orthographic camera scale", gui)
lordcrc@384
  2407
            scale = cam.scale / 2
lordcrc@384
  2408
        if camtype.get() == "realistic":
lordcrc@384
  2409
            
lordcrc@384
  2410
            if gui: gui.newline("  View:")
lordcrc@384
  2411
            fov = luxAttr(cam, "angle")
lordcrc@384
  2412
            str += luxFloat("fov", fov, 8.0, 170.0, "fov", "camera field-of-view angle", gui)
lordcrc@384
  2413
            if gui: luxFloat("lens", luxAttr(cam, "lens"), 1.0, 250.0, "focallength", "camera focal length", gui)
lordcrc@384
  2414
            
lordcrc@384
  2415
            
lordcrc@384
  2416
            if gui: gui.newline()
lordcrc@384
  2417
            str += luxFile("specfile", luxProp(cam, "camera.realistic.specfile", ""), "spec-file", "", gui, 1.0)
lordcrc@384
  2418
#            if gui: gui.newline()
lordcrc@384
  2419
# auto calc        str += luxFloat("filmdistance", luxProp(cam, "camera.realistic.filmdistance", 70.0), 0.1, 1000.0, "film-dist", "film-distance [mm]", gui)
lordcrc@384
  2420
            filmdiag = luxProp(cam, "camera.realistic.filmdiag", 35.0)
lordcrc@384
  2421
            str += luxFloat("filmdiag", filmdiag, 0.1, 1000.0, "film-diag", "[mm]", gui)
lordcrc@384
  2422
            if gui: gui.newline()
lordcrc@384
  2423
            fstop = luxProp(cam, "camera.realistic.fstop", 1.0)
lordcrc@384
  2424
            luxFloat("aperture_diameter", fstop, 0.1, 100.0, "f-stop", "", gui)
lordcrc@384
  2425
            dofdist = luxAttr(cam, "dofDist")
lordcrc@384
  2426
            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
  2427
            if gui:
lordcrc@384
  2428
                Draw.Button("S", evtLuxGui, gui.x, gui.y-gui.h, gui.h, gui.h, "focus selected object", lambda e,v:setFocus("S"))
lordcrc@384
  2429
                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
  2430
            focal = filmdiag.get()*0.001 / math.tan(fov.get() * math.pi / 360.0) / 2.0
lordcrc@384
  2431
            print("calculated focal length: %f mm"%(focal * 1000.0))
lordcrc@384
  2432
            aperture_diameter = focal / fstop.get()
lordcrc@384
  2433
            print("calculated aperture diameter: %f mm"%(aperture_diameter * 1000.0))
lordcrc@384
  2434
            str += "\n   \"float aperture_diameter\" [%f]"%(aperture_diameter*1000.0)
lordcrc@384
  2435
            filmdistance = dofdist.get() * focal / (dofdist.get() - focal)
lordcrc@384
  2436
            print("calculated film distance: %f mm"%(filmdistance * 1000.0))
lordcrc@384
  2437
            str += "\n   \"float filmdistance\" [%f]"%(filmdistance*1000.0)
lordcrc@384
  2438
lordcrc@384
  2439
        # Clipping
lordcrc@384
  2440
        useclip = luxProp(cam, "useclip", "false")
lordcrc@384
  2441
        luxCollapse("useclip", useclip, "Near & Far Clipping", "Enable Camera near and far clipping options", gui, 2.0)
lordcrc@384
  2442
        if(useclip.get() == "true"):
lordcrc@384
  2443
            if gui: gui.newline("  Clipping:")
lordcrc@384
  2444
            str += luxFloat("hither", luxAttr(cam, "clipStart"), 0.0, 100.0, "start", "near clip distance", gui)
lordcrc@384
  2445
            str += luxFloat("yon", luxAttr(cam, "clipEnd"), 1.0, 10000.0, "end", "far clip distance", gui)
lordcrc@384
  2446
lordcrc@384
  2447
        # Depth of Field
lordcrc@384
  2448
        usedof = luxProp(cam, "usedof", "false")
lordcrc@384
  2449
        
lordcrc@384
  2450
        if camtype.get() in ["perspective", "orthographic"]:
lordcrc@384
  2451
            luxCollapse("usedof", usedof, "Depth of Field & Bokeh", "Enable Depth of Field & Aperture options", gui, 2.0)
lordcrc@384
  2452
            
lordcrc@384
  2453
            
lordcrc@384
  2454
            if usedof.get() == "true":
lordcrc@384
  2455
                
lordcrc@384
  2456
                if gui: gui.newline("  DOF:")
lordcrc@384
  2457
                
lordcrc@384
  2458
                lr = luxProp(cam, "camera.lensradius", 0.01)
lordcrc@384
  2459
                fs = luxProp(cam, "camera.fstop", 2.8)
lordcrc@384
  2460
                
lordcrc@384
  2461
                if camtype.get() == "perspective":
lordcrc@384
  2462
                    
lordcrc@384
  2463
                    usefstop = luxProp(cam, "usefstop", "false")
lordcrc@384
  2464
                    luxBool("usefstop", usefstop, "Use f/stop", "Use f/stop to define DOF effect", gui, 1.0)
lordcrc@384
  2465
                    
lordcrc@384
  2466
                    LR_SCALE = 1000.0       # lr in metres -> mm
lordcrc@384
  2467
                    FL_SCALE = 1.0          # fl in mm -> mm
lordcrc@384
  2468
                    
lordcrc@384
  2469
                    def lr_2_fs(fl, lr):
lordcrc@384
  2470
                        lr += 0.00000001
lordcrc@384
  2471
                        return fl / ( 2.0 * lr )
lordcrc@384
  2472
                    
lordcrc@384
  2473
                    def fs_2_lr(fl, fs):
lordcrc@384
  2474
                        return fl / ( 2.0 * fs )
lordcrc@384
  2475
                    
lordcrc@384
  2476
                    if usefstop.get() == 'true':
lordcrc@384
  2477
                        lr.set(fs_2_lr(fl.get() * FL_SCALE, fs.get()) / LR_SCALE)
lordcrc@384
  2478
                        luxFloat("fstop", fs, 0.9, 64.0, "fstop", "Defines the lens aperture.", gui)
lordcrc@384
  2479
                        str += luxFloat("lensradius", lr, 0.0, 1.0, "", "", None)
lordcrc@384
  2480
                    else:
lordcrc@384
  2481
                        fs.set(lr_2_fs(fl.get() * FL_SCALE, lr.get() * LR_SCALE))
lordcrc@384
  2482
                        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
  2483
                else:
lordcrc@384
  2484
                    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
  2485
                
lordcrc@384
  2486
                focustype = luxProp(cam, "camera.focustype", "autofocus")
lordcrc@384
  2487
                luxOption("focustype", focustype, ["autofocus", "manual", "object"], "Focus Type", "Choose the focus behaviour", gui)
lordcrc@384
  2488
                
lordcrc@384
  2489
    
lordcrc@384
  2490
                if focustype.get() == "autofocus":
lordcrc@384
  2491
                    str += luxBool("autofocus",luxProp(cam, "camera.autofocus", "true"), "autofocus", "Enable automatic focus", gui)
lordcrc@384
  2492
                if focustype.get() == "object":
lordcrc@384
  2493
                    objectfocus = luxProp(cam, "camera.objectfocus", "")
lordcrc@384
  2494
                    luxString("objectfocus", objectfocus, "object", "Always focus camera on named object", gui, 1.0)
lordcrc@384
  2495
                    dofdist = luxAttr(cam, "dofDist")
lordcrc@384
  2496
                    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
  2497
                    if objectfocus.get() != "":
jensverwiebe@385
  2498
                        try:
jensverwiebe@385
  2499
                            setFocus(objectfocus.get())
jensverwiebe@385
  2500
                        except:
jensverwiebe@386
  2501
                            luxProp(cam, "camera.objectfocus", "").set("")
jensverwiebe@386
  2502
                            Draw.PupMenu("WARNING: focus-object does not match existing object-name")
jensverwiebe@386
  2503
                            if LuxIsGUI: Draw.Redraw()
jensverwiebe@385
  2504
                                                                  
lordcrc@384
  2505
                if focustype.get() == "manual":
lordcrc@384
  2506
                    dofdist = luxAttr(cam, "dofDist")
lordcrc@384
  2507
                    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
  2508
                    if gui:
lordcrc@384
  2509
                        Draw.Button("S", evtLuxGui, gui.x, gui.y-gui.h, gui.h, gui.h, "focus selected object", lambda e,v:setFocus("S"))
lordcrc@384
  2510
                        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
  2511
lordcrc@384
  2512
        if camtype.get() == "perspective" and usedof.get() == "true":
lordcrc@384
  2513
            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
  2514
            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
  2515
            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
  2516
lordcrc@384
  2517
        useaspect = luxProp(cam, "useaspectratio", "false")
lordcrc@384
  2518
        aspectratio = luxProp(cam, "ratio", 1.3333)
lordcrc@384
  2519
        if camtype.get() in ["perspective", "orthographic"]:
lordcrc@384
  2520
            useshift = luxProp(cam, "camera.useshift", "false")
lordcrc@384
  2521
            luxCollapse("useshift", useshift, "Architectural (Lens Shift) & Aspect Ratio", "Enable Lens Shift and Aspect Ratio options", gui, 2.0)
lordcrc@384
  2522
            if(useshift.get() == "true"):
lordcrc@384
  2523
                if gui: gui.newline("  Shift:")
lordcrc@384
  2524
                luxFloat("X", luxAttr(cam, "shiftX"), -2.0, 2.0, "X", "horizontal lens shift", gui)
lordcrc@384
  2525
                luxFloat("Y", luxAttr(cam, "shiftY"), -2.0, 2.0, "Y", "vertical lens shift", gui)
lordcrc@384
  2526
lordcrc@384
  2527
                if gui: gui.newline("  AspectRatio:")
lordcrc@384
  2528
                luxBool("useaspectratio", useaspect, "Custom", "Define a custom frame aspect ratio", gui)
lordcrc@384
  2529
                if useaspect.get() == "true":
lordcrc@384
  2530
                    str += luxFloat("frameaspectratio", aspectratio, 0.0001, 3.0, "aspectratio", "Frame aspect ratio", gui)
lordcrc@384
  2531
            if context:
lordcrc@384
  2532
                if useaspect.get() == "true":
lordcrc@384
  2533
                    ratio = 1./aspectratio.get()
lordcrc@384
  2534
                else:
lordcrc@384
  2535
                        ratio = float(context.sizeY)/float(context.sizeX)
lordcrc@384
  2536
                if ratio < 1.0:
lordcrc@384
  2537
                    screenwindow = [(2*cam.shiftX-1)*scale, (2*cam.shiftX+1)*scale, (2*cam.shiftY-ratio)*scale, (2*cam.shiftY+ratio)*scale]
lordcrc@384
  2538
                else:
lordcrc@384
  2539
                    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
  2540
                # render region option
lordcrc@384
  2541
                if context.borderRender:
lordcrc@384
  2542
                    (x1,y1,x2,y2) = context.border
lordcrc@384
  2543
                    screenwindow = [screenwindow[0]*(1-x1)+screenwindow[1]*x1, screenwindow[0]*(1-x2)+screenwindow[1]*x2,\
lordcrc@384
  2544
                            screenwindow[2]*(1-y1)+screenwindow[3]*y1, screenwindow[2]*(1-y2)+screenwindow[3]*y2]
lordcrc@384
  2545
                str += "\n   \"float screenwindow\" [%f %f %f %f]"%(screenwindow[0], screenwindow[1], screenwindow[2], screenwindow[3])
lordcrc@384
  2546
lordcrc@384
  2547
        # Note - radiance - this is a work in progress
lordcrc@384
  2548
        # Flash lamp option for perspective and ortho cams
lordcrc@384
  2549
#        if camtype.get() in ["perspective", "orthographic"]:
lordcrc@384
  2550
#            useflash = luxProp(cam, "useflash", "false")
lordcrc@384
  2551
#            luxBool("useflash", useflash, "Flash Lamp", "Enable Camera mounted flash lamp options", gui, 2.0)
lordcrc@384
  2552
lordcrc@384
  2553
        # Motion Blur Options (common to all cameras)
lordcrc@384
  2554
        usemblur = luxProp(cam, "usemblur", "false")
lordcrc@384
  2555
        luxCollapse("usemblur", usemblur, "Motion Blur", "Enable Motion Blur", gui, 2.0)
lordcrc@384
  2556
        if(usemblur.get() == "true"):    
lordcrc@384
  2557
            if gui: gui.newline("  Shutter:")
lordcrc@384
  2558
            mblurpreset = luxProp(cam, "mblurpreset", "true")
lordcrc@384
  2559
            luxBool("mblurpreset", mblurpreset, "Preset", "Enable use of Shutter Presets", gui, 0.4)
lordcrc@384
  2560
            if(mblurpreset.get() == "true"):
lordcrc@384
  2561
                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
  2562
                shutterpreset = luxProp(cam, "camera.shutterspeedpreset", "full frame")
lordcrc@384
  2563
                luxOption("shutterpreset", shutterpreset, shutterpresets, "shutterspeed", "Choose the Shutter speed preset.", gui, 1.0)
lordcrc@384
  2564
lordcrc@384
  2565
                fpspresets = ["10 FPS", "12 FPS", "20 FPS", "25 FPS", "29.99 FPS", "30 FPS", "50 FPS", "60 FPS"]
lordcrc@384
  2566
                shutfps = luxProp(cam, "camera.shutfps", "25 FPS")
lordcrc@384
  2567
                luxOption("shutfps", shutfps, fpspresets, "@", "Choose the number of frames per second as the time base.", gui, 0.6)
lordcrc@384
  2568
lordcrc@384
  2569
                sfps = shutfps.get()
lordcrc@384
  2570
                fps = 25
lordcrc@384
  2571
                if sfps == "10 FPS": fps = 10
lordcrc@384
  2572
                elif sfps == "12 FPS": fps = 12
lordcrc@384
  2573
                elif sfps == "20 FPS": fps = 20
lordcrc@384
  2574
                elif sfps == "25 FPS": fps = 25
lordcrc@384
  2575
                elif sfps == "29.99 FPS": fps = 29.99
lordcrc@384
  2576
                elif sfps == "30 FPS": fps = 30
lordcrc@384
  2577
                elif sfps == "50 FPS": fps = 50
lordcrc@384
  2578
                elif sfps == "60 FPS": fps = 60
lordcrc@384
  2579
lordcrc@384
  2580
                spre = shutterpreset.get()
lordcrc@384
  2581
                open = 0.0
lordcrc@384
  2582
                close = 1.0
lordcrc@384
  2583
                if spre == "full frame": close = 1.0
lordcrc@384
  2584
                elif spre == "half frame": close = 0.5
lordcrc@384
  2585
                elif spre == "quarter frame": close = 0.25
lordcrc@384
  2586
                elif spre == "1/25": close = 1.0 / 25.0 * fps
lordcrc@384
  2587
                elif spre == "1/30": close = 1.0 / 30.0 * fps
lordcrc@384
  2588
                elif spre == "1/45": close = 1.0 / 45.0 * fps
lordcrc@384
  2589
                elif spre == "1/60": close = 1.0 / 60.0 * fps
lordcrc@384
  2590
                elif spre == "1/85": close = 1.0 / 85.0 * fps
lordcrc@384
  2591
                elif spre == "1/125": close = 1.0 / 125.0 * fps
lordcrc@384
  2592
                elif spre == "1/250": close = 1.0 / 250.0 * fps
lordcrc@384
  2593
                elif spre == "1/500": close = 1.0 / 500.0 * fps
lordcrc@384
  2594
lordcrc@384
  2595
                str += "\n   \"float shutteropen\" [%f]\n   \"float shutterclose\" [%f] "%(open,close)
lordcrc@384
  2596
lordcrc@384
  2597
            else:
lordcrc@384
  2598
                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
  2599
                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
  2600
lordcrc@384
  2601
            str += luxOption("shutterdistribution", luxProp(cam, "camera.shutterdistribution", "uniform"), ["uniform", "gaussian"], "distribution", "Choose the shutter sampling distribution.", gui, 2.0)
lordcrc@384
  2602
            objectmblur = luxProp(cam, "objectmblur", "true")
lordcrc@384
  2603
            luxBool("objectmblur", objectmblur, "Object", "Enable Motion Blur for scene object motions", gui, 1.0)
lordcrc@384
  2604
            cammblur = luxProp(cam, "cammblur", "true")
lordcrc@384
  2605
            luxBool("cammblur", cammblur, "Camera", "Enable Motion Blur for Camera motion", gui, 1.0)
lordcrc@384
  2606
    return str
lordcrc@384
  2607
lordcrc@384
  2608
lordcrc@384
  2609
def get_render_resolution(scn, gui = None):
lordcrc@384
  2610
    context = scn.getRenderingContext()
lordcrc@384
  2611
    scale = luxProp(scn, "film.scale", "100 %")
lordcrc@384
  2612
    scale = int(scale.get()[:-1])
lordcrc@384
  2613
    xr = luxAttr(context, "sizeX").get()*scale/100
lordcrc@384
  2614
    yr = luxAttr(context, "sizeY").get()*scale/100
lordcrc@384
  2615
    
lordcrc@384
  2616
    return xr, yr
lordcrc@384
  2617
lordcrc@384
  2618
def luxFilm(scn, gui=None):
lordcrc@384
  2619
    str = ""
lordcrc@384
  2620
    if scn:
lordcrc@384
  2621
        filmtype = luxProp(scn, "film.type", "fleximage")
lordcrc@384
  2622
        str = luxIdentifier("Film", filmtype, ["fleximage"], "FILM", "select film type", gui)
lordcrc@384
  2623
        if filmtype.get() == "fleximage":
lordcrc@384
  2624
            context = scn.getRenderingContext()
lordcrc@384
  2625
            if context:
lordcrc@384
  2626
                if gui: gui.newline("  Resolution:")
lordcrc@384
  2627
                
lordcrc@384
  2628
                xr,yr = get_render_resolution(scn, gui)
lordcrc@384
  2629
                
lordcrc@384
  2630
                luxInt("xresolution", luxAttr(context, "sizeX"), 0, 8192, "X", "width of the render", gui, 0.666)
lordcrc@384
  2631
                luxInt("yresolution", luxAttr(context, "sizeY"), 0, 8192, "Y", "height of the render", gui, 0.666)
lordcrc@384
  2632
                scale = luxProp(scn, "film.scale", "100 %")
lordcrc@384
  2633
                luxOption("", scale, ["400 %", "200 %", "100 %", "75 %", "50 %", "25 %"], "scale", "scale resolution", gui, 0.666)
lordcrc@384
  2634
                
lordcrc@384
  2635
                # render region option
lordcrc@384
  2636
                if context.borderRender:
lordcrc@384
  2637
                    (x1,y1,x2,y2) = context.border
lordcrc@384
  2638
                    if (x1==x2) and (y1==y2): print("WARNING: empty render-region, use SHIFT-B to set render region in Blender.")
lordcrc@384
  2639
                    str += "\n   \"integer xresolution\" [%d] \n   \"integer yresolution\" [%d]"%(xr*(x2-x1), yr*(y2-y1))
lordcrc@384
  2640
                else:
lordcrc@384
  2641
                    str += "\n   \"integer xresolution\" [%d] \n   \"integer yresolution\" [%d]"%(xr, yr)
lordcrc@384
  2642
lordcrc@384
  2643
            if gui: gui.newline("  Halt:")
lordcrc@384
  2644
            str += luxInt("haltspp", luxProp(scn, "haltspp", 0), 0, 32768, "haltspp", "Stop rendering after specified amount of samples per pixel / 0 = never halt", gui)
dade@435
  2645
            str += luxInt("halttime", luxProp(scn, "halttime", 0), 0, 86400, "halttime", "Stop rendering after specified number of seconds / 0 = never halt", gui)
lordcrc@384
  2646
            palpha = luxProp(scn, "film.premultiplyalpha", "false")
lordcrc@384
  2647
            str += luxBool("premultiplyalpha", palpha, "premultiplyalpha", "Pre multiply film alpha channel during normalization", gui)
lordcrc@384
  2648
    
lordcrc@384
  2649
            if gui: gui.newline("  Tonemap:")
lordcrc@384
  2650
            tonemapkernel =    luxProp(scn, "film.tonemapkernel", "reinhard")
lordcrc@384
  2651
            str += luxOption("tonemapkernel", tonemapkernel, ["reinhard", "linear", "contrast", "maxwhite"], "Tonemapping Kernel", "Select the tonemapping kernel to use", gui, 2.0)
lordcrc@384
  2652
            if tonemapkernel.get() == "reinhard":
lordcrc@384
  2653
                autoywa = luxProp(scn, "film.reinhard.autoywa", "true")
lordcrc@384
  2654
                #str += luxBool("reinhard_autoywa", autoywa, "auto Ywa", "Automatically determine World Adaption Luminance", gui)
lordcrc@384
  2655
                if autoywa.get() == "false":
lordcrc@384
  2656
                    str += luxFloat("reinhard_ywa", luxProp(scn, "film.reinhard.ywa", 0.1), 0.001, 1.0, "Ywa", "Display/World Adaption Luminance", gui)
lordcrc@384
  2657
                str += luxFloat("reinhard_prescale", luxProp(scn, "film.reinhard.prescale", 1.0), 0.0, 10.0, "preScale", "Image scale before tonemap operator", gui)
lordcrc@384
  2658
                str += luxFloat("reinhard_postscale", luxProp(scn, "film.reinhard.postscale", 1.2), 0.0, 10.0, "postScale", "Image scale after tonemap operator", gui)
lordcrc@384
  2659
                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
  2660
            elif tonemapkernel.get() == "linear":
lordcrc@384
  2661
                str += luxFloat("linear_sensitivity", luxProp(scn, "film.linear.sensitivity", 50.0), 0.0, 1000.0, "sensitivity", "Adaption/Sensitivity", gui)
lordcrc@384
  2662
                str += luxFloat("linear_exposure", luxProp(scn, "film.linear.exposure", 1.0), 0.001, 1.0, "exposure", "Exposure duration in seconds", gui)
lordcrc@384
  2663
                str += luxFloat("linear_fstop", luxProp(scn, "film.linear.fstop", 2.8), 0.1, 64.0, "Fstop", "F-Stop", gui)
lordcrc@384
  2664
                str += luxFloat("linear_gamma", luxProp(scn, "film.linear.gamma", 1.0), 0.0, 8.0, "gamma", "Tonemap operator gamma correction", gui)
lordcrc@384
  2665
            elif tonemapkernel.get() == "contrast":
lordcrc@384
  2666
                str += luxFloat("contrast_ywa", luxProp(scn, "film.contrast.ywa", 0.1), 0.001, 1.0, "Ywa", "Display/World Adaption Luminance", gui)
lordcrc@384
  2667
lordcrc@384
  2668
            if gui: gui.newline("  Display:")
lordcrc@384
  2669
            str += luxInt("displayinterval", luxProp(scn, "film.displayinterval", 12), 4, 3600, "interval", "Set display Interval (seconds)", gui)
lordcrc@384
  2670
            
lordcrc@384
  2671
            if gui: gui.newline("  Write:")
lordcrc@384
  2672
            str += luxInt("writeinterval", luxProp(scn, "film.writeinterval", 120), 12, 3600, "interval", "Set display Interval (seconds)", gui)
lordcrc@384
  2673
lordcrc@384
  2674
        # Image File Outputs
lordcrc@384
  2675
lordcrc@384
  2676
        # LDR clamping method
lordcrc@384
  2677
        if gui: gui.newline("  Clamping:")
lordcrc@384
  2678
        ldrclampmethod = luxProp(scn, "film.ldr_clamp_method", "lum")
lordcrc@384
  2679
        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
  2680
        if gui: gui.newline()
lordcrc@384
  2681
lordcrc@384
  2682
        # OpenEXR Output
lordcrc@384
  2683
        saveexr = luxProp(scn, "film.write_exr", "false")
lordcrc@384
  2684
        str += luxCollapse("write_exr", saveexr, "OpenEXR Output", "Enable OpenEXR output", gui, 2.0)
lordcrc@384
  2685
lordcrc@384
  2686
        if saveexr.get() == "true":
lordcrc@384
  2687
            if gui: gui.newline("  OpenEXR:")
lordcrc@384
  2688
lordcrc@384
  2689
            exrchannels = luxProp(scn, "film.write_exr_channels", "RGBA")
lordcrc@384
  2690
            str += luxOption("write_exr_channels", exrchannels, ["Y", "YA", "RGB", "RGBA"], "Channels", "Select channels type to write", gui, 0.5)
lordcrc@384
  2691
            exrres = luxProp(scn, "film.write_exr_halftype", "true")
lordcrc@384
  2692
            str += luxBool("write_exr_halftype", exrres, "16bit Half", "Enable 16bit Half resolution output, otherwise 32bit float", gui, 0.5)
lordcrc@384
  2693
            exrcompression = luxProp(scn, "film.write_exr_compression", "PIZ (lossless)")
lordcrc@384
  2694
            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
  2695
lordcrc@384
  2696
            exrimaging = luxProp(scn, "film.write_exr_imaging", "true")
lordcrc@384
  2697
            str += luxBool("write_exr_applyimaging", exrimaging, "Apply Imaging/Tonemapping", "Apply Imaging and Tonemapping pipeline", gui, 1.2)
lordcrc@384
  2698
        
lordcrc@384
  2699
            if exrimaging.get()=="true":
lordcrc@384
  2700
                exrgamutclamp = luxProp(scn, "film.write_exr_gamutclamp", "true")
lordcrc@384
  2701
                str += luxBool("write_exr_gamutclamp", exrgamutclamp, "Gamut Clamp", "Clamp out of gamut (bright) pixel values", gui, 0.8)
lordcrc@384
  2702
lordcrc@384
  2703
            if gui: gui.newline()
lordcrc@384
  2704
            # Zbuf output
lordcrc@384
  2705
            exrZ = luxProp(scn, "film.write_exr_Z", "true")
lordcrc@384
  2706
            str += luxBool("write_exr_ZBuf", exrZ, "ZBuf", "Enable Z Depth Buffer channel", gui, 0.8)
lordcrc@384
  2707
            if exrZ.get() == "true":
lordcrc@384
  2708
                exrZNormalize = luxProp(scn, "film.write_exr_ZNorm", "None")
lordcrc@384
  2709
                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
  2710
lordcrc@384
  2711
        # PNG Output
lordcrc@384
  2712
        savepng = luxProp(scn, "film.write_png", "true")
lordcrc@384
  2713
        str += luxCollapse("write_png", savepng, "PNG Output", "Enable PNG (Portable Network Graphics) output", gui, 2.0)
lordcrc@384
  2714
lordcrc@384
  2715
        if savepng.get() == "true":
lordcrc@384
  2716
            if gui: gui.newline("  PNG:")
lordcrc@384
  2717
            pngchannels = luxProp(scn, "film.write_png_channels", "RGB")
lordcrc@384
  2718
            str += luxOption("write_png_channels", pngchannels, ["Y", "YA", "RGB", "RGBA"], "Channels", "Select channels type to write", gui, 0.5)
lordcrc@384
  2719
            png16bit = luxProp(scn, "film.write_png_16bit", "false")
lordcrc@384
  2720
            str += luxBool("write_png_16bit", png16bit, "16bit", "Enable 16bits per channel resolution PNG output", gui, 0.5)
lordcrc@384
  2721
            pnggamutclamp = luxProp(scn, "film.write_png_gamutclamp", "true")
lordcrc@384
  2722
            str += luxBool("write_png_gamutclamp", pnggamutclamp, "Gamut Clamp", "Clamp out of gamut (bright) pixel values", gui, 1.0)
lordcrc@384
  2723
lordcrc@384
  2724
        # Zbuf output
lordcrc@384
  2725
        #pngZ = luxProp(scn, "film.write_png_ZBuf", "false")
lordcrc@384
  2726
        #str += luxBool("write_png_ZBuf", pngZ, "ZBuf (Separate)", "Enable Z Depth Buffer channel", gui, 0.8)
lordcrc@384
  2727
        #if pngZ.get() == "true":
lordcrc@384
  2728
        #    pngZNormalize = luxProp(scn, "film.write_png_ZNorm", "Min/Max")
lordcrc@384
  2729
        #    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
  2730
lordcrc@384
  2731
        # TGA Output
lordcrc@384
  2732
        savetga = luxProp(scn, "film.write_tga", "false")
lordcrc@384
  2733
        str += luxCollapse("write_tga", savetga, "TGA Output", "Enable TGA output", gui, 2.0)
lordcrc@384
  2734
lordcrc@384
  2735
        if savetga.get() == "true":
lordcrc@384
  2736
            if gui: gui.newline("  TGA:")
lordcrc@384
  2737
            tgachannels = luxProp(scn, "film.write_tga_channels", "RGB")
lordcrc@384
  2738
            str += luxOption("write_tga_channels", tgachannels, ["Y", "RGB", "RGBA"], "Channels", "Select channels type to write", gui, 0.5)
lordcrc@384
  2739
            tgagamutclamp = luxProp(scn, "film.write_tga_gamutclamp", "true")
lordcrc@384
  2740
            str += luxBool("write_tga_gamutclamp", tgagamutclamp, "Gamut Clamp", "Clamp out of gamut (bright) pixel values", gui, 1.5)
lordcrc@384
  2741
lordcrc@384
  2742
        # Zbuf output
lordcrc@384
  2743
        #tgaZ = luxProp(scn, "film.write_tga_ZBuf", "false")
lordcrc@384
  2744
        #str += luxBool("write_tga_ZBuf", tgaZ, "ZBuf (Separate)", "Enable Z Depth Buffer channel", gui, 0.8)
lordcrc@384
  2745
        #if tgaZ.get() == "true":
lordcrc@384
  2746
        #    tgaZNormalize = luxProp(scn, "film.write_tga_ZNorm", "Min/Max")
lordcrc@384
  2747
        #    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
  2748
lordcrc@384
  2749
lordcrc@384
  2750
        # override output image dir in case of command line batch mode 
lordcrc@384
  2751
        overrideop = luxProp(scn, "overrideoutputpath", "")
lordcrc@384
  2752
        if overrideop.get() != "":
lordcrc@384
  2753
            filebase = os.path.splitext(os.path.basename(Blender.Get('filename')))[0]
lordcrc@384
  2754
            filename = overrideop.get() + "/" + filebase + "-%05d" %  (Blender.Get('curframe'))
lordcrc@384
  2755
            str += "\n   \"string filename\" [\"%s\"]"%(filename)
lordcrc@384
  2756
        else:
lordcrc@384
  2757
            fn = luxProp(scn, "filename", "default-%05d" %  (Blender.Get('curframe')))
lordcrc@384
  2758
            str += luxString("filename", fn, "File name", "save file name", None)
lordcrc@384
  2759
    
lordcrc@384
  2760
        if gui: gui.newline("  Resume:")
lordcrc@384
  2761
        resumeflm = luxProp(scn, "film.write_resume_flm", "false")
lordcrc@384
  2762
        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
  2763
        restartflm = luxProp(scn, "film.restart_resume_flm", "true")
lordcrc@384
  2764
        str += luxBool("restart_resume_flm", restartflm, "Restart/Erase", "Restart with a black flm, even it a previous flm exists", gui)
lordcrc@384
  2765
        if gui: gui.newline("  Reject:")
lordcrc@384
  2766
        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
  2767
        debugmode = luxProp(scn, "film.debug", "false")
lordcrc@384
  2768
        str += luxBool("debug", debugmode, "debug", "Turn on debug reporting and switch off reject", gui)
lordcrc@384
  2769
    
lordcrc@384
  2770
        # Colorspace
lordcrc@384
  2771
        if gui: gui.newline("  Colorspace:")
lordcrc@384
  2772
    
lordcrc@384
  2773
        cspaceusepreset = luxProp(scn, "film.colorspaceusepreset", "true")
lordcrc@384
  2774
        luxBool("colorspaceusepreset", cspaceusepreset, "Preset", "Select from a list of predefined presets", gui, 0.4)
lordcrc@384
  2775
    
lordcrc@384
  2776
        # Default values for 'sRGB - HDTV (ITU-R BT.709-5)'
lordcrc@384
  2777
        cspacewhiteX = luxProp(scn, "film.cspacewhiteX", 0.314275)
lordcrc@384
  2778
        cspacewhiteY = luxProp(scn, "film.cspacewhiteY", 0.329411)
lordcrc@384
  2779
        cspaceredX = luxProp(scn, "film.cspaceredX", 0.63)
lordcrc@384
  2780
        cspaceredY = luxProp(scn, "film.cspaceredY", 0.34)
lordcrc@384
  2781
        cspacegreenX = luxProp(scn, "film.cspacegreenX", 0.31)
lordcrc@384
  2782
        cspacegreenY = luxProp(scn, "film.cspacegreenY", 0.595)
lordcrc@384
  2783
        cspaceblueX = luxProp(scn, "film.cspaceblueX", 0.155)
lordcrc@384
  2784
        cspaceblueY = luxProp(scn, "film.cspaceblueY", 0.07)
lordcrc@384
  2785
        gamma = luxProp(scn, "film.gamma", 2.2)
lordcrc@384
  2786
    
lordcrc@384
  2787
        if(cspaceusepreset.get() == "true"):
lordcrc@384
  2788
            # preset controls
lordcrc@384
  2789
            cspace = luxProp(scn, "film.colorspace", "sRGB - HDTV (ITU-R BT.709-5)")
lordcrc@384
  2790
            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
  2791
            luxOption("colorspace", cspace, cspaces, "Colorspace", "select output working colorspace", gui, 1.6)
lordcrc@384
  2792
    
lordcrc@384
  2793
            if cspace.get()=="ROMM RGB":
lordcrc@384
  2794
                cspacewhiteX.set(0.346); cspacewhiteY.set(0.359) # D50
lordcrc@384
  2795
                cspaceredX.set(0.7347); cspaceredY.set(0.2653)
lordcrc@384
  2796
                cspacegreenX.set(0.1596); cspacegreenY.set(0.8404)
lordcrc@384
  2797
                cspaceblueX.set(0.0366); cspaceblueY.set(0.0001)
lordcrc@384
  2798
            elif cspace.get()=="Adobe RGB 98":
lordcrc@384
  2799
                cspacewhiteX.set(0.313); cspacewhiteY.set(0.329) # D65
lordcrc@384
  2800
                cspaceredX.set(0.64); cspaceredY.set(0.34)
lordcrc@384
  2801
                cspacegreenX.set(0.21); cspacegreenY.set(0.71)
lordcrc@384
  2802
                cspaceblueX.set(0.15); cspaceblueY.set(0.06)
lordcrc@384
  2803
            elif cspace.get()=="Apple RGB":
lordcrc@384
  2804
                cspacewhiteX.set(0.313); cspacewhiteY.set(0.329) # D65
lordcrc@384
  2805
                cspaceredX.set(0.625); cspaceredY.set(0.34)
lordcrc@384
  2806
                cspacegreenX.set(0.28); cspacegreenY.set(0.595)
lordcrc@384
  2807
                cspaceblueX.set(0.155); cspaceblueY.set(0.07)
lordcrc@384
  2808
            elif cspace.get()=="NTSC (FCC 1953, ITU-R BT.470-2 System M)":
lordcrc@384
  2809
                cspacewhiteX.set(0.310); cspacewhiteY.set(0.316) # C
lordcrc@384
  2810
                cspaceredX.set(0.67); cspaceredY.set(0.33)
lordcrc@384
  2811
                cspacegreenX.set(0.21); cspacegreenY.set(0.71)
lordcrc@384
  2812
                cspaceblueX.set(0.14); cspaceblueY.set(0.08)
lordcrc@384
  2813
            elif cspace.get()=="NTSC (1979) (SMPTE C, SMPTE-RP 145)":
lordcrc@384
  2814
                cspacewhiteX.set(0.313); cspacewhiteY.set(0.329) # D65
lordcrc@384
  2815
                cspaceredX.set(0.63); cspaceredY.set(0.34)
lordcrc@384
  2816
                cspacegreenX.set(0.31); cspacegreenY.set(0.595)
lordcrc@384
  2817
                cspaceblueX.set(0.155); cspaceblueY.set(0.07)
lordcrc@384
  2818
            elif cspace.get()=="PAL/SECAM (EBU 3213, ITU-R BT.470-6)":
lordcrc@384
  2819
                cspacewhiteX.set(0.313); cspacewhiteY.set(0.329) # D65
lordcrc@384
  2820
                cspaceredX.set(0.64); cspaceredY.set(0.33)
lordcrc@384
  2821
                cspacegreenX.set(0.29); cspacegreenY.set(0.60)
lordcrc@384
  2822
                cspaceblueX.set(0.15); cspaceblueY.set(0.06)
lordcrc@384
  2823
            elif cspace.get()=="CIE (1931) E":
lordcrc@384
  2824
                cspacewhiteX.set(0.333); cspacewhiteY.set(0.333) # E
lordcrc@384
  2825
                cspaceredX.set(0.7347); cspaceredY.set(0.2653)
lordcrc@384
  2826
                cspacegreenX.set(0.2738); cspacegreenY.set(0.7174)
lordcrc@384
  2827
                cspaceblueX.set(0.1666); cspaceblueY.set(0.0089)
lordcrc@384
  2828
    
lordcrc@384
  2829
            whitepointusecspace = luxProp(scn, "film.whitepointusecolorspace", "true")
lordcrc@384
  2830
            luxBool("whitepointusecolorspace", whitepointusecspace, "Colorspace Whitepoint", "Use default whitepoint for selected colorspace", gui, 1.0)
lordcrc@384
  2831
            gammausecspace = luxProp(scn, "film.gammausecolorspace", "true")
lordcrc@384
  2832
            luxBool("gammausecolorspace", gammausecspace, "Colorspace Gamma", "Use default output gamma for selected colorspace", gui, 1.0)
lordcrc@384
  2833
    
lordcrc@384
  2834
            if(whitepointusecspace.get() == "false"):
lordcrc@384
  2835
                if gui: gui.newline("  Whitepoint:")
lordcrc@384
  2836
                whitepointusepreset = luxProp(scn, "film.whitepointusepreset", "true")
lordcrc@384
  2837
                luxBool("whitepointusepreset", whitepointusepreset, "Preset", "Select from a list of predefined presets", gui, 0.4)
lordcrc@384
  2838
    
lordcrc@384
  2839
                if(whitepointusepreset.get() == "true"):
lordcrc@384
  2840
                    whitepointpresets = ["E", "D50", "D55", "D65", "D75", "A", "B", "C", "9300", "F2", "F7", "F11"]
lordcrc@384
  2841
                    whitepointpreset = luxProp(scn, "film.whitepointpreset", "D65")
lordcrc@384
  2842
                    luxOption("whitepointpreset", whitepointpreset, whitepointpresets, "  PRESET", "select Whitepoint preset", gui, 1.6)
lordcrc@384
  2843
    
lordcrc@384
  2844
                    if whitepointpreset.get()=="E": cspacewhiteX.set(0.333); cspacewhiteY.set(0.333)
lordcrc@384
  2845
                    elif whitepointpreset.get()=="D50": cspacewhiteX.set(0.346); cspacewhiteY.set(0.359)
lordcrc@384
  2846
                    elif whitepointpreset.get()=="D55": cspacewhiteX.set(0.332); cspacewhiteY.set(0.347)
lordcrc@384
  2847
                    elif whitepointpreset.get()=="D65": cspacewhiteX.set(0.313); cspacewhiteY.set(0.329)
lordcrc@384
  2848
                    elif whitepointpreset.get()=="D75": cspacewhiteX.set(0.299); cspacewhiteY.set(0.315)
lordcrc@384
  2849
                    elif whitepointpreset.get()=="A": cspacewhiteX.set(0.448); cspacewhiteY.set(0.407)
lordcrc@384
  2850
                    elif whitepointpreset.get()=="B": cspacewhiteX.set(0.348); cspacewhiteY.set(0.352)
lordcrc@384
  2851
                    elif whitepointpreset.get()=="C": cspacewhiteX.set(0.310); cspacewhiteY.set(0.316)
lordcrc@384
  2852
                    elif whitepointpreset.get()=="9300": cspacewhiteX.set(0.285); cspacewhiteY.set(0.293)
lordcrc@384
  2853
                    elif whitepointpreset.get()=="F2": cspacewhiteX.set(0.372); cspacewhiteY.set(0.375)
lordcrc@384
  2854
                    elif whitepointpreset.get()=="F7": cspacewhiteX.set(0.313); cspacewhiteY.set(0.329)
lordcrc@384
  2855
                    elif whitepointpreset.get()=="F11": cspacewhiteX.set(0.381); cspacewhiteY.set(0.377)
lordcrc@384
  2856
                else:
lordcrc@384
  2857
                    luxFloat("white X", cspacewhiteX, 0.0, 1.0, "white X", "Whitepoint X weight", gui, 0.8)
lordcrc@384
  2858
                    luxFloat("white Y", cspacewhiteY, 0.0, 1.0, "white Y", "Whitepoint Y weight", gui, 0.8)
lordcrc@384
  2859
    
lordcrc@384
  2860
            if(gammausecspace.get() == "false"):
lordcrc@384
  2861
                if gui: gui.newline("  Gamma:")
lordcrc@384
  2862
                luxFloat("gamma", gamma, 0.1, 6.0, "gamma", "Output and RGC Gamma", gui, 2.0)
lordcrc@384
  2863
        else:
lordcrc@384
  2864
            # manual controls
lordcrc@384
  2865
            luxFloat("white X", cspacewhiteX, 0.0, 1.0, "white X", "Whitepoint X weight", gui, 0.8)
lordcrc@384
  2866
            luxFloat("white Y", cspacewhiteY, 0.0, 1.0, "white Y", "Whitepoint Y weight", gui, 0.8)
lordcrc@384
  2867
            luxFloat("red X", cspaceredX, 0.0, 1.0, "red X", "Red component X weight", gui, 1.0)
lordcrc@384
  2868
            luxFloat("red Y", cspaceredY, 0.0, 1.0, "red Y", "Red component Y weight", gui, 1.0)
lordcrc@384
  2869
            luxFloat("green X", cspacegreenX, 0.0, 1.0, "green X", "Green component X weight", gui, 1.0)
lordcrc@384
  2870
            luxFloat("green Y", cspacegreenY, 0.0, 1.0, "green Y", "Green component Y weight", gui, 1.0)
lordcrc@384
  2871
            luxFloat("blue X", cspaceblueX, 0.0, 1.0, "blue X", "Blue component X weight", gui, 1.0)
lordcrc@384
  2872
            luxFloat("blue Y", cspaceblueY, 0.0, 1.0, "blue Y", "Blue component Y weight", gui, 1.0)
lordcrc@384
  2873
            if gui: gui.newline("  Gamma:")
lordcrc@384
  2874
            luxFloat("gamma", gamma, 0.1, 6.0, "gamma", "Output and RGC Gamma", gui, 2.0)
lordcrc@384
  2875
            
lordcrc@384
  2876
        str += "\n   \"float colorspace_white\" [%f %f]"%(cspacewhiteX.get(), cspacewhiteY.get())
lordcrc@384
  2877
        str += "\n   \"float colorspace_red\" [%f %f]"%(cspaceredX.get(), cspaceredY.get())
lordcrc@384
  2878
        str += "\n   \"float colorspace_green\" [%f %f]"%(cspacegreenX.get(), cspacegreenY.get())
lordcrc@384
  2879
        str += "\n   \"float colorspace_blue\" [%f %f]"%(cspaceblueX.get(), cspaceblueY.get())
lordcrc@384
  2880
        str += "\n   \"float gamma\" [%f]"%(gamma.get())
lordcrc@384
  2881
lordcrc@384
  2882
    return str
lordcrc@384
  2883
lordcrc@384
  2884
lordcrc@384
  2885
def luxPixelFilter(scn, gui=None):
lordcrc@384
  2886
    global icon_c_filter
lordcrc@384
  2887
    str = ""
lordcrc@384
  2888
    if scn:
lordcrc@384
  2889
        filtertype = luxProp(scn, "pixelfilter.type", "mitchell")
lordcrc@384
  2890
        str = luxIdentifier("PixelFilter", filtertype, ["box", "gaussian", "mitchell", "sinc", "triangle"], "FILTER", "select pixel filter type", gui, icon_c_filter)
lordcrc@384
  2891
lordcrc@384
  2892
        # Advanced toggle
lordcrc@384
  2893
        parammodeadvanced = luxProp(scn, "parammodeadvanced", "false")
lordcrc@384
  2894
        showadvanced = luxProp(scn, "pixelfilter.showadvanced", parammodeadvanced.get())
lordcrc@384
  2895
        luxBool("advanced", showadvanced, "Advanced", "Show advanced options", gui, 0.6)
lordcrc@384
  2896
        # Help toggle
lordcrc@384
  2897
        showhelp = luxProp(scn, "pixelfilter.showhelp", "false")
lordcrc@384
  2898
        luxHelp("help", showhelp, "Help", "Show Help Information", gui, 0.4)
lordcrc@384
  2899
lordcrc@384
  2900
        if filtertype.get() == "box":
lordcrc@384
  2901
            if showadvanced.get()=="true":
lordcrc@384
  2902
                # Advanced parameters
lordcrc@384
  2903
                if gui: gui.newline()
lordcrc@384
  2904
                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
  2905
                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
  2906
        if filtertype.get() == "gaussian":
lordcrc@384
  2907
            if showadvanced.get()=="true":
lordcrc@384
  2908
                # Advanced parameters
lordcrc@384
  2909
                if gui: gui.newline()
lordcrc@384
  2910
                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
  2911
                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
  2912
                if gui: gui.newline()
lordcrc@384
  2913
                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
  2914
        if filtertype.get() == "mitchell":
lordcrc@384
  2915
            if showadvanced.get()=="false":
lordcrc@384
  2916
                # Default parameters
lordcrc@384
  2917
                if gui: gui.newline("", 8, 0, None, [0.4,0.4,0.4])
lordcrc@384
  2918
                slidval = luxProp(scn, "pixelfilter.mitchell.sharp", 0.25)
lordcrc@384
  2919
                luxFloat("sharpness", slidval, 0.0, 1.0, "sharpness", "Specify amount between blurred (left) and sharp/ringed (right)", gui, 2.0, 1)
lordcrc@384
  2920
                # rule: B + 2*c = 1.0
lordcrc@384
  2921
                C = slidval.getFloat() * 0.5
lordcrc@384
  2922
                B = 1.0 - slidval.getFloat()
lordcrc@384
  2923
                str += "\n   \"float B\" [%f]"%(B)
lordcrc@384
  2924
                str += "\n   \"float C\" [%f]"%(C)
lordcrc@384
  2925
lordcrc@384
  2926
            if showadvanced.get()=="true":
lordcrc@384
  2927
                # Advanced parameters
lordcrc@384
  2928
                if gui: gui.newline()
lordcrc@384
  2929
                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
  2930
                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
  2931
                if gui: gui.newline()
lordcrc@384
  2932
    
lordcrc@384
  2933
                optmode = luxProp(scn, "pixelfilter.mitchell.optmode", "slider")
lordcrc@384
  2934
                luxOption("optmode", optmode, ["slider", "preset", "manual"], "Mode", "Mode of configuration", gui, 0.5)
lordcrc@384
  2935
    
lordcrc@384
  2936
                if(optmode.get() == "slider"):
lordcrc@384
  2937
                    slidval = luxProp(scn, "pixelfilter.mitchell.sharp", 0.33)
lordcrc@384
  2938
                    luxFloat("sharpness", slidval, 0.0, 1.0, "sharpness", "Specify amount between blurred (left) and sharp/ringed (right)", gui, 1.5, 1)
lordcrc@384
  2939
                    # rule: B + 2*c = 1.0
lordcrc@384
  2940
                    C = slidval.getFloat() * 0.5
lordcrc@384
  2941
                    B = 1.0 - slidval.getFloat()
lordcrc@384
  2942
                    str += "\n   \"float B\" [%f]"%(B)
lordcrc@384
  2943
                    str += "\n   \"float C\" [%f]"%(C)
lordcrc@384
  2944
                elif(optmode.get() == "preset"):
lordcrc@384
  2945
                    print("not implemented")
lordcrc@384
  2946
                else:
lordcrc@384
  2947
                    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
  2948
                    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
  2949
lordcrc@384
  2950
        if filtertype.get() == "sinc":
lordcrc@384
  2951
            if showadvanced.get()=="true":
lordcrc@384
  2952
                # Advanced parameters
lordcrc@384
  2953
                if gui: gui.newline()
lordcrc@384
  2954
                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
  2955
                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
  2956
                if gui: gui.newline()
lordcrc@384
  2957
                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
  2958
        if filtertype.get() == "triangle":
lordcrc@384
  2959
            if showadvanced.get()=="true":
lordcrc@384
  2960
                # Advanced parameters
lordcrc@384
  2961
                if gui: gui.newline()
lordcrc@384
  2962
                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
  2963
                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
  2964
    return str            
lordcrc@384
  2965
lordcrc@384
  2966
def luxSampler(scn, gui=None):
lordcrc@384
  2967
    global icon_c_sampler, icon_help
lordcrc@384
  2968
    str = ""
lordcrc@384
  2969
    if scn:
lordcrc@384
  2970
        samplertype = luxProp(scn, "sampler.type", "metropolis")
lordcrc@384
  2971
        str = luxIdentifier("Sampler", samplertype, ["metropolis", "erpt", "lowdiscrepancy", "random"], "SAMPLER", "select sampler type", gui, icon_c_sampler)
lordcrc@384
  2972
lordcrc@384
  2973
        # Advanced toggle
lordcrc@384
  2974
        parammodeadvanced = luxProp(scn, "parammodeadvanced", "false")
lordcrc@384
  2975
        showadvanced = luxProp(scn, "sampler.showadvanced", parammodeadvanced.get())
lordcrc@384
  2976
        luxBool("advanced", showadvanced, "Advanced", "Show advanced options", gui, 0.6)
lordcrc@384
  2977
        # Help toggle
lordcrc@384
  2978
        showhelp = luxProp(scn, "sampler.showhelp", "false")
lordcrc@384
  2979
        luxHelp("help", showhelp, "Help", "Show Help Information", gui, 0.4)
lordcrc@384
  2980
lordcrc@384
  2981
        if samplertype.get() == "metropolis":
lordcrc@384
  2982
            if showadvanced.get()=="false":
lordcrc@384
  2983
                # Default parameters
lordcrc@384
  2984
                if gui: gui.newline("  Mutation:", 8, 0, None, [0.4,0.4,0.4])
lordcrc@384
  2985
                strength = luxProp(scn, "sampler.metro.strength", 0.6)
lordcrc@384
  2986
                luxFloat("strength", strength, 0.0, 1.0, "strength", "Mutation Strength (lmprob = 1.0-strength)", gui, 2.0, 1)
lordcrc@384
  2987
                v = 1.0 - strength.get()
lordcrc@384
  2988
                str += "\n   \"float largemutationprob\" [%f]"%v
lordcrc@384
  2989
            if showadvanced.get()=="true":
lordcrc@384
  2990
                # Advanced parameters
lordcrc@384
  2991
                if gui: gui.newline("  Mutation:")
lordcrc@384
  2992
                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
  2993
                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
  2994
                if gui: gui.newline("  Screen:")
lordcrc@384
  2995
                #str += luxInt("initsamples", luxProp(scn, "sampler.metro.initsamples", 262144), 1, 1000000, "initsamples", "", gui)
lordcrc@384
  2996
                str += luxBool("usevariance",luxProp(scn, "sampler.metro.usevariance", "false"), "usevariance", "Accept based on variance", gui, 1.0)
lordcrc@384
  2997
lordcrc@384
  2998
            if showhelp.get()=="true":
lordcrc@384
  2999
                if gui: gui.newline("  Description:", 8, 0, icon_help, [0.4,0.5,0.56])
lordcrc@384
  3000
                r = gui.getRect(2,1); BGL.glRasterPos2i(r[0],r[1]+5) 
lordcrc@384
  3001
                Draw.Text("A Metropolis-Hastings mutating sampler which implements MLT", 'small')    
lordcrc@384
  3002
lordcrc@384
  3003
        if samplertype.get() == "erpt":
lordcrc@384
  3004
            #str += luxInt("initsamples", luxProp(scn, "sampler.erpt.initsamples", 100000), 1, 1000000, "initsamples", "", gui)
lordcrc@384
  3005
            if gui: gui.newline("  Mutation:")
lordcrc@384
  3006
            str += luxInt("chainlength", luxProp(scn, "sampler.erpt.chainlength", 512), 1, 32768, "chainlength", "The number of mutations from a given seed", gui)
lordcrc@384
  3007
            if gui: gui.newline()
lordcrc@384
  3008
            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
  3009
lordcrc@384
  3010
        if samplertype.get() == "lowdiscrepancy":
lordcrc@384
  3011
            if gui: gui.newline("  PixelSampler:")
lordcrc@384
  3012
            str += luxOption("pixelsampler", luxProp(scn, "sampler.lowdisc.pixelsampler", "lowdiscrepancy"), ["linear", "tile", "random", "vegas","lowdiscrepancy","hilbert"], "pixel-sampler", "select pixel-sampler", gui)
lordcrc@384
  3013
            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
  3014
lordcrc@384
  3015
        if samplertype.get() == "random":
lordcrc@384
  3016
            if gui: gui.newline("  PixelSampler:")
lordcrc@384
  3017
            str += luxOption("pixelsampler", luxProp(scn, "sampler.random.pixelsampler", "vegas"), ["linear", "tile", "random", "vegas","lowdiscrepancy","hilbert"], "pixel-sampler", "select pixel-sampler", gui)
lordcrc@384
  3018
            if gui: gui.newline()
lordcrc@384
  3019
            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
  3020
    return str            
lordcrc@384
  3021
lordcrc@384
  3022
def luxSurfaceIntegrator(scn, gui=None):
lordcrc@384
  3023
    global icon_c_integrator
lordcrc@384
  3024
    str = ""
lordcrc@384
  3025
    if scn:
lordcrc@384
  3026
        integratortype = luxProp(scn, "sintegrator.type", "bidirectional")
lordcrc@384
  3027
        
lordcrc@384
  3028
        str = luxIdentifier("SurfaceIntegrator", integratortype, ["directlighting", "path", "bidirectional", "exphotonmap", "distributedpath", "igi" ], "INTEGRATOR", "select surface integrator type", gui, icon_c_integrator)
lordcrc@384
  3029
lordcrc@384
  3030
        # Advanced toggle
lordcrc@384
  3031
        parammodeadvanced = luxProp(scn, "parammodeadvanced", "false")
lordcrc@384
  3032
        showadvanced = luxProp(scn, "sintegrator.showadvanced", parammodeadvanced.get())
lordcrc@384
  3033
        luxBool("advanced", showadvanced, "Advanced", "Show advanced options", gui, 0.6)
lordcrc@384
  3034
        # Help toggle
lordcrc@384
  3035
        showhelp = luxProp(scn, "sintegrator.showhelp", "false")
lordcrc@384
  3036
        luxHelp("help", showhelp, "Help", "Show Help Information", gui, 0.4)
lordcrc@384
  3037
lordcrc@384
  3038
        if integratortype.get() == "directlighting":
lordcrc@384
  3039
            if showadvanced.get()=="false":
lordcrc@384
  3040
                # Default parameters
lordcrc@384
  3041
                if gui: gui.newline("  Depth:", 8, 0, None, [0.4,0.4,0.4])
lordcrc@384
  3042
                str += luxInt("maxdepth", luxProp(scn, "sintegrator.dlighting.maxdepth", 8), 0, 2048, "bounces", "The maximum recursion depth for ray casting", gui, 2.0)
lordcrc@384
  3043
lordcrc@384
  3044
            if showadvanced.get()=="true":
lordcrc@384
  3045
                # Advanced parameters
lordcrc@384
  3046
                str += luxOption("strategy", luxProp(scn, "sintegrator.dlighting.strategy", "auto"), ["one", "all", "auto"], "strategy", "select directlighting strategy", gui)
lordcrc@384
  3047
                if gui: gui.newline("  Depth:")
lordcrc@384
  3048
                str += luxInt("maxdepth", luxProp(scn, "sintegrator.dlighting.maxdepth", 8), 0, 2048, "max-depth", "The maximum recursion depth for ray casting", gui)
lordcrc@384
  3049
                if gui: gui.newline()
lordcrc@384
  3050
lordcrc@384
  3051
        if integratortype.get() == "path":
lordcrc@384
  3052
            if showadvanced.get()=="false":
lordcrc@384
  3053
                # Default parameters
lordcrc@384
  3054
                if gui: gui.newline("  Depth:", 8, 0, None, [0.4,0.4,0.4])
lordcrc@384
  3055
                str += luxInt("maxdepth", luxProp(scn, "sintegrator.path.maxdepth", 10), 0, 2048, "bounces", "The maximum recursion depth for ray casting", gui, 1.0)
lordcrc@384
  3056
                ienv = luxProp(scn, "sintegrator.path.ienvironment", "true")
lordcrc@384
  3057
                str += luxBool("includeenvironment", ienv, "Include Environment", "Enable/Disable rendering of environment lightsources", gui)
lordcrc@384
  3058
lordcrc@384
  3059
            if showadvanced.get()=="true":
lordcrc@384
  3060
                # Advanced parameters
lordcrc@384
  3061
                if gui: gui.newline("  Depth:")
lordcrc@384
  3062
                str += luxInt("maxdepth", luxProp(scn, "sintegrator.path.maxdepth", 10), 0, 2048, "maxdepth", "The maximum recursion depth for ray casting", gui)
lordcrc@384
  3063
                str += luxOption("strategy", luxProp(scn, "sintegrator.path.strategy", "auto"), ["one", "all", "auto"], "strategy", "select directlighting strategy", gui)
lordcrc@384
  3064
                if gui: gui.newline("  RR:")
lordcrc@384
  3065
                rrstrat = luxProp(scn, "sintegrator.path.rrstrategy", "efficiency")
lordcrc@384
  3066
                str += luxOption("rrstrategy", rrstrat, ["efficiency", "probability", "none"], "RR strategy", "select Russian Roulette path termination strategy", gui)
lordcrc@384
  3067
                if rrstrat.get() == "probability":
lordcrc@384
  3068
                    str += luxFloat("rrcontinueprob", luxProp(scn, "sintegrator.path.rrcontinueprob", 0.65), 0.0, 1.0, "rrprob", "Russian roulette continue probability", gui)
lordcrc@384
  3069
                ienv = luxProp(scn, "sintegrator.path.ienvironment", "true")
lordcrc@384
  3070
                str += luxBool("includeenvironment", ienv, "Include Environment", "Enable/Disable rendering of environment lightsources", gui)
lordcrc@384
  3071
lordcrc@384
  3072
        if integratortype.get() == "bidirectional":
lordcrc@384
  3073
            if showadvanced.get()=="false":
lordcrc@384
  3074
                # Default parameters
lordcrc@384
  3075
                if gui: gui.newline("  Depth:", 8, 0, None, [0.4,0.4,0.4])
lordcrc@384
  3076
                bounces = luxProp(scn, "sintegrator.bidir.bounces", 16)
lordcrc@384
  3077
                luxInt("bounces", bounces, 5, 32, "bounces", "The maximum recursion depth for ray casting (in both directions)", gui, 2.0)
lordcrc@384
  3078
                str += "\n   \"integer eyedepth\" [%i]\n"%bounces.get()
lordcrc@384
  3079
                str += "   \"integer lightdepth\" [%i]"%bounces.get()
lordcrc@384
  3080
lordcrc@384
  3081
            if showadvanced.get()=="true":
lordcrc@384
  3082
                # Advanced parameters
lordcrc@384
  3083
                if gui: gui.newline("  Depth:")
lordcrc@384
  3084
                str += luxInt("eyedepth", luxProp(scn, "sintegrator.bidir.eyedepth", 16), 0, 2048, "eyedepth", "The maximum recursion depth for ray casting", gui)
lordcrc@384
  3085
                str += luxInt("lightdepth", luxProp(scn, "sintegrator.bidir.lightdepth", 16), 0, 2048, "lightdepth", "The maximum recursion depth for light ray casting", gui)
lordcrc@384
  3086
                str += luxOption("strategy", luxProp(scn, "sintegrator.bidir.strategy", "auto"), ["one", "all", "auto"], "strategy", "select directlighting strategy", gui)
doug@395
  3087
                
doug@395
  3088
                str += luxFloat('eyerrthreshold', luxProp(scn, "sintegrator.bidir.eyerrthreshold", 0), 0, 1, "eyerrthreshold", "The minimum probability for russian roulette eye subpath termination ", gui)
doug@395
  3089
                str += luxFloat('lightrrthreshold', luxProp(scn, "sintegrator.bidir.lightrrthreshold", 0), 0, 1, "lightrrthreshold", "The minimum probability for russian roulette light subpath termination ", gui)
lordcrc@384
  3090
lordcrc@384
  3091
        if integratortype.get() == "exphotonmap":
lordcrc@384
  3092
            if gui: gui.newline("  Render:")
lordcrc@384
  3093
            str += luxOption("renderingmode", luxProp(scn, "sintegrator.photonmap.renderingmode", "directlighting"), ["directlighting", "path"], "renderingmode", "select rendering mode", gui)
lordcrc@384
  3094
            str += luxOption("strategy", luxProp(scn, "sintegrator.photonmap.strategy", "auto"), ["one", "all", "auto"], "strategy", "select directlighting strategy", gui)
lordcrc@384
  3095
            str += luxInt("maxphotondepth", luxProp(scn, "sintegrator.photonmap.maxphotondepth", 10), 1, 1024, "maxphotondepth", "The maximum recursion depth of photon tracing", gui)
lordcrc@384
  3096
            str += luxInt("maxdepth", luxProp(scn, "sintegrator.photonmap.maxdepth", 6), 1, 1024, "maxdepth", "The maximum recursion depth of specular reflection and refraction", gui)
lordcrc@384
  3097
            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
  3098
            str += luxInt("nused", luxProp(scn, "sintegrator.photonmap.nused", 50), 0, 1000000, "nused", "The number of photons to use in density estimation", gui)
lordcrc@384
  3099
lordcrc@384
  3100
            if gui: gui.newline("  Photons:")
lordcrc@384
  3101
            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
  3102
            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
  3103
            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
  3104
            if gui: gui.newline("  FinalGather:")
lordcrc@384
  3105
            fg = luxProp(scn, "sintegrator.photonmap.fgather", "true")
lordcrc@384
  3106
            str += luxBool("finalgather", fg, "finalgather", "Enable use of final gather during rendering", gui)
lordcrc@384
  3107
            if fg.get() == "true":
lordcrc@384
  3108
                rrstrat = luxProp(scn, "sintegrator.photonmap.gatherrrstrategy", "efficiency")
lordcrc@384
  3109
                str += luxOption("gatherrrstrategy", rrstrat, ["efficiency", "probability", "none"], "RR strategy", "select Russian Roulette gather termination strategy", gui)
lordcrc@384
  3110
                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
  3111
                str += luxFloat("gatherangle", luxProp(scn, "sintegrator.photonmap.gangle", 10.0), 0.0, 360.0, "gatherangle", "Angle for final gather", gui)
lordcrc@384
  3112
                if rrstrat.get() == "probability":
lordcrc@384
  3113
                    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
  3114
lordcrc@384
  3115
        if integratortype.get() == "distributedpath":
lordcrc@384
  3116
            str += luxOption("strategy", luxProp(scn, "sintegrator.distributedpath.strategy", "auto"), ["one", "all", "auto"], "strategy", "select directlighting strategy", gui)
lordcrc@384
  3117
            if gui: gui.newline("  Direct:")
lordcrc@384
  3118
            str += luxBool("directsampleall",luxProp(scn, "sintegrator.distributedpath.directsampleall", "true"), "Direct ALL", "Include diffuse direct light sample at first vertex", gui, 0.7)
lordcrc@384
  3119
            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
  3120
            str += luxBool("indirectsampleall",luxProp(scn, "sintegrator.distributedpath.indirectsampleall", "false"), "Indirect ALL", "Include diffuse direct light sample at first vertex", gui, 0.7)
lordcrc@384
  3121
            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
  3122
            if gui: gui.newline("  Diffuse:")
lordcrc@384
  3123
            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
  3124
            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
  3125
            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
  3126
            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
  3127
            str += luxBool("directdiffuse",luxProp(scn, "sintegrator.distributedpath.directdiffuse", "true"), "DL", "Include diffuse direct light sample at first vertex", gui, 0.20)
lordcrc@384
  3128
            str += luxBool("indirectdiffuse",luxProp(scn, "sintegrator.distributedpath.indirectdiffuse", "true"), "IDL", "Include diffuse indirect light sample at first vertex", gui, 0.20)
lordcrc@384
  3129
            if gui: gui.newline("  Glossy:")
lordcrc@384
  3130
            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
  3131
            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
  3132
            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
  3133
            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
  3134
            str += luxBool("directglossy",luxProp(scn, "sintegrator.distributedpath.directglossy", "true"), "DL", "Include glossy direct light sample at first vertex", gui, 0.20)
lordcrc@384
  3135
            str += luxBool("indirectglossy",luxProp(scn, "sintegrator.distributedpath.indirectglossy", "true"), "IDL", "Include glossy indirect light sample at first vertex", gui, 0.20)
lordcrc@384
  3136
            if gui: gui.newline("  Specular:")
lordcrc@384
  3137
            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
  3138
            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
  3139
            #if gui: gui.newline("  Caustics:")
lordcrc@384
  3140
            #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
  3141
            #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
  3142
lordcrc@384
  3143
            usereject = luxProp(scn, "sintegrator.distributedpath.usereject", "false")
lordcrc@384
  3144
            luxCollapse("usereject", usereject, "Rejection", "Enable Rejection system to eliminate bright contributions", gui, 2.0)
lordcrc@384
  3145
lordcrc@384
  3146
            if usereject.get()=="true":
lordcrc@384
  3147
                if gui: gui.newline("  Diffuse:")
lordcrc@384
  3148
                
lordcrc@384
  3149
                diffusereflectreject = luxProp(scn, "sintegrator.distributedpath.difreflreject", "false")
lordcrc@384
  3150
                str += luxBool("diffusereflectreject", diffusereflectreject, "Reflect", "Enable Rejection for Diffuse Reflection", gui, 0.4)
lordcrc@384
  3151
                if diffusereflectreject.get()=="true":
lordcrc@384
  3152
                    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
  3153
            
lordcrc@384
  3154
                diffuserefractreject = luxProp(scn, "sintegrator.distributedpath.difrefrreject", "false")
lordcrc@384
  3155
                str += luxBool("diffuserefractreject", diffuserefractreject, "Refract", "Enable Rejection for Diffuse Refraction", gui, 0.4)
lordcrc@384
  3156
                if diffuserefractreject.get()=="true":
lordcrc@384
  3157
                    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
  3158
            
lordcrc@384
  3159
                if gui: gui.newline("  Glossy:")
lordcrc@384
  3160
                
lordcrc@384
  3161
                glossyreflectreject = luxProp(scn, "sintegrator.distributedpath.glosreflreject", "false")
lordcrc@384
  3162
                str += luxBool("glossyreflectreject", glossyreflectreject, "Reflect", "Enable Rejection for Glossy Reflection", gui, 0.4)
lordcrc@384
  3163
                if glossyreflectreject.get()=="true":
lordcrc@384
  3164
                    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
  3165
            
lordcrc@384
  3166
                glossyrefractreject = luxProp(scn, "sintegrator.distributedpath.glosrefrreject", "false")
lordcrc@384
  3167
                str += luxBool("glossyrefractreject", glossyrefractreject, "Refract", "Enable Rejection for Glossy Refraction", gui, 0.4)
lordcrc@384
  3168
                if glossyrefractreject.get()=="true":
lordcrc@384
  3169
                    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
  3170
    
lordcrc@384
  3171
        if integratortype.get() == "igi":
lordcrc@384
  3172
            if gui: gui.newline("  Depth:", 8, 0, None, [0.4,0.4,0.4])
lordcrc@384
  3173
            depth = luxProp(scn, "sintegrator.igi.maxdepth", 5)
lordcrc@384
  3174
            luxInt("maxdepth", depth, 1, 32, "maxdepth", "The maximum recursion depth for ray casting", gui, 2.0)
lordcrc@384
  3175
            if showadvanced.get()=="true":
lordcrc@384
  3176
                # Advanced parameters
lordcrc@384
  3177
                if gui: gui.newline("  VLights:")
lordcrc@384
  3178
                str += luxInt("nsets", luxProp(scn, "sintegrator.igi.nsets", 4), 1, 100, "nsets", "The number of virtual lights sets", gui)
lordcrc@384
  3179
                str += luxInt("nlights", luxProp(scn, "sintegrator.igi.nlights", 64), 1, 1000, "nlights", "The number of light paths per light set", gui)
lordcrc@384
  3180
                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
  3181
lordcrc@384
  3182
    
lordcrc@384
  3183
    return str
lordcrc@384
  3184
lordcrc@384
  3185
def luxVolumeIntegrator(scn, gui=None):
lordcrc@384
  3186
    global icon_c_volumeintegrator
lordcrc@384
  3187
    str = ""
lordcrc@384
  3188
    if scn:
lordcrc@384
  3189
        integratortype = luxProp(scn, "vintegrator.type", "single")
lordcrc@384
  3190
        str = luxIdentifier("VolumeIntegrator", integratortype, ["emission", "single"], "VOLUME INT", "select volume integrator type", gui, icon_c_volumeintegrator)
lordcrc@384
  3191
        if integratortype.get() == "emission":
lordcrc@384
  3192
            str += luxFloat("stepsize", luxProp(scn, "vintegrator.emission.stepsize", 1.0), 0.0, 100.0, "stepsize", "Stepsize for volumes", gui)
lordcrc@384
  3193
        if integratortype.get() == "single":
lordcrc@384
  3194
            str += luxFloat("stepsize", luxProp(scn, "vintegrator.emission.stepsize", 1.0), 0.0, 100.0, "stepsize", "Stepsize for volumes", gui)
lordcrc@384
  3195
    return str
lordcrc@384
  3196
lordcrc@384
  3197
def luxEnvironment(scn, gui=None):
lordcrc@384
  3198
    global icon_c_environment
lordcrc@384
  3199
    str = ""
lordcrc@384
  3200
    if scn:
lordcrc@384
  3201
        envtype = luxProp(scn, "env.type", "infinite")
lordcrc@384
  3202
        lsstr = luxIdentifier("LightSource", envtype, ["none", "infinite", "sunsky"], "ENVIRONMENT", "select environment light type", gui, icon_c_environment)
lordcrc@384
  3203
        if gui: gui.newline()
lordcrc@384
  3204
        str = ""
lordcrc@384
  3205
        
lordcrc@384
  3206
        if envtype.get() != "none":
lordcrc@384
  3207
            
lordcrc@384
  3208
            if envtype.get() in ["infinite", "sunsky"]:
lordcrc@384
  3209
                env_lg = luxProp(scn, "env.lightgroup", "default")
lordcrc@384
  3210
                luxString("env.lightgroup", env_lg, "lightgroup", "Environment light group", gui)
lordcrc@384
  3211
                if luxProp(scn, "nolg", "false").get()!="true":
lordcrc@384
  3212
                    lsstr = '\nLightGroup "' + env_lg.get() + '"' + lsstr
lordcrc@384
  3213
                rotZ = luxProp(scn, "env.rotation", 0.0)
lordcrc@384
  3214
                rotY = luxProp(scn, "env.rotationY", 0.0)
lordcrc@384
  3215
                rotX = luxProp(scn, "env.rotationX", 0.0)
lordcrc@384
  3216
                if gui: gui.newline()
lordcrc@384
  3217
                luxFloat("rotation", rotX, 0.0, 360.0, "rot X", "environment rotation X", gui, 0.66)
lordcrc@384
  3218
                luxFloat("rotation", rotY, 0.0, 360.0, "rot Y", "environment rotation Y", gui, 0.66)
lordcrc@384
  3219
                luxFloat("rotation", rotZ, 0.0, 360.0, "rot Z", "environment rotation Z", gui, 0.66)
lordcrc@384
  3220
                if rotZ.get() != 0 or rotY.get() != 0 or rotX.get() != 0:
lordcrc@384
  3221
                    str += "\tRotate %d 1 0 0\n"%(rotX.get())
lordcrc@384
  3222
                    str += "\tRotate %d 0 1 0\n"%(rotY.get())
lordcrc@384
  3223
                    str += "\tRotate %d 0 0 1\n"%(rotZ.get())
lordcrc@384
  3224
            str += "\t"+lsstr
lordcrc@384
  3225
lordcrc@384
  3226
            infinitehassun = 0
lordcrc@384
  3227
            if envtype.get() == "infinite":
lordcrc@384
  3228
                mapping = luxProp(scn, "env.infinite.mapping", "latlong")
lordcrc@384
  3229
                mappings = ["latlong","angular","vcross"]
lordcrc@384
  3230
                mapstr = luxOption("mapping", mapping, mappings, "mapping", "Select mapping type", gui, 0.5)
lordcrc@384
  3231
                map = luxProp(scn, "env.infinite.mapname", "")
lordcrc@384
  3232
                mapstr += luxFile("mapname", map, "map-file", "filename of the environment map", gui, 1.5)
lordcrc@384
  3233
                mapstr += luxFloat("gamma", luxProp(scn, "env.infinite.gamma", 1.0), 0.0, 6.0, "gamma", "", gui, 1.0)
lordcrc@384
  3234
                
lordcrc@384
  3235
                if map.get() != "":
lordcrc@384
  3236
                    str += mapstr
lordcrc@384
  3237
                else:
lordcrc@384
  3238
                    try:
lordcrc@384
  3239
                        worldcolor = Blender.World.Get('World').getHor()
lordcrc@384
  3240
                        str += "\n   \"color L\" [%g %g %g]" %(worldcolor[0], worldcolor[1], worldcolor[2])
lordcrc@384
  3241
                    except: pass
lordcrc@384
  3242
lordcrc@384
  3243
                str += luxFloat("gain", luxProp(scn, "env.infinite.gain", 1.0), 0.0001, 100.0, "gain", "Infinite Env Gain", gui, 1.0)
lordcrc@384
  3244
lordcrc@384
  3245
                infinitesun = luxProp(scn, "env.infinite.hassun", "false")
lordcrc@384
  3246
                luxCollapse("infinitesun", infinitesun, "Sun Component", "Add Sunlight Component", gui, 2.0)
lordcrc@384
  3247
                if(infinitesun.get() == "true"):
lordcrc@384
  3248
                    sun_lg = luxProp(scn, "env.sun_lightgroup", "default")
lordcrc@384
  3249
                    luxString("env.lightgroup", sun_lg, "lightgroup", "Sun component light group", gui)
lordcrc@384
  3250
                    if luxProp(scn, "nolg", "false").get()!="true":
lordcrc@384
  3251
                        str += '\nLightGroup "' + sun_lg.get() + '"'
lordcrc@384
  3252
                    str += "\nLightSource \"sun\" "
lordcrc@384
  3253
                    infinitehassun = 1
lordcrc@384
  3254
lordcrc@384
  3255
lordcrc@384
  3256
            if envtype.get() == "sunsky" or infinitehassun == 1:
lordcrc@384
  3257
                
lordcrc@384
  3258
                
lordcrc@384
  3259
                sun = None
lordcrc@384
  3260
                for obj in scn.objects:
lordcrc@384
  3261
                    if (obj.getType() == "Lamp") and ((obj.Layers & scn.Layers) > 0):
lordcrc@384
  3262
                        if obj.getData(mesh=1).getType() == 1: # sun object # data
lordcrc@384
  3263
                            sun = obj
lordcrc@384
  3264
                if sun:
lordcrc@384
  3265
                    str += luxFloat("gain", luxProp(scn, "env.sunsky.gain", 1.0), 0.0001, 100.0, "gain", "Sky gain", gui)
lordcrc@384
  3266
                    
lordcrc@384
  3267
                    invmatrix = Mathutils.Matrix(sun.getInverseMatrix())
lordcrc@384
  3268
                    str += "\n   \"vector sundir\" [%f %f %f]\n" %(invmatrix[0][2], invmatrix[1][2], invmatrix[2][2])
lordcrc@384
  3269
                    str += luxFloat("relsize", luxProp(scn, "env.sunsky.relsize", 1.0), 0.0, 100.0, "rel.size", "relative sun size", gui)
lordcrc@384
  3270
                    str += luxFloat("turbidity", luxProp(scn, "env.sunsky.turbidity", 2.2), 2.0, 50.0, "turbidity", "Sky turbidity", gui)
lordcrc@384
  3271
                    
lordcrc@384
  3272
                    showGeo = luxProp(sun, 'sc.show', 'false')
lordcrc@384
  3273
                    if gui:
lordcrc@384
  3274
                        luxCollapse("sc.show", showGeo, "Geographic Sun", "Set sun position by world location, date and time", gui, 2.0)
lordcrc@384
  3275
                    if gui and showGeo.get() == 'true':
lordcrc@384
  3276
                        gui.newline("Geographic:")
lordcrc@384
  3277
                        sc = sun_calculator(sun)
lordcrc@384
  3278
                        
lordcrc@384
  3279
                        luxInt("sc.day", luxProp(sun, "sc.day", 1), 1, 31, "day", "Local date: day", gui, 0.66)
lordcrc@384
  3280
                        luxInt("sc.month", luxProp(sun, "sc.month", 1), 1, 12, "month", "Local date: month", gui, 0.67)
lordcrc@384
  3281
                        luxInt("sc.year", luxProp(sun, "sc.year", 2009), 1800, 2100, "year", "Local date: year", gui, 0.66)
lordcrc@384
  3282
                        
lordcrc@384
  3283
                        luxInt("sc.hour", luxProp(sun, "sc.hour", 0), 0, 23, "hour", "Local time: hour", gui, 0.72)
lordcrc@384
  3284
                        luxInt("sc.minute", luxProp(sun, "sc.minute", 0), 0, 59, "minute", "Local time: minute", gui, 0.72)
lordcrc@384
  3285
                        luxBool("sc.dst", luxProp(sun, "sc.dst", 'false'), "DST", "DST", gui, 0.28)
lordcrc@384
  3286
                        r = gui.getRect(0.28,1)
lordcrc@384
  3287
                        Draw.Button("NOW", 0, r[0], r[1], r[2], r[3], "Set to current time", lambda e,v: sc.now())
lordcrc@384
  3288
                        
lordcrc@384
  3289
                        r = gui.getRect(0.3,1)
lordcrc@384
  3290
                        Draw.Button("Preset", 0, r[0], r[1], r[2], r[3], "Choose a preset location", lambda e,v: sc.set_location(
lordcrc@384
  3291
                            Draw.PupTreeMenu(sun_calculator.location_list)
lordcrc@384
  3292
                        ))
lordcrc@384
  3293
                        
lordcrc@384
  3294
                        luxFloat("sc.lat", luxProp(sun, "sc.lat", 0.0), -90.0, 90.0, "lat", "Location: latitude", gui, 0.56)
lordcrc@384
  3295
                        luxFloat("sc.long", luxProp(sun, "sc.long", 0.0), -180.0, 180.0, "long", "Location: longitude", gui, 0.56)
lordcrc@384
  3296
                        luxInt("sc.tz", luxProp(sun, "sc.tz", 0), -12, 12, "timezone", "Local time: timezone offset from GMT", gui, 0.56)
lordcrc@384
  3297
                        
lordcrc@384
  3298
                        r = gui.getRect(2,1)
lordcrc@384
  3299
                        Draw.Button("Calculate", 0, r[0], r[1], r[2], r[3], "Calculate sun's position", lambda e,v: sc.compute())
lordcrc@384
  3300
                    
lordcrc@384
  3301
                else:
lordcrc@384
  3302
                    if gui:
lordcrc@384
  3303
                        gui.newline(); r = gui.getRect(2,1); BGL.glRasterPos2i(r[0],r[1]+5) 
lordcrc@384
  3304
                        Draw.Text("create a blender Sun Lamp")
lordcrc@384
  3305
lordcrc@384
  3306
lordcrc@384
  3307
            str += "\n"
lordcrc@384
  3308
        #if gui: gui.newline("GLOBAL:", 8, 0, None, [0.75,0.5,0.25])
lordcrc@384
  3309
        #luxFloat("scale", luxProp(scn, "global.scale", 1.0), 0.0, 10.0, "scale", "global world scale", gui)
lordcrc@384
  3310
        
lordcrc@384
  3311
    return str
lordcrc@384
  3312
lordcrc@384
  3313
class sun_calculator:
lordcrc@384
  3314
    #Based on SunLight v1.0 by Miguel Kabantsov (miguelkab@gmail.com)
lordcrc@384
  3315
    #Replaces the faulty sun position calculation algorythm with a precise calculation (Source for algorythm: http://de.wikipedia.org/wiki/Sonnenstand),
lordcrc@384
  3316
    #Co-Ordinates: http://www.bcca.org/misc/qiblih/latlong.html
lordcrc@384
  3317
    #Author: Nils-Peter Fischer (Nils-Peter.Fischer@web.de)
lordcrc@384
  3318
    
lordcrc@384
  3319
    sun = None
lordcrc@384
  3320
    
lordcrc@384
  3321
    lat = 0
lordcrc@384
  3322
    long = 0
lordcrc@384
  3323
    
lordcrc@384
  3324
    hour = 0
lordcrc@384
  3325
    min = 0
lordcrc@384
  3326
    tz = 0
lordcrc@384
  3327
    dst = 'false'
lordcrc@384
  3328
    
lordcrc@384
  3329
    day = 0
lordcrc@384
  3330
    month = 0
lordcrc@384
  3331
    year = 0
lordcrc@384
  3332
    
lordcrc@384
  3333
    location_list = [
lordcrc@384
  3334
        ("EUROPE",[
lordcrc@384
  3335
            ("Antwerp, Belgium",          67),
lordcrc@384
  3336
            ("Berlin, Germany",            1),
lordcrc@384
  3337
            ("Bratislava, Slovak Republic", 70),
lordcrc@384
  3338
            ("Brno, Czech Republic",      72),
lordcrc@384
  3339
            ("Brussles, Belgium",         68),
lordcrc@384
  3340
            ("Geneva, Switzerland",       65),
lordcrc@384
  3341
            ("Helsinki, Finland",          7),
lordcrc@384
  3342
            ("Innsbruck, Austria",        62),
lordcrc@384
  3343
            ("Kyiv, Ukraine",             64),
lordcrc@384
  3344
            ("London, England",           10),
lordcrc@384
  3345
            ("Lyon, France",              66),
lordcrc@384
  3346
            ("Nitra, Slovak Republic",    69),
lordcrc@384
  3347
            ("Oslo, Norway",              58),
lordcrc@384
  3348
            ("Paris, France",             15),
lordcrc@384
  3349
            ("Praha, Czech Republic",     71),
lordcrc@384
  3350
            ("Rome, Italy",               18),
lordcrc@384
  3351
            ("Telfs, Austria",            63),
lordcrc@384
  3352
            ("Warsaw, Poland",            74),
lordcrc@384
  3353
            ("Wroclaw, Poland",           73),
lordcrc@384
  3354
            ("Zurich, Switzerland",       21),
lordcrc@384
  3355
        ]),
lordcrc@384
  3356
    
lordcrc@384
  3357
        ("WORLD CITIES", [
lordcrc@384
  3358
            ("Beijing, China",             0),
lordcrc@384
  3359
            ("Bombay, India",              2),
lordcrc@384
  3360
            ("Buenos Aires, Argentina",    3),
lordcrc@384
  3361
            ("Cairo, Egypt",               4),
lordcrc@384
  3362
            ("Cape Town, South Africa",    5),
lordcrc@384
  3363
            ("Caracas, Venezuela",         6),
lordcrc@384
  3364
            ("Curitiba, Brazil",          60),
lordcrc@384
  3365
            ("Hong Kong, China",           8),
lordcrc@384
  3366
            ("Jerusalem, Israel",          9),
lordcrc@384
  3367
            ("Joinville, Brazil",         61),
lordcrc@384
  3368
            ("Mexico City, Mexico",       11),
lordcrc@384
  3369
            ("Moscow, Russia",            12),
lordcrc@384
  3370
            ("New Delhi, India",          13),
lordcrc@384
  3371
            ("Ottawa, Canada",            14),
lordcrc@384
  3372
            ("Rio de Janeiro, Brazil",    16),
lordcrc@384
  3373
            ("Riyadh, Saudi Arabia",      17),
lordcrc@384
  3374
            ("Sao Paulo, Brazil",         59),
lordcrc@384
  3375
            ("Sydney, Australia",         19),
lordcrc@384
  3376
            ("Tokyo, Japan",              20), 
lordcrc@384
  3377
        ]),
lordcrc@384
  3378
        
lordcrc@384
  3379
        ("US CITIES", [
lordcrc@384
  3380
            ("Albuquerque, NM",           22),
lordcrc@384
  3381
            ("Anchorage, AK",             23),
lordcrc@384
  3382
            ("Atlanta, GA",               24),
lordcrc@384
  3383
            ("Austin, TX",                25),
lordcrc@384
  3384
            ("Birmingham, AL",            26),
lordcrc@384
  3385
            ("Bismarck, ND",              27),
lordcrc@384
  3386
            ("Boston, MA",                28),
lordcrc@384
  3387
            ("Boulder, CO",               29),
lordcrc@384
  3388
            ("Chicago, IL",               30),
lordcrc@384
  3389
            ("Dallas, TX",                31),
lordcrc@384
  3390
            ("Denver, CO",                32),
lordcrc@384
  3391
            ("Detroit, MI",               33),
lordcrc@384
  3392
            ("Honolulu, HI",              34),
lordcrc@384
  3393
            ("Houston, TX",               35),
lordcrc@384
  3394
            ("Indianapolis, IN",          36),
lordcrc@384
  3395
            ("Jackson, MS",               37),
lordcrc@384
  3396
            ("Kansas City, MO",           38),
lordcrc@384
  3397
            ("Los Angeles, CA",           39),
lordcrc@384
  3398
            ("Menomonee Falls, WI",       40),
lordcrc@384
  3399
            ("Miami, FL",                 41),
lordcrc@384
  3400
            ("Minneapolis, MN",           42),
lordcrc@384
  3401
            ("New Orleans, LA",           43),
lordcrc@384
  3402
            ("New York City, NY",         44),
lordcrc@384
  3403
            ("Oklahoma City, OK",         45),
lordcrc@384
  3404
            ("Philadelphia, PA",          46),
lordcrc@384
  3405
            ("Phoenix, AZ",               47),
lordcrc@384
  3406
            ("Pittsburgh, PA",            48),
lordcrc@384
  3407
            ("Portland, ME",              49),
lordcrc@384
  3408
            ("Portland, OR",              50),
lordcrc@384
  3409
            ("Raleigh, NC",               51),
lordcrc@384
  3410
            ("Richmond, VA",              52),
lordcrc@384
  3411
            ("Saint Louis, MO",           53),
lordcrc@384
  3412
            ("San Diego, CA",             54),
lordcrc@384
  3413
            ("San Francisco, CA",         55),
lordcrc@384
  3414
            ("Seattle, WA",               56),
lordcrc@384
  3415
            ("Washington DC",             57),
lordcrc@384
  3416
        ])
lordcrc@384
  3417
    ]
lordcrc@384
  3418
lordcrc@384
  3419
    location_data = {
lordcrc@384
  3420
        # Europe
lordcrc@384
  3421
        67:   ( 51.2167, 4.4, 1),
lordcrc@384
  3422
        1:    ( 52.33, 13.30, 1),
lordcrc@384
  3423
        70:   ( 48.17, 17.17, 1),
lordcrc@384
  3424
        72:   ( 49.2, 16.63, 1),
lordcrc@384
  3425
        68:   ( 58.8467, 4.3525, 1),
lordcrc@384
  3426
        65:   ( 46.217, 6.150, 1),
lordcrc@384
  3427
        7:    ( 60.1667, 24.9667,2),
lordcrc@384
  3428
        62:   ( 47.2672, 11.3928, 1),
lordcrc@384
  3429
        64:   ( 50.75, 30.0833, 2),
lordcrc@384
  3430
        10:   ( 51.50, 0.0, 0),
lordcrc@384
  3431
        66:   ( 45.767, 4.833, 1),
lordcrc@384
  3432
        69:   ( 48.32, 18.07, 1),
lordcrc@384
  3433
        58:   ( 59.56, 10.41, 1),
lordcrc@384
  3434
        15:   ( 48.8667, 2.667, 1),
lordcrc@384
  3435
        71:   ( 50.08, 14.46, 1),
lordcrc@384
  3436
        18:   ( 41.90, 12.4833, 1),
lordcrc@384
  3437
        63:   ( 47.3, 11.0667, 1),
lordcrc@384
  3438
        74:   ( 52.232, 21.008, 1),
lordcrc@384
  3439
        73:   ( 51.108, 17.038, 1),
lordcrc@384
  3440
        21:   ( 47.3833, 8.5333, 1),
lordcrc@384
  3441
    
lordcrc@384
  3442
        # World Cities
lordcrc@384
  3443
        0:    ( 39.9167, 116.4167, 8),
lordcrc@384
  3444
        2:    ( 18.9333, 72.8333, 5.5),
lordcrc@384
  3445
        3:    (-34.60, -58.45, -3),
lordcrc@384
  3446
        4:    ( 30.10, 31.3667, 2),
lordcrc@384
  3447
        5:    (-33.9167, 18.3667, 2),
lordcrc@384
  3448
        6:    ( 10.50, -66.9333, -4),
lordcrc@384
  3449
        60:   (-25.4278, -49.2731, -3),
lordcrc@384
  3450
        8:    ( 22.25, 114.1667, 8),
lordcrc@384
  3451
        9:    ( 31.7833, 35.2333, 2),
lordcrc@384
  3452
        61:   (-29.3044, -48.8456, -3),
lordcrc@384
  3453
        11:   ( 19.4, -99.15, -6),
lordcrc@384
  3454
        12:   ( 55.75, 37.5833, 3),
lordcrc@384
  3455
        13:   ( 28.6, 77.2, 5.5),
lordcrc@384
  3456
        14:   ( 45.41667, -75.7, -5),
lordcrc@384
  3457
        16:   (-22.90, -43.2333, -3),
lordcrc@384
  3458
        17:   ( 24.633, 46.71667, 3),
lordcrc@384
  3459
        59:   ( -23.5475, -46.6361, -3),
lordcrc@384
  3460
        19:   (-33.8667,151.2167,10),
lordcrc@384
  3461
        20:   ( 35.70, 139.7667, 9), 
lordcrc@384
  3462
    
lordcrc@384
  3463
        # US Cities
lordcrc@384
  3464
        22:   ( 35.0833, -106.65, -7),
lordcrc@384
  3465
        23:   ( 61.217, -149.90, -9),
lordcrc@384
  3466
        24:   ( 33.733, -84.383, -5),
lordcrc@384
  3467
        25:   ( 30.283, -97.733, -6),
lordcrc@384
  3468
        26:   ( 33.521, -86.8025, -6),
lordcrc@384
  3469
        27:   ( 46.817, -100.783, -6),
lordcrc@384
  3470
        28:   ( 42.35, -71.05, -5),
lordcrc@384
  3471
        29:   ( 40.125, -105.237, -7),
lordcrc@384
  3472
        30:   ( 41.85, -87.65, -6),
lordcrc@384
  3473
        31:   ( 32.46, -96.47, -6),
lordcrc@384
  3474
        32:   ( 39.733, -104.983, -7),
lordcrc@384
  3475
        33:   ( 42.333, -83.05, -5),
lordcrc@384
  3476
        34:   ( 21.30, -157.85, -10),
lordcrc@384
  3477
        35:   ( 29.75, -95.35, -6),
lordcrc@384
  3478
        36:   ( 39.767, -86.15, -5),
lordcrc@384
  3479
        37:   ( 32.283, -90.183, -6),
lordcrc@384
  3480
        38:   ( 39.083, -94.567, -6),
lordcrc@384
  3481
        39:   ( 34.05, -118.233, -8),
lordcrc@384
  3482
        40:   ( 43.11, -88.10, -6),
lordcrc@384
  3483
        41:   ( 25.767, -80.183, -5),
lordcrc@384
  3484
        42:   ( 44.967, -93.25, -6),
lordcrc@384
  3485
        43:   ( 29.95, -90.067, -6),
lordcrc@384
  3486
        44:   ( 40.7167, -74.0167, -5),
lordcrc@384
  3487
        45:   ( 35.483, -97.533, -6),
lordcrc@384
  3488
        46:   ( 39.95, -75.15, -5),
lordcrc@384
  3489
        47:   ( 33.433, -112.067,-7),
lordcrc@384
  3490
        48:   ( 40.433, -79.9833, -5),
lordcrc@384
  3491
        49:   ( 43.666, -70.283, -5),
lordcrc@384
  3492
        50:   ( 45.517, -122.65, -8),
lordcrc@384
  3493
        51:   ( 35.783, -78.65, -5),
lordcrc@384
  3494
        52:   ( 37.5667, -77.450, -5),
lordcrc@384
  3495
        53:   ( 38.6167, -90.1833, -6),
lordcrc@384
  3496
        54:   ( 32.7667, -117.2167, -8),
lordcrc@384
  3497
        55:   ( 37.7667, -122.4167, -8),
lordcrc@384
  3498
        56:   ( 47.60, -122.3167, -8),
lordcrc@384
  3499
        57:   ( 38.8833, -77.0333, -5),
lordcrc@384
  3500
    }
lordcrc@384
  3501
lordcrc@384
  3502
    def __init__(self, sun):
lordcrc@384
  3503
        self.sun = sun
lordcrc@384
  3504
    
lordcrc@384
  3505
    def now(self):
lordcrc@384
  3506
        ct = time.localtime()
lordcrc@384
  3507
        
lordcrc@384
  3508
        if ct[8] == 0:
lordcrc@384
  3509
            dst = 'false'
lordcrc@384
  3510
        else:
lordcrc@384
  3511
            dst = 'true'
lordcrc@384
  3512
        
lordcrc@384
  3513
        luxProp(self.sun, 'sc.day', 0).set(ct[2])
lordcrc@384
  3514
        luxProp(self.sun, 'sc.month', 0).set(ct[1])
lordcrc@384
  3515
        luxProp(self.sun, 'sc.year', 0).set(ct[0])
lordcrc@384
  3516
        luxProp(self.sun, 'sc.hour', 0).set(ct[3])
lordcrc@384
  3517
        luxProp(self.sun, 'sc.minute', 0).set(ct[4])
lordcrc@384
  3518
        luxProp(self.sun, 'sc.dst', 0).set(dst)
lordcrc@384
  3519
        
lordcrc@384
  3520
        self.compute()
lordcrc@384
  3521
        
lordcrc@384
  3522
    def set_location(self, location):
lordcrc@384
  3523
        if location < 0: return
lordcrc@384
  3524
        
lordcrc@384
  3525
        lat, long, tz = self.location_data[location]
lordcrc@384
  3526
        luxProp(self.sun, "sc.lat", 0).set(lat)
lordcrc@384
  3527
        luxProp(self.sun, "sc.long", 0).set(long)
lordcrc@384
  3528
        luxProp(self.sun, "sc.tz", 0).set(tz)
lordcrc@384
  3529
        
lordcrc@384
  3530
        self.compute()
lordcrc@384
  3531
    
lordcrc@384
  3532
    def compute(self):
lordcrc@384
  3533
        
lordcrc@384
  3534
        self.lat  = luxProp(self.sun, "sc.lat", 0).get()
lordcrc@384
  3535
        self.long = luxProp(self.sun, "sc.long", 0).get()
lordcrc@384
  3536
        self.tz   = luxProp(self.sun, "sc.tz", 0).get()
lordcrc@384
  3537
        
lordcrc@384
  3538
        self.hour = luxProp(self.sun, "sc.hour", 0).get()
lordcrc@384
  3539
        self.min  = luxProp(self.sun, "sc.minute", 0).get()
lordcrc@384
  3540
        self.dst  = luxProp(self.sun, "sc.dst", 'false').get()
lordcrc@384
  3541
        if self.dst == 'true':
lordcrc@384
  3542
            self.dst = 1
lordcrc@384
  3543
        else:
lordcrc@384
  3544
            self.dst = 0
lordcrc@384
  3545
        
lordcrc@384
  3546
        self.day   = luxProp(self.sun, "sc.day", 0).get()
lordcrc@384
  3547
        self.month = luxProp(self.sun, "sc.month", 0).get()
lordcrc@384
  3548
        self.year  = luxProp(self.sun, "sc.year", 0).get()
lordcrc@384
  3549
        
lordcrc@384
  3550
        
lordcrc@384
  3551
        az,el = self.geoSunData(
lordcrc@384
  3552
            self.lat,
lordcrc@384
  3553
            self.long,
lordcrc@384
  3554
            self.year,
lordcrc@384
  3555
            self.month,
lordcrc@384
  3556
            self.day,
lordcrc@384
  3557
            self.hour + self.min/60.0,
lordcrc@384
  3558
            -self.tz + self.dst
lordcrc@384
  3559
        )
lordcrc@384
  3560
        
lordcrc@384
  3561
        self.sun.rot = math.radians(90-el), 0, math.radians(-az)
lordcrc@384
  3562
        
lordcrc@384
  3563
        Window.Redraw()
lordcrc@384
  3564
        
lordcrc@384
  3565
        
lordcrc@384
  3566
    # --- THE FOLLOWING METHODS ARE ADAPTED FROM LUXMAYA ---
lordcrc@384
  3567
    
lordcrc@384
  3568
    # mathematical helpers
lordcrc@384
  3569
    def sind(self, deg):
lordcrc@384
  3570
        return math.sin(math.radians(deg))
lordcrc@384
  3571
    
lordcrc@384
  3572
    def cosd(self, deg):
lordcrc@384
  3573
        return math.cos(math.radians(deg))
lordcrc@384
  3574
    
lordcrc@384
  3575
    def tand(self, deg):
lordcrc@384
  3576
        return math.tan(math.radians(deg))
lordcrc@384
  3577
    
lordcrc@384
  3578
    def asind(self, deg):
lordcrc@384
  3579
        return math.degrees(math.asin(deg))
lordcrc@384
  3580
    
lordcrc@384
  3581
    def atand(self, deg):
lordcrc@384
  3582
        return math.degrees(math.atan(deg))
lordcrc@384
  3583
    
lordcrc@384
  3584
    
lordcrc@384
  3585
    def geo_sun_astronomicJulianDate(self, Year, Month, Day, LocalTime, Timezone):
lordcrc@384
  3586
        """
lordcrc@384
  3587
        See quoted source in class header for explanation
lordcrc@384
  3588
        """
lordcrc@384
  3589
        
lordcrc@384
  3590
        if Month > 2.0:
lordcrc@384
  3591
            Y = Year
lordcrc@384
  3592
            M = Month
lordcrc@384
  3593
        else:
lordcrc@384
  3594
            Y = Year - 1.0
lordcrc@384
  3595
            M = Month + 12.0
lordcrc@384
  3596
            
lordcrc@384
  3597
        UT = LocalTime - Timezone
lordcrc@384
  3598
        hour = UT / 24.0
lordcrc@384
  3599
        A = int(Y/100.0)
lordcrc@384
  3600
        B = 2.0 - A+int(A/4.0)
lordcrc@384
  3601
        
lordcrc@384
  3602
        JD = math.floor(365.25*(Y+4716.0)) + math.floor(30.6001*(M+1.0)) + Day + hour + B - 1524.4
lordcrc@384
  3603
        
lordcrc@384
  3604
        return JD
lordcrc@384
  3605
    
lordcrc@384
  3606
    def geoSunData(self, Latitude, Longitude, Year, Month, Day, LocalTime, Timezone):
lordcrc@384
  3607
        """
lordcrc@384
  3608
        See quoted source in class header for explanation
lordcrc@384
  3609
        """
lordcrc@384
  3610
        
lordcrc@384
  3611
        JD = self.geo_sun_astronomicJulianDate(Year, Month, Day, LocalTime, Timezone)
lordcrc@384
  3612
        
lordcrc@384
  3613
        phi = Latitude
lordcrc@384
  3614
        llambda = Longitude
lordcrc@384
  3615
                
lordcrc@384
  3616
        n = JD - 2451545.0
lordcrc@384
  3617
        LDeg = (280.460 + 0.9856474*n) - (math.floor((280.460 + 0.9856474*n)/360.0) * 360.0)
lordcrc@384
  3618
        gDeg = (357.528 + 0.9856003*n) - (math.floor((357.528 + 0.9856003*n)/360.0) * 360.0)
lordcrc@384
  3619
        LambdaDeg = LDeg + 1.915 * self.sind(gDeg) + 0.02 * self.sind(2.0*gDeg)
lordcrc@384
  3620
        
lordcrc@384
  3621
        epsilonDeg = 23.439 - 0.0000004*n
lordcrc@384
  3622
        
lordcrc@384
  3623
        alphaDeg = self.atand( (self.cosd(epsilonDeg) * self.sind(LambdaDeg)) / self.cosd(LambdaDeg) )
lordcrc@384
  3624
        if self.cosd(LambdaDeg) < 0.0:
lordcrc@384
  3625
            alphaDeg += 180.0
lordcrc@384
  3626
            
lordcrc@384
  3627
        deltaDeg = self.asind( self.sind(epsilonDeg) * self.sind(LambdaDeg) )
lordcrc@384
  3628
        
lordcrc@384
  3629
        JDNull = self.geo_sun_astronomicJulianDate(Year, Month, Day, 0.0, 0.0)
lordcrc@384
  3630
        
lordcrc@384
  3631
        TNull = (JDNull - 2451545.0) / 36525.0
lordcrc@384
  3632
        T = LocalTime - Timezone
lordcrc@384
  3633
        
lordcrc@384
  3634
        thetaGh = 6.697376 + 2400.05134*TNull + 1.002738*T
lordcrc@384
  3635
        thetaGh -= math.floor(thetaGh/24.0) * 24.0
lordcrc@384
  3636
        
lordcrc@384
  3637
        thetaG = thetaGh * 15.0
lordcrc@384
  3638
        theta = thetaG + llambda
lordcrc@384
  3639
        
lordcrc@384
  3640
        tau = theta - alphaDeg
lordcrc@384
  3641
        
lordcrc@384
  3642
        a = self.atand( self.sind(tau) / ( self.cosd(tau)*self.sind(phi) - self.tand(deltaDeg)*self.cosd(phi)) )
lordcrc@384
  3643
        if self.cosd(tau)*self.sind(phi) - self.tand(deltaDeg)*self.cosd(phi) < 0.0:
lordcrc@384
  3644
            a += 180.0
lordcrc@384
  3645
        
lordcrc@384
  3646
        h = self.asind( self.cosd(deltaDeg)*self.cosd(tau)*self.cosd(phi) + self.sind(deltaDeg)*self.sind(phi) )
lordcrc@384
  3647
        
lordcrc@384
  3648
        R = 1.02 / (self.tand (h+(10.3/(h+5.11))))
lordcrc@384
  3649
        hR = h + R/60.0
lordcrc@384
  3650
        
lordcrc@384
  3651
        azimuth = a
lordcrc@384
  3652
        elevation = hR
lordcrc@384
  3653
        
lordcrc@384
  3654
        return azimuth, elevation
lordcrc@384
  3655
lordcrc@384
  3656
def luxAccelerator(scn, gui=None):
lordcrc@384
  3657
    str = ""
lordcrc@384
  3658
    if scn:
lordcrc@384
  3659
        acceltype = luxProp(scn, "accelerator.type", "tabreckdtree")
lordcrc@384
  3660
        str = luxIdentifier("Accelerator", acceltype, ["none", "tabreckdtree", "grid", "bvh", "qbvh"], "ACCEL", "select accelerator type", gui)
lordcrc@384
  3661
        if acceltype.get() == "tabreckdtree":
lordcrc@384
  3662
            if gui: gui.newline()
lordcrc@384
  3663
            str += luxInt("intersectcost", luxProp(scn, "accelerator.kdtree.interscost", 80), 0, 1000, "inters.cost", "specifies how expensive ray-object intersections are", gui)
lordcrc@384
  3664
            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
  3665
            if gui: gui.newline()
lordcrc@384
  3666
            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
  3667
            if gui: gui.newline()
lordcrc@384
  3668
            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
  3669
            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
  3670
        if acceltype.get() == "unsafekdtree":
lordcrc@384
  3671
            if gui: gui.newline()
lordcrc@384
  3672
            str += luxInt("intersectcost", luxProp(scn, "accelerator.kdtree.interscost", 80), 0, 1000, "inters.cost", "specifies how expensive ray-object intersections are", gui)
lordcrc@384
  3673
            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
  3674
            if gui: gui.newline()
lordcrc@384
  3675
            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
  3676
            if gui: gui.newline()
lordcrc@384
  3677
            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
  3678
            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
  3679
        if acceltype.get() == "grid":
lordcrc@384
  3680
            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
  3681
        if acceltype.get() == "qbvh":
lordcrc@384
  3682
            if gui: gui.newline()
lordcrc@384
  3683
            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
  3684
    return str
lordcrc@384
  3685
lordcrc@384
  3686
def luxSystem(scn, gui=None):
lordcrc@384
  3687
    if scn:
lordcrc@384
  3688
        if gui: gui.newline("PATHS:", 10)
lordcrc@384
  3689
        lp = luxProp(scn, "lux", "")
lordcrc@384
  3690
        lp.set(Blender.sys.dirname(lp.get())+os.sep)
lordcrc@384
  3691
        luxPath("LUX dir", lp, "lux binary dir", "Lux installation path", gui, 2.0)
lordcrc@384
  3692
lordcrc@384
  3693
#        luxFile("GUI filename", luxProp(scn, "lux", ""), "lux-file", "filename and path of the lux GUI executable", gui, 2.0)
lordcrc@384
  3694
#        luxFile("Console filename", luxProp(scn, "luxconsole", ""), "lux-file-console", "filename and path of the lux console executable", gui, 2.0)
lordcrc@384
  3695
        if gui: gui.newline()
lordcrc@384
  3696
        luxFile("datadir", luxProp(scn, "datadir", ""), "default out dir", "default.lxs save path", gui, 2.0)
lordcrc@384
  3697
lordcrc@384
  3698
        if gui: gui.newline()
lordcrc@384
  3699
        pm = ["absolute","relative","flat"]
lordcrc@384
  3700
        luxOption("pathmode", luxProp(scn, "pathmode", "absolute"), pm, "path-mode", "select format for paths on export", gui, 2.0)
lordcrc@384
  3701
lordcrc@384
  3702
        if gui: gui.newline("PRIORITY:", 10)
lordcrc@384
  3703
        luxnice = luxProp(scn, "luxnice", 10)
lordcrc@384
  3704
        if osys.platform=="win32":
lordcrc@384
  3705
            r = gui.getRect(2, 1)
lordcrc@384
  3706
            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
  3707
        else: luxInt("nice", luxnice, -20, 19, "nice", "nice value. Range goes from -20 (highest priority) to 19 (lowest)", gui)
lordcrc@384
  3708
lordcrc@384
  3709
        luxBool("noopengl", luxProp(scn, "noopengl", "false"), "Disable OpenGL", "(workaround for some buggy display drivers)", gui, 1.0)
lordcrc@384
  3710
lordcrc@384
  3711
lordcrc@384
  3712
        if gui: gui.newline("THREADS:", 10)
lordcrc@384
  3713
        autothreads = luxProp(scn, "autothreads", "true")
lordcrc@384
  3714
        luxBool("autothreads", autothreads, "Auto Detect", "Automatically use all available processors", gui, 1.0)
lordcrc@384
  3715
        if autothreads.get()=="false":
lordcrc@384
  3716
            luxInt("threads", luxProp(scn, "threads", 1), 1, 100, "threads", "number of threads used for rendering", gui, 1.0)
doug@404
  3717
#        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
  3718
lordcrc@384
  3719
        if gui: gui.newline("ANIM:", 10)
lordcrc@384
  3720
        useparamkeys = luxProp(scn, "useparamkeys", "false")
lordcrc@384
  3721
        luxBool("useparamkeys", useparamkeys, "Enable Parameter IPO Keyframing", "Enables keyframing of luxblend parameters", gui, 2.0)
lordcrc@384
  3722
lordcrc@384
  3723
        if gui: gui.newline("PARAMS:", 10)
lordcrc@384
  3724
        parammodeadvanced = luxProp(scn, "parammodeadvanced", "false")
lordcrc@384
  3725
        luxBool("parammodeadvanced", parammodeadvanced, "Default Advanced Parameters", "Always use advanced parameters by default", gui, 2.0)
lordcrc@384
  3726
lordcrc@384
  3727
        if gui: gui.newline("PREVIEW:", 10)
lordcrc@384
  3728
        qs = ["low","medium","high","very high"]
lordcrc@384
  3729
        defprevmat = luxProp(scn, "defprevmat", "high")
lordcrc@384
  3730
        luxOption("defprevmat", defprevmat, qs, "Materials", "Select default preview quality in material editor for materials", gui, 1.0)
lordcrc@384
  3731
lordcrc@384
  3732
        if gui: gui.newline("GAMMA:", 10)
lordcrc@384
  3733
        luxBool("RGC", luxProp(scn, "RGC", "true"), "RGC", "use reverse gamma correction", gui)
lordcrc@384
  3734
        luxBool("ColClamp", luxProp(scn, "colorclamp", "false"), "ColClamp", "clamp all colors to 0.0-0.9", gui)
lordcrc@384
  3735
        if gui: gui.newline("MESH:", 10)
lordcrc@384
  3736
        luxBool("mesh_optimizing", luxProp(scn, "mesh_optimizing", "true"), "optimize meshes", "Optimize meshes during export", gui, 2.0)
lordcrc@384
  3737
        #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
  3738
        #if gui: gui.newline()
lordcrc@384
  3739
        #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
  3740
        if gui: gui.newline("INSTANCING:", 10)
lordcrc@384
  3741
        luxInt("instancing_threshold", luxProp(scn, "instancing_threshold", 2), 0, 1000000, "object instancing threshold", "Threshold to created instanced objects", gui, 2.0)
lordcrc@384
  3742
        
lordcrc@384
  3743
        # dougal2 packed images, enable this when implemented in Lux itself
lordcrc@384
  3744
        #if gui: gui.newline('TEXTURES:',10)
lordcrc@384
  3745
        #impack = luxProp(scn, 'packtextures', 'false')
lordcrc@384
  3746
        #luxBool('impack', impack, 'Pack All Images', '', gui, 2.0)
lordcrc@384
  3747
        
lordcrc@384
  3748
        if gui: 
lordcrc@384
  3749
            network=luxProp(scn,"network","false")
lordcrc@384
  3750
            gui.newline("NETWORK:", 10)
lordcrc@384
  3751
            luxCollapse("network",network, "network", "enable network option", gui, 2.0)
lordcrc@384
  3752
            if(network.get() == "true"):
lordcrc@384
  3753
                network_use_file=luxProp(scn,"network_use_file","false")
lordcrc@384
  3754
                luxBool ("use file",network_use_file,"use file", "get list of servers from file; one per line",gui,2.0)
lordcrc@384
  3755
                if (network_use_file.get() == "true"):
lordcrc@384
  3756
                    luxFile("file", luxProp(scn, "network_file_path", ""), "file", "file where servers are defined", gui, 1.0)         
lordcrc@384
  3757
                else :     
lordcrc@384
  3758
                    #gui.newline("")
lordcrc@384
  3759
                    luxString("Servers",luxProp(scn,"network_servers",""),"servers","coma separated list of servers",gui,1.0)
lordcrc@384
  3760
                #gui.newline("")
dade@447
  3761
                luxInt("network_interval",luxProp(scn,"newtork_interval",180),0,9999,"update interval","interval between network refresh",gui)
lordcrc@384
  3762
lordcrc@384
  3763
lordcrc@384
  3764
def scalelist(list, factor):
lordcrc@384
  3765
    for i in range(len(list)): list[i] = list[i] * factor
lordcrc@384
  3766
    return list
lordcrc@384
  3767
lordcrc@384
  3768
lordcrc@384
  3769
def luxMapping(key, mat, gui, level=0):
lordcrc@384
  3770
    global icon_map2d, icon_map2dparam
lordcrc@384
  3771
    if gui: gui.newline("2Dmap:", -2, level, icon_map2d)
lordcrc@384
  3772
    mapping = luxProp(mat, key+".mapping", "uv")
lordcrc@384
  3773
    mappings = ["uv","spherical","cylindrical","planar"]
lordcrc@384
  3774
    str = luxOption("mapping", mapping, mappings, "mapping", "", gui, 0.5)
lordcrc@384
  3775
    if mapping.get() == "uv":
lordcrc@384
  3776
    	if gui: gui.newline()
lordcrc@384
  3777
        str += luxFloat("uscale", luxProp(mat, key+".uscale", 1.0), -100.0, 100.0, "Us", "u-scale", gui, 0.5)
lordcrc@384
  3778
        str += luxFloat("vscale", luxProp(mat, key+".vscale", -1.0), -100.0, 100.0, "Vs", "v-scale", gui, 0.5)
lordcrc@384
  3779
        str += luxFloat("udelta", luxProp(mat, key+".udelta", 0.0), -100.0, 100.0, "Ud", "u-delta", gui, 0.5)
lordcrc@384
  3780
        str += luxFloat("vdelta", luxProp(mat, key+".vdelta", 0.0), -100.0, 100.0, "Vd", "v-delta", gui, 0.5)
lordcrc@384
  3781
    if mapping.get() == "planar":
lordcrc@384
  3782
        str += luxFloat("udelta", luxProp(mat, key+".udelta", 0.0), -100.0, 100.0, "Ud", "u-delta", gui, 0.75)
lordcrc@384
  3783
        str += luxFloat("vdelta", luxProp(mat, key+".vdelta", 0.0), -100.0, 100.0, "Vd", "v-delta", gui, 0.75)
lordcrc@384
  3784
        if gui: gui.newline("v1:", -2, level+1, icon_map2dparam)
lordcrc@384
  3785
        str += luxVector("v1", luxProp(mat, key+".v1", "1 0 0"), -100.0, 100.0, "v1", "v1-vector", gui, 2.0)
lordcrc@384
  3786
        if gui: gui.newline("v2:", -2, level+1, icon_map2dparam)
lordcrc@384
  3787
        str += luxVector("v2", luxProp(mat, key+".v2", "0 1 0"), -100.0, 100.0, "v2", "v2-vector", gui, 2.0)
lordcrc@384
  3788
    return str
lordcrc@384
  3789
lordcrc@384
  3790
def lux3DMapping(key, mat, gui, level=0):
lordcrc@384
  3791
    global icon_map3dparam
lordcrc@384
  3792
    str = ""
lordcrc@384
  3793
    if gui: gui.newline("scale:", -2, level, icon_map3dparam)
lordcrc@384
  3794
    str += luxVectorUniform("scale", luxProp(mat, key+".3dscale", 1.0), 0.001, 1000.0, "scale", "scale-vector", gui, 2.0)
lordcrc@384
  3795
    if gui: gui.newline("rot:", -2, level, icon_map3dparam)
lordcrc@384
  3796
    str += luxVector("rotate", luxProp(mat, key+".3drotate", "0 0 0"), -360.0, 360.0, "rotate", "rotate-vector", gui, 2.0)
lordcrc@384
  3797
    if gui: gui.newline("move:", -2, level, icon_map3dparam)
lordcrc@384
  3798
    str += luxVector("translate", luxProp(mat, key+".3dtranslate", "0 0 0"), -1000.0, 1000.0, "move", "translate-vector", gui, 2.0)
lordcrc@384
  3799
    return str
lordcrc@384
  3800
    
lordcrc@384
  3801
def getTreeNameById(tree, i): # helper function to retrive name of the selected treemenu-item
lordcrc@384
  3802
    for t in tree:
lordcrc@384
  3803
        if type(t)==types.TupleType:
lordcrc@384
  3804
            if type(t[1])==types.ListType: 
lordcrc@384
  3805
                n=getTreeNameById(t[1], i)
lordcrc@384
  3806
                if n: return n
lordcrc@384
  3807
            elif t[1]==i: return t[0]
lordcrc@384
  3808
    return None    
lordcrc@384
  3809
lordcrc@384
  3810
def luxTexture(name, parentkey, type, default, min, max, caption, hint, mat, gui, matlevel, texlevel=0, lightsource=0, overrideicon=""):
lordcrc@384
  3811
    global icon_tex, icon_texcol, icon_texmix, icon_texmixcol, icon_texparam, icon_spectex
lordcrc@384
  3812
    def c(t1, t2):
lordcrc@384
  3813
        return (t1[0]+t2[0], t1[1]+t2[1])
lordcrc@384
  3814
    def alternativedefault(type, default):
lordcrc@384
  3815
        if type=="float": return 0.0
lordcrc@384
  3816
        else: return "0.0 0.0 0.0"
lordcrc@384
  3817
    level = matlevel + texlevel
lordcrc@384
  3818
    keyname = "%s:%s"%(parentkey, name)
lordcrc@384
  3819
    texname = "%s:%s"%(mat.getName(), keyname)
lordcrc@384
  3820
#    if gui: gui.newline(caption+":", 0, level)
lordcrc@384
  3821
    if(lightsource == 0):
lordcrc@384
  3822
        if texlevel == 0: texture = luxProp(mat, keyname+".texture", "imagemap")
lordcrc@384
  3823
        else: texture = luxProp(mat, keyname+".texture", "constant")
lordcrc@384
  3824
    else:
lordcrc@384
  3825
        texture = luxProp(mat, keyname+".texture", "blackbody")
lordcrc@384
  3826
lordcrc@384
  3827
    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
  3828
lordcrc@384
  3829
    if gui:
lordcrc@384
  3830
        if(overrideicon != ""):
lordcrc@384
  3831
            icon = overrideicon
lordcrc@384
  3832
        else:
lordcrc@384
  3833
            icon = icon_tex
lordcrc@384
  3834
            if texture.get() in ["mix", "scale", "checkerboard", "dots"]:
lordcrc@384
  3835
                if type=="color": icon = icon_texmixcol
lordcrc@384
  3836
                else: icon = icon_texmix
lordcrc@384
  3837
            elif texture.get() in ["constant", "blackbody", "equalenergy", "frequency", "gaussian", "regulardata", "irregulardata"]:
lordcrc@384
  3838
                icon = icon_spectex
lordcrc@384
  3839
            else:
lordcrc@384
  3840
                if type=="color": icon = icon_texcol
lordcrc@384
  3841
                else: icon = icon_tex
lordcrc@384
  3842
        if (texlevel > 0): gui.newline(caption+":", -2, level, icon, scalelist([0.5,0.5,0.5],2.0/(level+2)))
lordcrc@384
  3843
        else: gui.newline("texture:", -2, level, icon, scalelist([0.5,0.5,0.5],2.0/(level+2)))
lordcrc@384
  3844
    luxOption("texture", texture, textures, "texture", "", gui, 2)
lordcrc@384
  3845
    str = "Texture \"%s\" \"%s\" \"%s\""%(texname, type, texture.get())
lordcrc@384
  3846
lordcrc@384
  3847
    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
  3848
    if gui: # Draw Texture level Material preview
lordcrc@384
  3849
        luxPreview(mat, parentkey, 1, False, False, name, gui, texlevel, [0.5, 0.5, 0.5])
lordcrc@384
  3850
        # Add an offset for next controls
lordcrc@384
  3851
        #r = gui.getRect(1.0, 1)
lordcrc@384
  3852
        #gui.x += 140
lordcrc@384
  3853
lordcrc@384
  3854
    if texture.get() == "constant":
lordcrc@384
  3855
        value = luxProp(mat, keyname+".value", default)
lordcrc@384
  3856
        if type == "float": luxFloat("value", value, min, max, "", "", gui, 1.1)
lordcrc@384
  3857
        elif type == "color": luxRGB("value", value, max, "", "", gui, 2)
lordcrc@384
  3858
# direct version
lordcrc@384
  3859
        if type == "color": return ("", " \"%s %s\" [%s]"%(type, name, value.getRGC()))
lordcrc@384
  3860
        return ("", " \"%s %s\" [%s]"%(type, name, value.get()))
lordcrc@384
  3861
# indirect version
lordcrc@384
  3862
#        if type == "color": str += " \"%s value\" [%s]"%(type, value.getRGC())
lordcrc@384
  3863
#        else: str += " \"%s value\" [%s]"%(type, value.get())
lordcrc@384
  3864
lordcrc@384
  3865
    if texture.get() == "blackbody":
lordcrc@384
  3866
        if gui:
lordcrc@384
  3867
            if gui.xmax-gui.x < gui.w: gui.newline()
lordcrc@384
  3868
            r = gui.getRect(1.0, 1)
lordcrc@384
  3869
            gui.newline()
lordcrc@384
  3870
            drawBar(bar_blackbody, gui.xmax-gui.w-7, r[1])
lordcrc@384
  3871
        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
  3872
lordcrc@384
  3873
    if texture.get() == "lampspectrum":
lordcrc@384
  3874
        lampstring = luxProp(mat, keyname+".lampstring", "Incandescent2")
lordcrc@384
  3875
        lamppreset = luxProp(mat, keyname+".lampspectrum", "PHILIPS [Argenta] 200W Incandescent Lamp")
lordcrc@384
  3876
        if gui:
lordcrc@384
  3877
            def setLamp(i, value, preset, tree, dict): # callback function to set ior value after selection
lordcrc@384
  3878
                if i >= 0:
lordcrc@384
  3879
                    value.set(dict[i])
lordcrc@384
  3880
                    preset.set(getTreeNameById(tree, i))
lordcrc@384
  3881
lordcrc@384
  3882
            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
  3883
lordcrc@384
  3884
            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
  3885
lordcrc@384
  3886
            r = gui.getRect(2.0, 1)
lordcrc@384
  3887
            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
  3888
        str += luxString("name", lampstring, "Lamp", "Choose measured Lamp Spectrum", None, 2.0)
lordcrc@384
  3889
lordcrc@384
  3890
    if texture.get() == "equalenergy":
lordcrc@384
  3891
        if gui:
lordcrc@384
  3892
            if gui.xmax-gui.x < gui.w: gui.newline()
lordcrc@384
  3893
            r = gui.getRect(1.0, 1)
lordcrc@384
  3894
            gui.newline()
lordcrc@384
  3895
            drawBar(bar_equalenergy, gui.xmax-gui.w-7, r[1])
lordcrc@384
  3896
        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
  3897
lordcrc@384
  3898
    if texture.get() == "frequency":
lordcrc@384
  3899
        str += luxFloat("freq", luxProp(mat, keyname+".freq", 0.01), 0.01, 100.0, "frequency", "Frequency in nm", gui, 2.0, 1)
lordcrc@384
  3900
        str += luxFloat("phase", luxProp(mat, keyname+".phase", 0.5), 0.0, 1.0, "phase", "Phase", gui, 1.1, 1)
lordcrc@384
  3901
        str += luxFloat("energy", luxProp(mat, keyname+".energy", 1.0), 0.0, 1.0, "energy", "Amount of mean energy", gui, 0.9, 1)
lordcrc@384
  3902
lordcrc@384
  3903
    if texture.get() == "gaussian":
lordcrc@384
  3904
        if gui:
lordcrc@384
  3905
            if gui.xmax-gui.x < gui.w: gui.newline()
lordcrc@384
  3906
            r = gui.getRect(1.0, 1)
lordcrc@384
  3907
            gui.newline()
lordcrc@384
  3908
            drawBar(bar_spectrum, gui.xmax-gui.w-7, r[1])
lordcrc@384
  3909
        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
  3910
        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
  3911
        str += luxFloat("energy", luxProp(mat, keyname+".energy", 1.0), 0.0, 1.0, "energy", "Amount of mean energy", gui, 0.9, 1)
lordcrc@384
  3912
lordcrc@384
  3913
    if texture.get() == "imagemap":
jensverwiebe@389
  3914
        if gui: gui.newline("IM-clip:", -2, level)
doug@387
  3915
        str += luxOption("wrap", luxProp(mat, keyname+".wrap", "repeat"), ["repeat","black","clamp"], "repeat", "", gui, 1.0)
lordcrc@384
  3916
jensverwiebe@389
  3917
        if gui: gui.newline("IM-source:", -2, level)
jensverwiebe@389
  3918
lordcrc@384
  3919
        # ZANQDO
lordcrc@384
  3920
        texturefilename = luxProp(mat, keyname+".filename", "")
doug@387
  3921
        extimage = luxProp(mat, keyname+'.externalimage', "true")
doug@387
  3922
        luxBool("External Image", extimage, "External Image", "External Image", gui, 1.0)
jensverwiebe@388
  3923
        if gui: gui.newline("IM-path:", -2, level)
doug@387
  3924
        if extimage.get() == "true":
doug@387
  3925
            luxFile("filename", texturefilename, "file", "texture file path", gui, 2.0)
doug@387
  3926
        else:
jensverwiebe@388
  3927
            bil = [i.filename for i in Image.Get() if '.' in i.filename]
jensverwiebe@388
  3928
            try:
jensverwiebe@388
  3929
                uti = [i.filename for i in Image.Get() if '.' not in i.filename]
jensverwiebe@388
  3930
                if len(uti) > 0:
jensverwiebe@388
  3931
                    luxLabel("INFO: Images not listed here must be saved first", gui)
jensverwiebe@388
  3932
            except: pass    
doug@387
  3933
            if len(bil) > 0:
doug@387
  3934
                luxOption("Image", texturefilename, bil, "Blender Images", "Blender Image", gui, 2.0)
doug@387
  3935
            else:
doug@387
  3936
                luxLabel("No Blender Images - Load Image in the Image Editor", gui)
lordcrc@384
  3937
        # dougal2 image file packing
lordcrc@384
  3938
        impack = luxProp(Scene.GetCurrent(), 'packtextures', 'false')
lordcrc@384
  3939
        
lordcrc@384
  3940
        if impack.get() == 'false':
lordcrc@384
  3941
            str += luxFile("filename", texturefilename, "file", "texture file path", None, 2.0)
lordcrc@384
  3942
        else:
lordcrc@384
  3943
            import zlib, base64
lordcrc@384
  3944
            def get_image_data(filename):
lordcrc@384
  3945
                try:
lordcrc@384
  3946
                    f=open(filename,'rb')
lordcrc@384
  3947
                    d=f.read()
lordcrc@384
  3948
                    f.close()
lordcrc@384
  3949
                except:
lordcrc@384
  3950
                    print('Error reading image data from %s' % filename)
lordcrc@384
  3951
                    d = ''
lordcrc@384
  3952
                return base64.b64encode(zlib.compress(d))
lordcrc@384
  3953
            imdata = get_image_data(texturefilename.get())
lordcrc@384
  3954
            str += '\r\n   "string imagedata" ["%s"]' % imdata
lordcrc@384
  3955
        
lordcrc@384
  3956
        useseq = luxProp(mat, keyname+".useseq", "false")
lordcrc@384
  3957
        luxCollapse("usesew", useseq, "Sequence", "", gui, 2.0)
lordcrc@384
  3958
    
lordcrc@384
  3959
        if useseq.get() == "true":
lordcrc@384
  3960
            seqframes = luxProp(mat, keyname+".seqframes", 100)
lordcrc@384
  3961
            luxInt("frames", seqframes, 1, 100000, "Frames", "", gui, 0.5)
lordcrc@384
  3962
            seqoffset = luxProp(mat, keyname+".seqoffset", 0)
lordcrc@384
  3963
            luxInt("offset", seqoffset, 0, 100000, "Offset", "", gui, 0.5)
lordcrc@384
  3964
            seqstartframe = luxProp(mat, keyname+".seqsframe", 1)
lordcrc@384
  3965
            luxInt("startframe", seqstartframe, 1, 100000, "StartFr", "", gui, 0.5)
lordcrc@384
  3966
            seqcyclic = luxProp(mat, keyname+".seqcycl", "false")
lordcrc@384
  3967
            luxBool("cyclic", seqcyclic, "Cyclic", "", gui, 0.5)
lordcrc@384
  3968
    
lordcrc@384
  3969
            
lordcrc@384
  3970
            totalframes = seqframes.get()
lordcrc@384
  3971
            currentframe = Blender.Get('curframe')
lordcrc@384
  3972
    
lordcrc@384
  3973
            if(currentframe < seqstartframe.get()):
lordcrc@384
  3974
                fnumber = 1 + seqoffset.get()
lordcrc@384
  3975
            else:
lordcrc@384
  3976
                fnumber = (currentframe - (seqstartframe.get()-1)) + seqoffset.get()
lordcrc@384
  3977
    
lordcrc@384
  3978
            if(fnumber > seqframes.get()):
lordcrc@384
  3979
                if(seqcyclic.get() == "false"):
lordcrc@384
  3980
                    fnumber = seqframes.get()
lordcrc@384
  3981
                else:
lordcrc@384
  3982
                    fnumber = currentframe % seqframes.get()
lordcrc@384
  3983
    
lordcrc@384
  3984
            import re
lordcrc@384
  3985
            def get_seq_filename(number, filename):
lordcrc@384
  3986
                m = re.findall(r'(\d+)', filename)
lordcrc@384
  3987
                if len(m) == 0:
lordcrc@384
  3988
                    return "ERR: Can't find pattern"
lordcrc@384
  3989
    
lordcrc@384
  3990
                rightmost_number = m[len(m)-1]
lordcrc@384
  3991
                seq_length = len(rightmost_number)
lordcrc@384
  3992
    
lordcrc@384
  3993
                nstr = "%i" %number
lordcrc@384
  3994
                new_seq_number = nstr.zfill(seq_length)
lordcrc@384
  3995
     
lordcrc@384
  3996
                return filename.replace(rightmost_number, new_seq_number)
lordcrc@384
  3997
     
lordcrc@384
  3998
            texturefilename.set(get_seq_filename(fnumber, texturefilename.get()))
lordcrc@384
  3999
            if gui: gui.newline()
lordcrc@384
  4000
    
lordcrc@384
  4001
        str += luxFloat("gamma", luxProp(mat, keyname+".gamma", texturegamma()), 0.0, 6.0, "gamma", "", gui, 0.75)
lordcrc@384
  4002
        str += luxFloat("gain", luxProp(mat, keyname+".gain", 1.0), 0.0, 10.0, "gain", "", gui, 0.5)
lordcrc@384
  4003
        filttype = luxProp(mat, keyname+".filtertype", "bilinear")
lordcrc@384
  4004
        filttypes = ["mipmap_ewa","mipmap_trilinear","bilinear","nearest"]
lordcrc@384
  4005
        str += luxOption("filtertype", filttype, filttypes, "filtertype", "Choose the filtering method to use for the image texture", gui, 0.75)
lordcrc@384
  4006
        
lordcrc@384
  4007
        if filttype.get() == "mipmap_ewa" or filttype.get() == "mipmap_trilinear":    
lordcrc@384
  4008
            str += luxFloat("maxanisotropy", luxProp(mat, keyname+".maxanisotropy", 8.0), 1.0, 512.0, "maxaniso", "", gui, 1.0)
lordcrc@384
  4009
            str += luxInt("discardmipmaps", luxProp(mat, keyname+".discardmipmaps", 0), 0, 1, "discardmips", "", gui, 1.0)
lordcrc@384
  4010
    
lordcrc@384
  4011
        str += luxMapping(keyname, mat, gui, level+1)
lordcrc@384
  4012
lordcrc@384
  4013
    if texture.get() == "mix":
lordcrc@384
  4014
        (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
  4015
        (s, l) = c((s, l), luxTexture("tex1", keyname, type, default, min, max, "tex1", "", mat, gui, matlevel, texlevel+1, lightsource))
lordcrc@384
  4016
        (s, l) = c((s, l), luxTexture("tex2", keyname, type, alternativedefault(type, default), min, max, "tex2", "", mat, gui, matlevel, texlevel+1, lightsource))
lordcrc@384
  4017
        str = s + str + l
lordcrc@384
  4018
lordcrc@384
  4019
    if texture.get() == "scale":
lordcrc@384
  4020
        (s, l) = c(("", ""), luxTexture("tex1", keyname, type, default, min, max, "tex1", "", mat, gui, matlevel, texlevel+1, lightsource))
lordcrc@384
  4021
        (s, l) = c((s, l), luxTexture("tex2", keyname, type, alternativedefault(type, default), min, max, "tex2", "", mat, gui, matlevel, texlevel+1, lightsource))
lordcrc@384
  4022
        str = s + str + l
lordcrc@384
  4023
lordcrc@384
  4024
    if texture.get() == "bilerp":
lordcrc@384
  4025
        if type == "float":
lordcrc@384
  4026
            str += luxFloat("v00", luxProp(mat, keyname+".v00", 0.0), min, max, "v00", "", gui, 1.0)
lordcrc@384
  4027
            str += luxFloat("v01", luxProp(mat, keyname+".v01", 1.0), min, max, "v01", "", gui, 1.0)
lordcrc@384
  4028
            if gui: gui.newline("", -2)
lordcrc@384
  4029
            str += luxFloat("v10", luxProp(mat, keyname+".v10", 0.0), min, max, "v10", "", gui, 1.0)
lordcrc@384
  4030
            str += luxFloat("v11", luxProp(mat, keyname+".v11", 1.0), min, max, "v11", "", gui, 1.0)
lordcrc@384
  4031
        elif type == "color":
lordcrc@384
  4032
            if gui: gui.newline("          v00:", -2)
lordcrc@384
  4033
            str += luxRGB("v00", luxProp(mat, keyname+".v00", "0.0 0.0 0.0"), max, "v00", "", gui, 2.0)
lordcrc@384
  4034
            if gui: gui.newline("          v01:", -2)
lordcrc@384
  4035
            str += luxRGB("v01", luxProp(mat, keyname+".v01", "1.0 1.0 1.0"), max, "v01", "", gui, 2.0)
lordcrc@384
  4036
            if gui: gui.newline("          v10:", -2)
lordcrc@384
  4037
            str += luxRGB("v10", luxProp(mat, keyname+".v10", "0.0 0.0 0.0"), max, "v10", "", gui, 2.0)
lordcrc@384
  4038
            if gui: gui.newline("          v11:", -2)
lordcrc@384
  4039
            str += luxRGB("v11", luxProp(mat, keyname+".v11", "1.0 1.0 1.0"), max, "v11", "", gui, 2.0)
lordcrc@384
  4040
        str += luxMapping(keyname, mat, gui, level+1)
lordcrc@384
  4041
lordcrc@384
  4042
    if texture.get() == "windy":
lordcrc@384
  4043
        str += lux3DMapping(keyname, mat, gui, level+1)
lordcrc@384
  4044
        # this texture has no options 
lordcrc@384
  4045
lordcrc@384
  4046
    if texture.get() == "checkerboard":
lordcrc@384
  4047
        dim = luxProp(mat, keyname+".dim", 2)
lordcrc@384
  4048
        str += luxInt("dimension", dim, 2, 3, "dim", "", gui, 1)
lordcrc@384
  4049
        if dim.get() == 2: str += luxOption("aamode", luxProp(mat, keyname+".aamode", "closedform"), ["closedform","supersample","none"], "aamode", "antialiasing mode", gui, 0.6)
lordcrc@384
  4050
        if gui: gui.newline("", -2)
lordcrc@384
  4051
        (s, l) = c(("", ""), luxTexture("tex1", keyname, type, default, min, max, "tex1", "", mat, gui, matlevel, texlevel+1, lightsource))
lordcrc@384
  4052
        (s, l) = c((s, l), luxTexture("tex2", keyname, type, alternativedefault(type, default), min, max, "tex2", "", mat, gui, matlevel, texlevel+1, lightsource))
lordcrc@384
  4053
        str = s + str + l
lordcrc@384
  4054
        if dim.get() == 2: str += luxMapping(keyname, mat, gui, level+1) 
lordcrc@384
  4055
        if dim.get() == 3: str += lux3DMapping(keyname, mat, gui, level+1)
lordcrc@384
  4056
lordcrc@384
  4057
    if texture.get() == "dots":
lordcrc@384
  4058
        (s, l) = c(("", ""), luxTexture("inside", keyname, type, default, min, max, "inside", "", mat, gui, matlevel, texlevel+1, lightsource))
lordcrc@384
  4059
        (s, l) = c((s, l), luxTexture("outside", keyname, type, alternativedefault(type, default), min, max, "outside", "", mat, gui, matlevel, texlevel+1, lightsource))
lordcrc@384
  4060
        str = s + str + l
lordcrc@384
  4061
        str += luxMapping(keyname, mat, gui, level+1)
lordcrc@384
  4062
lordcrc@384
  4063
    if texture.get() == "fbm":
lordcrc@384
  4064
        str += luxInt("octaves", luxProp(mat, keyname+".octaves", 8), 1, 100, "octaves", "", gui, 1)
lordcrc@384
  4065
        # if gui: gui.newline("", -2)
lordcrc@384
  4066
        str += luxFloat("roughness", luxProp(mat, keyname+".roughness", 0.5), 0.0, 1.0, "roughness", "", gui, 1, 1)
lordcrc@384
  4067
        if gui: gui.newline("", -2)
lordcrc@384
  4068
        str += lux3DMapping(keyname, mat, gui, level+1)
lordcrc@384
  4069
lordcrc@384
  4070
    if texture.get() == "marble":
lordcrc@384
  4071
        str += luxInt("octaves", luxProp(mat, keyname+".octaves", 8), 1, 100, "octaves", "", gui, 1)
lordcrc@384
  4072
        # if gui: gui.newline("", -2)
lordcrc@384
  4073
        str += luxFloat("roughness", luxProp(mat, keyname+".roughness", 0.5), 0.0, 1.0, "roughness", "", gui, 1, 1)
lordcrc@384
  4074
        if gui: gui.newline("", -2)
lordcrc@384
  4075
        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
  4076
        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
  4077
        if gui: gui.newline("", -2)
lordcrc@384
  4078
        str += lux3DMapping(keyname, mat, gui, level+1)
lordcrc@384
  4079
lordcrc@384
  4080
    if texture.get() == "wrinkled":
lordcrc@384
  4081
        str += luxInt("octaves", luxProp(mat, keyname+".octaves", 8), 1, 100, "octaves", "", gui, 1)
lordcrc@384
  4082
        # if gui: gui.newline("", -2)
lordcrc@384
  4083
        str += luxFloat("roughness", luxProp(mat, keyname+".roughness", 0.5), 0.0, 1.0, "roughness", "", gui, 1, 1)
lordcrc@384
  4084
        if gui: gui.newline("", -2)
lordcrc@384
  4085
        str += lux3DMapping(keyname, mat, gui, level+1)
lordcrc@384
  4086
lordcrc@384
  4087
    if texture.get() == "brick":
lordcrc@384
  4088
        if gui: gui.newline("brick:", -2, level+1, icon_texparam)
lordcrc@384
  4089
lordcrc@384
  4090
        str += luxFloat("brickwidth", luxProp(mat, keyname+".brickwidth", 0.3), 0.0, 10.0, "brickwidth (X)", "", gui, 1.0)
lordcrc@384
  4091
        str += luxFloat("brickheight", luxProp(mat, keyname+".brickheight", 0.1), 0.0, 10.0, "brickheight (Z)", "", gui, 1.0)
lordcrc@384
  4092
        str += luxFloat("brickdepth", luxProp(mat, keyname+".brickdepth", 0.15), 0.0, 10.0, "brickdepth (Y)", "", gui, 1.0)
lordcrc@384
  4093
lordcrc@384
  4094
        if gui: gui.newline("mortar:", -2, level+1, icon_texparam)
lordcrc@384
  4095
lordcrc@384
  4096
        str += luxFloat("mortarsize", luxProp(mat, keyname+".mortarsize", 0.01), 0.0, 1.0, "mortarsize", "", gui, 1.0)
lordcrc@384
  4097
lordcrc@384
  4098
        (s, l) = c(("", ""), luxTexture("bricktex", keyname, type, default, min, max, "bricktex", "", mat, gui, matlevel, texlevel+1, lightsource))
lordcrc@384
  4099
        (s, l) = c((s, l), luxTexture("mortartex", keyname, type, alternativedefault(type, default), min, max, "mortartex", "", mat, gui, matlevel, texlevel+1, lightsource))
lordcrc@384
  4100
        str = s + str + l
lordcrc@384
  4101
lordcrc@384
  4102
        str += lux3DMapping(keyname, mat, gui, level+1)
lordcrc@384
  4103
lordcrc@384
  4104
    if texture.get() == "blender_marble":
lordcrc@384
  4105
        if gui: gui.newline("noise:", -2, level+1, icon_texparam)
lordcrc@384
  4106
lordcrc@384
  4107
        mtype = luxProp(mat, keyname+".mtype", "soft")
lordcrc@384
  4108
        mtypes = ["soft","sharp","sharper"]
lordcrc@384
  4109
        str += luxOption("type", mtype, mtypes, "type", "", gui, 0.5)
lordcrc@384
  4110
lordcrc@384
  4111
        noisetype = luxProp(mat, keyname+".noisetype", "hard_noise")
lordcrc@384
  4112
        noisetypes = ["soft_noise","hard_noise"]
lordcrc@384
  4113
        str += luxOption("noisetype", noisetype, noisetypes, "noisetypes", "", gui, 0.75)
lordcrc@384
  4114
lordcrc@384
  4115
        str += luxInt("noisedepth", luxProp(mat, keyname+".noisedepth", 2), 0, 6, "noisedepth", "", gui, 0.75)
lordcrc@384
  4116
lordcrc@384
  4117
        str += luxFloat("noisesize", luxProp(mat, keyname+".noisesize", 0.25), 0.0, 2.0, "noisesize", "", gui, 1.0)
lordcrc@384
  4118
        str += luxFloat("turbulance", luxProp(mat, keyname+".turbulance", 5.0), 0.0, 200.0, "turbulance", "", gui, 1.0)
lordcrc@384
  4119
lordcrc@384
  4120
        if gui: gui.newline("basis:", -2, level+1, icon_texparam)
lordcrc@384
  4121
        noisebasis2 = luxProp(mat, keyname+".noisebasis2", "sin")
lordcrc@384
  4122
        noisebasises2 = ["sin","saw","tri"]
lordcrc@384
  4123
        str += luxOption("noisebasis2", noisebasis2, noisebasises2, "noisebasis2", "", gui, 0.7)
lordcrc@384
  4124
lordcrc@384
  4125
        noisebasis = luxProp(mat, keyname+".noisebasis", "blender_original")
lordcrc@384
  4126
        noisebasises = ["blender_original","original_perlin", "improved_perlin", "voronoi_f1", "voronoi_f2", "voronoi_f3", "voronoi_f4", "voronoi_f2f1", "voronoi_crackle", "cell_noise"]
lordcrc@384
  4127
        str += luxOption("noisebasis", noisebasis, noisebasises, "noisebasis", "", gui, 1.3)
lordcrc@384
  4128
lordcrc@384
  4129
        if gui: gui.newline("level:", -2, level+1, icon_texparam)
lordcrc@384
  4130
        str += luxFloat("bright", luxProp(mat, keyname+".bright", 1.0), 0.0, 2.0, "bright", "", gui, 1.0)
lordcrc@384
  4131
        str += luxFloat("contrast", luxProp(mat, keyname+".contrast", 1.0), 0.0, 10.0, "contrast", "", gui, 1.0)
lordcrc@384
  4132
lordcrc@384
  4133
        (s, l) = c(("", ""), luxTexture("tex1", keyname, type, default, min, max, "tex1", "", mat, gui, matlevel, texlevel+1, lightsource))
lordcrc@384
  4134
        (s, l) = c((s, l), luxTexture("tex2", keyname, type, alternativedefault(type, default), min, max, "tex2", "", mat, gui, matlevel, texlevel+1, lightsource))
lordcrc@384
  4135
        str = s + str + l
lordcrc@384
  4136
lordcrc@384
  4137
        str += lux3DMapping(keyname, mat, gui, level+1)
lordcrc@384
  4138
lordcrc@384
  4139
    if texture.get() == "blender_musgrave":
lordcrc@384
  4140
        if gui: gui.newline("type:", -2, level+1, icon_texparam)
lordcrc@384
  4141
        mtype = luxProp(mat, keyname+".mtype", "multifractal")
lordcrc@384
  4142
        mtypes = ["multifractal","ridged_multifractal", "hybrid_multifractal", "hetero_terrain", "fbm"]
lordcrc@384
  4143
        str += luxOption("type", mtype, mtypes, "type", "", gui, 2.0)
lordcrc@384
  4144
lordcrc@384
  4145
        str += luxFloat("h", luxProp(mat, keyname+".h", 1.0), 0.0, 2.0, "h", "", gui, 0.5)
lordcrc@384
  4146
        str += luxFloat("lacu", luxProp(mat, keyname+".lacu", 2.0), 0.0, 6.0, "lacu", "", gui, 0.75)
lordcrc@384
  4147
        str += luxFloat("octs", luxProp(mat, keyname+".octs", 2.0), 0.0, 8.0, "octs", "", gui, 0.75)
lordcrc@384
  4148
lordcrc@384
  4149
        if mtype.get() == "hetero_terrain":
lordcrc@384
  4150
            str += luxFloat("offset", luxProp(mat, keyname+".offset", 2.0), 0.0, 6.0, "offset", "", gui, 2.0)
lordcrc@384
  4151
        if mtype.get() == "ridged_multifractal":
lordcrc@384
  4152
            str += luxFloat("offset", luxProp(mat, keyname+".offset", 2.0), 0.0, 6.0, "offset", "", gui, 1.25)
lordcrc@384
  4153
            str += luxFloat("gain", luxProp(mat, keyname+".gain", 2.0), 0.0, 6.0, "gain", "", gui, 0.75)
lordcrc@384
  4154
        if mtype.get() == "hybrid_multifractal":
lordcrc@384
  4155
            str += luxFloat("offset", luxProp(mat, keyname+".offset", 2.0), 0.0, 6.0, "offset", "", gui, 1.25)
lordcrc@384
  4156
            str += luxFloat("gain", luxProp(mat, keyname+".gain", 2.0), 0.0, 6.0, "gain", "", gui, 0.75)
lordcrc@384
  4157
lordcrc@384
  4158
        str += luxFloat("outscale", luxProp(mat, keyname+".outscale", 1.0), 0.0, 10.0, "iscale", "", gui, 1.0)
lordcrc@384
  4159
        str += luxFloat("noisesize", luxProp(mat, keyname+".noisesize", 0.25), 0.0, 2.0, "noisesize", "", gui, 1.0)
lordcrc@384
  4160
lordcrc@384
  4161
        if gui: gui.newline("basis:", -2, level+1, icon_texparam)
lordcrc@384
  4162
        noisebasis = luxProp(mat, keyname+".noisebasis", "blender_original")
lordcrc@384
  4163
        noisebasises = ["blender_original","original_perlin", "improved_perlin", "voronoi_f1", "voronoi_f2", "voronoi_f3", "voronoi_f4", "voronoi_f2f1", "voronoi_crackle", "cell_noise"]
lordcrc@384
  4164
        str += luxOption("noisebasis", noisebasis, noisebasises, "noisebasis", "", gui, 2.0)
lordcrc@384
  4165
lordcrc@384
  4166
        if gui: gui.newline("level:", -2, level+1, icon_texparam)
lordcrc@384
  4167
        str += luxFloat("bright", luxProp(mat, keyname+".bright", 1.0), 0.0, 2.0, "bright", "", gui, 1.0)
lordcrc@384
  4168
        str += luxFloat("contrast", luxProp(mat, keyname+".contrast", 1.0), 0.0, 10.0, "contrast", "", gui, 1.0)
lordcrc@384
  4169
lordcrc@384
  4170
        (s, l) = c(("", ""), luxTexture("tex1", keyname, type, default, min, max, "tex1", "", mat, gui, matlevel, texlevel+1, lightsource))
lordcrc@384
  4171
        (s, l) = c((s, l), luxTexture("tex2", keyname, type, alternativedefault(type, default), min, max, "tex2", "", mat, gui, matlevel, texlevel+1, lightsource))
lordcrc@384
  4172
        str = s + str + l
lordcrc@384
  4173
lordcrc@384
  4174
        str += lux3DMapping(keyname, mat, gui, level+1)
lordcrc@384
  4175
lordcrc@384
  4176
    if texture.get() == "blender_wood":
lordcrc@384
  4177
        if gui: gui.newline("noise:", -2, level+1, icon_texparam)
lordcrc@384
  4178
lordcrc@384
  4179
        mtype = luxProp(mat, keyname+".mtype", "bands")
lordcrc@384
  4180
        mtypes = ["bands","rings","bandnoise", "ringnoise"]
lordcrc@384
  4181
        str += luxOption("type", mtype, mtypes, "type", "", gui, 0.5)
lordcrc@384
  4182
lordcrc@384
  4183
        noisetype = luxProp(mat, keyname+".noisetype", "hard_noise")
lordcrc@384
  4184
        noisetypes = ["soft_noise","hard_noise"]
lordcrc@384
  4185
        str += luxOption("noisetype", noisetype, noisetypes, "noisetypes", "", gui, 0.75)
lordcrc@384
  4186
lordcrc@384
  4187
        str += luxFloat("noisesize", luxProp(mat, keyname+".noisesize", 0.25), 0.0, 2.0, "noisesize", "", gui, 1.0)
lordcrc@384
  4188
        str += luxFloat("turbulance", luxProp(mat, keyname+".turbulance", 5.0), 0.0, 200.0, "turbulance", "", gui, 1.0)
lordcrc@384
  4189
lordcrc@384
  4190
        if gui: gui.newline("basis:", -2, level+1, icon_texparam)
lordcrc@384
  4191
        noisebasis2 = luxProp(mat, keyname+".noisebasis2", "sin")
lordcrc@384
  4192
        noisebasises2 = ["sin","saw","tri"]
lordcrc@384
  4193
        str += luxOption("noisebasis2", noisebasis2, noisebasises2, "noisebasis2", "", gui, 0.7)
lordcrc@384
  4194
lordcrc@384
  4195
        noisebasis = luxProp(mat, keyname+".noisebasis", "blender_original")
lordcrc@384
  4196
        noisebasises = ["blender_original","original_perlin", "improved_perlin", "voronoi_f1", "voronoi_f2", "voronoi_f3", "voronoi_f4", "voronoi_f2f1", "voronoi_crackle", "cell_noise"]
lordcrc@384
  4197
        str += luxOption("noisebasis", noisebasis, noisebasises, "noisebasis", "", gui, 1.3)
lordcrc@384
  4198
lordcrc@384
  4199
        if gui: gui.newline("level:", -2, level+1, icon_texparam)
lordcrc@384
  4200
        str += luxFloat("bright", luxProp(mat, keyname+".bright", 1.0), 0.0, 2.0, "bright", "", gui, 1.0)
lordcrc@384
  4201
        str += luxFloat("contrast", luxProp(mat, keyname+".contrast", 1.0), 0.0, 10.0, "contrast", "", gui, 1.0)
lordcrc@384
  4202
lordcrc@384
  4203
        (s, l) = c(("", ""), luxTexture("tex1", keyname, type, default, min, max, "tex1", "", mat, gui, matlevel, texlevel+1, lightsource))
lordcrc@384
  4204
        (s, l) = c((s, l), luxTexture("tex2", keyname, type, alternativedefault(type, default), min, max, "tex2", "", mat, gui, matlevel, texlevel+1, lightsource))
lordcrc@384
  4205
        str = s + str + l
lordcrc@384
  4206
    
lordcrc@384
  4207
        str += lux3DMapping(keyname, mat, gui, level+1)
lordcrc@384
  4208
lordcrc@384
  4209
    if texture.get() == "blender_clouds":
lordcrc@384
  4210
        if gui: gui.newline("noise:", -2, level+1, icon_texparam)
lordcrc@384
  4211
lordcrc@384
  4212
        mtype = luxProp(mat, keyname+".mtype", "default")
lordcrc@384
  4213
        mtypes = ["default","color"]
lordcrc@384
  4214
        str += luxOption("type", mtype, mtypes, "type", "", gui, 0.5)
lordcrc@384
  4215
lordcrc@384
  4216
        noisetype = luxProp(mat, keyname+".noisetype", "hard_noise")
lordcrc@384
  4217
        noisetypes = ["soft_noise","hard_noise"]
lordcrc@384
  4218
        str += luxOption("noisetype", noisetype, noisetypes, "noisetypes", "", gui, 0.75)
lordcrc@384
  4219
lordcrc@384
  4220
        str += luxFloat("noisesize", luxProp(mat, keyname+".noisesize", 0.25), 0.0, 2.0, "noisesize", "", gui, 1.0)
lordcrc@384
  4221
        str += luxInt("noisedepth", luxProp(mat, keyname+".noisedepth", 2), 0, 6, "noisedepth", "", gui, 1.0)
lordcrc@384
  4222
lordcrc@384
  4223
        if gui: gui.newline("basis:", -2, level+1, icon_texparam)
lordcrc@384
  4224
        noisebasis = luxProp(mat, keyname+".noisebasis", "blender_original")
lordcrc@384
  4225
        noisebasises = ["blender_original","original_perlin", "improved_perlin", "voronoi_f1", "voronoi_f2", "voronoi_f3", "voronoi_f4", "voronoi_f2f1", "voronoi_crackle", "cell_noise"]
lordcrc@384
  4226
        str += luxOption("noisebasis", noisebasis, noisebasises, "noisebasis", "", gui, 1.3)
lordcrc@384
  4227
lordcrc@384
  4228
        if gui: gui.newline("level:", -2, level+1, icon_texparam)
lordcrc@384
  4229
        str += luxFloat("bright", luxProp(mat, keyname+".bright", 1.0), 0.0, 2.0, "bright", "", gui, 1.0)
lordcrc@384
  4230
        str += luxFloat("contrast", luxProp(mat, keyname+".contrast", 1.0), 0.0, 10.0, "contrast", "", gui, 1.0)
lordcrc@384
  4231
lordcrc@384
  4232
        (s, l) = c(("", ""), luxTexture("tex1", keyname, type, default, min, max, "tex1", "", mat, gui, matlevel, texlevel+1, lightsource))
lordcrc@384
  4233
        (s, l) = c((s, l), luxTexture("tex2", keyname, type, alternativedefault(type, default), min, max, "tex2", "", mat, gui, matlevel, texlevel+1, lightsource))
lordcrc@384
  4234
        str = s + str + l
lordcrc@384
  4235
    
lordcrc@384
  4236
        str += lux3DMapping(keyname, mat, gui, level+1)
lordcrc@384
  4237
lordcrc@384
  4238
    if texture.get() == "blender_blend":
lordcrc@384
  4239
        if gui: gui.newline("type:", -2, level+1, icon_texparam)
lordcrc@384
  4240
lordcrc@384
  4241
        mtype = luxProp(mat, keyname+".mtype", "lin")
lordcrc@384
  4242
        mtypes = ["lin","quad","ease","diag","sphere","halo","radial"]
lordcrc@384
  4243
        str += luxOption("type", mtype, mtypes, "type", "", gui, 0.5)
lordcrc@384
  4244
        
lordcrc@384
  4245
        mflag = luxProp(mat, keyname+".flag", "false")
lordcrc@384
  4246
        str += luxBool("flipxy", mflag, "flipXY", "", gui, 0.5)
lordcrc@384
  4247
lordcrc@384
  4248
        if gui: gui.newline("level:", -2, level+1, icon_texparam)
lordcrc@384
  4249
        str += luxFloat("bright", luxProp(mat, keyname+".bright", 1.0), 0.0, 2.0, "bright", "", gui, 1.0)
lordcrc@384
  4250
        str += luxFloat("contrast", luxProp(mat, keyname+".contrast", 1.0), 0.0, 10.0, "contrast", "", gui, 1.0)
lordcrc@384
  4251
lordcrc@384
  4252
        (s, l) = c(("", ""), luxTexture("tex1", keyname, type, default, min, max, "tex1", "", mat, gui, matlevel, texlevel+1, lightsource))
lordcrc@384
  4253
        (s, l) = c((s, l), luxTexture("tex2", keyname, type, alternativedefault(type, default), min, max, "tex2", "", mat, gui, matlevel, texlevel+1, lightsource))
lordcrc@384
  4254
        str = s + str + l
lordcrc@384
  4255
        
lordcrc@384
  4256
        str += lux3DMapping(keyname, mat, gui, level+1)
lordcrc@384
  4257
lordcrc@384
  4258
    if texture.get() == "blender_distortednoise":
lordcrc@384
  4259
        if gui: gui.newline("noise:", -2, level+1, icon_texparam)
lordcrc@384
  4260
        
lordcrc@384
  4261
        str += luxFloat("distamount", luxProp(mat, keyname+".distamount", 1.0), 0.0, 10.0, "distamount", "", gui, 1.0)
lordcrc@384
  4262
        str += luxFloat("noisesize", luxProp(mat, keyname+".noisesize", 0.25), 0.0, 2.0, "noisesize", "", gui, 1.0)
lordcrc@384
  4263
        str += luxFloat("nabla", luxProp(mat, keyname+".nabla", 0.025), 0.000, 2.0, "nabla", "", gui, 1.0)
lordcrc@384
  4264
        
lordcrc@384
  4265
        if gui: gui.newline("distortion:", -2, level+1, icon_texparam)
lordcrc@384
  4266
        ntype = luxProp(mat, keyname+".type", "blender_original")
lordcrc@384
  4267
        ntypes = ["blender_original","original_perlin", "improved_perlin", "voronoi_f1", "voronoi_f2", "voronoi_f3", "voronoi_f4", "voronoi_f2f1", "voronoi_crackle", "cell_noise"]
lordcrc@384
  4268
        str += luxOption("type", ntype, ntypes, "type", "", gui, 1.3)
lordcrc@384
  4269
        
lordcrc@384
  4270
        if gui: gui.newline("basis:", -2, level+1, icon_texparam)
lordcrc@384
  4271
        noisebasis = luxProp(mat, keyname+".noisebasis", "blender_original")
lordcrc@384
  4272
        noisebasises = ["blender_original","original_perlin", "improved_perlin", "voronoi_f1", "voronoi_f2", "voronoi_f3", "voronoi_f4", "voronoi_f2f1", "voronoi_crackle", "cell_noise"]
lordcrc@384
  4273
        str += luxOption("noisebasis", noisebasis, noisebasises, "noisebasis", "", gui, 1.3)
lordcrc@384
  4274
lordcrc@384
  4275
        if gui: gui.newline("level:", -2, level+1, icon_texparam)
lordcrc@384
  4276
        str += luxFloat("bright", luxProp(mat, keyname+".bright", 1.0), 0.0, 2.0, "bright", "", gui, 1.0)
lordcrc@384
  4277
        str += luxFloat("contrast", luxProp(mat, keyname+".contrast", 1.0), 0.0, 10.0, "contrast", "", gui, 1.0)
lordcrc@384
  4278
lordcrc@384
  4279
        (s, l) = c(("", ""), luxTexture("tex1", keyname, type, default, min, max, "tex1", "", mat, gui, matlevel, texlevel+1, lightsource))
lordcrc@384
  4280
        (s, l) = c((s, l), luxTexture("tex2", keyname, type, alternativedefault(type, default), min, max, "tex2", "", mat, gui, matlevel, texlevel+1, lightsource))
lordcrc@384
  4281
        str = s + str + l
lordcrc@384
  4282
        
lordcrc@384
  4283
        str += lux3DMapping(keyname, mat, gui, level+1)
lordcrc@384
  4284
lordcrc@384
  4285
    if texture.get() == "blender_noise":        
lordcrc@384
  4286
        if gui: gui.newline("level:", -2, level+1, icon_texparam)
lordcrc@384
  4287
        str += luxFloat("bright", luxProp(mat, keyname+".bright", 1.0), 0.0, 2.0, "bright", "", gui, 1.0)
lordcrc@384
  4288
        str += luxFloat("contrast", luxProp(mat, keyname+".contrast", 1.0), 0.0, 10.0, "contrast", "", gui, 1.0)
lordcrc@384
  4289
lordcrc@384
  4290
        (s, l) = c(("", ""), luxTexture("tex1", keyname, type, default, min, max, "tex1", "", mat, gui, matlevel, texlevel+1, lightsource))
lordcrc@384
  4291
        (s, l) = c((s, l), luxTexture("tex2", keyname, type, alternativedefault(type, default), min, max, "tex2", "", mat, gui, matlevel, texlevel+1, lightsource))
lordcrc@384
  4292
        str = s + str + l
lordcrc@384
  4293
        
lordcrc@384
  4294
        str += lux3DMapping(keyname, mat, gui, level+1)
lordcrc@384
  4295
        
lordcrc@384
  4296
    if texture.get() == "blender_magic":
lordcrc@384
  4297
        if gui: gui.newline("noise:", -2, level+1, icon_texparam)
lordcrc@384
  4298
        
lordcrc@384
  4299
        str += luxInt("noisedepth", luxProp(mat, keyname+".noisedepth", 2), 0.0, 10.0, "noisedepth", "", gui, 1.0)
lordcrc@384
  4300
        str += luxFloat("turbulance", luxProp(mat, keyname+".turbulance", 5.0), 0.0, 2.0, "turbulance", "", gui, 1.0)
lordcrc@384
  4301
lordcrc@384
  4302
        if gui: gui.newline("level:", -2, level+1, icon_texparam)
lordcrc@384
  4303
        str += luxFloat("bright", luxProp(mat, keyname+".bright", 1.0), 0.0, 2.0, "bright", "", gui, 1.0)
lordcrc@384
  4304
        str += luxFloat("contrast", luxProp(mat, keyname+".contrast", 1.0), 0.0, 10.0, "contrast", "", gui, 1.0)
lordcrc@384
  4305
lordcrc@384
  4306
        (s, l) = c(("", ""), luxTexture("tex1", keyname, type, default, min, max, "tex1", "", mat, gui, matlevel, texlevel+1, lightsource))
lordcrc@384
  4307
        (s, l) = c((s, l), luxTexture("tex2", keyname, type, alternativedefault(type, default), min, max, "tex2", "", mat, gui, matlevel, texlevel+1, lightsource))
lordcrc@384
  4308
        str = s + str + l
lordcrc@384
  4309
        
lordcrc@384
  4310
        str += lux3DMapping(keyname, mat, gui, level+1)
lordcrc@384
  4311
        
lordcrc@384
  4312
    if texture.get() == "blender_stucci":
lordcrc@384
  4313
        if gui: gui.newline("noise:", -2, level+1, icon_texparam)
lordcrc@384
  4314
        mtype = luxProp(mat, keyname+".mtype", "Plastic")
lordcrc@384
  4315
        mtypes = ["Plastic","Wall In","Wall Out"]
lordcrc@384
  4316
        str += luxOption("type", mtype, mtypes, "type", "", gui, 0.5)
lordcrc@384
  4317
lordcrc@384
  4318
        noisetype = luxProp(mat, keyname+".noisetype", "soft_noise")
lordcrc@384
  4319
        noisetypes = ["soft_noise","hard_noise"]
lordcrc@384
  4320
        str += luxOption("noisetype", noisetype, noisetypes, "noisetypes", "", gui, 0.75)
lordcrc@384
  4321
        
lordcrc@384
  4322
        str += luxFloat("noisesize", luxProp(mat, keyname+".noisesize", 0.25), 0.0, 10.0, "noisesize", "", gui, 1.0)
lordcrc@384
  4323
        str += luxFloat("turbulance", luxProp(mat, keyname+".turbulance", 5.0), 0.0, 200.0, "turbulance", "", gui, 1.0)
lordcrc@384
  4324
lordcrc@384
  4325
        noisebasis = luxProp(mat, keyname+".noisebasis", "blender_original")
lordcrc@384
  4326
        noisebasises = ["blender_original","original_perlin", "improved_perlin", "voronoi_f1", "voronoi_f2", "voronoi_f3", "voronoi_f4", "voronoi_f2f1", "voronoi_crackle", "cell_noise"]
lordcrc@384
  4327
        str += luxOption("noisebasis", noisebasis, noisebasises, "noisebasis", "", gui, 1.3)
lordcrc@384
  4328
lordcrc@384
  4329
        if gui: gui.newline("level:", -2, level+1, icon_texparam)
lordcrc@384
  4330
        str += luxFloat("bright", luxProp(mat, keyname+".bright", 1.0), 0.0, 2.0, "bright", "", gui, 1.0)
lordcrc@384
  4331
        str += luxFloat("contrast", luxProp(mat, keyname+".contrast", 1.0), 0.0, 10.0, "contrast", "", gui, 1.0)
lordcrc@384
  4332
lordcrc@384
  4333
        (s, l) = c(("", ""), luxTexture("tex1", keyname, type, default, min, max, "tex1", "", mat, gui, matlevel, texlevel+1, lightsource))
lordcrc@384
  4334
        (s, l) = c((s, l), luxTexture("tex2", keyname, type, alternativedefault(type, default), min, max, "tex2", "", mat, gui, matlevel, texlevel+1, lightsource))
lordcrc@384
  4335
        str = s + str + l
lordcrc@384
  4336
lordcrc@384
  4337
        str += lux3DMapping(keyname, mat, gui, level+1)
lordcrc@384
  4338
lordcrc@384
  4339
    if texture.get() == "blender_voronoi":
lordcrc@384
  4340
        #if gui: gui.newline("distmetric:", -2, level+1, icon_texparam)
lordcrc@384
  4341
        mtype = luxProp(mat, keyname+".distmetric", "actual_distance")
lordcrc@384
  4342
        mtypes = ["actual_distance","distance_squared","manhattan", "chebychev", "minkovsky_half", "minkovsky_four", "minkovsky"]
lordcrc@384
  4343
        str += luxOption("distmetric", mtype, mtypes, "distmetric", "", gui, 1.1)
lordcrc@384
  4344
lordcrc@384
  4345
        if gui: gui.newline("param:", -2, level+1, icon_texparam)
lordcrc@384
  4346
        str += luxFloat("minkovsky_exp", luxProp(mat, keyname+".minkovsky_exp", 2.5), 0.001, 10.0, "minkovsky_exp", "", gui, 1.0)
lordcrc@384
  4347
        str += luxFloat("outscale", luxProp(mat, keyname+".outscale", 1.0), 0.01, 10.0, "outscale", "", gui, 1.0)
lordcrc@384
  4348
        str += luxFloat("noisesize", luxProp(mat, keyname+".noisesize", 0.25), 0.0, 2.0, "noisesize", "", gui, 1.0)
lordcrc@384
  4349
        str += luxFloat("nabla", luxProp(mat, keyname+".nabla", 0.025), 0.001, 0.1, "nabla", "", gui, 1.0)
lordcrc@384
  4350
        if gui: gui.newline("wparam:", -2, level+1, icon_texparam)
lordcrc@384
  4351
        str += luxFloat("w1", luxProp(mat, keyname+".w1", 1.0), -2.0, 2.0, "w1", "", gui, 1.0)
lordcrc@384
  4352
        str += luxFloat("w2", luxProp(mat, keyname+".w2", 0.0), -2.0, 2.0, "w2", "", gui, 1.0)
lordcrc@384
  4353
        str += luxFloat("w3", luxProp(mat, keyname+".w3", 0.0), -2.0, 2.0, "w3", "", gui, 1.0)
lordcrc@384
  4354
        str += luxFloat("w4", luxProp(mat, keyname+".w4", 0.0), -2.0, 2.0, "w4", "", gui, 1.0)
lordcrc@384
  4355
lordcrc@384
  4356
        if gui: gui.newline("level:", -2, level+1, icon_texparam)
lordcrc@384
  4357
        str += luxFloat("bright", luxProp(mat, keyname+".bright", 1.0), 0.0, 2.0, "bright", "", gui, 1.0)
lordcrc@384
  4358
        str += luxFloat("contrast", luxProp(mat, keyname+".contrast", 1.0), 0.0, 10.0, "contrast", "", gui, 1.0)
lordcrc@384
  4359
lordcrc@384
  4360
        (s, l) = c(("", ""), luxTexture("tex1", keyname, type, default, min, max, "tex1", "", mat, gui, matlevel, texlevel+1, lightsource))
lordcrc@384
  4361
        (s, l) = c((s, l), luxTexture("tex2", keyname, type, alternativedefault(type, default), min, max, "tex2", "", mat, gui, matlevel, texlevel+1, lightsource))
lordcrc@384
  4362
        str = s + str + l
lordcrc@384
  4363
lordcrc@384
  4364
        str += lux3DMapping(keyname, mat, gui, level+1)
lordcrc@384
  4365
lordcrc@384
  4366
lordcrc@384
  4367
lordcrc@384
  4368
    return (str+"\n", " \"texture %s\" [\"%s\"]"%(name, texname))
lordcrc@384
  4369
lordcrc@384
  4370
lordcrc@384
  4371
def luxSpectrumTexture(name, key, default, max, caption, hint, mat, gui, level=0):
lordcrc@384
  4372
    global icon_col
lordcrc@384
  4373
    if gui: gui.newline(caption, 4, level, icon_col, scalelist([0.5,0.6,0.5],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
    link = luxRGB(name, value, max, "", hint, gui, 2.0)
lordcrc@384
  4379
    tex = luxProp(mat, keyname+".textured", False)
lordcrc@384
  4380
    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
  4381
    if tex.get()=="true":
lordcrc@384
  4382
        if gui: gui.newline("", -2)
lordcrc@384
  4383
        (str, link) = luxTexture(name, key, "color", default, 0, max, caption, hint, mat, gui, level+1)
lordcrc@384
  4384
        if value.getRGB() != (1.0, 1.0, 1.0):
lordcrc@384
  4385
            if str == "": # handle special case if texture is a just a constant
lordcrc@384
  4386
                str += "Texture \"%s\" \"color\" \"scale\" \"color tex1\" [%s] \"color tex2\" [%s]\n"%(texname+".scale", (link.rpartition("[")[2])[0:-1], value.get())
lordcrc@384
  4387
            else: str += "Texture \"%s\" \"color\" \"scale\" \"texture tex1\" [\"%s\"] \"color tex2\" [%s]\n"%(texname+".scale", texname, value.get())
lordcrc@384
  4388
            link = " \"texture %s\" [\"%s\"]"%(name, texname+".scale")
lordcrc@384
  4389
    return (str, link)
lordcrc@384
  4390
lordcrc@384
  4391
def luxLightSpectrumTexture(name, key, default, max, caption, hint, mat, gui, level=0):
lordcrc@384
  4392
    #if gui: gui.newline(caption, 4, level, icon_emission, scalelist([0.6,0.5,0.5],2.0/(level+2)))
lordcrc@384
  4393
    str = ""
lordcrc@384
  4394
    keyname = "%s:%s"%(key, name)
lordcrc@384
  4395
    texname = "%s:%s"%(mat.getName(), keyname)
lordcrc@384
  4396
    (str, link) = luxTexture(name, key, "color", default, 0, max, caption, hint, mat, gui, level+1, 0, 1)
lordcrc@384
  4397
    return (str, link)
lordcrc@384
  4398
lordcrc@384
  4399
def luxFloatTexture(name, key, default, min, max, caption, hint, mat, gui, level=0):
lordcrc@384
  4400
    global icon_float
lordcrc@384
  4401
    if gui: gui.newline(caption, 4, level, icon_float, scalelist([0.5,0.5,0.6],2.0/(level+2)))
lordcrc@384
  4402
    str = ""
lordcrc@384
  4403
    keyname = "%s:%s"%(key, name)
lordcrc@384
  4404
    texname = "%s:%s"%(mat.getName(), keyname)
lordcrc@384
  4405
    value = luxProp(mat, keyname, default)
lordcrc@384
  4406
    link = luxFloat(name, value, min, max, "", hint, gui, 2.0)
lordcrc@384
  4407
    tex = luxProp(mat, keyname+".textured", False)
lordcrc@384
  4408
    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
  4409
    if tex.get()=="true":
lordcrc@384
  4410
        if gui: gui.newline("", -2)
lordcrc@384
  4411
        (str, link) = luxTexture(name, key, "float", default, min, max, caption, hint, mat, gui, level+1)
lordcrc@384
  4412
        if value.get() != 1.0:
lordcrc@384
  4413
            if str == "": # handle special case if texture is a just a constant
lordcrc@384
  4414
                str += "Texture \"%s\" \"float\" \"scale\" \"float tex1\" [%s] \"float tex2\" [%s]\n"%(texname+".scale", (link.rpartition("[")[2])[0:-1], value.get())
lordcrc@384
  4415
            else: str += "Texture \"%s\" \"float\" \"scale\" \"texture tex1\" [\"%s\"] \"float tex2\" [%s]\n"%(texname+".scale", texname, value.get())
lordcrc@384
  4416
            link = " \"texture %s\" [\"%s\"]"%(name, texname+".scale")
lordcrc@384
  4417
    return (str, link)
lordcrc@384
  4418
lordcrc@384
  4419
def luxFloatSliderTexture(name, key, default, min, max, caption, hint, mat, gui, level=0):
lordcrc@384
  4420
        global icon_float
lordcrc@384
  4421
        if gui: gui.newline(caption, 4, level, icon_float, scalelist([0.5,0.5,0.6],2.0/(level+2)))
lordcrc@384
  4422
        str = ""
lordcrc@384
  4423
        keyname = "%s:%s"%(key, name)
lordcrc@384
  4424
        texname = "%s:%s"%(mat.getName(), keyname)
lordcrc@384
  4425
        value = luxProp(mat, keyname, default)
lordcrc@384
  4426
        link = luxFloat(name, value, min, max, caption, hint, gui, 2.0, 1)
lordcrc@384
  4427
        tex = luxProp(mat, keyname+".textured", False)
lordcrc@384
  4428
        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
  4429
        if tex.get()=="true":
lordcrc@384
  4430
                if gui: gui.newline("", -2)
lordcrc@384
  4431
                (str, link) = luxTexture(name, key, "float", default, min, max, caption, hint, mat, gui, level+1)
lordcrc@384
  4432
                if value.get() != 1.0:
lordcrc@384
  4433
                        if str == "": # handle special case if texture is a just a constant
lordcrc@384
  4434
                                str += "Texture \"%s\" \"float\" \"scale\" \"float tex1\" [%s] \"float tex2\" [%s]\n"%(texname+".scale", (link.rpartition("[")[2])[0:-1], value.get())
lordcrc@384
  4435
                        else: str += "Texture \"%s\" \"float\" \"scale\" \"texture tex1\" [\"%s\"] \"float tex2\" [%s]\n"%(texname+".scale", texname, value.get())
lordcrc@384
  4436
                        link = " \"texture %s\" [\"%s\"]"%(name, texname+".scale")
lordcrc@384
  4437
        return (str, link)
lordcrc@384
  4438
lordcrc@384
  4439
lordcrc@384
  4440
def luxExponentTexture(name, key, default, min, max, caption, hint, mat, gui, level=0):
lordcrc@384
  4441
    global icon_float
lordcrc@384
  4442
    if gui: gui.newline(caption, 4, level, icon_float, scalelist([0.5,0.5,0.6],2.0/(level+2)))
lordcrc@384
  4443
    str = ""
lordcrc@384
  4444
    keyname = "%s:%s"%(key, name)
lordcrc@384
  4445
    texname = "%s:%s"%(mat.getName(), keyname)
lordcrc@384
  4446
    value = luxProp(mat, keyname, default)
lordcrc@384
  4447
lordcrc@384
  4448
    if(value.get() == None): value.set(0.002)
lordcrc@384
  4449
lordcrc@384
  4450
#    link = luxFloat(name, value, min, max, "", hint, gui, 2.0)
lordcrc@384
  4451
    if gui:
lordcrc@384
  4452
        r = gui.getRect(2.0, 1)
lordcrc@384
  4453
        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
  4454
    link = " \"float %s\" [%f]"%(name, value.getFloat())
lordcrc@384
  4455
lordcrc@384
  4456
    tex = luxProp(mat, keyname+".textured", False)
lordcrc@384
  4457
    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
  4458
    if tex.get()=="true":
lordcrc@384
  4459
        if gui: gui.newline("", -2)
lordcrc@384
  4460
        (str, link) = luxTexture(name, key, "float", default, min, max, caption, hint, mat, gui, level+1)
lordcrc@384
  4461
        if value.get() != 1.0:
lordcrc@384
  4462
            if str == "": # handle special case if texture is a just a constant
lordcrc@384
  4463
                str += "Texture \"%s\" \"float\" \"scale\" \"float tex1\" [%s] \"float tex2\" [%s]\n"%(texname+".scale", (link.rpartition("[")[2])[0:-1], value.get())
lordcrc@384
  4464
            else: str += "Texture \"%s\" \"float\" \"scale\" \"texture tex1\" [\"%s\"] \"float tex2\" [%s]\n"%(texname+".scale", texname, value.get())
lordcrc@384
  4465
            link = " \"texture %s\" [\"%s\"]"%(name, texname+".scale")
lordcrc@384
  4466
    return (str, link)
lordcrc@384
  4467
lordcrc@384
  4468
lordcrc@384
  4469
def luxDispFloatTexture(name, key, default, min, max, caption, hint, mat, gui, level=0):
lordcrc@384
  4470
    global icon_float
lordcrc@384
  4471
    if gui: gui.newline(caption, 4, level, icon_float, scalelist([0.5,0.5,0.6],2.0/(level+2)))
lordcrc@384
  4472
    str = ""
lordcrc@384
  4473
    keyname = "%s:%s"%(key, name)
lordcrc@384
  4474
    texname = "%s:%s"%(mat.getName(), keyname)
lordcrc@384
  4475
    value = luxProp(mat, keyname, default)
lordcrc@384
  4476
    link = luxFloat(name, value, min, max, "", hint, gui, 2.0)
lordcrc@384
  4477
    tex = luxProp(mat, keyname+".textured", False)
lordcrc@384
  4478
    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
  4479
    if tex.get()=="true":
lordcrc@384
  4480
        if gui: gui.newline("", -2)
lordcrc@384
  4481
        (str, link) = luxTexture(name, key, "float", default, min, max, caption, hint, mat, gui, level+1)
lordcrc@384
  4482
        str += "Texture \"%s\" \"float\" \"scale\" \"texture tex1\" [\"%s\"] \"float tex2\" [%s]\n"%(texname+".scale", texname, value.get())
lordcrc@384
  4483
        link = " \"texture %s\" [\"%s\"]"%(name, texname+".scale")
lordcrc@384
  4484
    return (str, link)
lordcrc@384
  4485
lordcrc@384
  4486
def luxIORFloatTexture(name, key, default, min, max, caption, hint, mat, gui, level=0):
lordcrc@384
  4487
    # IOR preset data
lordcrc@384
  4488
    iornames = ["0Z *** Gases @ 0 C ***", "01 - Vacuum", "02 - Air @ STP", "03 - Air", "04 - Helium", "05 - Hydrogen", "06 - Carbon dioxide",
lordcrc@384
  4489
    "1Z *** LIQUIDS @ 20 C ***", "11 - Benzene", "12 - Water", "13 - Ethyl alcohol", "14 - Carbon tetrachloride", "15 - Carbon disulfide", 
lordcrc@384
  4490
    "2Z *** SOLIDS at room temperature ***", "21 - Diamond", "22 - Strontium titanate", "23 - Amber", "24 - Fused silica glass", "25 - sodium chloride", 
lordcrc@384
  4491
    "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
  4492
    iorvals = [1.0, 1.0, 1.0002926, 1.000293, 1.000036, 1.000132, 1.00045,
lordcrc@384
  4493
    1.501, 1.501, 1.333, 1.361, 1.461, 1.628,
lordcrc@384
  4494
    2.419, 2.419, 2.41, 1.55, 1.458, 1.50,
lordcrc@384
  4495
    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
  4496
lordcrc@384
  4497
    global icon_float
lordcrc@384
  4498
    if gui: gui.newline(caption, 4, level, icon_float, scalelist([0.5,0.5,0.6],2.0/(level+2)))
lordcrc@384
  4499
    str = ""
lordcrc@384
  4500
    keyname = "%s:%s"%(key, name)
lordcrc@384
  4501
    texname = "%s:%s"%(mat.getName(), keyname)
lordcrc@384
  4502
    value = luxProp(mat, keyname, default)
lordcrc@384
  4503
lordcrc@384
  4504
    iorusepreset = luxProp(mat, keyname+".iorusepreset", "true")
lordcrc@384
  4505
    luxBool("iorusepreset", iorusepreset, "Preset", "Select from a list of predefined presets", gui, 0.4)
lordcrc@384
  4506
lordcrc@384
  4507
    if(iorusepreset.get() == "true"):
lordcrc@384
  4508
        iorpreset = luxProp(mat, keyname+".iorpreset", "24 - Fused silica glass")
lordcrc@384
  4509
        if gui:
lordcrc@384
  4510
            def setIor(i, value, preset, tree, dict): # callback function to set ior value after selection                
lordcrc@384
  4511
                if i >= 0:
lordcrc@384
  4512
                    value.set(dict[i])
lordcrc@384
  4513
                    preset.set(getTreeNameById(tree, i))
tom@398
  4514
            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
  4515
            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
  4516
            r = gui.getRect(1.6, 1)
lordcrc@384
  4517
            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
  4518
        link = luxFloat(name, value, min, max, "IOR", hint, None, 1.6)
lordcrc@384
  4519
    else:
lordcrc@384
  4520
        link = luxFloat(name, value, min, max, "IOR", hint, gui, 1.6, 1)
lordcrc@384
  4521
lordcrc@384
  4522
    tex = luxProp(mat, keyname+".textured", False)
lordcrc@384
  4523
    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
  4524
    if tex.get()=="true":
lordcrc@384
  4525
        if gui: gui.newline("", -2)
lordcrc@384
  4526
        (str, link) = luxTexture(name, key, "float", default, min, max, caption, hint, mat, gui, level+1)
lordcrc@384
  4527
        if value.get() != 1.0:
lordcrc@384
  4528
            str += "Texture \"%s\" \"float\" \"scale\" \"texture tex1\" [\"%s\"] \"float tex2\" [%s]\n"%(texname+".scale", texname, value.get())
lordcrc@384
  4529
            link = " \"texture %s\" [\"%s\"]"%(name, texname+".scale")
lordcrc@384
  4530
    return (str, link)
lordcrc@384
  4531
lordcrc@384
  4532
def luxCauchyBFloatTexture(name, key, default, min, max, caption, hint, mat, gui, level=0):
lordcrc@384
  4533
    # IOR preset data
lordcrc@384
  4534
    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
  4535
    cauchybvals = [ 0.00354, 0.00420, 0.00459, 0.00531, 0.00743, 0.01342 ]
lordcrc@384
  4536
lordcrc@384
  4537
    global icon_float
lordcrc@384
  4538
    if gui: gui.newline(caption, 4, level, icon_float, scalelist([0.5,0.5,0.6],2.0/(level+2)))
lordcrc@384
  4539
    str = ""
lordcrc@384
  4540
    keyname = "%s:%s"%(key, name)
lordcrc@384
  4541
    texname = "%s:%s"%(mat.getName(), keyname)
lordcrc@384
  4542
    value = luxProp(mat, keyname, default)
lordcrc@384
  4543
lordcrc@384
  4544
    cauchybusepreset = luxProp(mat, keyname+".cauchybusepreset", "true")
lordcrc@384
  4545
    luxBool("cauchybusepreset", cauchybusepreset, "Preset", "Select from a list of predefined presets", gui, 0.4)
lordcrc@384
  4546
lordcrc@384
  4547
    if(cauchybusepreset.get() == "true"):
lordcrc@384
  4548
        cauchybpreset = luxProp(mat, keyname+".cauchybpreset", "01 - Fused silica glass")
lordcrc@384
  4549
        luxOption("cauchybpreset", cauchybpreset, cauchybnames, "  PRESET", "select CauchyB preset", gui, 1.6)
lordcrc@384
  4550
        idx = cauchybnames.index(cauchybpreset.get())
lordcrc@384
  4551
        value.set(cauchybvals[idx])
lordcrc@384
  4552
        link = luxFloat(name, value, min, max, "cauchyb", hint, None, 1.6)
lordcrc@384
  4553
    else:
lordcrc@384
  4554
        link = luxFloat(name, value, min, max, "cauchyb", hint, gui, 1.6, 1)
lordcrc@384
  4555
lordcrc@384
  4556
    tex = luxProp(mat, keyname+".textured", False)
lordcrc@384
  4557
    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
  4558
    if tex.get()=="true":
lordcrc@384
  4559
        if gui: gui.newline("", -2)
lordcrc@384
  4560
        (str, link) = luxTexture(name, key, "float", default, min, max, caption, hint, mat, gui, level+1)
lordcrc@384
  4561
        if value.get() != 1.0:
lordcrc@384
  4562
            str += "Texture \"%s\" \"float\" \"scale\" \"texture tex1\" [\"%s\"] \"float tex2\" [%s]\n"%(texname+".scale", texname, value.get())
lordcrc@384
  4563
            link = " \"texture %s\" [\"%s\"]"%(name, texname+".scale")
lordcrc@384
  4564
    return (str, link)
lordcrc@384
  4565
lordcrc@384
  4566
def luxLight(name, kn, mat, gui, level):
lordcrc@384
  4567
    if gui:
lordcrc@384
  4568
        if name != "": gui.newline(name+":", 10, level)
lordcrc@384
  4569
        else: gui.newline("color:", 0, level+1)
lordcrc@384
  4570
    (str,link) = luxLightSpectrumTexture("L", kn+"light", "1.0 1.0 1.0", 1.0, "Spectrum", "", mat, gui, level+1)
lordcrc@384
  4571
    if gui: gui.newline("")
lordcrc@384
  4572
    link += luxFloat("power", luxProp(mat, kn+"light.power", 100.0), 0.0, 10000.0, "Power(W)", "AreaLight Power in Watts", gui)
lordcrc@384
  4573
    link += luxFloat("efficacy", luxProp(mat, kn+"light.efficacy", 17.0), 0.0, 100.0, "Efficacy(lm/W)", "Efficacy Luminous flux/watt", gui)
lordcrc@384
  4574
    if gui: gui.newline("")
lordcrc@384
  4575
    link += luxFloat("gain", luxProp(mat, kn+"light.gain", 1.0), 0.0, 100.0, "gain", "Gain/scale multiplier", gui)
lordcrc@384
  4576
    lightgroup = luxProp(mat, kn+"light.lightgroup", "default")
lordcrc@384
  4577
    luxString("lightgroup", lightgroup, "group", "assign light to a named light-group", gui, 1.0)
lordcrc@384
  4578
lordcrc@384
  4579
    if gui: gui.newline("Photometric")
lordcrc@384
  4580
    pm = luxProp(mat, kn+"light.usepm", "false")
lordcrc@384
  4581
    luxCollapse("photometric", pm, "Photometric Diagram", "Enable Photometric Diagram options", gui, 2.0)
lordcrc@384
  4582
lordcrc@384
  4583
    if(pm.get()=="true"):
lordcrc@384
  4584
        pmtype = luxProp(mat, kn+"light.pmtype", "IESna")
lordcrc@384
  4585
        pmtypes = ["IESna", "imagemap"]
lordcrc@384
  4586
        luxOption("type", pmtype, pmtypes, "type", "Choose Photometric data type to use", gui, 0.6)
lordcrc@384
  4587
        if(pmtype.get() == "imagemap"):
lordcrc@384
  4588
            map = luxProp(mat, kn+"light.pmmapname", "")
lordcrc@384
  4589
            link += luxFile("mapname", map, "map-file", "filename of the photometric map", gui, 1.4)
lordcrc@384
  4590
        if(pmtype.get() == "IESna"):
lordcrc@384
  4591
            map = luxProp(mat, kn+"light.pmiesname", "")
lordcrc@384
  4592
            link += luxFile("iesname", map, "ies-file", "filename of the IES photometric data file", gui, 1.4)
lordcrc@384
  4593
lordcrc@384
  4594
    has_bump_options = 0
lordcrc@384
  4595
    has_object_options = 1
lordcrc@384
  4596
    return (str, link)
lordcrc@384
  4597
lordcrc@384
  4598
def luxLamp(name, kn, mat, gui, level):
lordcrc@384
  4599
    if gui:
lordcrc@384
  4600
        if name != "": gui.newline(name+":", 10, level)
lordcrc@384
  4601
        else: gui.newline("color:", 0, level+1)
lordcrc@384
  4602
#    if gui: gui.newline("", 10, level)
lordcrc@384
  4603
    (str,link) = luxLightSpectrumTexture("L", kn+"light", "1.0 1.0 1.0", 1.0, "Spectrum", "", mat, gui, level+1)
lordcrc@384
  4604
    if gui: gui.newline("")
lordcrc@384
  4605
    link += luxFloat("gain", luxProp(mat, kn+"light.gain", 1.0), 0.0, 100.0, "gain", "Gain/scale multiplier", gui)
lordcrc@384
  4606
    lightgroup = luxProp(mat, kn+"light.lightgroup", "default")
lordcrc@384
  4607
    luxString("lightgroup", lightgroup, "group", "assign light to a named light-group", gui, 1.0)
lordcrc@384
  4608
lordcrc@384
  4609
    if gui: gui.newline("Photometric")
lordcrc@384
  4610
    pm = luxProp(mat, kn+"light.usepm", "false")
lordcrc@384
  4611
    luxBool("photometric", pm, "Photometric Diagram", "Enable Photometric Diagram options", gui, 2.0)
lordcrc@384
  4612
lordcrc@384
  4613
    if(pm.get()=="true"):
lordcrc@384
  4614
        pmtype = luxProp(mat, kn+"light.pmtype", "IESna")
lordcrc@384
  4615
        pmtypes = ["IESna", "imagemap"]
lordcrc@384
  4616
        luxOption("type", pmtype, pmtypes, "type", "Choose Photometric data type to use", gui, 0.6)
lordcrc@384
  4617
        if(pmtype.get() == "imagemap"):
lordcrc@384
  4618
            map = luxProp(mat, kn+"light.pmmapname", "")
lordcrc@384
  4619
            link += luxFile("mapname", map, "map-file", "filename of the photometric map", gui, 1.4)
lordcrc@384
  4620
        if(pmtype.get() == "IESna"):
lordcrc@384
  4621
            map = luxProp(mat, kn+"light.pmiesname", "")
lordcrc@384
  4622
            link += luxFile("iesname", map, "ies-file", "filename of the IES photometric data file", gui, 1.4)
lordcrc@384
  4623
lordcrc@384
  4624
        link += luxBool("flipz", luxProp(mat, kn+"light.flipZ", "true"), "Flip Z", "Flip Z direction in mapping", gui, 2.0)
lordcrc@384
  4625
lordcrc@384
  4626
    return (str, link)
lordcrc@384
  4627
lordcrc@384
  4628
def luxSpot(name, kn, mat, gui, level):
lordcrc@384
  4629
    if gui:
lordcrc@384
  4630
        if name != "": gui.newline(name+":", 10, level)
lordcrc@384
  4631
        else: gui.newline("color:", 0, level+1)
lordcrc@384
  4632
#    if gui: gui.newline("", 10, level)
lordcrc@384
  4633
    (str,link) = luxLightSpectrumTexture("L", kn+"light", "1.0 1.0 1.0", 1.0, "Spectrum", "", mat, gui, level+1)
lordcrc@384
  4634
    if gui: gui.newline("")
lordcrc@384
  4635
    link += luxFloat("gain", luxProp(mat, kn+"light.gain", 1.0), 0.0, 100.0, "gain", "Gain/scale multiplier", gui)
lordcrc@384
  4636
    lightgroup = luxProp(mat, kn+"light.lightgroup", "default")
lordcrc@384
  4637
    luxString("lightgroup", lightgroup, "group", "assign light to a named light-group", gui, 1.0)
lordcrc@384
  4638
lordcrc@384
  4639
    if gui: gui.newline("Projection")
lordcrc@384
  4640
    proj = luxProp(mat, kn+"light.usetexproj", "false")
lordcrc@384
  4641
    luxBool("projection", proj, "Texture Projection", "Enable imagemap texture projection", gui, 2.0)
lordcrc@384
  4642
lordcrc@384
  4643
    if(proj.get() == "true"):
lordcrc@384
  4644
        map = luxProp(mat, kn+"light.pmmapname", "")
lordcrc@384
  4645
        link += luxFile("mapname", map, "map-file", "filename of the photometric map", gui, 2.0)
lordcrc@384
  4646
lordcrc@384
  4647
    return (str, link)
lordcrc@384
  4648
lordcrc@384
  4649
lordcrc@384
  4650
def Preview_Sphereset(mat, kn, state):
lordcrc@384
  4651
    if state=="true":
lordcrc@384
  4652
        luxProp(mat, kn+"prev_sphere", "true").set("true")
lordcrc@384
  4653
        luxProp(mat, kn+"prev_plane", "false").set("false")
lordcrc@384
  4654
        luxProp(mat, kn+"prev_torus", "false").set("false")
lordcrc@384
  4655
def Preview_Planeset(mat, kn, state):
lordcrc@384
  4656
    if state=="true":
lordcrc@384
  4657
        luxProp(mat, kn+"prev_sphere", "true").set("false")
lordcrc@384
  4658
        luxProp(mat, kn+"prev_plane", "false").set("true")
lordcrc@384
  4659
        luxProp(mat, kn+"prev_torus", "false").set("false")
lordcrc@384
  4660
def Preview_Torusset(mat, kn, state):
lordcrc@384
  4661
    if state=="true":
lordcrc@384
  4662
        luxProp(mat, kn+"prev_sphere", "true").set("false")
lordcrc@384
  4663
        luxProp(mat, kn+"prev_plane", "false").set("false")
lordcrc@384
  4664
        luxProp(mat, kn+"prev_torus", "false").set("true")
lordcrc@384
  4665
lordcrc@384
  4666
lordcrc@384
  4667
    
lordcrc@384
  4668
lordcrc@384
  4669
def Preview_Update(mat, kn, defLarge, defType, texName, name, level):
lordcrc@384
  4670
    #print("%s %s %s %s %s %s %s" % (mat, kn, defLarge, defType, texName, name, level))
lordcrc@384
  4671
lordcrc@384
  4672
    global previewing
lordcrc@384
  4673
    previewing = True
lordcrc@384
  4674
    
lordcrc@384
  4675
    Blender.Window.WaitCursor(True)
lordcrc@384
  4676
    scn = Scene.GetCurrent()
lordcrc@384
  4677
    
lordcrc@384
  4678
    # set path mode to absolute for preview
lordcrc@384
  4679
    pm_prop = luxProp(scn, "pathmode", "absolute")
lordcrc@384
  4680
    pm = pm_prop.get()
lordcrc@384
  4681
    pm_prop.set('absolute')
lordcrc@384
  4682
    
lordcrc@384
  4683
lordcrc@384
  4684
    # Size of preview thumbnail
lordcrc@384
  4685
    thumbres = 110 # default 110x110
lordcrc@384
  4686
    if(defLarge):
lordcrc@384
  4687
        large = luxProp(mat, kn+"prev_large", "true")
lordcrc@384
  4688
    else:
lordcrc@384
  4689
        large = luxProp(mat, kn+"prev_large", "false")
lordcrc@384
  4690
    if(large.get() == "true"):
lordcrc@384
  4691
        thumbres = 140 # small 140x140
lordcrc@384
  4692
lordcrc@384
  4693
    thumbbuf = thumbres*thumbres*3
lordcrc@384
  4694
lordcrc@384
  4695
#        consolebin = luxProp(scn, "luxconsole", "").get()
lordcrc@384
  4696
    
lordcrc@384
  4697
    p = get_lux_pipe(scn, buf=thumbbuf, type="luxconsole")
lordcrc@384
  4698
lordcrc@384
  4699
    # Unremark to write debugging output to file
lordcrc@384
  4700
    # p.stdin = open('c:\preview.lxs', 'w')
lordcrc@384
  4701
lordcrc@384
  4702
    if defType == 0:    
lordcrc@384
  4703
        prev_sphere = luxProp(mat, kn+"prev_sphere", "true")
lordcrc@384
  4704
        prev_plane = luxProp(mat, kn+"prev_plane", "false")
lordcrc@384
  4705
        prev_torus = luxProp(mat, kn+"prev_torus", "false")
lordcrc@384
  4706
    elif defType == 1:
lordcrc@384
  4707
        prev_sphere = luxProp(mat, kn+"prev_sphere", "false")
lordcrc@384
  4708
        prev_plane = luxProp(mat, kn+"prev_plane", "true")
lordcrc@384
  4709
        prev_torus = luxProp(mat, kn+"prev_torus", "false")
lordcrc@384
  4710
    else:
lordcrc@384
  4711
        prev_sphere = luxProp(mat, kn+"prev_sphere", "false")
lordcrc@384
  4712
        prev_plane = luxProp(mat, kn+"prev_plane", "false")
lordcrc@384
  4713
        prev_torus = luxProp(mat, kn+"prev_torus", "true")
lordcrc@384
  4714
lordcrc@384
  4715
    # Zoom
lordcrc@384
  4716
    if luxProp(mat, kn+"prev_zoom", "false").get() == "true":
lordcrc@384
  4717
        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
  4718
    else:
lordcrc@384
  4719
        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
  4720
    # Fleximage
lordcrc@384
  4721
    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
  4722
    p.stdin.write('PixelFilter "sinc"\n')
lordcrc@384
  4723
    # Quality
lordcrc@384
  4724
    scn = Scene.GetCurrent()
lordcrc@384
  4725
    defprevmat = luxProp(scn, "defprevmat", "high")
lordcrc@384
  4726
    quality = luxProp(mat, kn+"prev_quality", defprevmat.get())
lordcrc@384
  4727
    if quality.get()=="low":
lordcrc@384
  4728
        p.stdin.write('Sampler "lowdiscrepancy" "string pixelsampler" ["hilbert"] "integer pixelsamples" [2]\n')
lordcrc@384
  4729
    elif quality.get()=="medium":
lordcrc@384
  4730
        p.stdin.write('Sampler "lowdiscrepancy" "string pixelsampler" ["hilbert"] "integer pixelsamples" [4]\n')
lordcrc@384
  4731
    elif quality.get()=="high":
lordcrc@384
  4732
        p.stdin.write('Sampler "lowdiscrepancy" "string pixelsampler" ["hilbert"] "integer pixelsamples" [8]\n')
lordcrc@384
  4733
    else: 
lordcrc@384
  4734
        p.stdin.write('Sampler "lowdiscrepancy" "string pixelsampler" ["hilbert"] "integer pixelsamples" [32]\n')
lordcrc@384
  4735
    # SurfaceIntegrator
lordcrc@384
  4736
    if(prev_plane.get()=="false"):
lordcrc@384
  4737
        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
  4738
    else:
lordcrc@384
  4739
        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
  4740
    # World
lordcrc@384
  4741
    p.stdin.write('WorldBegin\n')
lordcrc@384
  4742
    if(prev_sphere.get()=="true"):
lordcrc@384
  4743
        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
  4744
    elif (prev_plane.get()=="true"):
lordcrc@384
  4745
        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
  4746
    else:
lordcrc@384
  4747
        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
  4748
    obwidth = luxProp(mat, kn+"prev_obwidth", 1.0)
lordcrc@384
  4749
    obw = obwidth.get()
lordcrc@384
  4750
    p.stdin.write('TransformBegin\n')
lordcrc@384
  4751
    p.stdin.write('Scale %f %f %f\n'%(obw,obw,obw))
lordcrc@384
  4752
    if texName:
lordcrc@384
  4753
        print("texture "+texName+"  "+name)
lordcrc@384
  4754
        (str, link) = luxTexture(texName, name, "color", "1.0 1.0 1.0", None, None, "", "", mat, None, 0, level)
lordcrc@384
  4755
        link = link.replace(" "+texName+"\"", " Kd\"") # swap texture name to "Kd"
lordcrc@384
  4756
        p.stdin.write(str+"\n")
lordcrc@384
  4757
        p.stdin.write("Material \"matte\" "+link+"\n") 
lordcrc@384
  4758
    else:
lordcrc@384
  4759
        # Material
lordcrc@384
  4760
        p.stdin.write(luxMaterial(mat))
lordcrc@384
  4761
        link = luxProp(mat,"link","").get()
lordcrc@384
  4762
        if kn!="": link = link.rstrip("\"")+":"+kn.strip(".:")+"\""
lordcrc@384
  4763
        p.stdin.write(link+'\n')
lordcrc@384
  4764
    p.stdin.write('TransformEnd\n')
lordcrc@384
  4765
    # Shape
lordcrc@384
  4766
    if(prev_sphere.get()=="true"):
lordcrc@384
  4767
        p.stdin.write('Shape "sphere" "float radius" [1.0]\n')
lordcrc@384
  4768
    elif (prev_plane.get()=="true"):
lordcrc@384
  4769
        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
  4770
    elif (prev_torus.get()=="true"):
lordcrc@384
  4771
        p.stdin.write('Shape "torus" "float radius" [1.0]\n')
lordcrc@384
  4772
    p.stdin.write('AttributeEnd\n')
lordcrc@384
  4773
    # Checkerboard floor
lordcrc@384
  4774
    if(prev_plane.get()=="false"):
lordcrc@384
  4775
        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
  4776
        p.stdin.write('Texture "checks" "color" "checkerboard"')
lordcrc@384
  4777
        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
  4778
        p.stdin.write('"string mapping" ["uv"] "float uscale" [36.8] "float vscale" [36.0]\n')
lordcrc@384
  4779
        p.stdin.write('Material "matte" "texture Kd" ["checks"]\n')
lordcrc@384
  4780
        p.stdin.write('Shape "loopsubdiv" "integer nlevels" [3] "bool dmnormalsmooth" ["true"] "bool dmsharpboundary" ["false"] ')
lordcrc@384
  4781
        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
  4782
        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
  4783
        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
  4784
        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
  4785
        p.stdin.write('AttributeEnd\n')
lordcrc@384
  4786
    # Lightsource
lordcrc@384
  4787
    if(prev_plane.get()=="false"):
lordcrc@384
  4788
        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
  4789
    else:
lordcrc@384
  4790
        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
  4791
    area = luxProp(mat, kn+"prev_arealight", "false")
lordcrc@384
  4792
    if(area.get() == "false"):
lordcrc@384
  4793
        p.stdin.write('Texture "pL" "color" "blackbody" "float temperature" [6500.0]\n')
lordcrc@384
  4794
        p.stdin.write('LightSource "point" "texture L" ["pL"] "float gain" [0.002]')
lordcrc@384
  4795
    else:
lordcrc@384
  4796
        p.stdin.write('ReverseOrientation\n')
lordcrc@384
  4797
        p.stdin.write('AreaLightSource "area" "color L" [1.0 1.0 1.0]\n')
lordcrc@384
  4798
        if(prev_plane.get()=="false"):
lordcrc@384
  4799
            p.stdin.write(' "float gain" [0.3]\n')
lordcrc@384
  4800
        p.stdin.write('Shape "disk" "float radius" [1.0]\nAttributeEnd\n')
lordcrc@384
  4801
    p.stdin.write('WorldEnd\n')
lordcrc@384
  4802
    
lordcrc@384
  4803
    previewing = False
lordcrc@384
  4804
lordcrc@384
  4805
    data = p.communicate()[0]
lordcrc@384
  4806
    p.stdin.close()
lordcrc@384
  4807
    
lordcrc@384
  4808
    # restore path mode
lordcrc@384
  4809
    pm_prop.set(pm)    
lordcrc@384
  4810
    
lordcrc@384
  4811
    datalen = len(data)
lordcrc@384
  4812
    if(datalen < thumbbuf): 
lordcrc@384
  4813
        print("error on preview: got %i bytes, expected %i" % (datalen, thumbbuf))
lordcrc@384
  4814
        return
lordcrc@384
  4815
    global previewCache
lordcrc@384
  4816
    image = luxImage()
lordcrc@384
  4817
    image.decodeLuxConsole(thumbres, thumbres, data)
lordcrc@384
  4818
    previewCache[(mat.name+":"+kn).__hash__()] = image
lordcrc@384
  4819
    Draw.Redraw()
lordcrc@384
  4820
    Blender.Window.WaitCursor(False)
lordcrc@384
  4821
lordcrc@384
  4822
def luxPreview(mat, name, defType=0, defEnabled=False, defLarge=False, texName=None, gui=None, level=0, color=None):
lordcrc@384
  4823
    
lordcrc@384
  4824
lordcrc@384
  4825
    if gui:
lordcrc@384
  4826
        kn = name
lordcrc@384
  4827
        if texName: kn += ":"+texName
lordcrc@384
  4828
        if kn != "": kn += "."
lordcrc@384
  4829
        if(defEnabled == True):
lordcrc@384
  4830
            showpreview = luxProp(mat, kn+"prev_show", "true")
lordcrc@384
  4831
        else:
lordcrc@384
  4832
            showpreview = luxProp(mat, kn+"prev_show", "false")
lordcrc@384
  4833
        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
  4834
        if showpreview.get()=="true": 
lordcrc@384
  4835
            if(defLarge):
lordcrc@384
  4836
                large = luxProp(mat, kn+"prev_large", "true")
lordcrc@384
  4837
            else:
lordcrc@384
  4838
                large = luxProp(mat, kn+"prev_large", "false")
lordcrc@384
  4839
            voffset = -8
lordcrc@384
  4840
            rr = 5.65 
lordcrc@384
  4841
            if(large.get() == "true"):
lordcrc@384
  4842
                rr = 7
lordcrc@384
  4843
                voffset = 22
lordcrc@384
  4844
            gui.newline()
lordcrc@384
  4845
            r = gui.getRect(1.1, rr)
lordcrc@384
  4846
            if(color != None):
lordcrc@384
  4847
                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
  4848
            try: previewCache[(mat.name+":"+kn).__hash__()].draw(r[0]-82, r[1]+4)
lordcrc@384
  4849
            except: pass
lordcrc@384
  4850
lordcrc@384
  4851
            prev_sphere = luxProp(mat, kn+"prev_sphere", "true")
lordcrc@384
  4852
            prev_plane = luxProp(mat, kn+"prev_plane", "false")
lordcrc@384
  4853
            prev_torus = luxProp(mat, kn+"prev_torus", "false")
lordcrc@384
  4854
            if defType == 1:
lordcrc@384
  4855
                prev_sphere = luxProp(mat, kn+"prev_sphere", "false")
lordcrc@384
  4856
                prev_plane = luxProp(mat, kn+"prev_plane", "true")
lordcrc@384
  4857
                prev_torus = luxProp(mat, kn+"prev_torus", "false")
lordcrc@384
  4858
            elif defType == 2:
lordcrc@384
  4859
                prev_sphere = luxProp(mat, kn+"prev_sphere", "false")
lordcrc@384
  4860
                prev_plane = luxProp(mat, kn+"prev_plane", "false")
lordcrc@384
  4861
                prev_torus = luxProp(mat, kn+"prev_torus", "true")
lordcrc@384
  4862
lordcrc@384
  4863
            # preview mode toggle buttons
lordcrc@384
  4864
            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
  4865
            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
  4866
            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
  4867
lordcrc@384
  4868
            # Zoom toggle
lordcrc@384
  4869
            zoom = luxProp(mat, kn+"prev_zoom", "false")
lordcrc@384
  4870
            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
  4871
lordcrc@384
  4872
            area = luxProp(mat, kn+"prev_arealight", "false")
lordcrc@384
  4873
            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
  4874
lordcrc@384
  4875
            # Object width
lordcrc@384
  4876
            obwidth = luxProp(mat, kn+"prev_obwidth", 1.0)
lordcrc@384
  4877
            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
  4878
lordcrc@384
  4879
            # large/small size
lordcrc@384
  4880
            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
  4881
lordcrc@384
  4882
            # Preview Quality
lordcrc@384
  4883
            qs = ["low","medium","high","very high"]
lordcrc@384
  4884
            scn = Scene.GetCurrent()
lordcrc@384
  4885
            defprevmat = luxProp(scn, "defprevmat", "high")
lordcrc@384
  4886
            quality = luxProp(mat, kn+"prev_quality", defprevmat.get())
lordcrc@384
  4887
            luxOptionRect("quality", quality, qs, "  Quality", "select preview quality", gui, r[0]+200, r[1]+100+voffset, 88, 18)
lordcrc@384
  4888
lordcrc@384
  4889
            # Update preview
lordcrc@384
  4890
            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
  4891
lordcrc@384
  4892
            # Reset depths after getRect()
lordcrc@384
  4893
            gui.y -= 92+voffset
lordcrc@384
  4894
            gui.y -= gui.h
lordcrc@384
  4895
            gui.hmax = 18 + 4
lordcrc@384
  4896
lordcrc@384
  4897
def luxMaterialBlock(name, luxname, key, mat, gui=None, level=0, str_opt=""):
lordcrc@384
  4898
    global icon_mat, icon_matmix, icon_map3dparam
lordcrc@384
  4899
    def c(t1, t2):
lordcrc@384
  4900
        return (t1[0]+t2[0], t1[1]+t2[1])
lordcrc@384
  4901
    str = ""
lordcrc@384
  4902
    if key == "": keyname = kn = name
lordcrc@384
  4903
    else: keyname = kn = "%s:%s"%(key, name)
lordcrc@384
  4904
    if kn != "": kn += "."
lordcrc@384
  4905
    if keyname == "": matname = mat.getName()
lordcrc@384
  4906
    else: matname = "%s:%s"%(mat.getName(), keyname)
lordcrc@384
  4907
lordcrc@384
  4908
    if mat:
lordcrc@384
  4909
        mattype = luxProp(mat, kn+"type", "matte")
lordcrc@384
  4910
        # Set backwards compatibility of glossy material from plastic and substrate
lordcrc@384
  4911
        if(mattype.get() == "substrate" or mattype.get() == "plastic"):
lordcrc@384
  4912
            mattype.set("glossy")
lordcrc@384
  4913
lordcrc@384
  4914
        # this is reverse order than in shown in the dropdown list
lordcrc@384
  4915
        materials = ["null","mix","mirror","shinymetal","metal","mattetranslucent","matte","glossy","roughglass","glass","carpaint"]
lordcrc@384
  4916
        
lordcrc@384
  4917
        if level == 0: materials = ["portal","light","boundvolume"]+materials
lordcrc@384
  4918
        if gui:
lordcrc@384
  4919
            icon = icon_mat
lordcrc@384
  4920
            if mattype.get() == "mix": icon = icon_matmix
lordcrc@384
  4921
            if level == 0: gui.newline("Material type:", 12, level, icon, [0.75,0.5,0.25])
lordcrc@384
  4922
            else: gui.newline(name+":", 12, level, icon, scalelist([0.75,0.6,0.25],2.0/(level+2)))
lordcrc@384
  4923
lordcrc@384
  4924
lordcrc@384
  4925
        link = luxOption("type", mattype, materials, "  TYPE", "select material type", gui)
lordcrc@384
  4926
        showadvanced = luxProp(mat, kn+"showadvanced", "false")
lordcrc@384
  4927
        luxBool("advanced", showadvanced, "Advanced", "Show advanced options", gui, 0.6)
lordcrc@384
  4928
        showhelp = luxProp(mat, kn+"showhelp", "false")
lordcrc@384
  4929
        luxHelp("help", showhelp, "Help", "Show Help Information", gui, 0.4)
lordcrc@384
  4930
lordcrc@384
  4931
        # show copy/paste menu button
lordcrc@384
  4932
        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
  4933
lordcrc@384
  4934
        # Draw Material preview option
lordcrc@384
  4935
        showmatprev = False
lordcrc@384
  4936
        if level == 0:
lordcrc@384
  4937
            showmatprev = True
lordcrc@384
  4938
        if gui: luxPreview(mat, keyname, 0, showmatprev, True, None, gui, level, [0.746, 0.625, 0.5])
lordcrc@384
  4939
lordcrc@384
  4940
lordcrc@384
  4941
        if gui: gui.newline()
lordcrc@384
  4942
        has_object_options   = 0 # disable object options by default
lordcrc@384
  4943
        has_bump_options     = 0 # disable bump mapping options by default
lordcrc@384
  4944
        has_emission_options = 0 # disable emission options by default
lordcrc@384
  4945
        has_compositing_options = 0 # disable compositing options by default
lordcrc@384
  4946
lordcrc@384
  4947
        if mattype.get() == "mix":
lordcrc@384
  4948
            (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
  4949
            (str,link) = c((str,link), luxMaterialBlock("mat1", "namedmaterial1", keyname, mat, gui, level+1))
lordcrc@384
  4950
            (str,link) = c((str,link), luxMaterialBlock("mat2", "namedmaterial2", keyname, mat, gui, level+1))
lordcrc@384
  4951
            has_bump_options = 0
lordcrc@384
  4952
            has_object_options = 1
lordcrc@384
  4953
            has_emission_options = 1
lordcrc@384
  4954
            has_compositing_options = 0
lordcrc@384
  4955
lordcrc@384
  4956
        if mattype.get() == "light":
lordcrc@384
  4957
            if luxProp(Scene.GetCurrent(), "nolg", "false").get()!="true":
lordcrc@384
  4958
                lightgroup = luxProp(mat, kn+"light.lightgroup", "default")
lordcrc@384
  4959
                link = "LightGroup \"%s\"\n"%lightgroup.get()
lordcrc@384
  4960
            else:
lordcrc@384
  4961
                link = ''
lordcrc@384
  4962
            link += "AreaLightSource \"area\""
lordcrc@384
  4963
            (str,link) = c((str,link), luxLight("", kn, mat, gui, level))
lordcrc@384
  4964
            has_bump_options = 0
lordcrc@384
  4965
            has_object_options = 1
lordcrc@384
  4966
            has_emission_options = 0
lordcrc@384
  4967
            has_compositing_options = 1
lordcrc@384
  4968
lordcrc@384
  4969
        if mattype.get() == "boundvolume":
lordcrc@384
  4970
            link = ""
lordcrc@384
  4971
            voltype = luxProp(mat, kn+"vol.type", "homogeneous")
lordcrc@384
  4972
            vols = ["homogeneous", "exponential", "cloud"]
lordcrc@384
  4973
            vollink = luxOption("type", voltype, vols, "type", "", gui)
lordcrc@384
  4974
            if voltype.get() == "homogeneous":
lordcrc@384
  4975
                link = "Volume \"homogeneous\""
lordcrc@384
  4976
            if voltype.get() == "exponential":
lordcrc@384
  4977
                link = "Volume \"exponential\""
lordcrc@384
  4978
            if voltype.get() == "cloud":
lordcrc@384
  4979
                link = "Volume \"cloud\""
lordcrc@384
  4980
lordcrc@384
  4981
            if gui: gui.newline("absorption:", 0, level+1)
lordcrc@384
  4982
            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
  4983
            if gui: gui.newline("scattering:", 0, level+1)
lordcrc@384
  4984
            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
  4985
            if gui: gui.newline("emission:", 0, level+1)
lordcrc@384
  4986
            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
  4987
            if gui: gui.newline("assymetry:", 0, level+1)
lordcrc@384
  4988
            link += luxFloat("g", luxProp(mat, kn+"vol.g", 0.0), 0.0, 100.0, "g", "The phase function asymmetry parameter", gui)
lordcrc@384
  4989
lordcrc@384
  4990
            if voltype.get() == "exponential":
lordcrc@384
  4991
                if gui: gui.newline("form:", 0, level+1)
lordcrc@384
  4992
                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
  4993
                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
  4994
                if gui: gui.newline("updir:", 0, level+1)
lordcrc@384
  4995
                link += luxVector("updir", luxProp(mat, kn+"vol.updir", "0 0 1"), -1.0, 1.0, "updir", "Up direction vector", gui, 2.0)
lordcrc@384
  4996
lordcrc@384
  4997
            if voltype.get() == "cloud":
lordcrc@384
  4998
                if gui: gui.newline("cloud:", 0, level+1)
lordcrc@384
  4999
                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
  5000
                link += luxFloat("noisescale", luxProp(mat, kn+"vol.noisescale", 0.3), 0.1, 2.0, "noisesize", "Size of cloud noise", gui)
lordcrc@384
  5001
                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
  5002
                link += luxFloat("noiseoffset", luxProp(mat, kn+"vol.noiseoffset", 0.0), 0.0, 1000.0, "noiseoffset", "Useful for creating unique clouds", gui )
lordcrc@384
  5003
                link += luxInt("octaves", luxProp(mat, kn+"vol.octaves", 3), 1, 8, "octaves", "Sets the amount of detail for the noise", gui )
lordcrc@384
  5004
                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
  5005
                link += luxFloat("sharpness", luxProp(mat, kn+"vol.sharpness", 6.0), 0.2, 10.0, "sharpness", "Sets the sharpness of the noise", gui)
lordcrc@384
  5006
                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
  5007
                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
  5008
                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
  5009
                link += luxFloat("spheresize", luxProp(mat, kn+"vol.spheresize", 0.15), 0.05, 0.55, "spheresize", "Size of cumulus spheres", gui)
lordcrc@384
  5010
 
lordcrc@384
  5011
            link += str_opt
lordcrc@384
  5012
lordcrc@384
  5013
            has_bump_options = 0
lordcrc@384
  5014
            has_object_options = 0
lordcrc@384
  5015
            has_emission_options = 0
lordcrc@384
  5016
lordcrc@384
  5017
            return (str, link)
lordcrc@384
  5018
lordcrc@384
  5019
        if mattype.get() == "carpaint":
lordcrc@384
  5020
            if gui: gui.newline("Preset:", 0, level+1)
lordcrc@384
  5021
            carname = luxProp(mat, kn+"carpaint.name", "Custom")
lordcrc@384
  5022
            cars = ["Custom","ford f8","polaris silber","opel titan","bmw339","2k acrylack","white","blue","blue matte"]
lordcrc@384
  5023
            carlink = luxOption("name", carname, cars, "name", "", gui)
lordcrc@384
  5024
            if carname.get() == "Custom":
lordcrc@384
  5025
                (str,link) = c((str,link), luxSpectrumTexture("Kd", keyname, "1.0 1.0 1.0", 1.0, "diffuse", "", mat, gui, level+1))
lordcrc@384
  5026
                (str,link) = c((str,link), luxSpectrumTexture("Ks1", keyname, "1.0 1.0 1.0", 1.0, "specular1", "", mat, gui, level+1))
lordcrc@384
  5027
                (str,link) = c((str,link), luxSpectrumTexture("Ks2", keyname, "1.0 1.0 1.0", 1.0, "specular2", "", mat, gui, level+1))
lordcrc@384
  5028
                (str,link) = c((str,link), luxSpectrumTexture("Ks3", keyname, "1.0 1.0 1.0", 1.0, "specular3", "", mat, gui, level+1))
lordcrc@384
  5029
                (str,link) = c((str,link), luxFloatTexture("R1", keyname, 1.0, 0.0, 1.0, "R1", "", mat, gui, level+1))
lordcrc@384
  5030
                (str,link) = c((str,link), luxFloatTexture("R2", keyname, 1.0, 0.0, 1.0, "R2", "", mat, gui, level+1))
lordcrc@384
  5031
                (str,link) = c((str,link), luxFloatTexture("R3", keyname, 1.0, 0.0, 1.0, "R3", "", mat, gui, level+1))
lordcrc@384
  5032
                (str,link) = c((str,link), luxFloatTexture("M1", keyname, 1.0, 0.0, 1.0, "M1", "", mat, gui, level+1))
lordcrc@384
  5033
                (str,link) = c((str,link), luxFloatTexture("M2", keyname, 1.0, 0.0, 1.0, "M2", "", mat, gui, level+1))
lordcrc@384
  5034
                (str,link) = c((str,link), luxFloatTexture("M3", keyname, 1.0, 0.0, 1.0, "M3", "", mat, gui, level+1))
lordcrc@384
  5035
            else: link += carlink
lordcrc@384
  5036
            absorption = luxProp(mat, keyname+".useabsorption", "false")
lordcrc@384
  5037
            luxCollapse("absorption", absorption, "Absorption", "Enable Coating Absorption", gui, 2.0)
lordcrc@384
  5038
            if absorption.get() == "true":
lordcrc@384
  5039
                (str,link) = c((str,link), luxSpectrumTexture("Ka", keyname, "0.2 0.2 0.2", 1.0, "absorption", "", mat, gui, level+1))
lordcrc@384
  5040
                (str,link) = c((str,link), luxFloatTexture("d", keyname, 5.0, 0.0, 15.0, "depth", "", mat, gui, level+1))
lordcrc@384
  5041
            has_bump_options = 1
lordcrc@384
  5042
            has_object_options = 1
lordcrc@384
  5043
            has_emission_options = 1
lordcrc@384
  5044
            has_compositing_options = 1
lordcrc@384
  5045
        
lordcrc@384
  5046
        if mattype.get() == "glass":
lordcrc@384
  5047
            (str,link) = c((str,link), luxSpectrumTexture("Kr", keyname, "1.0 1.0 1.0", 1.0, "reflection", "", mat, gui, level+1))
lordcrc@384
  5048
            (str,link) = c((str,link), luxSpectrumTexture("Kt", keyname, "1.0 1.0 1.0", 1.0, "transmission", "", mat, gui, level+1))
lordcrc@384
  5049
            (str,link) = c((str,link), luxIORFloatTexture("index", keyname, 1.5, 1.0, 6.0, "IOR", "", mat, gui, level+1))
lordcrc@384
  5050
            architectural = luxProp(mat, keyname+".architectural", "false")
lordcrc@384
  5051
            link += luxBool("architectural", architectural, "architectural", "Enable architectural glass", gui, 2.0)
lordcrc@384
  5052
            if architectural.get() == "false":
lordcrc@384
  5053
                chromadisp = luxProp(mat, keyname+".chromadisp", "false")
lordcrc@384
  5054
                luxCollapse("chromadisp", chromadisp, "Dispersive Refraction", "Enable Chromatic Dispersion", gui, 2.0)
lordcrc@384
  5055
                if chromadisp.get() == "true":
lordcrc@384
  5056
                    (str,link) = c((str,link), luxCauchyBFloatTexture("cauchyb", keyname, 0.0, 0.0, 1.0, "cauchyb", "", mat, gui, level+1))
lordcrc@384
  5057
                thinfilm = luxProp(mat, keyname+".thinfilm", "false")
lordcrc@384
  5058
                luxCollapse("thinfilm", thinfilm, "Thin Film Coating", "Enable Thin Film Coating", gui, 2.0)
lordcrc@384
  5059
                if thinfilm.get() == "true":
lordcrc@384
  5060
                    (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
  5061
                    (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
  5062
            has_bump_options = 1
lordcrc@384
  5063
            has_object_options = 1
lordcrc@384
  5064
            has_emission_options = 1
lordcrc@384
  5065
            has_compositing_options = 1
lordcrc@384
  5066
            
lordcrc@384
  5067
        if mattype.get() == "matte":
lordcrc@384
  5068
            orennayar = luxProp(mat, keyname+".orennayar", "false")
lordcrc@384
  5069
            (str,link) = c((str,link), luxSpectrumTexture("Kd", keyname, "1.0 1.0 1.0", 1.0, "diffuse", "", mat, gui, level+1))
lordcrc@384
  5070
            luxCollapse("orennayar", orennayar, "Oren-Nayar", "Enable Oren-Nayar BRDF", gui, 2.0)
lordcrc@384
  5071
            if orennayar.get() == "true":
lordcrc@384
  5072
                (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
  5073
            has_bump_options = 1
lordcrc@384
  5074
            has_object_options = 1
lordcrc@384
  5075
            has_emission_options = 1
lordcrc@384
  5076
            has_compositing_options = 1
lordcrc@384
  5077
        
lordcrc@384
  5078
        if mattype.get() == "mattetranslucent":
lordcrc@384
  5079
            orennayar = luxProp(mat, keyname+".orennayar", "false")
lordcrc@384
  5080
            (str,link) = c((str,link), luxSpectrumTexture("Kr", keyname, "1.0 1.0 1.0", 1.0, "reflection", "", mat, gui, level+1))
lordcrc@384
  5081
            (str,link) = c((str,link), luxSpectrumTexture("Kt", keyname, "1.0 1.0 1.0", 1.0, "transmission", "", mat, gui, level+1))
lordcrc@384
  5082
            luxCollapse("orennayar", orennayar, "Oren-Nayar", "Enable Oren-Nayar BRDF", gui, 2.0)
lordcrc@384
  5083
            if orennayar.get() == "true":
lordcrc@384
  5084
                (str,link) = c((str,link), luxFloatTexture("sigma", keyname, 0.0, 0.0, 100.0, "sigma", "", mat, gui, level+1))
lordcrc@384
  5085
            has_bump_options = 1
lordcrc@384
  5086
            has_object_options = 1
lordcrc@384
  5087
            has_emission_options = 1
lordcrc@384
  5088
            has_compositing_options = 1
lordcrc@384
  5089
        
lordcrc@384
  5090
        if mattype.get() == "metal":
lordcrc@384
  5091
            if gui: gui.newline("name:", 0, level+1)
lordcrc@384
  5092
            metalname = luxProp(mat, kn+"metal.name", "")
lordcrc@384
  5093
            metals = ["aluminium","amorphous carbon","silver","gold","copper"]
lordcrc@384
  5094
lordcrc@384
  5095
            if not(metalname.get() in metals):
lordcrc@384
  5096
                metals.append(metalname.get())
lordcrc@384
  5097
            metallink = luxOption("name", metalname, metals, "name", "", gui, 1.88)
lordcrc@384
  5098
            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
  5099
            link += luxstr(metallink)
lordcrc@384
  5100
            anisotropic = luxProp(mat, kn+"metal.anisotropic", "false")
lordcrc@384
  5101
            if gui:
lordcrc@384
  5102
                gui.newline("")
lordcrc@384
  5103
                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
  5104
            if anisotropic.get()=="true":
lordcrc@384
  5105
                (str,link) = c((str,link), luxExponentTexture("uroughness", keyname, 0.002, 0.0, 1.0, "u-exponent", "", mat, gui, level+1))
lordcrc@384
  5106
                (str,link) = c((str,link), luxExponentTexture("vroughness", keyname, 0.002, 0.0, 1.0, "v-exponent", "", mat, gui, level+1))
lordcrc@384
  5107
            else:
lordcrc@384
  5108
                (s, l) = luxExponentTexture("uroughness", keyname, 0.002, 0.0, 1.0, "exponent", "", mat, gui, level+1)
lordcrc@384
  5109
                (str,link) = c((str,link), (s, l))
lordcrc@384
  5110
                link += l.replace("uroughness", "vroughness", 1)
lordcrc@384
  5111
                
lordcrc@384
  5112
            has_bump_options = 1
lordcrc@384
  5113
            has_object_options = 1
lordcrc@384
  5114
            has_emission_options = 1
lordcrc@384
  5115
            has_compositing_options = 1
lordcrc@384
  5116
            
lordcrc@384
  5117
        if mattype.get() == "mirror":
lordcrc@384
  5118
            (str,link) = c((str,link), luxSpectrumTexture("Kr", keyname, "1.0 1.0 1.0", 1.0, "reflection", "", mat, gui, level+1))
lordcrc@384
  5119
            thinfilm = luxProp(mat, keyname+".thinfilm", "false")
lordcrc@384
  5120
            luxCollapse("thinfilm", thinfilm, "Thin Film Coating", "Enable Thin Film Coating", gui, 2.0)
lordcrc@384
  5121
            if thinfilm.get() == "true":
lordcrc@384
  5122
                (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
  5123
                (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
  5124
lordcrc@384
  5125
            has_bump_options = 1
lordcrc@384
  5126
            has_object_options = 1
lordcrc@384
  5127
            has_emission_options = 1
lordcrc@384
  5128
            has_compositing_options = 1
lordcrc@384
  5129
            
lordcrc@384
  5130
        if mattype.get() == "roughglass":
lordcrc@384
  5131
            (str,link) = c((str,link), luxSpectrumTexture("Kr", keyname, "1.0 1.0 1.0", 1.0, "reflection", "", mat, gui, level+1))
lordcrc@384
  5132
            (str,link) = c((str,link), luxSpectrumTexture("Kt", keyname, "1.0 1.0 1.0", 1.0, "transmission", "", mat, gui, level+1))
lordcrc@384
  5133
            anisotropic = luxProp(mat, kn+"roughglass.anisotropic", "false")
lordcrc@384
  5134
            if gui:
lordcrc@384
  5135
                gui.newline("")
lordcrc@384
  5136
                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
  5137
            if anisotropic.get()=="true":
lordcrc@384
  5138
                (str,link) = c((str,link), luxExponentTexture("uroughness", keyname, 0.002, 0.0, 1.0, "u-exponent", "", mat, gui, level+1))
lordcrc@384
  5139
                (str,link) = c((str,link), luxExponentTexture("vroughness", keyname, 0.002, 0.0, 1.0, "v-exponent", "", mat, gui, level+1))
lordcrc@384
  5140
            else:
lordcrc@384
  5141
                (s, l) = luxExponentTexture("uroughness", keyname, 0.002, 0.0, 1.0, "exponent", "", mat, gui, level+1)
lordcrc@384
  5142
                (str,link) = c((str,link), (s, l))
lordcrc@384
  5143
                link += l.replace("uroughness", "vroughness", 1)
lordcrc@384
  5144
            (str,link) = c((str,link), luxIORFloatTexture("index", keyname, 1.5, 1.0, 6.0, "IOR", "", mat, gui, level+1))
lordcrc@384
  5145
            chromadisp = luxProp(mat, keyname+".chromadisp", "false")
lordcrc@384
  5146
            luxCollapse("chromadisp", chromadisp, "Dispersive Refraction", "Enable Chromatic Dispersion", gui, 2.0)
lordcrc@384
  5147
            if chromadisp.get() == "true":
lordcrc@384
  5148
                (str,link) = c((str,link), luxCauchyBFloatTexture("cauchyb", keyname, 0.0, 0.0, 1.0, "cauchyb", "", mat, gui, level+1))
lordcrc@384
  5149
            has_bump_options = 1
lordcrc@384
  5150
            has_object_options = 1
lordcrc@384
  5151
            has_emission_options = 1
lordcrc@384
  5152
            has_compositing_options = 1
lordcrc@384
  5153
            
lordcrc@384
  5154
        if mattype.get() == "shinymetal":
lordcrc@384
  5155
            (str,link) = c((str,link), luxSpectrumTexture("Kr", keyname, "1.0 1.0 1.0", 1.0, "reflection", "", mat, gui, level+1))
lordcrc@384
  5156
            (str,link) = c((str,link), luxSpectrumTexture("Ks", keyname, "1.0 1.0 1.0", 1.0, "specular", "", mat, gui, level+1))
lordcrc@384
  5157
            anisotropic = luxProp(mat, kn+"shinymetal.anisotropic", "false")
lordcrc@384
  5158
            if gui:
lordcrc@384
  5159
                gui.newline("")
lordcrc@384
  5160
                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
  5161
            if anisotropic.get()=="true":
lordcrc@384
  5162
                (str,link) = c((str,link), luxExponentTexture("uroughness", keyname, 0.002, 0.0, 1.0, "u-exponent", "", mat, gui, level+1))
lordcrc@384
  5163
                (str,link) = c((str,link), luxExponentTexture("vroughness", keyname, 0.002, 0.0, 1.0, "v-exponent", "", mat, gui, level+1))
lordcrc@384
  5164
            else:
lordcrc@384
  5165
                (s, l) = luxExponentTexture("uroughness", keyname, 0.002, 0.0, 1.0, "exponent", "", mat, gui, level+1)
lordcrc@384
  5166
                (str,link) = c((str,link), (s, l))
lordcrc@384
  5167
                link += l.replace("uroughness", "vroughness", 1)
lordcrc@384
  5168
lordcrc@384
  5169
            thinfilm = luxProp(mat, keyname+".thinfilm", "false")
lordcrc@384
  5170
            luxCollapse("thinfilm", thinfilm, "Thin Film Coating", "Enable Thin Film Coating", gui, 2.0)
lordcrc@384
  5171
            if thinfilm.get() == "true":
lordcrc@384
  5172
                (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
  5173
                (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
  5174
lordcrc@384
  5175
            has_bump_options = 1
lordcrc@384
  5176
            has_object_options = 1
lordcrc@384
  5177
            has_emission_options = 1
lordcrc@384
  5178
            has_compositing_options = 1
lordcrc@384
  5179
            
lordcrc@384
  5180
        if mattype.get() == "glossy":
lordcrc@384
  5181
            (str,link) = c((str,link), luxSpectrumTexture("Kd", keyname, "1.0 1.0 1.0", 1.0, "diffuse", "", mat, gui, level+1))
lordcrc@384
  5182
            useior = luxProp(mat, keyname+".useior", "false")
lordcrc@384
  5183
            if gui:
lordcrc@384
  5184
                gui.newline("")
lordcrc@384
  5185
                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
  5186
            if useior.get() == "true":
lordcrc@384
  5187
                (str,link) = c((str,link), luxIORFloatTexture("index", keyname, 1.5, 1.0, 50.0, "IOR", "", mat, gui, level+1))
lordcrc@384
  5188
                link += " \"color Ks\" [1.0 1.0 1.0]"    
lordcrc@384
  5189
            else:
lordcrc@384
  5190
                (str,link) = c((str,link), luxSpectrumTexture("Ks", keyname, "1.0 1.0 1.0", 1.0, "specular", "", mat, gui, level+1))
lordcrc@384
  5191
                link += " \"float index\" [0.0]"    
lordcrc@384
  5192
            anisotropic = luxProp(mat, kn+"glossy.anisotropic", "false")
lordcrc@384
  5193
            if gui:
lordcrc@384
  5194
                gui.newline("")
lordcrc@384
  5195
                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
  5196
            if anisotropic.get()=="true":
lordcrc@384
  5197
                (str,link) = c((str,link), luxExponentTexture("uroughness", keyname, 0.002, 0.0, 1.0, "u-exponent", "", mat, gui, level+1))
lordcrc@384
  5198
                (str,link) = c((str,link), luxExponentTexture("vroughness", keyname, 0.002, 0.0, 1.0, "v-exponent", "", mat, gui, level+1))
lordcrc@384
  5199
            else:
lordcrc@384
  5200
                (s, l) = luxExponentTexture("uroughness", keyname, 0.002, 0.0, 1.0, "exponent", "", mat, gui, level+1)
lordcrc@384
  5201
                (str,link) = c((str,link), (s, l))
lordcrc@384
  5202
                link += l.replace("uroughness", "vroughness", 1)
lordcrc@384
  5203
lordcrc@384
  5204
            absorption = luxProp(mat, keyname+".useabsorption", "false")
lordcrc@384
  5205
            luxCollapse("absorption", absorption, "Absorption", "Enable Coating Absorption", gui, 2.0)
lordcrc@384
  5206
            if absorption.get() == "true":
lordcrc@384
  5207
                (str,link) = c((str,link), luxSpectrumTexture("Ka", keyname, "0.2 0.2 0.2", 1.0, "absorption", "", mat, gui, level+1))
lordcrc@384
  5208
                (str,link) = c((str,link), luxFloatTexture("d", keyname, 0.15, 0.0, 15.0, "depth", "", mat, gui, level+1))
lordcrc@384
  5209
            has_bump_options = 1
lordcrc@384
  5210
            has_object_options = 1
lordcrc@384
  5211
            has_emission_options = 1
lordcrc@384
  5212
            has_compositing_options = 1
lordcrc@384
  5213
            
lordcrc@384
  5214
        if mattype.get() == 'null':
lordcrc@384
  5215
            has_emission_options = 1
lordcrc@384
  5216
lordcrc@384
  5217
        # Bump mapping options (common)
lordcrc@384
  5218
        if (has_bump_options == 1):
lordcrc@384
  5219
            usebump = luxProp(mat, keyname+".usebump", "false")
lordcrc@384
  5220
            luxCollapse("usebump", usebump, "Bump Map", "Enable Bump Mapping options", gui, 2.0)
lordcrc@384
  5221
            if usebump.get() == "true":
tom@408
  5222
                (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
  5223
lordcrc@384
  5224
        # emission options (common)
lordcrc@384
  5225
        if (level == 0):
lordcrc@384
  5226
            if (has_emission_options == 1):
lordcrc@384
  5227
                if gui: gui.newline("", 2, level, None, [0.6,0.6,0.4])
lordcrc@384
  5228
                useemission = luxProp(mat, "emission", "false")
lordcrc@384
  5229
                luxCollapse("useemission", useemission, "Emission", "Enable emission options", gui, 2.0)
lordcrc@384
  5230
                if useemission.get() == "true":
lordcrc@384
  5231
                    # emission GUI is here but lux export will be done later 
lordcrc@384
  5232
                    luxLight("", "", mat, gui, level)
lordcrc@384
  5233
            else: luxProp(mat, "emission", "false").set("false") # prevent from exporting later
lordcrc@384
  5234
lordcrc@384
  5235
lordcrc@384
  5236
        # Compositing options (common)
lordcrc@384
  5237
        # Note - currently only display options when using distributedpath integrator
lordcrc@384
  5238
        integratortype = luxProp(Scene.GetCurrent(), "sintegrator.type", "bidirectional")
lordcrc@384
  5239
        if (integratortype.get() == "distributedpath" and level == 0):
lordcrc@384
  5240
            if (has_compositing_options == 1):
lordcrc@384
  5241
                if gui: gui.newline("", 2, level, None, [0.4,0.4,0.6])
lordcrc@384
  5242
                usecompo = luxProp(mat, "compo", "false")
lordcrc@384
  5243
                luxCollapse("compo", usecompo, "Compositing", "Enable Compositing options", gui, 2.0)
lordcrc@384
  5244
                if usecompo.get() == "true":
lordcrc@384
  5245
                    if gui: gui.newline("", 2, level, None, [0.35,0.35,0.55])
lordcrc@384
  5246
                    usecompoviz = luxProp(mat, "compo_viz", "false")
lordcrc@384
  5247
                    luxCollapse("compo_viz", usecompoviz, "Visibility", "Enable Visibility Compositing options", gui, 2.0)
lordcrc@384
  5248
                    if usecompoviz.get() == "true":
lordcrc@384
  5249
                        if gui: gui.newline("View", 2, level, None, [0.35,0.35,0.55])
lordcrc@384
  5250
                        compovizmat = luxProp(mat, "compo_viz_mat", "true")
lordcrc@384
  5251
                        link += luxBool("compo_visible_material", compovizmat, "Material", "Enable View Visibility of Material", gui, 1.0)
lordcrc@384
  5252
                        compovizemi = luxProp(mat, "compo_viz_emi", "true")
lordcrc@384
  5253
                        link += luxBool("compo_visible_emission", compovizemi, "Emission", "Enable View Visibility of Emission", gui, 1.0)
lordcrc@384
  5254
                        
lordcrc@384
  5255
                        if gui: gui.newline("Indirect", 2, level, None, [0.35,0.35,0.55])
lordcrc@384
  5256
                        compovizmati = luxProp(mat, "compo_viz_mati", "true")
lordcrc@384
  5257
                        link += luxBool("compo_visible_indirect_material", compovizmati, "Material", "Enable InDirect Visibility of Material", gui, 1.0)
lordcrc@384
  5258
                        compovizemii = luxProp(mat, "compo_viz_emii", "true")
lordcrc@384
  5259
                        link += luxBool("compo_visible_indirect_emission", compovizemii, "Emission", "Enable InDirect Visibility of Emission", gui, 1.0)
lordcrc@384
  5260
                    
lordcrc@384
  5261
                    if gui: gui.newline("", 2, level, None, [0.4,0.4,0.6])
lordcrc@384
  5262
                    overridealpha = luxProp(mat, "compo_o_alpha", "false")
lordcrc@384
  5263
                    link += luxCollapse("compo_override_alpha", overridealpha, "Override Alpha", "Enable Manual control of alpha value", gui, 2.0)
lordcrc@384
  5264
                    if overridealpha.get() == "true":
lordcrc@384
  5265
                        if gui: gui.newline("Alpha", 2, level, None, [0.4,0.4,0.6])
lordcrc@384
  5266
                        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
  5267
                    usecolorkey = luxProp(mat, "compo_usekey", "false")
lordcrc@384
  5268
                    if gui: gui.newline("", 2, level, None, [0.35,0.35,0.55])
lordcrc@384
  5269
                    link += luxCollapse("compo_use_key", usecolorkey, "Chroma Key", "Enable Chroma Object key", gui, 2.0)
lordcrc@384
  5270
                    if usecolorkey.get() == "true":
lordcrc@384
  5271
                        if gui: gui.newline("Key", 2, level, None, [0.35,0.35,0.55])
lordcrc@384
  5272
                        link += luxRGB("compo_key_color", luxProp(mat, "compo_key_color", "0.0 0.0 1.0"), 1.0, "key", "", gui, 2.0)
lordcrc@384
  5273
lordcrc@384
  5274
        # transformation options (common)
lordcrc@384
  5275
        if (level == 0) and mattype.get() not in ['portal', 'null']:
lordcrc@384
  5276
            if gui: gui.newline("", 2, level, None, [0.6,0.6,0.4])
lordcrc@384
  5277
            usetransformation = luxProp(mat, "transformation", "false")
lordcrc@384
  5278
            luxCollapse("usetransformation", usetransformation, "Texture Transformation", "Enable transformation option", gui, 2.0)
lordcrc@384
  5279
            if usetransformation.get() == "true":
lordcrc@384
  5280
                scale = luxProp(mat, "3dscale", 1.0)
lordcrc@384
  5281
                rotate = luxProp(mat, "3drotate", "0 0 0")
lordcrc@384
  5282
                translate = luxProp(mat, "3dtranslate", "0 0 0")
lordcrc@384
  5283
                if gui:
lordcrc@384
  5284
                    gui.newline("scale:", -2, level, icon_map3dparam)
lordcrc@384
  5285
                    luxVectorUniform("scale", scale, 0.001, 1000.0, "scale", "scale-vector", gui, 2.0)
lordcrc@384
  5286
                    gui.newline("rot:", -2, level, icon_map3dparam)
lordcrc@384
  5287
                    luxVector("rotate", rotate, -360.0, 360.0, "rotate", "rotate-vector", gui, 2.0)
lordcrc@384
  5288
                    gui.newline("move:", -2, level, icon_map3dparam)
lordcrc@384
  5289
                    luxVector("translate", translate, -1000.0, 1000.0, "move", "translate-vector", gui, 2.0)
lordcrc@384
  5290
                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
  5291
lordcrc@384
  5292
        # Object options (common)
lordcrc@384
  5293
        if (level == 0) and (has_object_options == 1):
lordcrc@384
  5294
            if gui: gui.newline("Mesh:", 2, level, icon, [0.6,0.6,0.4])
lordcrc@384
  5295
            usesubdiv = luxProp(mat, "subdiv", "false")
lordcrc@384
  5296
            luxBool("usesubdiv", usesubdiv, "Subdivision", "Enable Loop Subdivision options", gui, 1.0)
lordcrc@384
  5297
            usedisp = luxProp(mat, "dispmap", "false")
lordcrc@384
  5298
            luxBool("usedisp", usedisp, "Displacement Map", "Enable Displacement mapping options", gui, 1.0)
lordcrc@384
  5299
            if usesubdiv.get() == "true" or usedisp.get() == "true":
lordcrc@384
  5300
                luxInt("sublevels", luxProp(mat, "sublevels", 2), 0, 12, "sublevels", "The number of levels of object subdivision", gui, 2.0)
lordcrc@384
  5301
                sharpbound = luxProp(mat, "sharpbound", "false")
lordcrc@384
  5302
                luxBool("sharpbound", sharpbound, "Sharpen Bounds", "Sharpen boundaries during subdivision", gui, 1.0)
lordcrc@384
  5303
                nsmooth = luxProp(mat, "nsmooth", "true")
lordcrc@384
  5304
                luxBool("nsmooth", nsmooth, "Smooth", "Smooth faces during subdivision", gui, 1.0)
lordcrc@384
  5305
            if usedisp.get() == "true":
lordcrc@384
  5306
                (str,ll) = c((str,link), luxDispFloatTexture("dispmap", keyname, 0.1, -10, 10.0, "dispmap", "Displacement Mapping amount", mat, gui, level+1))
lordcrc@384
  5307
                luxFloat("sdoffset",  luxProp(mat, "sdoffset", 0.0), 0.0, 1.0, "Offset", "Offset for displacement map", gui, 2.0)
lordcrc@384
  5308
                usesubdiv.set("true")
lordcrc@384
  5309
lordcrc@384
  5310
        if mattype.get() == "light":
lordcrc@384
  5311
            return (str, link)
lordcrc@384
  5312
lordcrc@384
  5313
        str += "MakeNamedMaterial \"%s\"%s\n"%(matname, link)
lordcrc@384
  5314
    return (str, " \"string %s\" [\"%s\"]"%(luxname, matname))
lordcrc@384
  5315
lordcrc@384
  5316
lordcrc@384
  5317
def luxMaterial(mat, gui=None):
lordcrc@384
  5318
    str = ""
lordcrc@384
  5319
    if mat:
lordcrc@384
  5320
        if luxProp(mat, "type", "").get()=="": # lux material not defined yet
lordcrc@384
  5321
            print("Blender material \"%s\" has no lux material definition, converting..."%(mat.getName()))
lordcrc@384
  5322
            try:
lordcrc@384
  5323
                convertMaterial(mat) # try converting the blender material to a lux material
lordcrc@384
  5324
            except: pass
lordcrc@384
  5325
        (str, link) = luxMaterialBlock("", "", "", mat, gui, 0)
lordcrc@384
  5326
        if luxProp(mat, "type", "matte").get() != "light":
lordcrc@384
  5327
            link = "NamedMaterial \"%s\""%(mat.getName())
lordcrc@384
  5328
        # export emission options (no gui)
lordcrc@384
  5329
        useemission = luxProp(mat, "emission", "false")
lordcrc@384
  5330
        if useemission.get() == "true":
lordcrc@384
  5331
            lightgroup = luxProp(mat, "light.lightgroup", "default")
lordcrc@384
  5332
            if luxProp(Scene.GetCurrent(), "nolg", "false").get()!="true":
lordcrc@384
  5333
                link += "\n\tLightGroup \"%s\"\n"%lightgroup.get()
lordcrc@384
  5334
            
lordcrc@384
  5335
            (estr, elink) = luxLight("", "", mat, None, 0)
lordcrc@384
  5336
            str += estr
lordcrc@384
  5337
            link += "\n\tAreaLightSource \"area\" "+elink 
lordcrc@384
  5338
            
lordcrc@384
  5339
        luxProp(mat, "link", "").set("".join(link))
lordcrc@384
  5340
        
lordcrc@384
  5341
    return str
lordcrc@384
  5342
        
lordcrc@384
  5343
lordcrc@384
  5344
def luxVolume(mat, gui=None):
lordcrc@384
  5345
    str = ""
lordcrc@384
  5346
    if mat:
lordcrc@384
  5347
        (str, link) = luxMaterialBlock("", "", "", mat, gui, 0)
lordcrc@384
  5348
        luxProp(mat, "link", "").set("".join(link))
lordcrc@384
  5349
    return str
lordcrc@384
  5350
lordcrc@384
  5351
runRenderAfterExport = None
lordcrc@384
  5352
def CBluxExport(default, run):
lordcrc@384
  5353
    global runRenderAfterExport
lordcrc@384
  5354
    runRenderAfterExport = run
lordcrc@384
  5355
    if default:
lordcrc@384
  5356
        datadir = luxProp(Scene.GetCurrent(), "datadir", "").get()
lordcrc@384
  5357
        if datadir=="": datadir = Blender.Get("datadir")
tom@407
  5358
        import os.path
tom@407
  5359
        if not os.path.exists(datadir):
tom@407
  5360
            Draw.PupMenu("ERROR: output directory does not exist!")
tom@407
  5361
            if LuxIsGUI:
tom@407
  5362
                Draw.Redraw()
tom@407
  5363
            return
lordcrc@384
  5364
        filename = datadir + os.sep + "default.lxs"
lordcrc@384
  5365
        save_still(filename)
lordcrc@384
  5366
    else:
lordcrc@384
  5367
        Window.FileSelector(save_still, "Export", sys.makename(Blender.Get("filename"), ".lxs"))
lordcrc@384
  5368
lordcrc@384
  5369
lordcrc@384
  5370
def CBluxAnimExport(default, run, fileselect=True):
lordcrc@384
  5371
    if default:
lordcrc@384
  5372
        datadir = luxProp(Scene.GetCurrent(), "datadir", "").get()
lordcrc@384
  5373
        if datadir=="": datadir = Blender.Get("datadir")
tom@407
  5374
        import os.path
tom@407
  5375
        if not os.path.exists(datadir):
tom@407
  5376
            Draw.PupMenu("ERROR: output directory does not exist!")
tom@407
  5377
            if LuxIsGUI:
tom@407
  5378
                Draw.Redraw()
tom@407
  5379
            return
lordcrc@384
  5380
        filename = datadir + os.sep + "default.lxs"
lordcrc@384
  5381
        save_anim(filename)
lordcrc@384
  5382
    else:
lordcrc@384
  5383
        if fileselect:
lordcrc@384
  5384
            Window.FileSelector(save_anim, "Export", sys.makename(Blender.Get("filename"), ".lxs"))
lordcrc@384
  5385
        else:
lordcrc@384
  5386
            datadir = luxProp(Scene.GetCurrent(), "datadir", "").get()
lordcrc@384
  5387
            if datadir=="": datadir = Blender.Get("datadir")
lordcrc@384
  5388
            filename = sys.makename(Blender.Get("filename") , ".lxs")
lordcrc@384
  5389
            save_anim(filename)
lordcrc@384
  5390
lordcrc@384
  5391
lordcrc@384
  5392
# convert a Blender material to lux material
lordcrc@384
  5393
def convertMaterial(mat):
lordcrc@384
  5394
    def dot(str):
lordcrc@384
  5395
        if str != "": return str+"."
lordcrc@384
  5396
        return str
lordcrc@384
  5397
    def ddot(str):
lordcrc@384
  5398
        if str != "": return str+":"
lordcrc@384
  5399
        return str
lordcrc@384
  5400
    def mapConstDict(value, constant_dict, lux_dict, default=None):
lordcrc@384
  5401
        for k,v in constant_dict.items():
lordcrc@384
  5402
            if (v == value) and (lux_dict.has_key(k)):
lordcrc@384
  5403
                return lux_dict[k]
lordcrc@384
  5404
        return default
lordcrc@384
  5405
lordcrc@384
  5406
    def convertMapping(name, tex):
lordcrc@384
  5407
        if tex.texco == Texture.TexCo["UV"]:
lordcrc@384
  5408
            luxProp(mat, dot(name)+"mapping","").set("uv")
lordcrc@384
  5409
            luxProp(mat, dot(name)+"uscale", 1.0).set(tex.size[0])
lordcrc@384
  5410
            luxProp(mat, dot(name)+"vscale", 1.0).set(-tex.size[1])
lordcrc@384
  5411
            luxProp(mat, dot(name)+"udelta", 0.0).set(tex.ofs[0]+0.5*(1.0-tex.size[0]))
lordcrc@384
  5412
            luxProp(mat, dot(name)+"vdelta", 0.0).set(-tex.ofs[1]-0.5*(1.0-tex.size[1]))
lordcrc@384
  5413
            if tex.mapping != Texture.Mappings["FLAT"]:
lordcrc@384
  5414
                print("Material Conversion Warning: for UV-texture-input only FLAT mapping is supported\n") 
lordcrc@384
  5415
        else:
lordcrc@384
  5416
            if tex.mapping == Texture.Mappings["FLAT"]:
jensverwiebe@409
  5417
                luxProp(mat, dot(name)+"mapping","").set("planar") # make planar-mapping convert correctly from blender(WYSIWYG)- jens
jensverwiebe@409
  5418
                luxProp(mat, dot(name)+"v1", "1.0 1.0 1.0").setVector((0.5*tex.size[0], 0.0, 0.0))
jensverwiebe@409
  5419
                luxProp(mat, dot(name)+"v2", "0.0 0.0 0.0").setVector((0.0, -0.5*tex.size[1], -0.0))
jensverwiebe@409
  5420
                luxProp(mat, dot(name)+"udelta", 0.0).set(tex.ofs[0]+0.5)
jensverwiebe@409
  5421
                luxProp(mat, dot(name)+"vdelta", 0.0).set(-tex.ofs[1]-0.5)
lordcrc@384
  5422
            elif tex.mapping == Texture.Mappings["TUBE"]:
lordcrc@384
  5423
                luxProp(mat, dot(name)+"mapping","").set("cylindrical")
lordcrc@384
  5424
            elif tex.mapping == Texture.Mappings["SPHERE"]:
lordcrc@384
  5425
                luxProp(mat, dot(name)+"mapping","").set("spherical")
lordcrc@384
  5426
            else: luxProp(mat, dot(name)+"mapping","").set("planar")
jensverwiebe@409
  5427
lordcrc@384
  5428
        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
  5429
        luxProp(mat, dot(name)+"3dtranslate", "0.0 0.0 0.0").setVector((-tex.ofs[0], -tex.ofs[1], -tex.ofs[2]))
lordcrc@384
  5430
lordcrc@384
  5431
    def convertColorband(colorband):
lordcrc@384
  5432
        # colorbands are not supported in lux - so lets extract a average low-side and high-side color
lordcrc@384
  5433
        cb = [colorband[0]] + colorband[:] + [colorband[-1]]
lordcrc@384
  5434
        cb[0][4], cb[-1][4] = 0.0, 1.0
lordcrc@384
  5435
        low, high = [0.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0]
lordcrc@384
  5436
        for i in range(1, len(cb)):
lordcrc@384
  5437
            for c in range(4):
lordcrc@384
  5438
                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
  5439
                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
  5440
        return low, high
lordcrc@384
  5441
lordcrc@384
  5442
    def createLuxTexture(name, tex):
lordcrc@384
  5443
        texture = tex.tex
lordcrc@384
  5444
        convertMapping(name, tex)
lordcrc@384
  5445
        if (texture.type == Texture.Types["IMAGE"]) and (texture.image) and (texture.image.filename!=""):
lordcrc@384
  5446
            luxProp(mat, dot(name)+"texture", "").set("imagemap")
lordcrc@384
  5447
            luxProp(mat, dot(name)+"filename", "").set(texture.image.filename)
lordcrc@384
  5448
            luxProp(mat, dot(name)+"wrap", "").set(mapConstDict(texture.extend, Texture.ExtendModes, {"REPEAT":"repeat", "EXTEND":"clamp", "CLIP":"black"}, ""))
lordcrc@384
  5449
        else:
lordcrc@384
  5450
            if tex.texco != Texture.TexCo["GLOB"]:
lordcrc@384
  5451
                print("Material Conversion Warning: procedural textures supports global mapping only\n")
lordcrc@384
  5452
            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
  5453
            luxProp(mat, dot(name)+"bright", 1.0).set(texture.brightness)
lordcrc@384
  5454
            luxProp(mat, dot(name)+"contrast", 1.0).set(texture.contrast)
lordcrc@384
  5455
            if texture.type == Texture.Types["CLOUDS"]:
lordcrc@384
  5456
                luxProp(mat, dot(name)+"texture", "").set("blender_clouds")
lordcrc@384
  5457
                luxProp(mat, dot(name)+"mtype", "").set(mapConstDict(texture.stype, Texture.STypes, {"CLD_DEFAULT":"default", "CLD_COLOR":"color"}, ""))
lordcrc@384
  5458
                luxProp(mat, dot(name)+"noisetype", "").set({"soft":"soft_noise", "hard":"hard_noise"}[texture.noiseType])
lordcrc@384
  5459
                luxProp(mat, dot(name)+"noisesize", 0.25).set(texture.noiseSize)
lordcrc@384
  5460
                luxProp(mat, dot(name)+"noisedepth", 2).set(texture.noiseDepth)
lordcrc@384
  5461
                luxProp(mat, dot(name)+"noisebasis", "").set(mapConstDict(texture.noiseBasis, Texture.Noise, noiseDict, ""))
lordcrc@384
  5462
            elif texture.type == Texture.Types["WOOD"]:
lordcrc@384
  5463
                luxProp(mat, dot(name)+"texture", "").set("blender_wood")
lordcrc@384
  5464
                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
  5465
                luxProp(mat, dot(name)+"noisebasis2", "").set(mapConstDict(texture.noiseBasis2, Texture.Noise, {"SINE":"sin", "SAW":"saw", "TRI":"tri"}, ""))
lordcrc@384
  5466
                luxProp(mat, dot(name)+"noisebasis", "").set(mapConstDict(texture.noiseBasis, Texture.Noise, noiseDict, ""))
lordcrc@384
  5467
                luxProp(mat, dot(name)+"noisetype", "").set({"soft":"soft_noise", "hard":"hard_noise"}[texture.noiseType])
lordcrc@384
  5468
                luxProp(mat, dot(name)+"noisesize", 0.25).set(texture.noiseSize)
lordcrc@384
  5469
                luxProp(mat, dot(name)+"turbulance", 0.25).set(texture.turbulence)
lordcrc@384
  5470
            elif texture.type == Texture.Types["MUSGRAVE"]:
lordcrc@384
  5471
                luxProp(mat, dot(name)+"texture", "").set("blender_musgrave")
lordcrc@384
  5472
                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
  5473
                luxProp(mat, dot(name)+"noisebasis", "").set(mapConstDict(texture.noiseBasis, Texture.Noise, noiseDict, ""))
lordcrc@384
  5474
                luxProp(mat, dot(name)+"noisesize", 0.25).set(texture.noiseSize)
lordcrc@384
  5475
                # 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
  5476
                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
  5477
                else: luxProp(mat, dot(name)+"h", 1.0).set(0.5) # use a default value
lordcrc@384
  5478
                # 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
  5479
                try:
lordcrc@384
  5480
                    luxProp(mat, dot(name)+"offset", 1.0).set(texture.offset)
lordcrc@384
  5481
                    luxProp(mat, dot(name)+"gain", 1.0).set(texture.gain)
lordcrc@384
  5482
                except AttributeError: pass
lordcrc@384
  5483
                luxProp(mat, dot(name)+"lacu", 2.0).set(texture.lacunarity)
lordcrc@384
  5484
                luxProp(mat, dot(name)+"octs", 2.0).set(texture.octs)
lordcrc@384
  5485
                luxProp(mat, dot(name)+"outscale", 1.0).set(texture.iScale)
lordcrc@384
  5486
            elif texture.type == Texture.Types["MARBLE"]:
lordcrc@384
  5487
                luxProp(mat, dot(name)+"texture", "").set("blender_marble")
lordcrc@384
  5488
                luxProp(mat, dot(name)+"mtype", "").set(mapConstDict(texture.stype, Texture.STypes, {"MBL_SOFT":"soft", "MBL_SHARP":"sharp", "MBL_SHARPER":"sharper"}, ""))
lordcrc@384
  5489
                luxProp(mat, dot(name)+"noisetype", "").set({"soft":"soft_noise", "hard":"hard_noise"}[texture.noiseType])
lordcrc@384
  5490
                luxProp(mat, dot(name)+"turbulance", 0.25).set(texture.turbulence)
lordcrc@384
  5491
                luxProp(mat, dot(name)+"noisedepth", 2).set(texture.noiseDepth)
lordcrc@384
  5492
                luxProp(mat, dot(name)+"noisebasis", "").set(mapConstDict(texture.noiseBasis, Texture.Noise, noiseDict, ""))
lordcrc@384
  5493
                luxProp(mat, dot(name)+"noisebasis2", "").set(mapConstDict(texture.noiseBasis2, Texture.Noise, {"SINE":"sin", "SAW":"saw", "TRI":"tri"}, ""))
lordcrc@384
  5494
                luxProp(mat, dot(name)+"noisesize", 0.25).set(texture.noiseSize)
lordcrc@384
  5495
            elif texture.type == Texture.Types["VORONOI"]:
lordcrc@384
  5496
                luxProp(mat, dot(name)+"texture", "").set("blender_voronoi")
lordcrc@384
  5497
                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
  5498
                luxProp(mat, dot(name)+"outscale", 1.0).set(texture.iScale)
lordcrc@384
  5499
                luxProp(mat, dot(name)+"noisesize", 0.25).set(texture.noiseSize)
lordcrc@384
  5500
                luxProp(mat, dot(name)+"minkosky_exp", 2.5).set(texture.exp)
lordcrc@384
  5501
                luxProp(mat, dot(name)+"w1", 1.0).set(texture.weight1)
lordcrc@384
  5502
                luxProp(mat, dot(name)+"w2", 0.0).set(texture.weight2)
lordcrc@384
  5503
                luxProp(mat, dot(name)+"w3", 0.0).set(texture.weight3)
lordcrc@384
  5504
                luxProp(mat, dot(name)+"w4", 0.0).set(texture.weight4)
lordcrc@384
  5505
            elif texture.type == Texture.Types["NOISE"]:
lordcrc@384
  5506
                luxProp(mat, dot(name)+"texture", "").set("blender_noise")
lordcrc@384
  5507
            elif texture.type == Texture.Types["DISTNOISE"]:
lordcrc@384
  5508
                luxProp(mat, dot(name)+"texture", "").set("blender_distortednoise")
lordcrc@384
  5509
                luxProp(mat, dot(name)+"distamount", 1.0).set(texture.distAmnt)
lordcrc@384
  5510
                luxProp(mat, dot(name)+"noisesize", 0.25).set(texture.noiseSize)
lordcrc@384
  5511
                luxProp(mat, dot(name)+"noisebasis", "").set(mapConstDict(texture.noiseBasis, Texture.Noise, noiseDict, ""))
lordcrc@384
  5512
                luxProp(mat, dot(name)+"noisebasis2", "").set(mapConstDict(texture.noiseBasis2, Texture.Noise, noiseDict, ""))
lordcrc@384
  5513
            elif texture.type == Texture.Types["MAGIC"]:
lordcrc@384
  5514
                luxProp(mat, dot(name)+"texture", "").set("blender_magic")
lordcrc@384
  5515
                luxProp(mat, dot(name)+"turbulance", 0.25).set(texture.turbulence)
lordcrc@384
  5516
                luxProp(mat, dot(name)+"noisedepth", 2).set(texture.noiseDepth)
lordcrc@384
  5517
            elif texture.type == Texture.Types["STUCCI"]:
lordcrc@384
  5518
                luxProp(mat, dot(name)+"texture", "").set("blender_stucci")
lordcrc@384
  5519
                luxProp(mat, dot(name)+"mtype", "").set(mapConstDict(texture.stype, Texture.STypes, {"STC_PLASTIC":"Plastic", "MSTC_WALLIN":"Wall In", "STC_WALLOUT":"Wall Out"}, ""))
lordcrc@384
  5520
                luxProp(mat, dot(name)+"noisetype", "").set({"soft":"soft_noise", "hard":"hard_noise"}[texture.noiseType])
lordcrc@384
  5521
                luxProp(mat, dot(name)+"noisesize", 0.25).set(texture.noiseSize)
lordcrc@384
  5522
                luxProp(mat, dot(name)+"turbulance", 0.25).set(texture.turbulence)
lordcrc@384
  5523
                luxProp(mat, dot(name)+"noisebasis", "").set(mapConstDict(texture.noiseBasis, Texture.Noise, noiseDict, ""))
lordcrc@384
  5524
            elif texture.type == Texture.Types["BLEND"]:
lordcrc@384
  5525
                luxProp(mat, dot(name)+"texture", "").set("blender_blend")
lordcrc@384
  5526
                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
  5527
                luxProp(mat, dot(name)+"flipXY", "false").set({0:"false", 1:"true"}[texture.rot90])
lordcrc@384
  5528
            else:
lordcrc@384
  5529
                print("Material Conversion Warning: SORRY, this procedural texture isn\'t implemented in conversion\n")
lordcrc@384
  5530
lordcrc@384
  5531
    def convertTextures(basename, texs, type="float", channel="col", val=1.0):
lordcrc@384
  5532
        tex = texs.pop()
lordcrc@384
  5533
        texture = tex.tex
lordcrc@384
  5534
        isImagemap = (texture.type == Texture.Types["IMAGE"]) and (texture.image) and (texture.image.filename!="")
lordcrc@384
  5535
        if channel == "col":
lordcrc@384
  5536
            if texture.flags & Texture.Flags["COLORBAND"] > 0:
lordcrc@384
  5537
                cbLow, cbHigh = convertColorband(texture.colorband)
lordcrc@384
  5538
                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
  5539
                if tex.noRGB:
lordcrc@384
  5540
                    lum1, lum2 = (val1[0]+val1[1]+val1[2])/3.0, (val2[0]+val2[1]+val2[2])/3.0
lordcrc@384
  5541
                    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
  5542
            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
  5543
            else: val1, alpha1, val2, alpha2 = tex.col, 0.0, tex.col, tex.colfac
lordcrc@384
  5544
        elif channel == "nor": val1, alpha1, val2, alpha2 = tex.norfac * 0.01, 0.0, tex.norfac * 0.01, 1.0
lordcrc@384
  5545
        else: val1, alpha1, val2, alpha2 = 1.0, 0.0, 1.0, tex.varfac
lordcrc@384
  5546
        if (tex.neg)^((channel=="nor") and (tex.mtNor<0)): val1, alpha1, val2, alpha2 = val2, alpha2, val1, alpha1
lordcrc@384
  5547
        luxProp(mat, dot(basename)+"textured", "").set("true")
lordcrc@384
  5548
lordcrc@384
  5549
        name = basename
lordcrc@384
  5550
        if (alpha1 < 1.0) or (alpha2 < 1.0): # texture with transparency
lordcrc@384
  5551
            luxProp(mat, dot(basename)+"texture", "").set("mix")
lordcrc@384
  5552
            if alpha1 == alpha2: # constant alpha
lordcrc@384
  5553
                luxProp(mat, ddot(basename)+"amount.value", 1.0).set(alpha1)
lordcrc@384
  5554
            else:
lordcrc@384
  5555
                createLuxTexture(ddot(basename)+"amount", tex)
lordcrc@384
  5556
                luxProp(mat, ddot(basename)+"amount:tex1.value", 1.0).set(alpha1)
lordcrc@384
  5557
                luxProp(mat, ddot(basename)+"amount:tex2.value", 1.0).set(alpha2)
lordcrc@384
  5558
            # transparent to next texture
lordcrc@384
  5559
            name = ddot(basename)+"tex1"
lordcrc@384
  5560
            if len(texs) > 0:
lordcrc@384
  5561
                convertTextures(ddot(basename)+"tex1", texs, type, channel, val)
lordcrc@384
  5562
            else:
lordcrc@384
  5563
                if type=="float": luxProp(mat, ddot(basename)+"tex1.value", 1.0).set(val)
lordcrc@384
  5564
                else: luxProp(mat, ddot(basename)+"tex1.value", "1.0 1.0 1.0").setRGB((val[0], val[1], val[2]))
lordcrc@384
  5565
            name = ddot(basename)+"tex2"
lordcrc@384
  5566
        if val1 == val2: # texture with different colors / value
lordcrc@384
  5567
            if type == "col": luxProp(mat, dot(name)+"value", "1.0 1.0 1.0").setRGB(val1)
lordcrc@384
  5568
            else: luxProp(mat, dot(name)+"value", 1.0).set(val1)
lordcrc@384
  5569
        else:
lordcrc@384
  5570
            createLuxTexture(name, tex)
lordcrc@384
  5571
            if type == "col": luxProp(mat, ddot(name)+"tex1.value", "1.0 1.0 1.0").setRGB(val1)
lordcrc@384
  5572
            else: luxProp(mat, ddot(name)+"tex1.value", 1.0).set(val1)
lordcrc@384
  5573
            if type == "col": luxProp(mat, ddot(name)+"tex2.value", "1.0 1.0 1.0").setRGB(val2)
lordcrc@384
  5574
            else: luxProp(mat, ddot(name)+"tex2.value", 1.0).set(val2)
lordcrc@384
  5575
lordcrc@384
  5576
lordcrc@384
  5577
    def convertDiffuseTexture(name):
lordcrc@384
  5578
        texs = []
lordcrc@384
  5579
        for tex in mat.getTextures():
lordcrc@384
  5580
            if tex and (tex.mapto & Texture.MapTo["COL"] > 0) and (tex.tex) and (tex.tex.type != Texture.Types["NONE"]): texs.append(tex)
lordcrc@384
  5581
        if len(texs) > 0:
lordcrc@384
  5582
            luxProp(mat, name, "").setRGB((mat.ref, mat.ref, mat.ref))
lordcrc@384
  5583
            convertTextures(name, texs, "col", "col", (mat.R, mat.G, mat.B))
lordcrc@384
  5584
    def convertSpecularTexture(name):
lordcrc@384
  5585
        texs = []
lordcrc@384
  5586
        for tex in mat.getTextures():
lordcrc@384
  5587
            if tex and (tex.mapto & Texture.MapTo["CSP"] > 0) and (tex.tex) and (tex.tex.type != Texture.Types["NONE"]): texs.append(tex)
lordcrc@384
  5588
        if len(texs) > 0:
lordcrc@384
  5589
            luxProp(mat, name, "").setRGB((mat.ref*mat.spec, mat.ref*mat.spec, mat.ref*mat.spec))
lordcrc@384
  5590
            convertTextures(name, texs, "col", "col", (mat.specR, mat.specG, mat.specB))
lordcrc@384
  5591
    def convertMirrorTexture(name):
lordcrc@384
  5592
        texs = []
lordcrc@384
  5593
        for tex in mat.getTextures():
lordcrc@384
  5594
            if tex and (tex.mapto & Texture.MapTo["CMIR"] > 0) and (tex.tex) and (tex.tex.type != Texture.Types["NONE"]): texs.append(tex)
lordcrc@384
  5595
        if len(texs) > 0:
lordcrc@384
  5596
            luxProp(mat, name, "").setRGB((mat.ref, mat.ref, mat.ref))
lordcrc@384
  5597
            convertTextures(name, texs, "col", "col", (mat.mirR, mat.mirG, mat.mirB))
lordcrc@384
  5598
    def convertBumpTexture(basename):
lordcrc@384
  5599
        texs = []
lordcrc@384
  5600
        for tex in mat.getTextures():
lordcrc@384
  5601
            if tex and (tex.mapto & Texture.MapTo["NOR"] > 0) and (tex.tex) and (tex.tex.type != Texture.Types["NONE"]): texs.append(tex)
lordcrc@384
  5602
        if len(texs) > 0:
lordcrc@384
  5603
            name = basename+":bumpmap"
lordcrc@384
  5604
            luxProp(mat, basename+".usebump", "").set("true")
lordcrc@384
  5605
            luxProp(mat, dot(name)+"textured", "").set("true")
lordcrc@384
  5606
            luxProp(mat, name, "").set(1.0)
lordcrc@384
  5607
            convertTextures(name, texs, "float", "nor", 0.0)
lordcrc@384
  5608
lordcrc@384
  5609
    def makeMatte(name):
lordcrc@384
  5610
        luxProp(mat, dot(name)+"type", "").set("matte")
lordcrc@384
  5611
        luxProp(mat, name+":Kd", "").setRGB((mat.R*mat.ref, mat.G*mat.ref, mat.B*mat.ref))
lordcrc@384
  5612
        convertDiffuseTexture(name+":Kd")
lordcrc@384
  5613
        convertBumpTexture(name)
lordcrc@384
  5614
    def makeGlossy(name, roughness):
lordcrc@384
  5615
        luxProp(mat, dot(name)+"type", "").set("glossy")
lordcrc@384
  5616
        luxProp(mat, name+":Kd", "").setRGB((mat.R*mat.ref, mat.G*mat.ref, mat.B*mat.ref))
lordcrc@384
  5617
        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
  5618
        luxProp(mat, name+":uroughness", 0.0).set(roughness)
lordcrc@384
  5619
        luxProp(mat, name+":vroughness", 0.0).set(roughness)
lordcrc@384
  5620
        convertDiffuseTexture(name+":Kd")
lordcrc@384
  5621
        convertSpecularTexture(name+":Ks")
lordcrc@384
  5622
        convertBumpTexture(name)
lordcrc@384
  5623
    def makeMirror(name):
lordcrc@384
  5624
        luxProp(mat, dot(name)+"type", "").set("mirror")
lordcrc@384
  5625
        luxProp(mat, name+":Kr", "").setRGB((mat.mirR, mat.mirG, mat.mirB))
lordcrc@384
  5626
        convertMirrorTexture(name+":Kr")
lordcrc@384
  5627
        convertBumpTexture(name)
lordcrc@384
  5628
    def makeGlass(name):
lordcrc@384
  5629
        luxProp(mat, dot(name)+"type", "").set("glass")
lordcrc@384
  5630
        luxProp(mat, name+":Kr", "").setRGB((0.0, 0.0, 0.0))
lordcrc@384
  5631
        luxProp(mat, name+":Kt", "").setRGB((mat.R, mat.G, mat.B))
lordcrc@384
  5632
        luxProp(mat, name+":index.iorusepreset", "").set("false")
lordcrc@384
  5633
        luxProp(mat, name+":index", 0.0).set(mat.getIOR())
lordcrc@384
  5634
        convertMirrorTexture(name+":Kr")
lordcrc@384
  5635
        convertDiffuseTexture(name+":Kt")
lordcrc@384
  5636
        convertBumpTexture(name)
lordcrc@384
  5637
    def makeRoughglass(name, roughness):
lordcrc@384
  5638
        luxProp(mat, dot(name)+"type", "").set("roughglass")
lordcrc@384
  5639
        luxProp(mat, name+":Kr", "").setRGB((0.0, 0.0, 0.0))
lordcrc@384
  5640
        luxProp(mat, name+":Kt", "").setRGB((mat.R, mat.G, mat.B))
lordcrc@384
  5641
        luxProp(mat, name+":index.iorusepreset", "").set("false")
lordcrc@384
  5642
        luxProp(mat, name+":index", 0.0).set(mat.getIOR())
lordcrc@384
  5643
        luxProp(mat, name+":uroughness", 0.0).set(roughness)
lordcrc@384
  5644
        luxProp(mat, name+":vroughness", 0.0).set(roughness)
lordcrc@384
  5645
        convertMirrorTexture(name+":Kr")
lordcrc@384
  5646
        convertDiffuseTexture(name+":Kt")
lordcrc@384
  5647
        convertBumpTexture(name)
lordcrc@384
  5648
    print("convert Blender material \"%s\" to lux material"%(mat.name))
lordcrc@384
  5649
    mat.properties['luxblend'] = {}
lordcrc@384
  5650
    if mat.emit > 0.0001:
lordcrc@384
  5651
        luxProp(mat, "type", "").set("light")
lordcrc@384
  5652
        luxProp(mat, "light.l", "").setRGB((mat.R, mat.G, mat.B))
lordcrc@384
  5653
        luxProp(mat, "light.gain", 1.0).set(mat.emit)
lordcrc@384
  5654
        return
lordcrc@384
  5655
    alpha = mat.alpha
lordcrc@384
  5656
    if not(mat.mode & Material.Modes.RAYTRANSP): alpha = 1.0
lordcrc@384
  5657
    alpha0name, alpha1name = "", ""
lordcrc@384
  5658
    if (alpha > 0.0) and (alpha < 1.0):
lordcrc@384
  5659
        luxProp(mat, "type", "").set("mix")
lordcrc@384
  5660
        luxProp(mat, ":amount", 0.0).set(alpha)
lordcrc@384
  5661
        alpha0name, alpha1name = "mat2", "mat1"
lordcrc@384
  5662
    if alpha > 0.0:
lordcrc@384
  5663
        mirror = mat.rayMirr
lordcrc@384
  5664
        if not(mat.mode & Material.Modes.RAYMIRROR): mirror = 0.0
lordcrc@384
  5665
        mirror0name, mirror1name = alpha1name, alpha1name
lordcrc@384
  5666
        if (mirror > 0.0) and (mirror < 1.0):
lordcrc@384
  5667
            luxProp(mat, dot(alpha1name)+"type", "").set("mix")
lordcrc@384
  5668
            luxProp(mat, alpha1name+":amount", 0.0).set(1.0 - mirror)
lordcrc@384
  5669
            mirror0name, mirror1name = ddot(alpha1name)+"mat1", ddot(alpha1name)+"mat2"
lordcrc@384
  5670
        if mirror > 0.0:
lordcrc@384
  5671
            if mat.glossMir < 1.0: makeGlossy(mirror1name, 1.0-mat.glossMir**2)
lordcrc@384
  5672
            else: makeMirror(mirror1name)
lordcrc@384
  5673
        if mirror < 1.0:
lordcrc@384
  5674
            if mat.spec > 0.0: makeGlossy(mirror0name, 1.0/mat.hard)
lordcrc@384
  5675
            else: makeMatte(mirror0name)
lordcrc@384
  5676
    if alpha < 1.0:
lordcrc@384
  5677
        if mat.glossTra < 1.0: makeRoughnessGlass(alpha0name, 1.0-mat.glossTra**2)
lordcrc@384
  5678
        else: makeGlass(alpha0name)
lordcrc@384
  5679
lordcrc@384
  5680
def convertAllMaterials():
lordcrc@384
  5681
    for mat in Material.Get(): convertMaterial(mat)
lordcrc@384
  5682
lordcrc@384
  5683
lordcrc@384
  5684
lordcrc@384
  5685
lordcrc@384
  5686
### Connect LRMDB ###
lordcrc@384
  5687
ConnectLrmdb = False
lordcrc@384
  5688
try:
lordcrc@384
  5689
    import socket  # try import of socket library
lordcrc@384
  5690
    ConnectLrmdb = True
lordcrc@384
  5691
    def downloadLRMDB(mat, id):
lordcrc@384
  5692
        if id.isalnum():
lordcrc@384
  5693
            DrawProgressBar(0.0,'Getting Material #'+id)
lordcrc@384
  5694
            try:
lordcrc@384
  5695
                HOST = 'www.luxrender.net'
lordcrc@384
  5696
                GET = '/lrmdb/en/material/download/'+id
lordcrc@384
  5697
                PORT = 80
lordcrc@384
  5698
                sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
lordcrc@384
  5699
                sock.connect((HOST, PORT))
lordcrc@384
  5700
                sock.send("GET %s HTTP/1.0\r\nHost: %s\r\n\r\n" % (GET, HOST))
lordcrc@384
  5701
                data = sock.recv(1024)
lordcrc@384
  5702
                str = ""
lordcrc@384
  5703
                while len(data):
lordcrc@384
  5704
                    str += data
lordcrc@384
  5705
                    data = sock.recv(1024)
lordcrc@384
  5706
                sock.close()
lordcrc@384
  5707
                if str.split("\n", 1)[0].find("200") < 0:
lordcrc@384
  5708
                    print("ERROR: server error: %s"%(str.split("\n",1)[0]))
lordcrc@384
  5709
                    return None
lordcrc@384
  5710
                str = (str.split("\r\n\r\n")[1]).strip()
lordcrc@384
  5711
                if (str[0]=="{") and (str[-1]=="}"):
lordcrc@384
  5712
                    return str2MatTex(str)
lordcrc@384
  5713
                print("ERROR: downloaded data is not a material or texture")
lordcrc@384
  5714
            except:
lordcrc@384
  5715
                print("ERROR: download failed")
lordcrc@384
  5716
                
lordcrc@384
  5717
            DrawProgressBar(1.0,'')
lordcrc@384
  5718
        else:
lordcrc@384
  5719
            print("ERROR: material id is not valid")
lordcrc@384
  5720
        return None
lordcrc@384
  5721
    
lordcrc@384
  5722
        
lordcrc@384
  5723
    #===========================================================================
lordcrc@384
  5724
    # COOKIETRANSPORT
lordcrc@384
  5725
    #===========================================================================
lordcrc@384
  5726
    
lordcrc@384
  5727
    #--------------------------------------------------------------------------- 
lordcrc@384
  5728
    # IMPORTS
lordcrc@384
  5729
    import cookielib, urllib2, xmlrpclib
lordcrc@384
  5730
    
lordcrc@384
  5731
    #---------------------------------------------------------------------------
lordcrc@384
  5732
    # pilfered from
lordcrc@384
  5733
    # https://fedorahosted.org/python-bugzilla/browser/bugzilla.py?rev=e6f699f06e92b1e49b1b8d2c8fbe89d9425a4a9a
lordcrc@384
  5734
    class CookieTransport(xmlrpclib.Transport):
lordcrc@384
  5735
        '''
lordcrc@384
  5736
        A subclass of xmlrpclib.Transport that supports cookies.
lordcrc@384
  5737
        '''
lordcrc@384
  5738
        
lordcrc@384
  5739
        cookiejar = None
lordcrc@384
  5740
        scheme = 'http'
lordcrc@384
  5741
        verbose = None
lordcrc@384
  5742
    
lordcrc@384
  5743
        # Cribbed from xmlrpclib.Transport.send_user_agent 
lordcrc@384
  5744
        def send_cookies(self, connection, cookie_request):
lordcrc@384
  5745
            '''
lordcrc@384
  5746
            Send all the cookie data that we have received
lordcrc@384
  5747
            '''
lordcrc@384
  5748
            
lordcrc@384
  5749
            if self.cookiejar is None:
lordcrc@384
  5750
                self.cookiejar = cookielib.CookieJar()
lordcrc@384
  5751
            elif self.cookiejar:
lordcrc@384
  5752
                # Let the cookiejar figure out what cookies are appropriate
lordcrc@384
  5753
                self.cookiejar.add_cookie_header(cookie_request)
lordcrc@384
  5754
                # Pull the cookie headers out of the request object...
lordcrc@384
  5755
                cookielist = list()
lordcrc@384
  5756
                for header, value in cookie_request.header_items():
lordcrc@384
  5757
                    if header.startswith('Cookie'):
lordcrc@384
  5758
                        cookielist.append([header, value])
lordcrc@384
  5759
                # ...and put them over the connection
lordcrc@384
  5760
                for header, value in cookielist:
lordcrc@384
  5761
                    connection.putheader(header, value)
lordcrc@384
  5762
    
lordcrc@384
  5763
        # This is the same request() method from xmlrpclib.Transport,
lordcrc@384
  5764
        # with a couple additions noted below
lordcrc@384
  5765
        def request(self, host, handler, request_body, verbose=0):
lordcrc@384
  5766
            '''
lordcrc@384
  5767
            Handle the request
lordcrc@384
  5768
            '''
lordcrc@384
  5769
            
lordcrc@384
  5770
            host_connection = self.make_connection(host)
lordcrc@384
  5771
            if verbose:
lordcrc@384
  5772
                host_connection.set_debuglevel(1)
lordcrc@384
  5773
    
lordcrc@384
  5774
            # ADDED: construct the URL and Request object for proper cookie handling
lordcrc@384
  5775
            request_url = "%s://%s/" % (self.scheme, host)
lordcrc@384
  5776
            cookie_request  = urllib2.Request(request_url) 
lordcrc@384
  5777
    
lordcrc@384
  5778
            self.send_request(host_connection, handler, request_body)
lordcrc@384
  5779
            self.send_host(host_connection, host) 
lordcrc@384
  5780
            
lordcrc@384
  5781
            # ADDED. creates cookiejar if None.
lordcrc@384
  5782
            self.send_cookies(host_connection, cookie_request)
lordcrc@384
  5783
            self.send_user_agent(host_connection)
lordcrc@384
  5784
            self.send_content(host_connection, request_body)
lordcrc@384
  5785
    
lordcrc@384
  5786
            errcode, errmsg, headers = host_connection.getreply()
lordcrc@384
  5787
    
lordcrc@384
  5788
            # ADDED: parse headers and get cookies here
lordcrc@384
  5789
            class CookieResponse:
lordcrc@384
  5790
                '''
lordcrc@384
  5791
                fake a response object that we can fill with the headers above
lordcrc@384
  5792
                '''
lordcrc@384
  5793
                
lordcrc@384
  5794
                def __init__(self, headers):
lordcrc@384
  5795
                    self.headers = headers
lordcrc@384
  5796
                    
lordcrc@384
  5797
                def info(self):
lordcrc@384
  5798
                    return self.headers
lordcrc@384
  5799
                
lordcrc@384
  5800
            cookie_response = CookieResponse(headers)
lordcrc@384
  5801
            
lordcrc@384
  5802
            # Okay, extract the cookies from the headers
lordcrc@384
  5803
            self.cookiejar.extract_cookies(cookie_response, cookie_request)
lordcrc@384
  5804
            
lordcrc@384
  5805
            # And write back any changes
lordcrc@384
  5806
            # DH THIS DOESN'T WORK
lordcrc@384
  5807
            # self.cookiejar.save(self.cookiejar.filename)
lordcrc@384
  5808
    
lordcrc@384
  5809
            if errcode != 200:
lordcrc@384
  5810
                raise xmlrpclib.ProtocolError(
lordcrc@384
  5811
                    host + handler,
lordcrc@384
  5812
                    errcode, errmsg,
lordcrc@384
  5813
                    headers
lordcrc@384
  5814
                )
lordcrc@384
  5815
    
lordcrc@384
  5816
            self.verbose = verbose
lordcrc@384
  5817
    
lordcrc@384
  5818
            try:
lordcrc@384
  5819
                sock = host_connection._conn.sock
lordcrc@384
  5820
            except AttributeError:
lordcrc@384
  5821
                sock = None
lordcrc@384
  5822
    
lordcrc@384
  5823
            return self._parse_response(host_connection.getfile(), sock)
lordcrc@384
  5824
    
lordcrc@384
  5825
lordcrc@384
  5826
    #===========================================================================
lordcrc@384
  5827
    # LRMDB Integration
lordcrc@384
  5828
    #===========================================================================
lordcrc@384
  5829
    class lrmdb:
lordcrc@384
  5830
        host              = 'http://www.luxrender.net/lrmdb/ixr'
lordcrc@384
  5831
        
lordcrc@384
  5832
        username          = ""
lordcrc@384
  5833
        password          = ""
lordcrc@384
  5834
        logged_in         = False
lordcrc@384
  5835
        
lordcrc@384
  5836
        SERVER            = None
lordcrc@384
  5837
        
lordcrc@384
  5838
        last_error_str    = None
lordcrc@384
  5839
        
lordcrc@384
  5840
        def last_error(self):
lordcrc@384
  5841
            return self.last_error_str #'LRMDB Connector: %s' %
lordcrc@384
  5842
        
lordcrc@384
  5843
        def login(self):
lordcrc@384
  5844
            try:
lordcrc@384
  5845
                result = self.SERVER.user.login(
lordcrc@384
  5846
                    self.username,
lordcrc@384
  5847
                    self.password
lordcrc@384
  5848
                )
lordcrc@384
  5849
                if not result:
lordcrc@384
  5850
                    raise
lordcrc@384
  5851
                else:
lordcrc@384
  5852
                    self.logged_in = True
lordcrc@384
  5853
                    return True
lordcrc@384
  5854
            except:
lordcrc@384
  5855
                self.last_error_str = 'Login Failed'
lordcrc@384
  5856
                self.logged_in = False
lordcrc@384
  5857
                return False
lordcrc@384
  5858
            
lordcrc@384
  5859
        def submit_object(self, mat, basekey, tex):
lordcrc@384
  5860
            if not self.check_creds(): return False
lordcrc@384
  5861
            
lordcrc@384
  5862
            try:
lordcrc@384
  5863
                result = 'Unknown Error'
lordcrc@384
  5864
                
lordcrc@384
  5865
                if tex:
lordcrc@384
  5866
                    name = Draw.PupStrInput('Name: ', '', 32)
lordcrc@384
  5867
                else:
lordcrc@384
  5868
                    name = mat.name
lordcrc@384
  5869
                
lordcrc@384
  5870
                result = self.SERVER.object.submit(
lordcrc@384
  5871
                    name,
lordcrc@384
  5872
                    MatTex2dict( getMatTex(mat, basekey, tex), tex )
lordcrc@384
  5873
                )
lordcrc@384
  5874
                if result is not True:
lordcrc@384
  5875
                    raise
lordcrc@384
  5876
                else:
lordcrc@384
  5877
                    return True
lordcrc@384
  5878
            except:
lordcrc@384
  5879
                self.last_error_str = 'Submit failed: %s' % result
lordcrc@384
  5880
                return False
lordcrc@384
  5881
        
lordcrc@384
  5882
        def check_creds(self):
lordcrc@384
  5883
            if self.SERVER is None:
lordcrc@384
  5884
                try:
lordcrc@384
  5885
                    self.SERVER = xmlrpclib.ServerProxy(self.host, transport=CookieTransport())
lordcrc@384
  5886
                except:
lordcrc@384
  5887
                    self.last_error_str = 'ServerProxy init failed'
lordcrc@384
  5888
                    return False
lordcrc@384
  5889
            
lordcrc@384
  5890
            
lordcrc@384
  5891
            if not self.logged_in:
lordcrc@384
  5892
                #if self.username is "":
lordcrc@384
  5893
                self.request_username()
lordcrc@384
  5894
                
lordcrc@384
  5895
                #if self.password is "":
lordcrc@384
  5896
                self.request_password()
lordcrc@384
  5897
                    
lordcrc@384
  5898
                return self.login()
lordcrc@384
  5899
            else:
lordcrc@384
  5900
                return True
lordcrc@384
  5901
                
lordcrc@384
  5902
        def request_username(self):
lordcrc@384
  5903
            self.username = Draw.PupStrInput("Username:", self.username, 32)
lordcrc@384
  5904
            
lordcrc@384
  5905
        def request_password(self):
lordcrc@384
  5906
            self.password = Draw.PupStrInput("Password:", self.password, 32)
lordcrc@384
  5907
lordcrc@384
  5908
    lrmdb_connector = lrmdb()
lordcrc@384
  5909
        
lordcrc@384
  5910
    
lordcrc@384
  5911
except: print("WARNING: LRMDB support not available")
lordcrc@384
  5912
lordcrc@384
  5913
lordcrc@384
  5914
lordcrc@384
  5915
### MatTex functions ###
lordcrc@384
  5916
### MatTex : is a dictionary of material or texture properties
lordcrc@384
  5917
lordcrc@384
  5918
def getMatTex(mat, basekey='', tex=False):
lordcrc@384
  5919
    global usedproperties, usedpropertiesfilterobj
lordcrc@384
  5920
    usedproperties = {}
lordcrc@384
  5921
    usedpropertiesfilterobj = mat
lordcrc@384
  5922
    luxMaterial(mat)
lordcrc@384
  5923
    dict = {}
lordcrc@384
  5924
    for k,v in usedproperties.items():
lordcrc@384
  5925
        if k[:len(basekey)]==basekey:
lordcrc@384
  5926
            if k[-9:] != '.textured':
lordcrc@384
  5927
                name = k[len(basekey):]
lordcrc@384
  5928
                if name == ".type": name = "type"
lordcrc@384
  5929
                dict[name] = v
lordcrc@384
  5930
    dict["__type__"] = ["material","texture"][bool(tex)]
lordcrc@384
  5931
    return dict
lordcrc@384
  5932
lordcrc@384
  5933
def putMatTex(mat, dict, basekey='', tex=None):
lordcrc@384
  5934
    if dict and (tex!=None) and (tex ^ (dict.has_key("__type__") and (dict["__type__"]=="texture"))):
lordcrc@384
  5935
        print("ERROR: Can't apply %s as %s"%(["texture","material"][bool(tex)],["material","texture"][bool(tex)]))
lordcrc@384
  5936
        return
lordcrc@384
  5937
    if dict:
lordcrc@384
  5938
        # remove all current properties in mat that starts with basekey
lordcrc@384
  5939
        try:
lordcrc@384
  5940
            d = mat.properties['luxblend']
lordcrc@384
  5941
            for k,v in d.convert_to_pyobject().items():
lordcrc@384
  5942
                kn = k
lordcrc@384
  5943
                if k[:7]=="__hash:":    # decode if entry is hashed (cause of 32chars limit)
lordcrc@384
  5944
                    l = v.split(" = ")
lordcrc@384
  5945
                    kn = l[0]
lordcrc@384
  5946
                if kn[:len(basekey)]==basekey:
lordcrc@384
  5947
                    del mat.properties['luxblend'][k]
lordcrc@384
  5948
        except: print("error") # pass
lordcrc@384
  5949
        # assign loaded properties
lordcrc@384
  5950
        for k,v in dict.items():
lordcrc@384
  5951
            try:
lordcrc@384
  5952
                if (basekey!="") and (k=="type"): k = ".type"
lordcrc@384
  5953
                # zuegs: following two lines should fix issue http://www.luxrender.net/forum/viewtopic.php?f=16&t=1618&p=14512#p14512
lordcrc@384
  5954
                if (basekey!="") and ((k[0]!=".") and (k[0]!=":")): k = ":"+k
lordcrc@384
  5955
                if (basekey=="") and (k[0:4]==":mat"): k = k[1:]
lordcrc@384
  5956
                luxProp(mat, basekey+k, None).set(v)
lordcrc@384
  5957
                if k[-8:] == '.texture':
lordcrc@384
  5958
                    luxProp(mat, basekey+k[:-8]+'.textured', 'false').set('true')
lordcrc@384
  5959
            except: pass
lordcrc@384
  5960
lordcrc@384
  5961
lordcrc@384
  5962
LBX_VERSION = '0.7'
lordcrc@384
  5963
lordcrc@384
  5964
def MatTex2dict(d, tex = None):
lordcrc@384
  5965
    global LBX_VERSION
lordcrc@384
  5966
    
lordcrc@384
  5967
    if LBX_VERSION == '0.6':
lordcrc@384
  5968
    
lordcrc@384
  5969
        if tex is not None and tex == True:
lordcrc@384
  5970
            d['LUX_DATA'] = 'TEXTURE'
lordcrc@384
  5971
        else:
lordcrc@384
  5972
            d['LUX_DATA'] = 'MATERIAL'
lordcrc@384
  5973
        
lordcrc@384
  5974
        d['LUX_VERSION'] = '0.6'
lordcrc@384
  5975
        
lordcrc@384
  5976
        return d
lordcrc@384
  5977
    
lordcrc@384
  5978
    elif LBX_VERSION == '0.7':
lordcrc@384
  5979
        definition = []
lordcrc@384
  5980
        for k in d.keys():
lordcrc@384
  5981
            if type(d[k]) == types.IntType:
lordcrc@384
  5982
                t = 'integer'
lordcrc@384
  5983
            if type(d[k]) == types.FloatType:
lordcrc@384
  5984
                t = 'float'
lordcrc@384
  5985
            if type(d[k]) == types.BooleanType:
lordcrc@384
  5986
                t = 'bool'
lordcrc@384
  5987
            if type(d[k]) == types.StringType:
lordcrc@384
  5988
                l=None
lordcrc@384
  5989
                try:
lordcrc@384
  5990
                    l = d[k].split(" ")
lordcrc@384
  5991
                except: pass
lordcrc@384
  5992
                if l==None or len(l)!=3:
lordcrc@384
  5993
                    t = 'string'
lordcrc@384
  5994
                else:
lordcrc@384
  5995
                    t = 'vector'
lordcrc@384
  5996
                
lordcrc@384
  5997
            definition.append([ t, k, d[k] ])
lordcrc@384
  5998
        
lordcrc@384
  5999
        
lordcrc@384
  6000
        lbx = {
lordcrc@384
  6001
            'type': d['__type__'],
lordcrc@384
  6002
            'version': '0.7',
lordcrc@384
  6003
            'definition': definition,
lordcrc@384
  6004
            'metadata': [
lordcrc@384
  6005
                ['string', 'generator', 'luxblend'],
lordcrc@384
  6006
            ]
lordcrc@384
  6007
        }
lordcrc@384
  6008
        
lordcrc@384
  6009
        return lbx
lordcrc@384
  6010
lordcrc@384
  6011
def format_dictStr(dictStr):
lordcrc@384
  6012
    result = ''
lordcrc@384
  6013
    pos = 0
lordcrc@384
  6014
    indentStr = '  '
lordcrc@384
  6015
    newLine = '\n'
lordcrc@384
  6016
    
lordcrc@384
  6017
    for char in dictStr:
lordcrc@384
  6018
        if char in ['}', ']']:
lordcrc@384
  6019
            result += newLine
lordcrc@384
  6020
            pos -= 1
lordcrc@384
  6021
            for j in range(0,pos):
lordcrc@384
  6022
                result += indentStr
lordcrc@384
  6023
                
lordcrc@384
  6024
        result += char
lordcrc@384
  6025
        
lordcrc@384
  6026
        if char in [',', '{', '[']:
lordcrc@384
  6027
            result += newLine
lordcrc@384
  6028
            if char in ['{', '[']:
lordcrc@384
  6029
                pos += 1
lordcrc@384
  6030
            for j in range(0,pos):
lordcrc@384
  6031
                result += indentStr
lordcrc@384
  6032
            
lordcrc@384
  6033
    return result
lordcrc@384
  6034
lordcrc@384
  6035
lordcrc@384
  6036
def MatTex2str(d, tex = None):
lordcrc@384
  6037
    global LBX_VERSION
lordcrc@384
  6038
    
lordcrc@384
  6039
    if LBX_VERSION == '0.6':
lordcrc@384
  6040
        return format_dictStr(str( MatTex2dict(d, tex) )) #.replace(", \'", ",\n\'")
lordcrc@384
  6041
    
lordcrc@384
  6042
    elif LBX_VERSION == '0.7':
lordcrc@384
  6043
        return format_dictStr(str( MatTex2dict(d, tex) )) #.replace("], \'", "],\r\n\'").replace("[","\r\n\t[")
lordcrc@384
  6044
        
lordcrc@384
  6045
lordcrc@384
  6046
def str2MatTex(s, tex = None):    # todo: this is not absolutely save from attacks!!!
lordcrc@384
  6047
    global LBX_VERSION
lordcrc@384
  6048
    
lordcrc@384
  6049
    s = s.strip()
lordcrc@384
  6050
    if (s[0]=='{') and (s[-1]=='}'):
lordcrc@384
  6051
        d = eval(s, dict(__builtins__=None))
lordcrc@384
  6052
        if type(d)==types.DictType:
lordcrc@384
  6053
            
lordcrc@384
  6054
            
lordcrc@384
  6055
            if LBX_VERSION == '0.6':
lordcrc@384
  6056
            
lordcrc@384
  6057
                if tex is not None and tex == True:
lordcrc@384
  6058
                    test_str = 'TEXTURE'
lordcrc@384
  6059
                else:
lordcrc@384
  6060
                    test_str = 'MATERIAL'
lordcrc@384
  6061
                    
lordcrc@384
  6062
                if   ('LUX_DATA' in d.keys() and d['LUX_DATA'] == test_str) \
lordcrc@384
  6063
                and  ('LUX_VERSION' in d.keys() and (d['LUX_VERSION'] == '0.6' or d['LUX_VERSION'] == 0.6)):
lordcrc@384
  6064
                    return d
lordcrc@384
  6065
                else:
lordcrc@384
  6066
                    reason = 'Missing/incorrect metadata'
lordcrc@384
  6067
                    
lordcrc@384
  6068
            elif LBX_VERSION == '0.7':
lordcrc@384
  6069
                
lordcrc@384
  6070
                def lb_list_to_dict(list):
lordcrc@384
  6071
                    d = {}
lordcrc@384
  6072
                    for t, k, v in list:
lordcrc@384
  6073
                        if t == 'float':
lordcrc@384
  6074
                            v = float(v)
lordcrc@384
  6075
                            
lordcrc@384
  6076
                        d[k] = v
lordcrc@384
  6077
                    return d
lordcrc@384
  6078
                
lordcrc@384
  6079
                if   ('version' in d.keys() and d['version'] in ['0.6', '0.7']) \
lordcrc@384
  6080
                and  ('type' in d.keys() and d['type'] in ['material', 'texture']) \
lordcrc@384
  6081
                and  ('definition' in d.keys()):
lordcrc@384
  6082
                    
lordcrc@384
  6083
                    
lordcrc@384
  6084
                    try:
lordcrc@384
  6085
                        definition = lb_list_to_dict(d['definition'])
lordcrc@384
  6086
                        
lordcrc@384
  6087
                        if 'metadata' in d.keys():
lordcrc@384
  6088
                            definition.update( lb_list_to_dict(d['metadata']) )
lordcrc@384
  6089
                        
lordcrc@384
  6090
                        return definition
lordcrc@384
  6091
                    except:
lordcrc@384
  6092
                        reason = 'Incorrect LBX definition data'
lordcrc@384
  6093
                else: 
lordcrc@384
  6094
                    reason = 'Missing/incorrect metadata'
lordcrc@384
  6095
            else:
lordcrc@384
  6096
                reason = 'Unknown LBX version'
lordcrc@384
  6097
        else:
lordcrc@384
  6098
            reason = 'Not a parsed dict'
lordcrc@384
  6099
    else:
lordcrc@384
  6100
        reason = 'Not a stored dict'
lordcrc@384
  6101
            
lordcrc@384
  6102
            
lordcrc@384
  6103
    print("ERROR: string to material/texture conversion failed: %s" % reason)
lordcrc@384
  6104
    return None
lordcrc@384
  6105
lordcrc@384
  6106
lordcrc@384
  6107
luxclipboard = None # global variable for copy/paste content
lordcrc@384
  6108
def showMatTexMenu(mat, basekey='', tex=False):
lordcrc@384
  6109
    global luxclipboard, ConnectLrmdb
lordcrc@384
  6110
    if tex: menu="Texture menu:%t"
lordcrc@384
  6111
    else: menu="Material menu:%t"
lordcrc@384
  6112
    menu += "|Copy%x1"
lordcrc@384
  6113
    try:
lordcrc@384
  6114
        if luxclipboard and (not(tex) ^ (luxclipboard["__type__"]=="texture")): menu +="|Paste%x2"
lordcrc@384
  6115
    except: pass
lordcrc@384
  6116
    if (tex):
lordcrc@384
  6117
        menu += "|Load LBT%x3|Save LBT%x4"
lordcrc@384
  6118
    else:
lordcrc@384
  6119
        menu += "|Load LBM%x3|Save LBM%x4"
lordcrc@384
  6120
    if  ConnectLrmdb:
lordcrc@384
  6121
        menu += "|Download from DB%x5" #not(tex) and
lordcrc@384
  6122
        menu += "|Upload to DB%x6"
lordcrc@384
  6123
lordcrc@384
  6124
#    menu += "|%l|dump material%x99|dump clipboard%x98"
lordcrc@384
  6125
    r = Draw.PupMenu(menu)
lordcrc@384
  6126
    if r==1:
lordcrc@384
  6127
        luxclipboard = getMatTex(mat, basekey, tex)
lordcrc@384
  6128
    elif r==2: putMatTex(mat, luxclipboard, basekey, tex)
lordcrc@384
  6129
    elif r==3: 
lordcrc@384
  6130
        scn = Scene.GetCurrent()
lordcrc@384
  6131
        if (tex):
lordcrc@384
  6132
            Window.FileSelector(lambda fn:loadMatTex(mat, fn, basekey, tex), "load texture", luxProp(scn, "lux", "").get()+os.sep+".lbt")
lordcrc@384
  6133
        else:
lordcrc@384
  6134
            Window.FileSelector(lambda fn:loadMatTex(mat, fn, basekey, tex), "load material", luxProp(scn, "lux", "").get()+os.sep+".lbm")
lordcrc@384
  6135
    elif r==4:
lordcrc@384
  6136
        scn = Scene.GetCurrent()
lordcrc@384
  6137
        if (tex):
lordcrc@384
  6138
            Window.FileSelector(lambda fn:saveMatTex(mat, fn, basekey, tex), "save texture", luxProp(scn, "lux", "").get()+os.sep+".lbt")
lordcrc@384
  6139
        else:
lordcrc@384
  6140
            Window.FileSelector(lambda fn:saveMatTex(mat, fn, basekey, tex), "save material", luxProp(scn, "lux", "").get()+os.sep+".lbm")
lordcrc@384
  6141
    elif r==5:
lordcrc@384
  6142
        if not tex:
lordcrc@384
  6143
            id = Draw.PupStrInput("Material ID:", "", 32)
lordcrc@384
  6144
        else:
lordcrc@384
  6145
            id = Draw.PupStrInput("Texture ID:", "", 32)
lordcrc@384
  6146
        if id: putMatTex(mat, downloadLRMDB(mat, id), basekey, tex)
lordcrc@384
  6147
    elif r==6:
lordcrc@384
  6148
        global lrmdb_connector
lordcrc@384
  6149
        if not lrmdb_connector.submit_object(mat, basekey, tex):
lordcrc@384
  6150
            msg = lrmdb_connector.last_error()
lordcrc@384
  6151
        else:
lordcrc@384
  6152
            msg = 'OK'
lordcrc@384
  6153
            
lordcrc@384
  6154
        Draw.PupMenu("Upload: "+msg+".%t|OK")
lordcrc@384
  6155
#    elif r==99:
lordcrc@384
  6156
#        for k,v in mat.properties['luxblend'].convert_to_pyobject().items(): print(k+"="+repr(v))
lordcrc@384
  6157
#    elif r==98:
lordcrc@384
  6158
#        for k,v in luxclipboard.items(): print(k+"="+repr(v))
lordcrc@384
  6159
#    prin()
lordcrc@384
  6160
    Draw.Redraw()
lordcrc@384
  6161
lordcrc@384
  6162
lordcrc@384
  6163
def saveMatTex(mat, fn, basekey='', tex=False):
lordcrc@384
  6164
    global LuxIsGUI
lordcrc@384
  6165
    d = getMatTex(mat, basekey, tex)
lordcrc@384
  6166
    file = open(fn, 'w')
lordcrc@384
  6167
    file.write(MatTex2str(d, tex))
lordcrc@384
  6168
    file.close()
lordcrc@384
  6169
    if LuxIsGUI: Draw.Redraw()
lordcrc@384
  6170
lordcrc@384
  6171
lordcrc@384
  6172
def loadMatTex(mat, fn, basekey='', tex=None):
lordcrc@384
  6173
    global LuxIsGUI
dade@445
  6174
    file = open(fn, 'rU')
lordcrc@384
  6175
    data = file.read()
lordcrc@384
  6176
    file.close()
lordcrc@384
  6177
    data = str2MatTex(data, tex)
lordcrc@384
  6178
    putMatTex(mat, data, basekey, tex) 
lordcrc@384
  6179
    if LuxIsGUI: Draw.Redraw()
lordcrc@384
  6180
lordcrc@384
  6181
lordcrc@384
  6182
activemat = None
lordcrc@384
  6183
def setactivemat(mat):
lordcrc@384
  6184
    global activemat
lordcrc@384
  6185
    activemat = mat
lordcrc@384
  6186
lordcrc@384
  6187
lordcrc@384
  6188
# scrollbar
lordcrc@384
  6189
class scrollbar:
lordcrc@384
  6190
    def __init__(self):
lordcrc@384
  6191
        self.position = 0 # current position at top (inside 0..height-viewHeight)
lordcrc@384
  6192
        self.height = 0 # total height of the content
lordcrc@384
  6193
        self.viewHeight = 0 # height of window
lordcrc@384
  6194
        self.x = 0 # horizontal position of the scrollbar
lordcrc@384
  6195
        self.scrolling = self.over = False # start without scrolling ;)
lordcrc@384
  6196
    def calcRects(self):
lordcrc@384
  6197
        # Blender doesn't give us direct access to the window size yet, but it does set the
lordcrc@384
  6198
        # GL scissor box for it, so we can get the size from that. (thx to Daniel Dunbar)
lordcrc@384
  6199
        size = BGL.Buffer(BGL.GL_FLOAT, 4)
lordcrc@384
  6200
        BGL.glGetFloatv(BGL.GL_SCISSOR_BOX, size)
lordcrc@384
  6201
        size = size.list # [winx, winy, width, height]
lordcrc@384
  6202
        self.winrect = size[:]
lordcrc@384
  6203
        self.viewHeight = size[3]
lordcrc@384
  6204
        size[0], size[1] = size[2]-20, 0 # [scrollx1, scrolly1, scrollx2, scrolly2]
lordcrc@384
  6205
        self.rect = size[:]
lordcrc@384
  6206
        if self.position < 0: self.position = 0
lordcrc@384
  6207
        if self.height < self.viewHeight: self.height = self.viewHeight
lordcrc@384
  6208
        if self.position > self.height-self.viewHeight: self.position = self.height-self.viewHeight
lordcrc@384
  6209
        self.factor = (size[3]-size[1]-4)/self.height
lordcrc@384
  6210
        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
  6211
    def draw(self):
lordcrc@384
  6212
        self.calcRects()
lordcrc@384
  6213
        BGL.glColor3f(0.5,0.5,0.5); BGL.glRectf(self.rect[0],self.rect[1],self.rect[2],self.rect[3])
lordcrc@384
  6214
        if self.over or self.scrolling: BGL.glColor3f(1.0,1.0,0.7)
lordcrc@384
  6215
        else: BGL.glColor3f(0.7,0.7,0.7)
lordcrc@384
  6216
        BGL.glRectf(self.sliderRect[0],self.sliderRect[1],self.sliderRect[2],self.sliderRect[3])
lordcrc@384
  6217
    def getTop(self):
lordcrc@384
  6218
        return self.viewHeight+self.position
lordcrc@384
  6219
    def scroll(self, delta):
lordcrc@384
  6220
        self.position = self.position + delta
lordcrc@384
  6221
        self.calcRects()
lordcrc@384
  6222
        Draw.Redraw()
lordcrc@384
  6223
    def Mouse(self):
lordcrc@384
  6224
        self.calcRects()
lordcrc@384
  6225
        coord, buttons = Window.GetMouseCoords(), Window.GetMouseButtons()
lordcrc@384
  6226
        over = (coord[0]>=self.winrect[0]+self.rect[0]) and (coord[0]<=self.winrect[0]+self.rect[2]) and \
lordcrc@384
  6227
               (coord[1]>=self.winrect[1]+self.rect[1]) and (coord[1]<=self.winrect[1]+self.rect[3])
lordcrc@384
  6228
        if Window.MButs.L and buttons > 0:
lordcrc@384
  6229
            if self.scrolling:
lordcrc@384
  6230
                if self.factor > 0: self.scroll((self.lastcoord[1]-coord[1])/self.factor)
lordcrc@384
  6231
                Draw.Redraw()
lordcrc@384
  6232
            elif self.over:
lordcrc@384
  6233
                self.scrolling = True
lordcrc@384
  6234
            self.lastcoord = coord
lordcrc@384
  6235
        elif self.scrolling:
lordcrc@384
  6236
            self.scrolling = False
lordcrc@384
  6237
            Draw.Redraw()
lordcrc@384
  6238
        if self.over != over: Draw.Redraw()
lordcrc@384
  6239
        self.over = over
lordcrc@384
  6240
lordcrc@384
  6241
scrollbar = scrollbar()
lordcrc@384
  6242
lordcrc@384
  6243
lordcrc@384
  6244
# gui main draw
lordcrc@384
  6245
def luxDraw():
lordcrc@384
  6246
    global icon_luxblend
lordcrc@384
  6247
lordcrc@384
  6248
    BGL.glClear(BGL.GL_COLOR_BUFFER_BIT)
lordcrc@384
  6249
lordcrc@384
  6250
    y = int(scrollbar.getTop()) # 420
lordcrc@384
  6251
    BGL.glColor3f(0.1,0.1,0.1); BGL.glRectf(0,0,440,y)
dade@423
  6252
    BGL.glColor3f(1.0,0.5,0.0); BGL.glRasterPos2i(130,y-21); Draw.Text("v%s"%__version__)
lordcrc@384
  6253
    BGL.glColor3f(0.9,0.9,0.9)
lordcrc@384
  6254
lordcrc@384
  6255
    drawLogo(icon_luxblend, 6, y-25)
lordcrc@384
  6256
lordcrc@384
  6257
    scn = Scene.GetCurrent()
lordcrc@384
  6258
    if scn:
lordcrc@384
  6259
        luxpage = luxProp(scn, "page", 0)
lordcrc@384
  6260
        gui = luxGui(y-70)
lordcrc@384
  6261
lordcrc@384
  6262
        # render presets
lordcrc@384
  6263
        BGL.glRasterPos2i(10,y-45); Draw.Text("Render presets:")
lordcrc@384
  6264
        luxpreset = luxProp(scn, "preset", "1C - Final - medium MLT/Path Tracing (indoor) (recommended)")
lordcrc@384
  6265
        presets = getScenePresets()
lordcrc@384
  6266
        presetskeys = presets.keys()
lordcrc@384
  6267
        presetskeys.sort()
lordcrc@384
  6268
        presetskeys.insert(0, "")
lordcrc@384
  6269
        presetsstr = "presets: %t"
lordcrc@384
  6270
        for i, v in enumerate(presetskeys): presetsstr = "%s %%x%d|%s"%(v, i, presetsstr)
lordcrc@384
  6271
        try: i = presetskeys.index(luxpreset.get())
lordcrc@384
  6272
        except ValueError: i = 0
lordcrc@384
  6273
        Draw.Menu(presetsstr, evtLuxGui, 110, y-50, 220, 18, i, "", lambda e,v: luxpreset.set(presetskeys[v]))
lordcrc@384
  6274
        Draw.Button("save", evtSavePreset, 330, y-50, 40, 18, "create a render-settings preset")
lordcrc@384
  6275
        Draw.Button("del", evtDeletePreset, 370, y-50, 40, 18, "delete a render-settings preset")
lordcrc@384
  6276
lordcrc@384
  6277
        # if preset is selected load values
lordcrc@384
  6278
        if luxpreset.get() != "":
lordcrc@384
  6279
            try:
lordcrc@384
  6280
                d = presets[luxpreset.get()]
lordcrc@384
  6281
                for k,v in d.items(): scn.properties['luxblend'][k] = v
lordcrc@384
  6282
            except: pass
lordcrc@384
  6283
lordcrc@384
  6284
        Draw.Button("Material", evtLuxGui, 10, y-70, 80, 16, "", lambda e,v:luxpage.set(0))
lordcrc@384
  6285
        Draw.Button("Cam/Env", evtLuxGui, 90, y-70, 80, 16, "", lambda e,v:luxpage.set(1))
lordcrc@384
  6286
        Draw.Button("Render", evtLuxGui, 170, y-70, 80, 16, "", lambda e,v:luxpage.set(2))
lordcrc@384
  6287
        Draw.Button("Output", evtLuxGui, 250, y-70, 80, 16, "", lambda e,v:luxpage.set(3))
lordcrc@384
  6288
        Draw.Button("System", evtLuxGui, 330, y-70, 80, 16, "", lambda e,v:luxpage.set(4))
lordcrc@384
  6289
        if luxpage.get() == 0:
lordcrc@384
  6290
            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
  6291
            obj = scn.objects.active
lordcrc@384
  6292
            if obj:
lordcrc@384
  6293
                if (obj.getType() == "Lamp"):
lordcrc@384
  6294
                    ltype = obj.getData(mesh=1).getType() # data
lordcrc@384
  6295
                    if (ltype == Lamp.Types["Area"]): luxLight("Area LIGHT", "", obj, gui, 0)
lordcrc@384
  6296
                    elif (ltype == Lamp.Types["Spot"]): luxSpot("Spot LIGHT", "", obj, gui, 0)
lordcrc@384
  6297
                    elif (ltype == Lamp.Types["Lamp"]): luxLamp("Point LIGHT", "", obj, gui, 0)
lordcrc@384
  6298
                else:
lordcrc@384
  6299
                    matfilter = luxProp(scn, "matlistfilter", "false")
lordcrc@384
  6300
                    mats = getMaterials(obj, True)
lordcrc@384
  6301
                    if (activemat == None) and (len(mats) > 0):
lordcrc@384
  6302
                        setactivemat(mats[0])
lordcrc@384
  6303
                    if matfilter.get() == "false":
lordcrc@384
  6304
                        mats = Material.Get()
lordcrc@384
  6305
                    matindex = 0
lordcrc@384
  6306
                    for i, v in enumerate(mats):
lordcrc@384
  6307
                        if v==activemat: matindex = i
lordcrc@384
  6308
                    matnames = [m.getName() for m in mats]
lordcrc@384
  6309
                    menustr = "Material: %t"
lordcrc@384
  6310
                    for i, v in enumerate(matnames): menustr = "%s %%x%d|%s"%(v, i, menustr)
lordcrc@384
  6311
                    gui.newline("MATERIAL:", 8) 
lordcrc@384
  6312
                    r = gui.getRect(1.1, 1)
lordcrc@384
  6313
                    Draw.Button("C", evtConvertMaterial, r[0]-gui.h, gui.y-gui.h, gui.h, gui.h, "convert blender material to lux material")
lordcrc@384
  6314
                    Draw.Menu(menustr, evtLuxGui, r[0], r[1], r[2], r[3], matindex, "", lambda e,v: setactivemat(mats[v]))
lordcrc@384
  6315
                    luxBool("", matfilter, "filter", "only show active object materials", gui, 0.5)
lordcrc@384
  6316
lordcrc@384
  6317
                    Draw.Button("L", evtLoadMaterial, gui.x, gui.y-gui.h, gui.h, gui.h, "load a material preset")
lordcrc@384
  6318
                    Draw.Button("S", evtSaveMaterial, gui.x+gui.h, gui.y-gui.h, gui.h, gui.h, "save a material preset")
lordcrc@384
  6319
                    Draw.Button("D", evtDeleteMaterial, gui.x+gui.h*2, gui.y-gui.h, gui.h, gui.h, "delete a material preset")
lordcrc@384
  6320
                    if len(mats) > 0:
lordcrc@384
  6321
                        setactivemat(mats[matindex])
lordcrc@384
  6322
                        luxMaterial(activemat, gui)
lordcrc@384
  6323
        if luxpage.get() == 1:
lordcrc@384
  6324
            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
  6325
            cam = scn.getCurrentCamera()
lordcrc@384
  6326
            if cam:
lordcrc@384
  6327
                r = gui.getRect(1.1, 1)
lordcrc@384
  6328
                luxCamera(cam.data, scn.getRenderingContext(), gui)
lordcrc@384
  6329
            gui.newline("", 10)
lordcrc@384
  6330
            luxEnvironment(scn, gui)
lordcrc@384
  6331
        if luxpage.get() == 2:
lordcrc@384
  6332
            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
  6333
            r = gui.getRect(1.1, 1)
lordcrc@384
  6334
            luxSampler(scn, gui)
lordcrc@384
  6335
            gui.newline("", 10)
lordcrc@384
  6336
            luxSurfaceIntegrator(scn, gui)
lordcrc@384
  6337
            gui.newline("", 10)
lordcrc@384
  6338
            luxVolumeIntegrator(scn, gui)
lordcrc@384
  6339
            gui.newline("", 10)
lordcrc@384
  6340
            luxPixelFilter(scn, gui)
lordcrc@384
  6341
        if luxpage.get() == 3:
lordcrc@384
  6342
            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
  6343
            r = gui.getRect(1.1, 1)
lordcrc@384
  6344
            luxFilm(scn, gui)
lordcrc@384
  6345
        if luxpage.get() == 4:
lordcrc@384
  6346
            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
  6347
            luxSystem(scn, gui)
lordcrc@384
  6348
            gui.newline("", 10)
lordcrc@384
  6349
            luxAccelerator(scn, gui)
lordcrc@384
  6350
            gui.newline("MATERIALS:", 10)
lordcrc@384
  6351
            r = gui.getRect(2,1)
lordcrc@384
  6352
            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
  6353
            gui.newline("SETTINGS:", 10)
lordcrc@384
  6354
            r = gui.getRect(2,1)
lordcrc@384
  6355
            Draw.Button("save defaults", 0, r[0], r[1], r[2], r[3], "save current settings as defaults", lambda e,v:saveluxdefaults())
lordcrc@384
  6356
        y = gui.y - 80
lordcrc@384
  6357
        if y > 0: y = 0 # bottom align of render button
lordcrc@384
  6358
        run = luxProp(scn, "run", "true")
lordcrc@384
  6359
        dlt = luxProp(scn, "default", "true")
lordcrc@384
  6360
        pipe = luxProp(scn, "pipe", "false")
lordcrc@384
  6361
        clay = luxProp(scn, "clay", "false")
lordcrc@384
  6362
        nolg = luxProp(scn, "nolg", "false")
lordcrc@384
  6363
        lxs = luxProp(scn, "lxs", "true")
lordcrc@384
  6364
        lxo = luxProp(scn, "lxo", "true")
lordcrc@384
  6365
        lxm = luxProp(scn, "lxm", "true")
lordcrc@384
  6366
        lxv = luxProp(scn, "lxv", "true")
lordcrc@384
  6367
        net = luxProp(scn, "netrenderctl", "false")
lordcrc@384
  6368
        donet = luxProp(scn, "donetrender", "true")
lordcrc@384
  6369
        
lordcrc@384
  6370
        global render_status_text
lordcrc@384
  6371
        global render_status
lordcrc@384
  6372
        
lordcrc@384
  6373
        if render_status == True:
lordcrc@384
  6374
            BGL.glRasterPos2i(10,y+20)
lordcrc@384
  6375
            Draw.Text(render_status_text)
lordcrc@384
  6376
        else:
lordcrc@384
  6377
            BGL.glRasterPos2i(10,y+5)
lordcrc@384
  6378
            Draw.Text(render_status_text, "tiny")
lordcrc@384
  6379
            
doug@410
  6380
            def check_pipe_def_exclusion(m, v):
doug@410
  6381
            	if m == 'd':
doug@410
  6382
            		dlt.set(["false","true"][bool(v)])
doug@410
  6383
            		
doug@410
  6384
            		if dlt.get() == 'true':
doug@410
  6385
            			pipe.set('false')
doug@410
  6386
            	elif m == 'p':
doug@410
  6387
            		pipe.set(["false","true"][bool(v)])
doug@410
  6388
            		
doug@410
  6389
            		if pipe.get() == 'true':
doug@410
  6390
            			dlt.set('false')
doug@410
  6391
            
lordcrc@384
  6392
            if (run.get()=="true"):
lordcrc@384
  6393
                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
  6394
                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
  6395
            else:
lordcrc@384
  6396
                Draw.Button("Export", 0, 10, y+20, 100, 36, "Export", lambda e,v:CBluxExport(dlt.get()=="true" or pipe.get()=="true", False))
lordcrc@384
  6397
                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
  6398
            
lordcrc@384
  6399
            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
  6400
            
lordcrc@384
  6401
            if (pipe.get() == 'false' and dlt.get() == 'true') or run.get()=='false':
doug@410
  6402
                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
  6403
            elif pipe.get() == 'true' and dlt.get() == 'false':
doug@410
  6404
                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
  6405
            else:
doug@410
  6406
                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
  6407
                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
  6408
            
lordcrc@384
  6409
            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
  6410
            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
  6411
            
lordcrc@384
  6412
            if pipe.get() == "false":
lordcrc@384
  6413
                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
  6414
                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
  6415
                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
  6416
                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
  6417
    
lordcrc@384
  6418
    BGL.glColor3f(0.9, 0.9, 0.9)
lordcrc@384
  6419
    
lordcrc@384
  6420
    BGL.glRasterPos2i(330,y+5) ; Draw.Text("Press Q or ESC to quit.", "tiny")
lordcrc@384
  6421
    scrollbar.height = scrollbar.getTop() - y
lordcrc@384
  6422
    scrollbar.draw()
lordcrc@384
  6423
lordcrc@384
  6424
render_status_text = ''
lordcrc@384
  6425
render_status = False
lordcrc@384
  6426
lordcrc@384
  6427
mouse_xr=1 
lordcrc@384
  6428
mouse_yr=1 
lordcrc@384
  6429
lordcrc@384
  6430
activeObject = None
lordcrc@384
  6431
activeEvent = None
lordcrc@384
  6432
lastEventTime = 0
lordcrc@384
  6433
key_tabs = {
lordcrc@384
  6434
    Draw.ONEKEY:     0,
lordcrc@384
  6435
    Draw.TWOKEY:     1,
lordcrc@384
  6436
    Draw.THREEKEY:   2,
lordcrc@384
  6437
    Draw.FOURKEY:    3,
lordcrc@384
  6438
    Draw.FIVEKEY:    4,
lordcrc@384
  6439
}
lordcrc@384
  6440
def luxEvent(evt, val):  # function that handles keyboard and mouse events
lordcrc@384
  6441
    global activeObject, activemat, activeEvent, lastEventTime, key_tabs
lordcrc@384
  6442
    if evt == Draw.ESCKEY or evt == Draw.QKEY:
lordcrc@384
  6443
        stop = Draw.PupMenu("OK?%t|Cancel export %x1")
lordcrc@384
  6444
        if stop == 1:
lordcrc@384
  6445
            Draw.Exit()
lordcrc@384
  6446
            return
lordcrc@384
  6447
    scn = Scene.GetCurrent()
lordcrc@384
  6448
    if scn:
lordcrc@384
  6449
        if scn.objects.active != activeObject:
lordcrc@384
  6450
            activeObject = scn.objects.active
lordcrc@384
  6451
            activemat = None
lordcrc@384
  6452
            Window.QRedrawAll()
lordcrc@384
  6453
    if (evt == Draw.MOUSEX) or (evt == Draw.MOUSEY): scrollbar.Mouse()
lordcrc@384
  6454
    if evt == Draw.WHEELUPMOUSE: scrollbar.scroll(-16)
lordcrc@384
  6455
    if evt == Draw.WHEELDOWNMOUSE: scrollbar.scroll(16)
lordcrc@384
  6456
    if evt == Draw.PAGEUPKEY: scrollbar.scroll(-50)
lordcrc@384
  6457
    if evt == Draw.PAGEDOWNKEY: scrollbar.scroll(50)
lordcrc@384
  6458
lordcrc@384
  6459
    # scroll to [T]op and [B]ottom
lordcrc@384
  6460
    if evt == Draw.TKEY:
lordcrc@384
  6461
        scrollbar.scroll(-scrollbar.position)
lordcrc@384
  6462
    if evt == Draw.BKEY:
lordcrc@384
  6463
        scrollbar.scroll(100000)   # Some large number should be enough ?!
lordcrc@384
  6464
lordcrc@384
  6465
    # R key shortcut to launch render
lordcrc@384
  6466
    # E key shortcut to export current scene (not render)
lordcrc@384
  6467
    # P key shortcut to preview current material
lordcrc@384
  6468
    # These keys need time and process-complete locks
lordcrc@384
  6469
    if evt in [Draw.RKEY, Draw.EKEY, Draw.PKEY]:
lordcrc@384
  6470
        if activeEvent == None and (sys.time() - lastEventTime) > 5:
lordcrc@384
  6471
            lastEventTime = sys.time()
lordcrc@384
  6472
            if evt == Draw.RKEY:
lordcrc@384
  6473
                activeEvent = 'RKEY'
lordcrc@384
  6474
                CBluxExport(luxProp(scn, "default", "true").get() == "true" or luxProp(scn, "pipe", "false").get() == "true", True)
lordcrc@384
  6475
                activeEvent = None
lordcrc@384
  6476
            if evt == Draw.EKEY:
lordcrc@384
  6477
                activeEvent = 'EKEY'
lordcrc@384
  6478
                CBluxExport(luxProp(scn, "default", "true").get() == "true" or luxProp(scn, "pipe", "false").get() == "true", False)
lordcrc@384
  6479
                activeEvent = None
lordcrc@384
  6480
            if evt == Draw.PKEY:
lordcrc@384
  6481
                activeEvent = 'PKEY'
lordcrc@384
  6482
                if activemat != None:
lordcrc@384
  6483
                    Preview_Update(activemat, '', True, 0, None, None, None)
lordcrc@384
  6484
                activeEvent = None
lordcrc@384
  6485
        
lordcrc@384
  6486
    # Switch GUI tabs with number keys
lordcrc@384
  6487
    if evt in key_tabs.keys():
lordcrc@384
  6488
        luxProp(scn, "page", 0).set(key_tabs[evt])        
lordcrc@384
  6489
        luxDraw()
lordcrc@384
  6490
        Window.QRedrawAll()
lordcrc@384
  6491
          
lordcrc@384
  6492
lordcrc@384
  6493
    # Handle icon button events - note - radiance - this is a work in progress! :)
lordcrc@384
  6494
#    if evt == Draw.LEFTMOUSE and not val: 
lordcrc@384
  6495
#           size=BGL.Buffer(BGL.GL_FLOAT, 4) 
lordcrc@384
  6496
#           BGL.glGetFloatv(BGL.GL_SCISSOR_BOX, size) 
lordcrc@384
  6497
#            size= [int(s) for s in size] 
lordcrc@384
  6498
#        mx, my = Window.GetMouseCoords()
lordcrc@384
  6499
#        mousex = mx - size[0]
lordcrc@384
  6500
#        print("mousex = %i"%mousex)
lordcrc@384
  6501
#        #if((mousex > 2) and (mousex < 25)):
lordcrc@384
  6502
#            # Mouse clicked in left button bar
lordcrc@384
  6503
#        if((mousex > 399) and (mousex < 418)):
lordcrc@384
  6504
#            # Mouse clicked in right button bar
lordcrc@384
  6505
#            mousey = my - size[1] - scrollbar.position
lordcrc@384
  6506
#            print("mousey = %i"%mousey)
lordcrc@384
  6507
            
lordcrc@384
  6508
    
lordcrc@384
  6509
def luxButtonEvt(evt):  # function that handles button events
lordcrc@384
  6510
    global usedproperties, usedpropertiesfilterobj
lordcrc@384
  6511
    if evt == evtLuxGui:
lordcrc@384
  6512
        Draw.Redraw()
lordcrc@384
  6513
    if evt == evtSavePreset:
lordcrc@384
  6514
        scn = Scene.GetCurrent()
lordcrc@384
  6515
        if scn:
lordcrc@384
  6516
            name = Draw.PupStrInput("preset name: ", "")
lordcrc@384
  6517
            if name != "":
lordcrc@384
  6518
                usedproperties = {}
lordcrc@384
  6519
                usedpropertiesfilterobj = None
lordcrc@384
  6520
                luxSurfaceIntegrator(scn)
lordcrc@384
  6521
                luxSampler(scn)
lordcrc@384
  6522
                luxPixelFilter(scn)
lordcrc@384
  6523
                # luxFilm(scn)
lordcrc@384
  6524
                luxAccelerator(scn)
lordcrc@384
  6525
                # luxEnvironment(scn)
lordcrc@384
  6526
                saveScenePreset(name, usedproperties.copy())
lordcrc@384
  6527
                luxProp(scn, "preset", "").set(name)
lordcrc@384
  6528
                Draw.Redraw()
lordcrc@384
  6529
    if evt == evtDeletePreset:
lordcrc@384
  6530
        presets = getScenePresets().keys()
lordcrc@384
  6531
        presets.sort()
lordcrc@384
  6532
        presetsstr = "delete preset: %t"
lordcrc@384
  6533
        for i, v in enumerate(presets): presetsstr += "|%s %%x%d"%(v, i)
lordcrc@384
  6534
        r = Draw.PupMenu(presetsstr, 20)
lordcrc@384
  6535
        if r >= 0:
lordcrc@384
  6536
            saveScenePreset(presets[r], None)
lordcrc@384
  6537
            Draw.Redraw()
lordcrc@384
  6538
lordcrc@384
  6539
    if evt == evtLoadMaterial:
lordcrc@384
  6540
        if activemat:
lordcrc@384
  6541
            mats = getMaterialPresets()
lordcrc@384
  6542
            matskeys = mats.keys()
lordcrc@384
  6543
            matskeys.sort()
lordcrc@384
  6544
            matsstr = "load preset: %t"
lordcrc@384
  6545
            for i, v in enumerate(matskeys): matsstr += "|%s %%x%d"%(v, i)
lordcrc@384
  6546
            r = Draw.PupMenu(matsstr, 20)
lordcrc@384
  6547
            if r >= 0:
lordcrc@384
  6548
                name = matskeys[r]
lordcrc@384
  6549
                try:
lordcrc@384
  6550
#                    for k,v in mats[name].items(): activemat.properties['luxblend'][k] = v
lordcrc@384
  6551
                    for k,v in mats[name].items(): luxProp(activemat, k, None).set(v)
lordcrc@384
  6552
                except: pass
lordcrc@384
  6553
                Draw.Redraw()
lordcrc@384
  6554
    if evt == evtSaveMaterial:
lordcrc@384
  6555
        if activemat:
lordcrc@384
  6556
            name = Draw.PupStrInput("preset name: ", "")
lordcrc@384
  6557
            if name != "":
lordcrc@384
  6558
                usedproperties = {}
lordcrc@384
  6559
                usedpropertiesfilterobj = activemat
lordcrc@384
  6560
                luxMaterial(activemat)
lordcrc@384
  6561
                saveMaterialPreset(name, usedproperties.copy())
lordcrc@384
  6562
                Draw.Redraw()
lordcrc@384
  6563
    if evt == evtDeleteMaterial:
lordcrc@384
  6564
        matskeys = getMaterialPresets().keys()
lordcrc@384
  6565
        matskeys.sort()
lordcrc@384
  6566
        matsstr = "delete preset: %t"
lordcrc@384
  6567
        for i, v in enumerate(matskeys): matsstr += "|%s %%x%d"%(v, i)
lordcrc@384
  6568
        r = Draw.PupMenu(matsstr, 20)
lordcrc@384
  6569
        if r >= 0:
lordcrc@384
  6570
            saveMaterialPreset(matskeys[r], None)
lordcrc@384
  6571
            Draw.Redraw()
lordcrc@384
  6572
    if evt == evtConvertMaterial:
lordcrc@384
  6573
        if activemat: convertMaterial(activemat)
lordcrc@384
  6574
        Draw.Redraw()
lordcrc@384
  6575
    if evt == evtLoadMaterial2:
lordcrc@384
  6576
        if activemat:
lordcrc@384
  6577
            scn = Scene.GetCurrent()
lordcrc@384
  6578
            Window.FileSelector(lambda fn:loadMatTex(activemat, fn), "load material", luxProp(scn, "lux", "").get()+os.sep+".lbm")
lordcrc@384
  6579
    if evt == evtSaveMaterial2:
lordcrc@384
  6580
        if activemat:
lordcrc@384
  6581
            scn = Scene.GetCurrent()
lordcrc@384
  6582
            Window.FileSelector(lambda fn:saveMaterial(activemat, fn), "save material", luxProp(scn, "lux", "").get()+os.sep+".lbm")
lordcrc@384
  6583
    
lordcrc@384
  6584
lordcrc@384
  6585
def setFocus(target):
lordcrc@384
  6586
    currentscene = Scene.GetCurrent()
lordcrc@384
  6587
    camObj = currentscene.objects.camera # currentscene.getCurrentCamera()
lordcrc@384
  6588
    if target == "S":
lordcrc@384
  6589
        try:
lordcrc@384
  6590
            refLoc = (Object.GetSelected()[0]).getLocation()
lordcrc@384
  6591
        except:
lordcrc@384
  6592
            print("select an object to focus\n")
lordcrc@384
  6593
    elif target == "C":
lordcrc@384
  6594
        refLoc = Window.GetCursorPos()
lordcrc@384
  6595
    else:
lordcrc@384
  6596
        refLoc = (Object.Get(target)).getLocation()
lordcrc@384
  6597
    dist = Mathutils.Vector(refLoc) - Mathutils.Vector(camObj.getLocation())
lordcrc@384
  6598
    camDir = camObj.getMatrix()[2]*(-1.0)
lordcrc@384
  6599
    camObj.getData(mesh=1).dofDist = (camDir[0]*dist[0]+camDir[1]*dist[1]+camDir[2]*dist[2])/camDir.length # data
lordcrc@384
  6600
lordcrc@384
  6601
lordcrc@384
  6602
# Parse command line arguments for batch mode rendering if supplied
lordcrc@384
  6603
lordcrc@384
  6604
try:
lordcrc@384
  6605
    batchindex = osys.argv.index('--batch')
lordcrc@384
  6606
    pyargs = osys.argv[osys.argv.index('--batch')+1:]
lordcrc@384
  6607
except: pyargs = []
lordcrc@384
  6608
lordcrc@384
  6609
if (pyargs != []) and (batchindex != 0):
dade@423
  6610
    print("\n\nLuxBlend v%s - BATCH mode\n"%__version__)
lordcrc@384
  6611
    LuxIsGUI = False
lordcrc@384
  6612
lordcrc@384
  6613
    scene = Scene.GetCurrent()
lordcrc@384
  6614
    context = scene.getRenderingContext()
lordcrc@384
  6615
lordcrc@384
  6616
    luxpath = ""
lordcrc@384
  6617
    import getopt
lordcrc@384
  6618
    o, a = getopt.getopt(pyargs, 's:e:o:t:l:',["scale=","haltspp=","run=", "lbm=", "lbt="])
lordcrc@384
  6619
lordcrc@384
  6620
    opts = {}
lordcrc@384
  6621
    for k,v in o:
lordcrc@384
  6622
        opts[k] = v
lordcrc@384
  6623
lordcrc@384
  6624
    if (opts.has_key('--run')) and (opts['--run'] == 'false'):
lordcrc@384
  6625
        print("Run: false")
lordcrc@384
  6626
        luxProp(scene, "run", "true").set("false")
lordcrc@384
  6627
    else:
lordcrc@384
  6628
        luxProp(scene, "run", "true").set("true")
lordcrc@384
  6629
lordcrc@384
  6630
    if opts.has_key('--scale'):
lordcrc@384
  6631
        print("Zoom: %s" %opts['--scale'])
lordcrc@384
  6632
        luxProp(scene, "film.scale", "100 %").set(opts['--scale'])
lordcrc@384
  6633
lordcrc@384
  6634
    if opts.has_key('--haltspp'):
lordcrc@384
  6635
        print("haltspp: %s" %opts['--haltspp'])
lordcrc@384
  6636
        luxProp(scene, "haltspp", 0).set(int(opts['--haltspp']))
lordcrc@384
  6637
lordcrc@384
  6638
    if opts.has_key('-s'):
lordcrc@384
  6639
        print("Start frame: %s" %opts['-s'])
lordcrc@384
  6640
        context.startFrame(int(opts['-s']))
lordcrc@384
  6641
    else:
lordcrc@384
  6642
        print("Error: Start frame not supplied (-s)"); osys.exit(1)
lordcrc@384
  6643
    if opts.has_key('-e'):
lordcrc@384
  6644
        print("End frame: %s" %opts['-e'])
lordcrc@384
  6645
        context.endFrame(int(opts['-e']))
lordcrc@384
  6646
    else:
lordcrc@384
  6647
        print("Error: End frame not supplied (-e)"); osys.exit(1)
lordcrc@384
  6648
    if opts.has_key('-l'):
lordcrc@384
  6649
        print("Path to lux binary: %s" %opts['-l'])
lordcrc@384
  6650
        luxbatchconsolemode = luxProp(scene, "luxbatchc", "false")
lordcrc@384
  6651
        luxbatchconsolemode.set("true")
lordcrc@384
  6652
        luxpathprop = luxProp(scene, "lux", "")
lordcrc@384
  6653
        luxpathprop.set(opts['-l'])
lordcrc@384
  6654
    else:
lordcrc@384
  6655
        print("Error: path to lux binary not supplied (-l)"); osys.exit(1)
lordcrc@384
  6656
    if opts.has_key('-o'):
lordcrc@384
  6657
        print("Image output path: %s" %opts['-o'])
lordcrc@384
  6658
        luxProp(scene, "overrideoutputpath", "").set(opts['-o'])
lordcrc@384
  6659
    else:
lordcrc@384
  6660
        print("Error: image output path not supplied (-o)"); osys.exit(1)
lordcrc@384
  6661
    if opts.has_key('-t'):
lordcrc@384
  6662
        print("Temporary export path: %s" %opts['-t'])
lordcrc@384
  6663
        luxProp(scene, "datadir", "").set(opts['-t'])
lordcrc@384
  6664
    else:
lordcrc@384
  6665
        print("Error: Temporary export path not supplied (-t)"); osys.exit(1)
lordcrc@384
  6666
    
lordcrc@384
  6667
    if opts.has_key('--lbm'):
lordcrc@384
  6668
        print("Load material: %s" %opts['--lbm'])
lordcrc@384
  6669
        mat = Material.Get("Material")
lordcrc@384
  6670
        if mat: loadMatTex(mat, opts['--lbm'])
lordcrc@384
  6671
        else:
lordcrc@384
  6672
            print("Error: No material with name \"Material\" found (--lbm)"); osys.exit(1)
lordcrc@384
  6673
            
lordcrc@384
  6674
    if opts.has_key('--lbt'):
lordcrc@384
  6675
        print("Load material: %s" %opts['--lbt'])
lordcrc@384
  6676
        mat = Material.Get("Material")
lordcrc@384
  6677
        if mat: loadMatTex(mat, opts['--lbt'], ':Kd')
lordcrc@384
  6678
        else:
lordcrc@384
  6679
            print("Error: No material with name \"Material\" found (--lbt)"); osys.exit(1)
lordcrc@384
  6680
lordcrc@384
  6681
#    CBluxAnimExport(True, True)
lordcrc@384
  6682
    CBluxAnimExport(True, True, False) # as by zukazuka (http://www.luxrender.net/forum/viewtopic.php?f=11&t=1288)
lordcrc@384
  6683
    osys.exit(0)
lordcrc@384
  6684
lordcrc@384
  6685
else:
dade@423
  6686
    print("\n\nLuxBlend v%s - UI mode\n"%__version__)
lordcrc@384
  6687
    from Blender.Window import DrawProgressBar
lordcrc@384
  6688
    LuxIsGUI = True
lordcrc@384
  6689
    
lordcrc@384
  6690
    Draw.Register(luxDraw, luxEvent, luxButtonEvt) # init GUI
lordcrc@384
  6691
lordcrc@384
  6692
    luxpathprop = luxProp(Scene.GetCurrent(), "lux", "")
lordcrc@384
  6693
    luxpath = luxpathprop.get()
lordcrc@384
  6694
    luxrun = luxProp(Scene.GetCurrent(), "run", True).get()
lordcrc@384
  6695
    checkluxpath = luxProp(Scene.GetCurrent(), "checkluxpath", True).get()
lordcrc@384
  6696
lordcrc@384
  6697
    if checkluxpath and luxrun:
lordcrc@384
  6698
        if (luxpath is None) or (sys.exists(luxpath)<=0):
doug@411
  6699
            # luxpath not valid, so delete entry from .blend scene file
lordcrc@384
  6700
            luxpathprop.delete()
lordcrc@384
  6701
            # and re-get luxpath, so we get the path from default-settings
lordcrc@384
  6702
            luxpath = luxpathprop.get()
doug@411
  6703
            #
tom@412
  6704
            LUXRENDER_ROOT = os.getenv('LUXRENDER_ROOT')
doug@411
  6705
            if LUXRENDER_ROOT is not None:
tom@413
  6706
                LUXRENDER_ROOT = LUXRENDER_ROOT + os.sep
doug@411
  6707
                luxpathprop.set(LUXRENDER_ROOT)
doug@411
  6708
                luxpath = LUXRENDER_ROOT
doug@411
  6709
                if sys.exists(luxpath)>0:
doug@411
  6710
                    print('LuxRender path set from LUXRENDER_ROOT environment variable')
doug@411
  6711
                    saveluxdefaults()
doug@411
  6712
            
lordcrc@384
  6713
            if (luxpath is None) or (sys.exists(luxpath)<=0):
lordcrc@384
  6714
                print("WARNING: LuxPath \"%s\" is not valid\n"%(luxpath))
lordcrc@384
  6715
                scn = Scene.GetCurrent()
lordcrc@384
  6716
                if scn:
lordcrc@384
  6717
                    r = Draw.PupMenu("Installation: Set path to the lux render software?%t|Yes%x1|No%x0|Never%x2")
lordcrc@384
  6718
                    if r == 1:
lordcrc@384
  6719
                        Window.FileSelector(lambda s:luxProp(scn, "lux", "").set(Blender.sys.dirname(s)+os.sep), "Select file in Lux path")
lordcrc@384
  6720
                        saveluxdefaults()
lordcrc@384
  6721
                    if r == 2:
lordcrc@384
  6722
                        newluxdefaults["checkluxpath"] = False
lordcrc@384
  6723
                        saveluxdefaults()
lordcrc@384
  6724
    else    :
jeanphi@439
  6725
        print("Lux path check disabled\n")