Skip to content
Snippets Groups Projects
render.py 88.3 KiB
Newer Older
Luca Bonavita's avatar
Luca Bonavita committed
# ##### BEGIN GPL LICENSE BLOCK #####
#
#  This program is free software; you can redistribute it and/or
#  modify it under the terms of the GNU General Public License
#  as published by the Free Software Foundation; either version 2
#  of the License, or (at your option) any later version.
#
#  This program is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU General Public License for more details.
#
#  You should have received a copy of the GNU General Public License
#  along with this program; if not, write to the Free Software Foundation,
#  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# ##### END GPL LICENSE BLOCK #####

Luca Bonavita's avatar
Luca Bonavita committed
import bpy
import subprocess
import os
import sys
import time
import math
Maurice Raybaud's avatar
Maurice Raybaud committed
from math import atan, pi, degrees, sqrt
Luca Bonavita's avatar
Luca Bonavita committed

import platform as pltfrm
if pltfrm.architecture()[0] == "64bit":
Luca Bonavita's avatar
Luca Bonavita committed
    bitness = 64
else:
    bitness = 32

Maurice Raybaud's avatar
Maurice Raybaud committed
##############################SF###########################
##############find image texture
Maurice Raybaud's avatar
Maurice Raybaud committed
def splitExt(path):
Maurice Raybaud's avatar
Maurice Raybaud committed
    if dotidx == -1:
Maurice Raybaud's avatar
Maurice Raybaud committed
    else:
        return path[dotidx:].upper().replace(".", "")
Maurice Raybaud's avatar
Maurice Raybaud committed

Maurice Raybaud's avatar
Maurice Raybaud committed
def imageFormat(imgF):
Maurice Raybaud's avatar
Maurice Raybaud committed
    ext_orig = splitExt(imgF)
    if ext_orig == 'JPG' or ext_orig == 'JPEG':
    elif ext_orig == 'GIF':
    elif ext_orig == 'TGA':
    elif ext_orig == 'IFF':
    elif ext_orig == 'PPM':
    elif ext_orig == 'PNG':
    elif ext_orig == 'SYS':
    elif ext_orig in ('TIFF', 'TIF'):
    elif ext_orig == 'EXR':
    elif ext_orig == 'HDR':
Maurice Raybaud's avatar
Maurice Raybaud committed
    print(imgF)
        print(" WARNING: texture image format not supported ")  # % (imgF , "")) #(ext_orig)))
Maurice Raybaud's avatar
Maurice Raybaud committed
    return ext

Maurice Raybaud's avatar
Maurice Raybaud committed
def imgMap(ts):
    image_map = ""
    if ts.mapping == 'FLAT':
        image_map = "map_type 0 "
    elif ts.mapping == 'SPHERE':
        image_map = "map_type 1 "  # map_type 7 in megapov
    elif ts.mapping == 'TUBE':
        image_map = "map_type 2 "
    #elif ts.mapping=="?":
    #    image_map = " map_type 3 "  # map_type 3 and 4 in development (?) for POV-Ray, currently they just seem to default back to Flat (type 0)
    #elif ts.mapping=="?":
    #    image_map = " map_type 4 "  # map_type 3 and 4 in development (?) for POV-Ray, currently they just seem to default back to Flat (type 0)
    if ts.texture.use_interpolation:
        image_map += " interpolate 2 "
    if ts.texture.extension == 'CLIP':
        image_map += " once "
    #image_map += "}"
    #if ts.mapping=='CUBE':
    #    image_map+= "warp { cubic } rotate <-90,0,180>"  # no direct cube type mapping. Though this should work in POV 3.7 it doesn't give that good results(best suited to environment maps?)
    #if image_map == "":
    #    print(" No texture image  found ")
Maurice Raybaud's avatar
Maurice Raybaud committed
    return image_map

Maurice Raybaud's avatar
Maurice Raybaud committed
def imgMapBG(wts):
    image_mapBG = ""
    if wts.texture_coords == 'VIEW':
        image_mapBG = " map_type 0 "  # texture_coords refers to the mapping of world textures
    elif wts.texture_coords == 'ANGMAP':
        image_mapBG = " map_type 1 "
    elif wts.texture_coords == 'TUBE':
        image_mapBG = " map_type 2 "

    if wts.texture.use_interpolation:
        image_mapBG += " interpolate 2 "
    if wts.texture.extension == 'CLIP':
        image_mapBG += " once "
    #image_mapBG += "}"
    #if wts.mapping == 'CUBE':
    #   image_mapBG += "warp { cubic } rotate <-90,0,180>"  # no direct cube type mapping. Though this should work in POV 3.7 it doesn't give that good results(best suited to environment maps?)
    #if image_mapBG == "":
    #    print(" No background texture image  found ")
Maurice Raybaud's avatar
Maurice Raybaud committed
    return image_mapBG

Maurice Raybaud's avatar
Maurice Raybaud committed
def splitFile(path):
Maurice Raybaud's avatar
Maurice Raybaud committed
    if idx == -1:
        idx = path.rfind("\\")
    return path[idx:].replace("/", "").replace("\\", "")
Maurice Raybaud's avatar
Maurice Raybaud committed
def splitPath(path):
Maurice Raybaud's avatar
Maurice Raybaud committed
    if idx == -1:
Maurice Raybaud's avatar
Maurice Raybaud committed
    else:
        return path[:idx]


def findInSubDir(filename, subdirectory=""):
    pahFile = ""
Maurice Raybaud's avatar
Maurice Raybaud committed
    if subdirectory:
        path = subdirectory
    else:
        path = os.getcwd()
    try:
        for root, dirs, names in os.walk(path):
            if filename in names:
                pahFile = os.path.join(root, filename)
        return pahFile
Campbell Barton's avatar
Campbell Barton committed
    except OSError:
Maurice Raybaud's avatar
Maurice Raybaud committed

def path_image(image):
    import os
    fn = bpy.path.abspath(image)
    fn_strip = os.path.basename(fn)
    if not os.path.isfile(fn):
        fn = findInSubDir(splitFile(fn), splitPath(bpy.data.filepath))
    fn = os.path.realpath(fn)
Maurice Raybaud's avatar
Maurice Raybaud committed
    return fn

##############end find image texture

        return name[hyphidx:].replace("-", "")

def safety(name, Level):
    # safety string name material
    #
    # Level=1 is for texture with No specular nor Mirror reflection
    # Level=2 is for texture with translation of spec and mir levels for when no map influences them
    # Level=3 is for texture with Maximum Spec and Mirror
Maurice Raybaud's avatar
Maurice Raybaud committed
    try:
Campbell Barton's avatar
Campbell Barton committed
        if int(name) > 0:
            prefix = "shader"
Campbell Barton's avatar
Campbell Barton committed
    except:
    prefix = "shader_"
        return prefix + name
        return prefix + name + "0"  # used for 0 of specular map
        return prefix + name + "1"  # used for 1 of specular map
Maurice Raybaud's avatar
Maurice Raybaud committed
##############end safety string name material
##############################EndSF###########################
Luca Bonavita's avatar
Luca Bonavita committed

Luca Bonavita's avatar
Luca Bonavita committed
def write_pov(filename, scene=None, info_callback=None):
Maurice Raybaud's avatar
Maurice Raybaud committed
    #file = filename
    file = open(filename, "w")
Luca Bonavita's avatar
Luca Bonavita committed

    # Only for testing
    if not scene:
        scene = bpy.data.scenes[0]

    render = scene.render
    world = scene.world
    global_matrix = mathutils.Matrix.Rotation(-pi / 2.0, 4, 'X')
        elif tabtype == '1':
    tab = setTab(scene.pov_indentation_character, scene.pov_indentation_spaces)
        if not scene.pov_tempfiles_enable:
            global tabLevel
            brackets = str_o.count("{") - str_o.count("}") + str_o.count("[") - str_o.count("]")
            if brackets < 0:
                tabLevel = tabLevel + brackets
            if tabLevel < 0:
                print("Indentation Warning: tabLevel = %s" % tabLevel)
                tabLevel = 0
            if tabLevel >= 1:
                file.write("%s" % tab * tabLevel)
            file.write(str_o)
            if brackets > 0:
                tabLevel = tabLevel + brackets
        else:
            file.write(str_o)
Luca Bonavita's avatar
Luca Bonavita committed
    def uniqueName(name, nameSeq):

        if name not in nameSeq:
            return name

        name_orig = name
        i = 1
        while name in nameSeq:
Luca Bonavita's avatar
Luca Bonavita committed
            i += 1
Luca Bonavita's avatar
Luca Bonavita committed
        return name

    def writeMatrix(matrix):
        tabWrite("matrix <%.6f, %.6f, %.6f,  %.6f, %.6f, %.6f,  %.6f, %.6f, %.6f,  %.6f, %.6f, %.6f>\n" %\
Luca Bonavita's avatar
Luca Bonavita committed
        (matrix[0][0], matrix[0][1], matrix[0][2], matrix[1][0], matrix[1][1], matrix[1][2], matrix[2][0], matrix[2][1], matrix[2][2], matrix[3][0], matrix[3][1], matrix[3][2]))

    def writeObjectMaterial(material, ob):
        # DH - modified some variables to be function local, avoiding RNA write
        # this should be checked to see if it is functionally correct
        if material:  # and material.transparency_method == 'RAYTRACE':  # Commented out: always write IOR to be able to use it for SSS, Fresnel reflections...
            # But there can be only one!
            if material.subsurface_scattering.use:  # SSS IOR get highest priority
                tabWrite("interior {\n")
                tabWrite("ior %.6f\n" % material.subsurface_scattering.ior)
            elif material.pov_mirror_use_IOR:  # Then the raytrace IOR taken from raytrace transparency properties and used for reflections if IOR Mirror option is checked
                tabWrite("interior {\n")
                tabWrite("ior %.6f\n" % material.raytrace_transparency.ior)
Maurice Raybaud's avatar
Maurice Raybaud committed
            else:
                tabWrite("interior {\n")
                tabWrite("ior %.6f\n" % material.raytrace_transparency.ior)
            pov_fake_caustics = False
            pov_photons_refraction = False
            pov_photons_reflection = False
            if material.pov_photons_reflection:
                pov_photons_reflection = True
            if material.pov_refraction_type == "0":
                pov_fake_caustics = False
                pov_photons_refraction = False
            elif material.pov_refraction_type == "1":
                pov_fake_caustics = True
                pov_photons_refraction = False
            elif material.pov_refraction_type == "2":
                pov_fake_caustics = False
                pov_photons_refraction = True
Luca Bonavita's avatar
Luca Bonavita committed

            #If only Raytrace transparency is set, its IOR will be used for refraction, but user can set up 'un-physical' fresnel reflections in raytrace mirror parameters.
            #Last, if none of the above is specified, user can set up 'un-physical' fresnel reflections in raytrace mirror parameters. And pov IOR defaults to 1.
Maurice Raybaud's avatar
Maurice Raybaud committed
            if material.pov_caustics_enable:
                    tabWrite("caustics %.3g\n" % material.pov_fake_caustics_power)
                    tabWrite("dispersion %.3g\n" % material.pov_photons_dispersion)  # Default of 1 means no dispersion
Luca Bonavita's avatar
Luca Bonavita committed
            # Other interior args
            if material.use_transparency and material.transparency_method == 'RAYTRACE':
                # fade_distance
                # In Blender this value has always been reversed compared to what tooltip says. 100.001 rather than 100 so that it does not get to 0
                # which deactivates the feature in POV
                tabWrite("fade_distance %.3g\n" % (100.001 - material.raytrace_transparency.depth_max))
                # fade_power
                tabWrite("fade_power %.3g\n" % material.raytrace_transparency.falloff)
                # fade_color
                tabWrite("fade_color <%.3g, %.3g, %.3g>\n" % material.pov_interior_fade_color[:])
Luca Bonavita's avatar
Luca Bonavita committed

Maurice Raybaud's avatar
Maurice Raybaud committed
            # (variable) dispersion_samples (constant count for now)
Maurice Raybaud's avatar
Loading
Loading full blame...