Пример #1
0
def povrayProcessSSS(rmeshes, outDir, settings, progressCallback = None):

    def progress(prog):
        if progressCallback == None:
            gui3d.app.progress(prog)
        else:
            progressCallback(prog)
    progress(0)

    progbase = 0
    nextpb = 1 - 0.65*settings['usebump']
    # get lightmap
    lmap = projection.mapSceneLighting(
        settings['scene'],progressCallback = lambda p: progress(0.3*nextpb*p))
    # prepare channels
    lmap = imgop.getChannel(lmap,1)
    alpha = imgop.shrinkSelection(projection.mapMask())
    for i in range(3):
        alpha = imgop.shrinkSelection(alpha)
    black = mh.Image(data = imgop.numpy.zeros((lmap.height, lmap.width, 1), dtype=imgop.numpy.uint8))
    # calculate blur level of each cannel, according to settings
    sssa = float(settings['SSSA'])
    # blue channel
    imgop.compose([black,black,lmap]).save(
        os.path.join(outDir, '%s_sss_bluelmap.png' % rmeshes[0].name))
    # green channel
    progress(0.4*nextpb)
    lmap = imgop.blurred(lmap, (float(lmap.width)/1024)*1.6*sssa, 13, lambda p: progress((0.4+0.3*p)*nextpb))
    imgop.compose([black,lmap,black]).save(
        os.path.join(outDir, '%s_sss_greenlmap.png' % rmeshes[0].name))
    # red channel
    progress(0.7*nextpb)
    lmap = imgop.blurred(lmap, (float(lmap.width)/1024)*3.2*sssa, 13, lambda p: progress((0.7+0.2*p)*nextpb))
    alpha = imgop.blurred(alpha, 4, 13, lambda p: progress((0.9+0.1*p)*nextpb))
    alpha.save(os.path.join(outDir, '%s_sss_alpha.png' % rmeshes[0].name))
    imgop.compose([lmap,black,black]).save(
        os.path.join(outDir, '%s_sss_redlmap.png' % rmeshes[0].name))
    progbase = nextpb
    progress(progbase)
    if settings['usebump']:
        bumpdata = rmeshes[0].material.bumpMapTexture
        if bumpdata is None:
            bumpdata = rmeshes[0].material.displacementMapTexture
        if bumpdata:
            # Export blurred bump maps
            lmap = imgop.Image(data = bumpdata)
            lmap = imgop.getChannel(lmap,1)
            lmap = imgop.blurred(lmap, (float(lmap.width)/1024)*1.6*sssa, 15,
                                 lambda p: progress(progbase+0.5*p*(1-progbase)))
            progress(progbase+0.5*(1-progbase))
            lmap.save(os.path.join(outDir, '%s_sss_greenbump.png' % rmeshes[0].name))
            lmap = imgop.blurred(lmap, (float(lmap.width)/1024)*3.2*sssa, 15,
                                 lambda p: progress(progbase+(0.5+0.5*p)*(1-progbase)))
            lmap.save(os.path.join(outDir, '%s_sss_redbump.png' % rmeshes[0].name))
        progress(1.0)
Пример #2
0
def povrayProcessSSS(stuffs, outDir, settings, progressCallback=None):
    def progress(prog):
        if progressCallback == None:
            gui3d.app.progress(prog)
        else:
            progressCallback(prog)

    progress(0)

    progbase = 0
    nextpb = 1 - 0.65 * settings['usebump']
    # get lightmap
    lmap = projection.mapSceneLighting(
        settings['scene'],
        progressCallback=lambda p: progress(0.3 * nextpb * p))
    lmap = imgop.getChannel(lmap, 1)
    # prepare channels
    black = imgop.Image(data=imgop.numpy.zeros((lmap.height, lmap.width, 1),
                                               dtype=imgop.numpy.uint8))
    # calculate blur level of each cannel, according to settings
    sssa = float(settings['SSSA'])
    # blue channel
    imgop.compose([black, black, lmap]).save(
        os.path.join(outDir, '%s_sss_bluelmap.png' % stuffs[0].name))
    # green channel
    progress(0.4 * nextpb)
    lmap2 = imgop.blurred(lmap, 16 * sssa, 13, lambda p: progress(
        (0.4 + 0.3 * p) * nextpb))
    imgop.compose([black, lmap2, black]).save(
        os.path.join(outDir, '%s_sss_greenlmap.png' % stuffs[0].name))
    # red channel
    progress(0.7 * nextpb)
    lmap2 = imgop.blurred(lmap2, 32 * sssa, 13, lambda p: progress(
        (0.7 + 0.3 * p) * nextpb))
    imgop.compose([lmap2, black, black]).save(
        os.path.join(outDir, '%s_sss_redlmap.png' % stuffs[0].name))
    progbase = nextpb
    progress(progbase)
    if settings['usebump']:
        # Export blurred bump maps
        lmap = imgop.Image(os.path.join(stuffs[0].bump[0], stuffs[0].bump[1]))
        lmap = imgop.getChannel(lmap, 1)
        lmap = imgop.blurred(
            lmap, (float(lmap.width) / 1024) * 1.6 * sssa, 15,
            lambda p: progress(progbase + 0.5 * p * (1 - progbase)))
        progress(progbase + 0.5 * (1 - progbase))
        lmap.save(os.path.join(outDir,
                               '%s_sss_greenbump.png' % stuffs[0].name))
        lmap = imgop.blurred(
            lmap, (float(lmap.width) / 1024) * 3.2 * sssa, 15,
            lambda p: progress(progbase + (0.5 + 0.5 * p) * (1 - progbase)))
        lmap.save(os.path.join(outDir, '%s_sss_redbump.png' % stuffs[0].name))
        progress(1.0)
Пример #3
0
def povrayProcessSSS(stuffs, outDir, settings, progressCallback = None):

    def progress(prog):
        if progressCallback == None:
            gui3d.app.progress(prog)
        else:
            progressCallback(prog)
    progress(0)
        
    progbase = 0
    nextpb = 1 - 0.65*settings['usebump']
    # get lightmap
    lmap = projection.mapSceneLighting(
        settings['scene'],progressCallback = lambda p: progress(0.3*nextpb*p))
    lmap = imgop.getChannel(lmap,1)
    # prepare channels
    black = imgop.Image(data=imgop.numpy.zeros((lmap.height, lmap.width, 1), dtype=imgop.numpy.uint8))
    # calculate blur level of each cannel, according to settings
    sssa = float(settings['SSSA'])
    # blue channel
    imgop.compose([black,black,lmap]).save(
        os.path.join(outDir, '%s_sss_bluelmap.png' % stuffs[0].name))
    # green channel
    progress(0.4*nextpb)
    lmap2 = imgop.blurred(lmap, 16*sssa, 13, lambda p: progress((0.4+0.3*p)*nextpb))
    imgop.compose([black,lmap2,black]).save(
        os.path.join(outDir, '%s_sss_greenlmap.png' % stuffs[0].name))
    # red channel
    progress(0.7*nextpb)
    lmap2 = imgop.blurred(lmap2, 32*sssa, 13, lambda p: progress((0.7+0.3*p)*nextpb))
    imgop.compose([lmap2,black,black]).save(
        os.path.join(outDir, '%s_sss_redlmap.png' % stuffs[0].name))
    progbase = nextpb
    progress(progbase)
    if settings['usebump']:
        # Export blurred bump maps
        lmap = imgop.Image(os.path.join(stuffs[0].bump[0], stuffs[0].bump[1]))
        lmap = imgop.getChannel(lmap,1)
        lmap = imgop.blurred(lmap, (float(lmap.width)/1024)*1.6*sssa, 15,
                             lambda p: progress(progbase+0.5*p*(1-progbase)))
        progress(progbase+0.5*(1-progbase))
        lmap.save(os.path.join(outDir, '%s_sss_greenbump.png' % stuffs[0].name))
        lmap = imgop.blurred(lmap, (float(lmap.width)/1024)*3.2*sssa, 15,
                             lambda p: progress(progbase+(0.5+0.5*p)*(1-progbase)))
        lmap.save(os.path.join(outDir, '%s_sss_redbump.png' % stuffs[0].name))
        progress(1.0)
Пример #4
0
def my_render(settings=None):
    if settings is None:
        settings = {'AA': True, 'lightmapSSS': False, 'scene': G.app.scene, 'dimensions': (230, 230)}

    if settings['lightmapSSS']:
        human = G.app.selectedHuman
        material_backup = material.Material(human.material)

        diffuse = imgop.Image(data=human.material.diffuseTexture)
        lmap = projection.mapSceneLighting(settings['scene'], border=human.material.sssRScale)
        lmapG = imgop.blurred(lmap, human.material.sssGScale, 13)
        lmapR = imgop.blurred(lmap, human.material.sssRScale, 13)
        lmap = imgop.compose([lmapR, lmapG, lmap])

        if not diffuse.isEmpty:
            lmap = imgop.resized(lmap, diffuse.width, diffuse.height, filter=image.FILTER_BILINEAR)
            lmap = imgop.multiply(lmap, diffuse)
            lmap.sourcePath = "Internal_Renderer_Lightmap_SSS_Texture"

        human.material.diffuseTexture = lmap
        human.configureShading(diffuse=True)
        human.shadeless = True

    if not mh.hasRenderToRenderbuffer():
        img = mh.grabScreen(0, 0, G.windowWidth, G.windowHeight)
        alphaImg = None
    else:
        width, height = settings['dimensions']
        if settings['AA']:
            width *= 2
            height *= 2

            img = mh.renderToBuffer(width, height)
            alphaImg = mh.renderAlphaMask(width, height)
            img = imgop.addAlpha(img, imgop.getChannel(alphaImg, 0))

        if settings['AA']:
            img = img.resized(width/2, height/2, filter=image.FILTER_BILINEAR)
            img.data[:, :, :] = img.data[:, :, (2, 1, 0, 3)]

    if settings['lightmapSSS']:
        human.material = material_backup

    return img
Пример #5
0
def Render(settings):
    progress = Progress.begin()

    if not mh.hasRenderToRenderbuffer():
        settings['dimensions'] = (G.windowWidth, G.windowHeight)

    if settings['lightmapSSS']:
        progress(0, 0.05, "Storing data")
        import material
        human = G.app.selectedHuman
        materialBackup = material.Material(human.material)

        progress(0.05, 0.1, "Projecting lightmaps")
        diffuse = imgop.Image(data=human.material.diffuseTexture)
        lmap = projection.mapSceneLighting(settings['scene'],
                                           border=human.material.sssRScale)
        progress(0.1, 0.4, "Applying medium scattering")
        lmapG = imgop.blurred(lmap, human.material.sssGScale, 13)
        progress(0.4, 0.7, "Applying high scattering")
        lmapR = imgop.blurred(lmap, human.material.sssRScale, 13)
        lmap = imgop.compose([lmapR, lmapG, lmap])
        if not diffuse.isEmpty:
            progress(0.7, 0.8, "Combining textures")
            lmap = imgop.resized(lmap,
                                 diffuse.width,
                                 diffuse.height,
                                 filter=image.FILTER_BILINEAR)
            progress(0.8, 0.9)
            lmap = imgop.multiply(lmap, diffuse)
        lmap.sourcePath = "Internal_Renderer_Lightmap_SSS_Texture"

        progress(0.9, 0.95, "Setting up renderer")
        human.material.diffuseTexture = lmap
        human.configureShading(diffuse=True)
        human.shadeless = True
        progress(0.95, 0.98, None)
    else:
        progress(0, 0.99, None)

    if not mh.hasRenderToRenderbuffer():
        # Limited fallback mode, read from screen buffer
        log.message("Fallback render: grab screen")
        img = mh.grabScreen(0, 0, G.windowWidth, G.windowHeight)
        alphaImg = None
    else:
        # Render to framebuffer object
        renderprog = Progress()
        renderprog(0, 0.99 - 0.59 * settings['AA'], "Rendering")
        width, height = settings['dimensions']
        log.message("Rendering at %sx%s", width, height)
        if settings['AA']:
            width = width * 2
            height = height * 2
        img = mh.renderToBuffer(width, height)
        alphaImg = mh.renderAlphaMask(width, height)
        img = imgop.addAlpha(img, imgop.getChannel(alphaImg, 0))

        if settings['AA']:
            renderprog(0.4, 0.99, "AntiAliasing")
            # Resize to 50% using bi-linear filtering
            img = img.resized(width / 2,
                              height / 2,
                              filter=image.FILTER_BILINEAR)
            # TODO still haven't figured out where components get swapped, but this hack appears to be necessary
            img.data[:, :, :] = img.data[:, :, (2, 1, 0, 3)]
        renderprog.finish()

    if settings['lightmapSSS']:
        progress(0.98, 0.99, "Restoring data")
        human.material = materialBackup

    progress(1, None, 'Rendering complete')

    gui3d.app.getCategory('Rendering').getTaskByName('Viewer').setImage(img)
    mh.changeTask('Rendering', 'Viewer')
    gui3d.app.statusPersist('Rendering complete')
Пример #6
0
def Render(settings):
    progress = Progress.begin()

    if not mh.hasRenderToRenderbuffer():
        settings['dimensions'] = (G.windowWidth, G.windowHeight)

    if settings['lightmapSSS']:
        progress(0, 0.05, "Storing data")
        import material
        human = G.app.selectedHuman
        materialBackup = material.Material(human.material)

        progress(0.05, 0.1, "Projecting lightmaps")
        diffuse = imgop.Image(data=human.material.diffuseTexture)
        lmap = projection.mapSceneLighting(settings['scene'],
                                           border=human.material.sssRScale)
        progress(0.1, 0.4, "Applying medium scattering")
        lmapG = imgop.blurred(lmap, human.material.sssGScale, 13)
        progress(0.4, 0.7, "Applying high scattering")
        lmapR = imgop.blurred(lmap, human.material.sssRScale, 13)
        lmap = imgop.compose([lmapR, lmapG, lmap])
        if not diffuse.isEmpty:
            progress(0.7, 0.8, "Combining textures")
            lmap = imgop.resized(lmap, diffuse.width, diffuse.height)
            progress(0.8, 0.9)
            lmap = imgop.multiply(lmap, diffuse)
        lmap.sourcePath = "Internal_Renderer_Lightmap_SSS_Texture"

        progress(0.9, 0.95, "Setting up renderer")
        human.material.diffuseTexture = lmap
        human.mesh.configureShading(diffuse=True)
        human.mesh.shadeless = True
        progress(0.95, 0.98, None)
    else:
        progress(0, 0.99, None)

    if not mh.hasRenderToRenderbuffer():
        # Limited fallback mode, read from screen buffer
        log.message("Fallback render: grab screen")
        img = mh.grabScreen(0, 0, G.windowWidth, G.windowHeight)
        alphaImg = None
    else:
        # Render to framebuffer object
        renderprog = Progress()
        renderprog(0, 0.99 - 0.59 * settings['AA'], "Rendering")
        width, height = settings['dimensions']
        log.message("Rendering at %sx%s", width, height)
        if settings['AA']:
            width = width * 2
            height = height * 2
        img = mh.renderToBuffer(width, height)
        alphaImg = mh.renderAlphaMask(width, height)
        img = imgop.addAlpha(img, imgop.getChannel(alphaImg, 0))

        if settings['AA']:
            renderprog(0.4, 0.99, "AntiAliasing")
            # Resize to 50% using Qt image class
            qtImg = img.toQImage()
            del img
            # Bilinear filtered resize for anti-aliasing
            scaledImg = qtImg.scaled(
                width / 2,
                height / 2,
                transformMode=gui.QtCore.Qt.SmoothTransformation)
            del qtImg
            img = scaledImg
            #img = image.Image(scaledImg)    # Convert back to MH image
            #del scaledImg
        renderprog.finish()

    if settings['lightmapSSS']:
        progress(0.98, 0.99, "Restoring data")
        human.material = materialBackup

    progress(1, None, 'Rendering complete')

    gui3d.app.getCategory('Rendering').getTaskByName('Viewer').setImage(img)
    mh.changeTask('Rendering', 'Viewer')
    gui3d.app.statusPersist('Rendering complete.')
Пример #7
0
def Render(settings):
    progress = Progress.begin()
    
    if not mh.hasRenderToRenderbuffer():
        settings['dimensions'] = (G.windowWidth, G.windowHeight)

    if settings['lightmapSSS']:
        progress(0, 0.05, "Storing data")
        import material
        human = G.app.selectedHuman
        materialBackup = material.Material(human.material)

        progress(0.05, 0.1, "Projecting lightmaps")
        diffuse = imgop.Image(data = human.material.diffuseTexture)
        lmap = projection.mapSceneLighting(
            settings['scene'], border = human.material.sssRScale)
        progress(0.1, 0.4, "Applying medium scattering")
        lmapG = imgop.blurred(lmap, human.material.sssGScale, 13)
        progress(0.4, 0.7, "Applying high scattering")
        lmapR = imgop.blurred(lmap, human.material.sssRScale, 13)
        lmap = imgop.compose([lmapR, lmapG, lmap])
        if not diffuse.isEmpty:
            progress(0.7, 0.8, "Combining textures")
            lmap = imgop.resized(lmap, diffuse.width, diffuse.height, filter=image.FILTER_BILINEAR)
            progress(0.8, 0.9)
            lmap = imgop.multiply(lmap, diffuse)
        lmap.sourcePath = "Internal_Renderer_Lightmap_SSS_Texture"

        progress(0.9, 0.95, "Setting up renderer")
        human.material.diffuseTexture = lmap
        human.configureShading(diffuse = True)
        human.shadeless = True
        progress(0.95, 0.98, None)
    else:
        progress(0, 0.99, None)
        
    if not mh.hasRenderToRenderbuffer():
        # Limited fallback mode, read from screen buffer
        log.message("Fallback render: grab screen")
        img = mh.grabScreen(0, 0, G.windowWidth, G.windowHeight)
        alphaImg = None
    else:
        # Render to framebuffer object
        renderprog = Progress()
        renderprog(0, 0.99 - 0.59 * settings['AA'], "Rendering")
        width, height = settings['dimensions']
        log.message("Rendering at %sx%s", width, height)
        if settings['AA']:
            width = width * 2
            height = height * 2
        img = mh.renderToBuffer(width, height)
        alphaImg = mh.renderAlphaMask(width, height)
        img = imgop.addAlpha(img, imgop.getChannel(alphaImg, 0))

        if settings['AA']:
            renderprog(0.4, 0.99, "AntiAliasing")
            # Resize to 50% using bi-linear filtering
            img = img.resized(width/2, height/2, filter=image.FILTER_BILINEAR)
            # TODO still haven't figured out where components get swapped, but this hack appears to be necessary
            img.data[:,:,:] = img.data[:,:,(2,1,0,3)]
        renderprog.finish()

    if settings['lightmapSSS']:
        progress(0.98, 0.99, "Restoring data")
        human.material = materialBackup

    progress(1, None, 'Rendering complete')

    gui3d.app.getCategory('Rendering').getTaskByName('Viewer').setImage(img)
    mh.changeTask('Rendering', 'Viewer')
    gui3d.app.statusPersist('Rendering complete')
Пример #8
0
def povrayExportMesh2(path, settings):
    """
    This function exports data in the form of a mesh2 humanoid object. The POV-Ray
    file generated is fairly inflexible, but is highly efficient.

    Parameters
    ----------

    path:
      *string*. The file system path to the output files that need to be generated.

    settings:
      *dictionary*. Settings passed from the GUI.
    """

    progress = Progress.begin()

    # Prepare the output directory.
    progress(0, 0.01, "Preparing Filesystem")
    if not os.path.isdir(path):
        os.makedirs(path)
    log.debug('POV-Ray output folder: %s', path)
    # Cleanup output folder
    for f in os.listdir(path):
        temppath = os.path.join(path, f)
        if os.path.isfile(temppath) and not os.path.splitext(f)[1] == '.png':
            os.remove(temppath)
    # Make empty source output folder
    path = os.path.join(path, 'source/')
    if os.path.isdir(path):
        for f in os.listdir(path):
            os.remove(os.path.join(path, f))
    else:
        os.makedirs(path)
    log.debug('POV-Ray source output folder: %s', path)

    # Open .inc file for writing.
    outputFileDescriptor = open(os.path.join(path, settings['name'] + ".inc"),
                                'w')

    # Write position and dimension constants.
    writeConstants(outputFileDescriptor, settings)

    # Collect and prepare all objects.
    progress(0.01, 0.2, "Analyzing Objects")
    rmeshes = collect.setupMeshes(settings['name'],
                                  gui3d.app.selectedHuman,
                                  hidden=False,
                                  subdivide=settings['subdivide'])

    # Analyze the materials of each richmesh to povray compatible format.
    MAfuncs = {
        'diffusedef':
        lambda T, S:
        'pigment {image_map {%(ft)s "%(fn)s" interpolate 2%(f)s%(t)s}}' % {
            'ft': getImageFType(T.getSaveExt()),
            'fn': T.getSaveName(),
            'f': ' filter all ' + str(S['filter']) if 'filter' in S else "",
            't': ' transmit all ' + str(S['transmit'])
            if 'transmit' in S else ""
        },
        'bumpdef':
        lambda T, S: 'normal {bump_map {%(ft)s "%(fn)s" interpolate 2} %(bi)f}'
        % {
            'ft':
            getImageFType(T.getSaveExt()),
            'fn':
            T.getSaveName(),
            'bi':
            T.Object.rmesh.material.bumpMapIntensity if T.successfulAlternative
            == 0 else T.Object.rmesh.material.displacementMapIntensity
        },
        'alphadef':
        lambda T, S: 'image_map {%(ft)s "%(fn)s" interpolate 2}' % {
            'ft': getImageFType(T.getSaveExt()),
            'fn': T.getSaveName()
        },
        'colordef':
        lambda T, S: 'rgb%(bf)s%(bt)s <#color#%(f)s%(t)s>' % {
            'bf': 'f' if 'filter' in S else "",
            'bt': 't' if 'transmit' in S else "",
            'f': ',' + str(S['filter']) if 'filter' in S else "",
            't': ',' + str(S['transmit']) if 'transmit' in S else ""
        },
        'makecolor':
        lambda s, ct=(1, 1, 1): s.replace('#color#', '%s,%s,%s' % ct),
        'getDiffuseColor':
        lambda T, S: T.Object.rmesh.material.diffuseColor.asTuple(),
        'getAmbience':
        lambda T, S: tuple([(v1 * v2 * S['multiply']
                             if 'multiply' in S else v1 * v2) for (v1, v2)
                            in zip(T.Object.rmesh.material.ambientColor.values,
                                   settings['scene'].environment.ambience)]),
        'specular':
        lambda T, S: str(
            numpy.average(T.Object.rmesh.material.specularColor.values)),
        'roughness':
        lambda T, S: str(1.0 - T.Object.rmesh.material.shininess),
        'diffuseInt':
        lambda T, S: str(T.Object.rmesh.material.diffuseIntensity),
        'pigment':
        lambda s: 'pigment {%s}' % s,
        'lmap':
        lambda RM: projection.mapSceneLighting(settings['scene'], RM.object.
                                               object),
        'blurlev':
        lambda img, mult: (mult * (float(img.width) / 1024)) if img else mult,
        'GBlur':
        lambda RM: RM.material.sssGScale,
        'RBlur':
        lambda RM: RM.material.sssRScale,
        'mapmask':
        lambda RM: projection.mapMask()
    }
    MAfuncs.update(matanalyzer.imgopfuncs)
    materials = matanalyzer.MaterialAnalysis(
        rmeshes,
        map={
            'diffuse':
            (['mat.diffuse'], 'diffusedef',
             ('pigment', ('makecolor', 'colordef', 'getDiffuseColor'))),
            'bump': (['mat.bump', 'mat.displacement'], 'bumpdef', None),
            'alpha': (['mat.transparency',
                       ('getAlpha', 'diffuse')], 'alphadef',
                      ('makecolor', 'colordef', ('param', (1, 1, 1)))),
            'lmap': [('getChannel', 'func.lmap', 1)],
            'bllmap':
            [('blur', 'lmap', ('blurlev', 'lmap', 'func.GBlur'), 13)],
            'bl2lmap':
            [('blur', 'bllmap', ('blurlev', 'lmap', 'func.RBlur'), 13)],
            'sss_bluelmap': [('compose', ('list', 'black', 'black', 'lmap'))],
            'sss_greenlmap':
            [('compose', ('list', 'black', 'bllmap', 'black'))],
            'sss_redlmap': [('compose', ('list', 'bl2lmap', 'black', 'black'))
                            ],
            'sss_alpha': [('blur', ('shrinkMask', 'func.mapmask', 4), 4, 13)],
            'sss_bluebump': ([('getChannel', 'bump', 1)], 'bumpdef', None),
            'sss_greenbump': ([('blur', 'sss_bluebump',
                                ('blurlev', 'sss_bluebump', 'func.GBlur'), 15)
                               ], 'bumpdef', None),
            'sss_redbump': ([('blur', 'sss_greenbump',
                              ('blurlev', 'sss_bluebump', 'func.RBlur'), 15)],
                            'bumpdef', None),
            'hairbump': (['bump'], 'bumpdef', 'alpha.bumpdef'),
            'ambient': ([None], ('makecolor', 'colordef', 'getAmbience')),
            'specular': ([None], 'specular'),
            'roughness': ([None], 'roughness'),
            'diffuseInt': ([None], 'diffuseInt'),
            'black': [('black', 'lmap')]
        },
        functions=MAfuncs)

    # If SSS is enabled, render the lightmaps.
    progress(0.25, 0.6, "Processing SubSurface Scattering")
    povrayProcessSSS(rmeshes, materials, path, settings)

    # Write mesh data for the object.
    progress(0.6, 0.9, "Writing Objects")
    povrayWriteMesh2(outputFileDescriptor, rmeshes)

    progress(0.9, 0.95, "Writing Materials")
    writeLights(settings['scene'], outputFileDescriptor)
    writeMaterials(outputFileDescriptor, rmeshes, materials, settings)
    outputFileDescriptor.close()

    # Write .pov scene file.
    writeScene(os.path.join(path, settings['name'] + ".pov"), rmeshes,
               settings)

    progress(0.95, 0.99, "Writing Textures")
    writeTextures(materials, path)

    progress(1.0, None,
             "Finished. Pov-Ray scene file exported successfully at %s" % path)