#--------------------------------------------------------------------
#   Primitive tsxPython (ptsxpy) sample script for trueSpace (tS)
#                         Material and Shader 1
#           (Emulation of the sample script in the SDK)
# $Id: material1_1a.py 89 2021-03-25 10:23:23Z 3DfromNULL $
#--------------------------------------------------------------------

import ptsxpy as p
import ptsxgp
#import os

def correct_unicode1( s1 ):
    s2 = ""
    for i in range( len( s1 ) ):
        o1 = ord( s1[ i ] )
        # Japanese halfwidth katakana
        if o1 >= 0xa1 and o1 <= 0xdf:
            s2 = s2 + chr( o1 - 0xa1 + 0xff61 )
        else:
            s2 = s2 + s1[ i ]
    return s2


#----------
# Get material info
#----------
def getmateinfo1( title, mat ):
    wk1 = CharArray( 1000 )
    s1 = String_p( wk1.p )
    print( "---------------", title )
    print( "mat=0x%08x" % mat )
    tt1 = p.MaterialGetTextureType( mat )
    print( "tex type=", tt1 )
    p.MaterialGetTextureFilename( mat, s1.p, 1000 )
    print( "s1.p=0x%08x %02x %02x %02x %02x ..." % (
     s1.p,
     ptsxgp.loaduchar( s1.p + 0 ),
     ptsxgp.loaduchar( s1.p + 1 ),
     ptsxgp.loaduchar( s1.p + 2 ),
     ptsxgp.loaduchar( s1.p + 3 ) ) )
    print( "s1=", s1.prt() )
    shtype1 = p.MaterialGetShadingType( mat )
    print( "shtype1=", shtype1, "(",
      "tsxSHADER_FLAT"  if shtype1 == 1 else
      "tsxSHADER_PHONG" if shtype1 == 2 else
      "tsxSHADER_METAL" if shtype1 == 4 else
      "undefined", ")" )
    # shader class tsxSHCLASS_xxxx
    shclsnams = (
     "tsxSHCLASS_UNDEFINED",
     "tsxSHCLASS_COLOR",
     "tsxSHCLASS_TRANSPARENCY",
     "tsxSHCLASS_REFLECTANCE",
     "tsxSHCLASS_DISPLACEMENT",
     "tsxSHCLASS_FOREGROUND",
     "tsxSHCLASS_BACKGROUND",
     "tsxSHCLASS_POSTPROCESS",
     "tsxSHCLASS_TONEMAPPING" )
    shparam_typenames = ( # tsxSHPARAM_xxxx
     "tsxSHPARAM_UNDEFINED",  # Undefined type
     "tsxSHPARAM_BOOL",       # compatible with bool
     "tsxSHPARAM_BYTE",       # compatible with unsigned char
     "tsxSHPARAM_SHORT",      # compatible with short
     "tsxSHPARAM_LONG",       # compatible with long
     "tsxSHPARAM_WORD",       # compatible with unsigned short
     "tsxSHPARAM_DWORD",      # compatible with unsigned long
     "tsxSHPARAM_FLOAT",      # compatible with float
     "tsxSHPARAM_DOUBLE",     # compatible with double
     "tsxSHPARAM_STRING",     # compatible with char*
     "tsxSHPARAM_VECTOR",     # compatible with float[3]
     "tsxSHPARAM_POINT",      # compatible with float[3]
     "tsxSHPARAM_COLOR",      # compatible with float[3]
     "tsxSHPARAM_COLOR4",     # compatible with float[4]
     "tsxSHPARAM_SHINFO",     # compatible with void*
     "tsxSHPARAM_GENERIC",
     "tsxSHPARAM_ENUM" )      # compatible with unsigned long
    wk1 = CharArray( 1000 )
    wk2 = CharArray( 1000 )
    for j in range( 9 ):
        print( "---- shader class %d (%s)" % ( j, shclsnams[ j ] ) )

        sh1 = p.ShaderGetActive( j )
        if sh1 == 0:
            print( "sh1=0" )
        else:
            shnam0 = p.ShaderGetInternalName( sh1 )
            print( "sh1=0x%08x, [%s]" % ( sh1, shnam0 ) )
            sid = p.ShaderGetID( sh1 )
            print( "sid=", sid )
            #sty = p.GetShadingTypeFromShader( sh1 )
            #print( "sty=", sty )
            scl1 = p.ShaderGetClass( sh1 )
            print( "scl1=", scl1 )

        si1 = p.MaterialGetShaderInfo( mat, j ) # shader info of each class
        print( "si1=0x%08x" % si1 )
        if si1 == 0:
            continue
        #cl1 = p.ShaderInfoGetClass( si1 ) # test
        #print( "cl1=", cl1 )              # test
        nsi = p.ShaderInfoGetParametersNumber( si1 )
        print( "num of param=", nsi )
        for i in range( nsi ):
            if tscode > 43:
                spnam1 = p.ShaderInfoGetConstParameterName( si1, i )
            else:
                #spnam1 = String_p( wk1.p )
                #spnam1 = p.ShaderInfoGetParameterName( si1, i, spnam1.p )
                ret = p.ShaderInfoGetParameterName( si1, i, wk1.p )
                spnam1 = String_p( wk1.p ).get()
            spvalp1 = p.ShaderInfoGetParameterValue( si1, i )
            sptyp1 = p.ParameterValueGetType( spvalp1 )
            ret = p.ParameterValueGetTypedValue( spvalp1, sptyp1, wk2.p  )
            if ret == e_tsxFALSE:
                print( "i=%d, sptyp1=%d, spvalp1=0x%08x ### error: ParameterValueGetTypedValue() returned e_tsxFALSE ###" % ( i, sptyp1, spvalp1 ) )
                # continuing
            if   sptyp1 == tsxSHPARAM_UNDEFINED:
                val = "(undefined)"
            elif   sptyp1 == tsxSHPARAM_BOOL:
                val = "0x%08x" % ptsxgp.loadulong( wk2.p )
            elif   sptyp1 == tsxSHPARAM_BYTE:
                val = ptsxgp.loaduchar( wk2.p )
            elif   sptyp1 == tsxSHPARAM_SHORT:
                val = ptsxgp.loadshort( wk2.p )
            elif   sptyp1 == tsxSHPARAM_LONG:
                val = ptsxgp.loadlong( wk2.p )
            elif   sptyp1 == tsxSHPARAM_WORD:
                val = ptsxgp.loadushort( wk2.p )
            elif   sptyp1 == tsxSHPARAM_DWORD:
                val = "0x%08x" % ptsxgp.loadulong( wk2.p )
            elif sptyp1 == tsxSHPARAM_FLOAT:
                val = ptsxgp.loadfloat( wk2.p )
            elif sptyp1 == tsxSHPARAM_DOUBLE:
                val = ptsxgp.loaddouble( wk2.p )
            elif sptyp1 == tsxSHPARAM_STRING:
                # not a pointer to a string but 4 bytes of "char **"
                val = String_p( ptsxgp.loadulong( wk2.p ) ).get()
            elif sptyp1 == tsxSHPARAM_VECTOR or \
                 sptyp1 == tsxSHPARAM_POINT:
                val = Vec3f_p( wk2.p ).get()
            elif sptyp1 == tsxSHPARAM_COLOR:
                #val = "%02x %02x %02x %02x  %02x %02x %02x %02x  %02x %02x %02x %02x" % (
                # ptsxgp.loaduchar( wk2.p + 0 ),
                # ptsxgp.loaduchar( wk2.p + 1 ),
                # ptsxgp.loaduchar( wk2.p + 2 ),
                # ptsxgp.loaduchar( wk2.p + 3 ),
                # ptsxgp.loaduchar( wk2.p + 4 ),
                # ptsxgp.loaduchar( wk2.p + 5 ),
                # ptsxgp.loaduchar( wk2.p + 6 ),
                # ptsxgp.loaduchar( wk2.p + 7 ),
                # ptsxgp.loaduchar( wk2.p + 8 ),
                # ptsxgp.loaduchar( wk2.p + 9 ),
                # ptsxgp.loaduchar( wk2.p + 10 ),
                # ptsxgp.loaduchar( wk2.p + 11 ) ) # for check
                vec1 = Vec3f_p( wk2.p )
                val = str( vec1.get() ) + \
                  " (%d,%d,%d)" % \
                  ( 255 * vec1.x(), 255 * vec1.y(), 255 * vec1.z() )
            elif sptyp1 == tsxSHPARAM_COLOR4:
                vec1 = Vec3f_p( wk2.p )
                r,g,b,a = \
                 vec1.x(), vec1.y(), vec1.z(), \
                 ptsxgp.loadfloat( wk2.p + 3 * sizeof_float )
                val = "(%f, %f, %f, %f) (%d,%d,%d)" % \
                 ( r, g, b, a, 255 * r, 255 * g, 255 * b, 255 * a )
            elif sptyp1 == tsxSHPARAM_SHINFO:
                val = "0x%08x" % ptsxgp.loadulong( wk2.p )
            elif sptyp1 == tsxSHPARAM_GENERIC:
                val = "%02x %02x %02x %02x ..." % (
                 ptsxgp.loaduchar( s1.p + 0 ),
                 ptsxgp.loaduchar( s1.p + 1 ),
                 ptsxgp.loaduchar( s1.p + 2 ),
                 ptsxgp.loaduchar( s1.p + 3 ) )
            elif sptyp1 == tsxSHPARAM_ENUM:
                val = "0x%08x" % ptsxgp.loadulong( wk2.p )
            else:
                val = "(unknown type)"
            print( "%3d 0x%08x %2d=%-10s %-18s" % ( i, spvalp1, sptyp1, shparam_typenames[ sptyp1 ] , spnam1 ), val )
            #
            sw1 = p.ParameterValueIsShaderInfo( spvalp1 )
            if sw1:
                print( "linked to another sheder info" )
                si2 = p.ParameterValueGetShaderInfo( spvalp1 )
                print( "si2=0x%08x" % si2 )
    print( "---------------" )


#----------
# Set material by an internal name pre-defined by tS.
#----------
def setmatebyshname( mattitle, mat, sh_internalname ):
    sh1 = search_shader( sh_internalname )
    if sh1 == 0:
        print( sh_internalname, " - Unknown shader internal name." )
        stop #### unknown shader internal name ####
    if tscode > 43: # tS5, tS6 (Model side of tS7)
        p.SetMaterialShaderByName( mat, sh_internalname )
    else: # tS4.3
        #--
        # In case of texture mapping, doing p.ShaderSelect( sh1 ) here may
        # let you paint an object in tS view pane using PolyhPaint() but
        # but it will peel off at rendering because shderinfo parameters
        # (number of values and each value) have not been changed according
        # to the shader. A few steps below link the shader to the material
        # editor with right shaderinfo parameters.
        #--
        scl1 = p.ShaderGetClass( sh1 )
        sic1 = p.MaterialGetShaderInfo( mat, scl1 ) # color shader
        print( "sic1=", sic1 )
        p.ShaderInfoSetShader( sic1, sh1 )
        #--
        # The shaderinfo sic1 and shader sh1 have already been linked to the
        # material mt1, At this time, don't do;
        #   p.MaterialSetShaderInfo( mat, sic1 )
        # It will set the number of shaderinfo to zero and you get an
        # unexpected materisl when you pick using the dropper tool.
        #--


#----------
# Search the default image file
#----------
def getdefaultimgfile():
    fnam1 = "CALIGARI.JPG"
    s1 = String_p( ptsxgp.getdlldir() )
    print( "s1=", s1.get() )
    if ptsxgp.getpymjrver() == 3:
        pos1 = s1.get().casefold().find( "\\tsx\\" )
    else:
        wks1 = s1.get()
        pos1 = wks1.find( "\\tsx\\" )         # tS7
        if pos1 == -1:
            pos1 = wks1.find( "\\Tsx\\" )     # tS5
            if pos1 == -1: 
                pos1 = wks1.find( "\\TSX\\" ) # tS4 default
                if pos1 == -1: 
                    stop ### dll path does not include the name "tsx".
    return s1.get()[0:pos1] + "\\TEXTURES\\" + fnam1

    #  If you use GetTSDir(), you need to take care of multiple paths
    # delimited by semicolon in texture path (see tSxAPI doc) and check
    # existence of the file.
    # The code using "os" module might be something like below.
    #
    #dir1 = p.GetTSDir( e_tsxPATH_TEXTURE )
    #lst1 = dir1.split( sep=";", maxsplit=100 )
    #fulltex1 = ""
    #for i in range( len( lst1 ) ):
    #    print( "i=", i, ", ", lst1[ i ] )
    #    lst2 = os.listdir( path=dir1 )
    #    if fnam1 in lst2:
    #        fulltex1 = dir1 + fnam1
    #        break
    #if fulltex1 == "":
    #    print( fnam1, " not found." )
    #    stop ### not found ###
    #print( "fulltex1=", fulltex1 )
    #return fulltex1

#----------
# Searches for a shader by internal name and return its pointer.
# ( SetMaterialShaderByName() alternative for tS4 )
#
# Lists internal name of all shaders if argument is empty string.
#----------
def search_shader( sh_internalname ):
    listonly = 1 if sh_internalname == "" else 0
    sh1 = p.ShaderGetFirst()
    shnam1 = ""
    for i in range( 1000 ):
        shnam1 = p.ShaderGetInternalName( sh1 )
        if listonly:
            print( "i=%3d %-15s" % ( i, shnam1 ) )
            #shnam2 = p.ShaderGetName( sh1 ) # decode needed depending on system
            #print( "shnam2=", shnam2 )      # decode needed depending on system
        else:
            if shnam1 == sh_internalname:
                break
        sh1 = p.ShaderGetNext( sh1 )
        if sh1 == NULL: # There is no next path.
            break
    if listonly:
        return 0
    if shnam1 == "":
        return 0  # not found
    return sh1

def getparap( mat, sh_cls, para_name ):
    si1 = p.MaterialGetShaderInfo( mat, sh_cls ) # shader info of each class
    if si1 == 0:
        print( "getparap(), The material does not have the class,", sh_cls )
        stop ### the material does not have the class ###
    nsi = p.ShaderInfoGetParametersNumber( si1 )
    wk1 = CharArray( 1000 )
    found = 0
    for i in range( nsi ):
        if tscode > 43:
            spnam1 = p.ShaderInfoGetConstParameterName( si1, i )
        else:
            #spnam1 = String_p( wk1.p )
            #ret = p.ShaderInfoGetParameterName( si1, i, spnam1.p )
            ret = p.ShaderInfoGetParameterName( si1, i, wk1.p )
            spnam1 = String_p( wk1.p ).get()
        #print( "i=", i, "spnam1=[%s]" % spnam1 )
        if spnam1 == para_name:
            found = 1
            break
    #print( "found=", found )
    if not found:
        print( "parameter name [%s] not found" % para_name )
        stop #### parameter name not found ####
    #print( "para_name=", para_name, ", index=", i )
    valp = p.ShaderInfoGetParameterValue( si1, i )
    return valp

#----------
# Set shader parameter value by name
#
#  If it's not necessary to check the name, you can simply alternate like;
#
# f1 = Float( 0.06 )
# p.ParameterValueSetData(
#  getparap( mat1, shcls, "ambient factor" ), f1.p ) # no problem
#
#  But please note that following code causes unexpected or indeterminable
# result because the pointer of the class instance could be deleted by
# destructor soon.
#
# p.ParameterValueSetData(
#  getparap( mat1, shcls, "ambient factor" ), Float( 0.06 ).p ) # wrong
#----------
def set1( mat, shcls, paraname, val ):
    spvalp1 = getparap( mat, shcls, paraname )
    sptyp1 = p.ParameterValueGetType( spvalp1 )
    if   sptyp1 == tsxSHPARAM_UNDEFINED:
        print( "set1() cannot set to undefined type parameter.  mat=0x%08x, shcls=%d, paraname=%s, val=%s, spvalp1=0x%08x" % ( mat, shcls, paraname, str( val ), spvalp1 ) )
        stop ## undefined type parameter ##
    elif   sptyp1 == tsxSHPARAM_BOOL:
        wk1 = Ulong( val )
    elif   sptyp1 == tsxSHPARAM_BYTE:
        wk1 = CharArray( 1 )
        ptsxgp.storeuchar( wk1.p, val )
    elif   sptyp1 == tsxSHPARAM_SHORT:
        wk1 = Short( val )
    elif   sptyp1 == tsxSHPARAM_LONG:
        wk1 = Long( val )
    elif   sptyp1 == tsxSHPARAM_WORD:
        wk1 = Ushort( val )
    elif   sptyp1 == tsxSHPARAM_DWORD:
        wk1 = Ulong( val )
    elif sptyp1 == tsxSHPARAM_FLOAT:
        wk1 = Float( val )
    elif sptyp1 == tsxSHPARAM_DOUBLE:
        wk1 = Double( val )
    elif sptyp1 == tsxSHPARAM_STRING:
        # val must be not a pointer to a string but 4 bytes of "char **"
        wk1 = Ulong( val )
    elif sptyp1 == tsxSHPARAM_VECTOR or \
         sptyp1 == tsxSHPARAM_POINT:
        wk1 = Vec3f( val[ 0 ], val[ 1 ], val[ 2 ] )
    elif sptyp1 == tsxSHPARAM_COLOR:
        wk1 = Vec3f( val[ 0 ] / 255. , val[ 1 ] / 255. , val[ 2 ] / 255.  )
        print( "color wk1=", wk1.prt() )
    elif sptyp1 == tsxSHPARAM_COLOR4:
        wk1 = FloatColor(
         val[ 0 ] / 255. , val[ 1 ] / 255. , val[ 2 ] / 255., val[ 3 ] / 255.  )
    elif sptyp1 == tsxSHPARAM_SHINFO:
        wk1 = Ulong( val )
    elif sptyp1 == tsxSHPARAM_GENERIC:
        print( "set1() does not support generic type parameter. mat=0x%08x, shcls=%d, paraname=%s, val=%s, spvalp1=0x%08x" % ( mat, shcls, paraname, str( val ), spvalp1 ) )
        stop ## generic type parameter ##
    elif sptyp1 == tsxSHPARAM_ENUM:
        wk1 = Ulong( val )
    else:
        print( "set1() unknown parameter type.  mat=0x%08x, shcls=%d, paraname=%s, val=%s, spvalp1=0x%08x" % ( mat, shcls, paraname, str( val ), spvalp1 ) )
        stop ## unknown parameter ##
    p.ParameterValueSetData( spvalp1, wk1.p )


#----------
# Main
#----------

# List all shaders (just for information)
search_shader( "" )

#----
# Backup the current material in the material editor
#----
wki0 = Ulong()
ret = p.MaterialCreateCopyActive( wki0.p )
print( "ret=", ret )
mat_sv = wki0.get()
getmateinfo1( "mat_sv", mat_sv ) #--- for check ---

# List of materials (for deleting)
matlist1 = []

#----
# Material 1
#----
# Make a new material
wki1 = Ulong()
p.MaterialCreate( wki1.p )
mat1 = wki1.get()
# Select a texture shader as active shader of the material editor.
setmatebyshname( "mat1", mat1, "caligari texture" ) # color shader
# Set a texture file to (the color shader) of the material
dflttex1 = getdefaultimgfile()
print( "setting texture file,", dflttex1 )
p.MaterialSetTextureFilename( mat1, dflttex1 )
# set parameter for texture
tp1 = TextureProps( 0., 0., 8., 8., tsxTXTR_ON )
print( "tp1=", tp1.prt() )
p.MaterialSetTextureProps( mat1, tp1.p )
# faceting type
p.MaterialSetFacetingType( mat1, tsxFACET_FACETED )
print( "dflttex1=", dflttex1 )

p.MaterialSetActive( mat1 )
matlist1.append( mat1 )
getmateinfo1( "mat1", mat1 ) #--- for check ---

# Add a scene object
cb1 = p.CreateCube( 1, 2., 2., 2. )
p.SceneAddObject( cb1, e_tsxFALSE )
vec1 = Vec3f( 3., 0., 0. )
p.GNodeSetLocation( cb1, vec1.p )

#----
# Material 2
#----
# Make a new material
wki2 = Ulong()
p.MaterialCreate( wki2.p )
mat2 = wki2.get()
p.MaterialSetTextureType( mat2, tsxTEXTURE_NONE )
p.MaterialSetTextureFilename( mat2, "" )
setmatebyshname( "mat2", mat2, "plain" ) # color shader
setmatebyshname( "mat2", mat2, "conductor" ) # refrectance shader

shcls = tsxSHCLASS_COLOR # color shader

set1( mat2, shcls, "colour", ( 161, 96, 0 ) )

shcls = tsxSHCLASS_REFLECTANCE # reflectance shader

set1( mat2, shcls, "ambient factor",   0.32 )
set1( mat2, shcls, "diffuse factor",   0.15 )
set1( mat2, shcls, "specular factor",  1.0  )
set1( mat2, shcls, "mirror factor",    0.64 )
set1( mat2, shcls, "roughness",        0.1  )
set1( mat2, shcls, "refraction red",   0.14 )
set1( mat2, shcls, "refraction green", 0.13 )
set1( mat2, shcls, "refraction blue",  0.16 )
set1( mat2, shcls, "absorption red",   3.76 )
set1( mat2, shcls, "absorption green", 4.38 )
set1( mat2, shcls, "absorption blue",  2.34 )

# faceting type
p.MaterialSetFacetingType( mat2, tsxFACET_AUTO )

p.MaterialSetActive( mat2 )
matlist1.append( mat2 )
getmateinfo1( "mat2", mat2 ) #--- for check ---

# Add a scene object
sp1 = p.CreateSphere( 64, 64, 1. )
p.SceneAddObject( sp1, e_tsxFALSE )
vec1 = Vec3f( 0., 3., 0. )
p.GNodeSetLocation( sp1, vec1.p )

#----
# Material 3
#----
wki3 = Ulong()
p.MaterialCreate( wki3.p )
mat3 = wki3.get()
p.MaterialSetTextureType( mat3, tsxTEXTURE_NONE )
setmatebyshname( "mat3", mat3, "plain" ) # color shader
setmatebyshname( "mat3", mat3, "phong" ) # refrectance shader

col1 = Color( 204, 204, 255, 100 )
print( "col1=", col1.prt() )
p.MaterialSetColor( mat3, col1.p )

p.MaterialSetActive( mat3 )
matlist1.append( mat3 )
getmateinfo1( "mat3", mat3 ) #--- for check ---

# Add a scene object
cn1 = p.CreateCone( 64, 2, 1., 2. )
p.SceneAddObject( cn1, e_tsxFALSE);
vec1 = Vec3f( 3., 3., 0. )
p.GNodeSetLocation( cn1, vec1.p )

#----
# Material 4
#----
# Make a new material
wki4 = Ulong()
p.MaterialCreate( wki4.p )
mat4 = wki4.get()
p.MaterialSetTextureType( mat4, tsxTEXTURE_NONE )
setmatebyshname( "mat4", mat4, "plain" )          # color shader
setmatebyshname( "mat4", mat4, "caligari phong" ) # refrectance shader
setmatebyshname( "mat4", mat4, "casting" )        # displacement shader

#
shcls = tsxSHCLASS_COLOR # color shader
set1( mat4, shcls, "colour", ( 210, 210, 210 ) )
#
shcls = tsxSHCLASS_REFLECTANCE # reflectance shader
set1( mat4, shcls, "ambient factor",     0.06 )
set1( mat4, shcls, "diffuse factor",     0.06 )
set1( mat4, shcls, "specular factor",    0.5 )
set1( mat4, shcls, "exponent",          10. )
set1( mat4, shcls, "specular colour",   ( 255, 255, 255 ) )
set1( mat4, shcls, "transmission factor", 0.95 )
set1( mat4, shcls, "mirror factor",      0.65 )
set1( mat4, shcls, "refraction",         1.34 )
#
shcls = tsxSHCLASS_DISPLACEMENT # displacement shader
set1( mat4, shcls, "scale",              0.2 )
set1( mat4, shcls, "casting amplitude",  0.02 )
set1( mat4, shcls, "dented amplitude",   0.8 )
set1( mat4, shcls, "dented scale",       1.0 )
set1( mat4, shcls, "dented threshold",   0.8 )
set1( mat4, shcls, "detail",            10 )


p.MaterialSetActive( mat4 )
matlist1.append( mat4 )
getmateinfo1( "mat4", mat4 ) #--- for check ---

# Add a scene object
cy1 = p.CreateCylinder( 6, 2, 1.5, 1.5, 2. )
p.SceneAddObject( cy1, e_tsxFALSE);
vec1 = Vec3f( 0., 0., 0. )
p.GNodeSetLocation( cy1, vec1.p )

#----
# Material 5
#----
# Make a new material
wki5 = Ulong()
p.MaterialCreate( wki5.p )
mat5 = wki5.get()
p.MaterialSetTextureType( mat5, tsxTEXTURE_NONE )

#
# Following comentized code is an example for "Granite" shader that tS4
# does not support. You can execute it on tS5 or higher.
#
#setmatebyshname( "mat5", mat5, "granite" ) # color shader
#setmatebyshname( "mat5", mat5, "caligari phong" )   # refrectance shader
#
##
#shcls = tsxSHCLASS_COLOR # color shader
#set1( mat5, shcls, "scale",              0.008 * 10 )
##set1( mat5, shcls, "type",               0x3ca3d70a
#set1( mat5, shcls, "mineral 1 colour",   ( 106, 103, 96 ) )
#set1( mat5, shcls, "mineral 2 colour",   ( 96, 79, 73 ) )
#set1( mat5, shcls, "mineral 3 colour",   ( 15, 17, 17 ) )
#set1( mat5, shcls, "mineral 4 colour",   (170, 158, 137 ) )
#set1( mat5, shcls, "fragment softness",  0.5 )
#set1( mat5, shcls, "fragment detail",    1.0 )
#set1( mat5, shcls, "fragment size",      0.8 )
#set1( mat5, shcls, "colour variation",   0.2 )
#set1( mat5, shcls, "cracks",             0.08 )
#set1( mat5, shcls, "colour noise",       0.15 )
#set1( mat5, shcls, "colour noise scale", 1.0 )
##
#shcls = tsxSHCLASS_REFLECTANCE # reflectance shader
#set1( mat5, shcls, "ambient factor",      0.1 )
#set1( mat5, shcls, "diffuse factor",      0.9 )
#set1( mat5, shcls, "specular factor",     0.1 )
#set1( mat5, shcls, "exponent",            3.0 )
#set1( mat5, shcls, "specular colour",     ( 255, 255, 255 ) )
#set1( mat5, shcls, "transmission factor", 0. )
#set1( mat5, shcls, "mirror factor",       0.14 )
#set1( mat5, shcls, "refraction",          0. )

setmatebyshname( "mat5", mat5, "marble" ) # color shader
setmatebyshname( "mat5", mat5, "caligari phong" )   # refrectance shader

shcls = tsxSHCLASS_COLOR # color shader
set1( mat5, shcls, "scale",         0.1 )
set1( mat5, shcls, "detail",        8 )
set1( mat5, shcls, "ground colour", (166,178,166) )
set1( mat5, shcls, "vein colour",   (120,124,123) )
set1( mat5, shcls, "vein contrast", 0.1 )
set1( mat5, shcls, "grain",         3.0 )
set1( mat5, shcls, "grain scale",   1.0 )

shcls = tsxSHCLASS_REFLECTANCE # reflectance shader
set1( mat5, shcls, "ambient factor",      0.1 )
set1( mat5, shcls, "diffuse factor",      0.39 )
set1( mat5, shcls, "specular factor",     0.13 )
set1( mat5, shcls, "exponent",            3.0 )
set1( mat5, shcls, "specular colour",     ( 255, 255, 255 ) )
set1( mat5, shcls, "transmission factor", 0. )
set1( mat5, shcls, "mirror factor",       0.11 )
set1( mat5, shcls, "refraction",          1.86 )


p.MaterialSetActive( mat5 )
matlist1.append( mat5 )
getmateinfo1( "mat5", mat5 ) #--- for check ---

# Add a scene object
cb2 = p.CreateCube( 1, 7., 7., 1. )
p.SceneAddObject( cb2, e_tsxFALSE )
vec1 = Vec3f( 1.5, 1.5, -1.5 )
p.GNodeSetLocation( cb2, vec1.p )


#----
# Restore the original material in the material editor.
#----
p.MaterialSetActive( mat_sv )

p.SceneDraw()

for i in matlist1:
    p.MaterialDestroy( i )

