Skip to content
Snippets Groups Projects
render.py 187 KiB
Newer Older
# ***** 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

Luca Bonavita's avatar
Luca Bonavita committed
import bpy
import subprocess
import os
import sys
import time
from math import atan, pi, degrees, sqrt, cos, sin
Maurice Raybaud's avatar
Maurice Raybaud committed
import random
import platform#
import subprocess#
from bpy.types import(Operator)
from . import df3 # for smoke rendering
from . import shading # for BI POV haders emulation
from . import primitives # for import and export of POV specific primitives
Maurice Raybaud's avatar
Maurice Raybaud committed
##############################SF###########################
##############find image texture
Maurice Raybaud's avatar
Maurice Raybaud committed
def imageFormat(imgF):
    ext = {
        'JPG': "jpeg",
        'JPEG': "jpeg",
        'GIF': "gif",
        'TGA': "tga",
        'IFF': "iff",
        'PPM': "ppm",
        'PNG': "png",
        'SYS': "sys",
        'TIFF': "tiff",
        'TIF': "tiff",
        'EXR': "exr",
        'HDR': "hdr",
    }.get(os.path.splitext(imgF)[-1].upper(), "")

Maurice Raybaud's avatar
Maurice Raybaud committed
    #if not ext:
        #print(" WARNING: texture image has no extension") #too verbose 
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 " 
    elif ts.mapping == 'TUBE':
        image_map = "map_type 2 "

    ## map_type 3 and 4 in development (?)
    ## for POV-Ray, currently they just seem to default back to Flat (type 0)
    #    image_map = " map_type 3 "
    #    image_map = " map_type 4 "
    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

def imgMapTransforms(ts):
    # XXX TODO: unchecked textures give error of variable referenced before assignment XXX
    # POV-Ray "scale" is not a number of repetitions factor, but ,its
    # inverse, a standard scale factor.
    # 0.5 Offset is needed relatively to scale because center of the
    # scale is 0.5,0.5 in blender and 0,0 in POV
    image_map_transforms = ""
    image_map_transforms = ("scale <%.4g,%.4g,%.4g> translate <%.4g,%.4g,%.4g>" % \
                  ( 1.0 / ts.scale.x,
                  1.0 / ts.scale.y,
                  1.0 / ts.scale.z,
                  0.5-(0.5/ts.scale.x) - (ts.offset.x),
                  0.5-(0.5/ts.scale.y) - (ts.offset.y),
                  ts.offset.z))    
    # image_map_transforms = (" translate <-0.5,-0.5,0.0> scale <%.4g,%.4g,%.4g> translate <%.4g,%.4g,%.4g>" % \
                  # ( 1.0 / ts.scale.x,
                  # 1.0 / ts.scale.y,
                  # 1.0 / ts.scale.z,
                  # (0.5 / ts.scale.x) + ts.offset.x,
                  # (0.5 / ts.scale.y) + ts.offset.y,
                  # ts.offset.z))
    # image_map_transforms = ("translate <-0.5,-0.5,0> scale <-1,-1,1> * <%.4g,%.4g,%.4g> translate <0.5,0.5,0> + <%.4g,%.4g,%.4g>" % \
                  # (1.0 / ts.scale.x, 
                  # 1.0 / ts.scale.y,
                  # 1.0 / ts.scale.z,
                  # ts.offset.x,
                  # ts.offset.y,
                  # ts.offset.z))
    return image_map_transforms

Maurice Raybaud's avatar
Maurice Raybaud committed
def imgMapBG(wts):
    image_mapBG = ""
    # texture_coords refers to the mapping of world textures:
    if wts.texture_coords == 'VIEW' or wts.texture_coords == 'GLOBAL':
        image_mapBG = " map_type 0 "
    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 path_image(image):
    return bpy.path.abspath(image.filepath, library=image.library).replace("\\","/")
    # .replace("\\","/") to get only forward slashes as it's what POV prefers, 
    # even on windows
Campbell Barton's avatar
Campbell Barton committed
# end find image texture
# -----------------------------------------------------------------------------
Campbell Barton's avatar
Campbell Barton committed
def string_strip_hyphen(name):
    return name.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_"
Campbell Barton's avatar
Campbell Barton committed
    name = string_strip_hyphen(name)
        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

def is_renderable(ob):
    return (ob.hide_render==False)
def renderable_objects():
    return [ob for ob in bpy.data.objects if is_renderable(ob)]
user_dir = bpy.utils.resource_path('USER')
preview_dir = os.path.join(user_dir, "preview")

## Make sure Preview directory exists and is empty
smokePath = os.path.join(preview_dir, "smoke.df3")

def write_global_setting(scene,file):
    file.write("global_settings {\n")
    file.write("    assumed_gamma %.6f\n"%scene.pov.assumed_gamma)
    if scene.pov.global_settings_default == False:
        if scene.pov.adc_bailout_enable and scene.pov.radio_enable == False:
            file.write("    adc_bailout %.6f\n"%scene.pov.adc_bailout)
        if scene.pov.ambient_light_enable:
            file.write("    ambient_light <%.6f,%.6f,%.6f>\n"%scene.pov.ambient_light[:])
        if scene.pov.irid_wavelength_enable:
            file.write("    irid_wavelength <%.6f,%.6f,%.6f>\n"%scene.pov.irid_wavelength[:])
        if scene.pov.charset_enable:
            file.write("    charset %s\n"%scene.pov.charset)
        if scene.pov.max_trace_level_enable:
            file.write("    max_trace_level %s\n"%scene.pov.max_trace_level)    
        if scene.pov.max_intersections_enable:
            file.write("    max_intersections %s\n"%scene.pov.max_intersections)
        if scene.pov.number_of_waves_enable:
            file.write("    number_of_waves %s\n"%scene.pov.number_of_waves)
        if scene.pov.noise_generator_enable:
            file.write("    noise_generator %s\n"%scene.pov.noise_generator) 
    if scene.pov.sslt_enable:
        file.write("    mm_per_unit %s\n"%scene.pov.mm_per_unit) 
        file.write("    subsurface {\n")
        file.write("        samples %s, %s\n"%(scene.pov.sslt_samples_max,scene.pov.sslt_samples_min))
        if scene.pov.sslt_radiosity:
            file.write("        radiosity on\n")
        file.write("}\n")

    if scene.pov.radio_enable:
        file.write("    radiosity {\n")
        file.write("        pretrace_start %.6f\n"%scene.pov.radio_pretrace_start) 
        file.write("        pretrace_end %.6f\n"%scene.pov.radio_pretrace_end) 
        file.write("        count %s\n"%scene.pov.radio_count) 
        file.write("        nearest_count %s\n"%scene.pov.radio_nearest_count) 
        file.write("        error_bound %.6f\n"%scene.pov.radio_error_bound)         
        file.write("        recursion_limit %s\n"%scene.pov.radio_recursion_limit) 
        file.write("        low_error_factor %.6f\n"%scene.pov.radio_low_error_factor) 
        file.write("        gray_threshold %.6f\n"%scene.pov.radio_gray_threshold) 
        file.write("        maximum_reuse %.6f\n"%scene.pov.radio_maximum_reuse) 
        file.write("        minimum_reuse %.6f\n"%scene.pov.radio_minimum_reuse) 
        file.write("        brightness %.6f\n"%scene.pov.radio_brightness) 
        file.write("        adc_bailout %.6f\n"%scene.pov.radio_adc_bailout)
        if scene.pov.radio_normal:
            file.write("        normal on\n") 
        if scene.pov.radio_always_sample:
            file.write("        always_sample on\n") 
        if scene.pov.radio_media:
            file.write("        media on\n") 
        if scene.pov.radio_subsurface:
            file.write("        subsurface on\n")
        file.write("    }\n")

    if scene.pov.photon_enable:
        file.write("    photons {\n")
        if scene.pov.photon_enable_count:
            file.write("        count %s\n"%scene.pov.photon_count)
        else:
            file.write("        spacing %.6g\n"%scene.pov.photon_spacing)
        if scene.pov.photon_gather:
            file.write("        gather %s, %s\n"%(scene.pov.photon_gather_min,scene.pov.photon_gather_max))
        if scene.pov.photon_autostop:
            file.write("        autostop %.4g\n"%scene.pov.photon_autostop_value)
        if scene.pov.photon_jitter_enable:
            file.write("        jitter %.4g\n"%scene.pov.photon_jitter)
        file.write("        max_trace_level %s\n"%scene.pov.photon_max_trace_level)
        if scene.pov.photon_adc:
            file.write("        adc_bailout %.6f\n"%scene.pov.photon_adc_bailout)
        if scene.pov.photon_media_enable:
            file.write("        media %s, %s\n"%(scene.pov.photon_media_steps,scene.pov.photon_media_factor))
        if scene.pov.photon_savefile or scene.pov.photon_loadfile:
            filePh = bpy.path.abspath(scene.pov.photon_map_file)
            if scene.pov.photon_savefile:
                file.write('save_file "%s"\n'%filePh)
            if scene.pov.photon_loadfile and os.path.exists(filePh):
                file.write('load_file "%s"\n'%filePh)
        file.write("}\n")
    file.write("}\n")

def write_object_modifiers(scene,ob,File):
    if ob.pov.hollow:
        File.write("hollow\n")
    if ob.pov.double_illuminate:
        File.write("double_illuminate\n")
    if ob.pov.sturm:
        File.write("sturm\n")
    if ob.pov.no_shadow:
        File.write("no_shadow\n")
    if ob.pov.no_image:
        File.write("no_image\n")
    if ob.pov.no_reflection:
        File.write("no_reflection\n")
    if ob.pov.no_radiosity:
        File.write("no_radiosity\n")
    if ob.pov.inverse:
        File.write("inverse\n")
    if ob.pov.hierarchy:
        File.write("hierarchy\n")
    if scene.pov.photon_enable:
        File.write("photons {\n")
        if ob.pov.target:
            File.write("target %.4g\n"%ob.pov.target_value)
        if ob.pov.refraction:
            File.write("refraction on\n")
        if ob.pov.reflection:
            File.write("reflection on\n")
        if ob.pov.pass_through:
            File.write("pass_through\n")
        File.write("}\n")
    # if ob.pov.object_ior > 1:
        # File.write("interior {\n")
        # File.write("ior %.4g\n"%ob.pov.object_ior)
        # if scene.pov.photon_enable and ob.pov.target and ob.pov.refraction and ob.pov.dispersion:
            # File.write("ior %.4g\n"%ob.pov.dispersion_value)
            # File.write("ior %s\n"%ob.pov.dispersion_samples) 
        # if scene.pov.photon_enable == False:
            # File.write("caustics %.4g\n"%ob.pov.fake_caustics_power)
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')
    comments = scene.pov.comments_enable and not scene.pov.tempfiles_enable
    linebreaksinlists = scene.pov.list_lf_enable and not scene.pov.tempfiles_enable
    feature_set = bpy.context.user_preferences.addons[__package__].preferences.branch_feature_set_povray
    using_uberpov = (feature_set=='uberpov')
    pov_binary = PovrayRender._locate_binary()
    if using_uberpov:
        print("Unofficial UberPOV feature set chosen in preferences")
    else:
        print("Official POV-Ray 3.7 feature set chosen in preferences")
    if 'uber' in pov_binary: 
        print("The name of the binary suggests you are probably rendering with Uber POV engine")
        print("The name of the binary suggests you are probably rendering with standard POV engine")
    tab = setTab(scene.pov.indentation_character, scene.pov.indentation_spaces)
    if not scene.pov.tempfiles_enable:
        def tabWrite(str_o):
            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:
        def tabWrite(str_o):
            file.write(str_o)
Luca Bonavita's avatar
Luca Bonavita committed
    def uniqueName(name, nameSeq):

        if name not in nameSeq:
Campbell Barton's avatar
Campbell Barton committed
            name = string_strip_hyphen(name)
Luca Bonavita's avatar
Luca Bonavita committed
            return name

        name_orig = name
        i = 1
        while name in nameSeq:
Luca Bonavita's avatar
Luca Bonavita committed
            i += 1
Campbell Barton's avatar
Campbell Barton committed
        name = string_strip_hyphen(name)
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" %
                 (matrix[0][0], matrix[1][0], matrix[2][0],
                  matrix[0][1], matrix[1][1], matrix[2][1],
                  matrix[0][2], matrix[1][2], matrix[2][2],
                  matrix[0][3], matrix[1][3], matrix[2][3]))
Luca Bonavita's avatar
Luca Bonavita committed

        sMatrix = ("matrix <%.6f, %.6f, %.6f,  %.6f, %.6f, %.6f,  %.6f, %.6f, %.6f,  %.6f, %.6f, %.6f>\n" %
                   (matrix[0][0], matrix[1][0], matrix[2][0],
                    matrix[0][1], matrix[1][1], matrix[2][1],
                    matrix[0][2], matrix[1][2], matrix[2][2],
                    matrix[0][3], matrix[1][3], matrix[2][3]))
    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
        # Commented out: always write IOR to be able to use it for SSS, Fresnel reflections...
        #if material and material.transparency_method == 'RAYTRACE':
        if material:
            # 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)
            # Then the raytrace IOR taken from raytrace transparency properties and used for
            # reflections if IOR Mirror option is checked.
            elif material.pov.mirror_use_IOR:
                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
                pov_photons_reflection = True
                pov_fake_caustics = False
                pov_photons_refraction = False
                pov_fake_caustics = True
                pov_photons_refraction = False
                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.
            if material.pov.caustics_enable:
                    tabWrite("caustics %.3g\n" % material.pov.fake_caustics_power)
                    # Default of 1 means no dispersion
                    tabWrite("dispersion %.6f\n" % material.pov.photons_dispersion)
                    tabWrite("dispersion_samples %.d\n" % material.pov.photons_dispersion_samples)
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)
            if material.pov.photons_reflection or material.pov.refraction_type=="2":
                tabWrite("photons{")
                tabWrite("target %.3g\n" % ob.pov.spacing_multiplier)
                if not ob.pov.collect_photons:
                    tabWrite("collect off\n")
                if pov_photons_refraction:
                    tabWrite("refraction on\n")
                if pov_photons_reflection:
                    tabWrite("reflection on\n")
                tabWrite("}\n")
Luca Bonavita's avatar
Luca Bonavita committed
    materialNames = {}
    DEF_MAT_NAME = "" #or "Default"?
Luca Bonavita's avatar
Luca Bonavita committed
    def exportCamera():
        camera = scene.camera
        # DH disabled for now, this isn't the correct context
        active_object = None  # bpy.context.active_object # does not always work  MR
        matrix = global_matrix * camera.matrix_world
        focal_point = camera.data.dof_distance
Luca Bonavita's avatar
Luca Bonavita committed

        # compute resolution
        Qsize = render.resolution_x / render.resolution_y
        tabWrite("#declare camLocation  = <%.6f, %.6f, %.6f>;\n" %
                 matrix.translation[:])
        tabWrite("#declare camLookAt = <%.6f, %.6f, %.6f>;\n" %
                 tuple([degrees(e) for e in matrix.to_3x3().to_euler()]))
Luca Bonavita's avatar
Luca Bonavita committed

        if scene.pov.baking_enable and active_object and active_object.type == 'MESH':
            tabWrite("mesh_camera{ 1 3\n")  # distribution 3 is what we want here
            tabWrite("mesh{%s}\n" % active_object.name)
            tabWrite("}\n")
            tabWrite("location <0,0,.01>")
            tabWrite("direction <0,0,-1>")
Maurice Raybaud's avatar
Maurice Raybaud committed
        # Using standard camera otherwise
        else:
            tabWrite("location  <0, 0, 0>\n")
            tabWrite("look_at  <0, 0, -1>\n")
            tabWrite("right <%s, 0, 0>\n" % - Qsize)
            tabWrite("up <0, 1, 0>\n")
            tabWrite("angle  %f\n" % (360.0 * atan(16.0 / camera.data.lens) / pi))

            tabWrite("rotate  <%.6f, %.6f, %.6f>\n" % \
                     tuple([degrees(e) for e in matrix.to_3x3().to_euler()]))
            tabWrite("translate <%.6f, %.6f, %.6f>\n" % matrix.translation[:])
            if camera.data.pov.dof_enable and focal_point != 0:
                tabWrite("aperture %.3g\n" % camera.data.pov.dof_aperture)
                tabWrite("blur_samples %d %d\n" % \
                         (camera.data.pov.dof_samples_min, camera.data.pov.dof_samples_max))
                tabWrite("variance 1/%d\n" % camera.data.pov.dof_variance)
                tabWrite("confidence %.3g\n" % camera.data.pov.dof_confidence)
                tabWrite("focal_point <0, 0, %f>\n" % focal_point)
        tabWrite("}\n")
Luca Bonavita's avatar
Luca Bonavita committed

Luca Bonavita's avatar
Luca Bonavita committed
    def exportLamps(lamps):
        # Incremented after each lamp export to declare its target
        # currently used for Fresnel diffuse shader as their slope vector:
        global lampCount
        lampCount = 0
Luca Bonavita's avatar
Luca Bonavita committed
        # Get all lamps
        for ob in lamps:
            lamp = ob.data

            matrix = global_matrix * ob.matrix_world
Luca Bonavita's avatar
Luca Bonavita committed

            # Color is modified by energy #muiltiplie by 2 for a better match --Maurice
            color = tuple([c * lamp.energy * 2.0 for c in lamp.color])
Luca Bonavita's avatar
Luca Bonavita committed

            tabWrite("light_source {\n")
            tabWrite("< 0,0,0 >\n")
            tabWrite("color rgb<%.3g, %.3g, %.3g>\n" % color)
Luca Bonavita's avatar
Luca Bonavita committed

            if lamp.type == 'POINT':
Luca Bonavita's avatar
Luca Bonavita committed
                pass
            elif lamp.type == 'SPOT':
Luca Bonavita's avatar
Luca Bonavita committed

                # Falloff is the main radius from the centre line
                tabWrite("falloff %.2f\n" % (degrees(lamp.spot_size) / 2.0))  # 1 TO 179 FOR BOTH
                tabWrite("radius %.6f\n" % \
                         ((degrees(lamp.spot_size) / 2.0) * (1.0 - lamp.spot_blend)))
Luca Bonavita's avatar
Luca Bonavita committed

                # Blender does not have a tightness equivilent, 0 is most like blender default.
Luca Bonavita's avatar
Luca Bonavita committed

Luca Bonavita's avatar
Luca Bonavita committed
            elif lamp.type == 'SUN':
                tabWrite("parallel\n")
                tabWrite("point_at  <0, 0, -1>\n")  # *must* be after 'parallel'
Luca Bonavita's avatar
Luca Bonavita committed

            elif lamp.type == 'AREA':
                tabWrite("area_illumination\n")
                tabWrite("fade_distance %.6f\n" % (lamp.distance / 2.0))
                # Area lights have no falloff type, so always use blenders lamp quad equivalent
                # for those?
                tabWrite("fade_power %d\n" % 2)
Luca Bonavita's avatar
Luca Bonavita committed
                size_x = lamp.size
                samples_x = lamp.shadow_ray_samples_x
                if lamp.shape == 'SQUARE':
                    size_y = size_x
                    samples_y = samples_x
                else:
                    size_y = lamp.size_y
                    samples_y = lamp.shadow_ray_samples_y

                tabWrite("area_light <%.6f,0,0>,<0,%.6f,0> %d, %d\n" % \
                         (size_x, size_y, samples_x, samples_y))
                if lamp.shadow_ray_sample_method == 'CONSTANT_JITTERED':
Luca Bonavita's avatar
Luca Bonavita committed
                else:
                    tabWrite("adaptive 1\n")
                    tabWrite("jitter\n")
Luca Bonavita's avatar
Luca Bonavita committed

            # HEMI never has any shadow_method attribute
            if(not scene.render.use_shadows or lamp.type == 'HEMI' or
               (lamp.type != 'HEMI' and lamp.shadow_method == 'NOSHADOW')):
Luca Bonavita's avatar
Luca Bonavita committed

            # Sun shouldn't be attenuated. Hemi and area lights have no falloff attribute so they
            # are put to type 2 attenuation a little higher above.
            if lamp.type not in {'SUN', 'AREA', 'HEMI'}:
                tabWrite("fade_distance %.6f\n" % (lamp.distance / 2.0))
Maurice Raybaud's avatar
Maurice Raybaud committed
                if lamp.falloff_type == 'INVERSE_SQUARE':
                    tabWrite("fade_power %d\n" % 2)  # Use blenders lamp quad equivalent
Maurice Raybaud's avatar
Maurice Raybaud committed
                elif lamp.falloff_type == 'INVERSE_LINEAR':
                    tabWrite("fade_power %d\n" % 1)  # Use blenders lamp linear
                # supposing using no fade power keyword would default to constant, no attenuation.
Maurice Raybaud's avatar
Maurice Raybaud committed
                    pass
                # Using Custom curve for fade power 3 for now.
                elif lamp.falloff_type == 'CUSTOM_CURVE':
Luca Bonavita's avatar
Luca Bonavita committed
            writeMatrix(matrix)


            lampCount += 1

            # v(A,B) rotates vector A about origin by vector B.
            file.write("#declare lampTarget%s= vrotate(<%.4g,%.4g,%.4g>,<%.4g,%.4g,%.4g>);\n" % \
                       (lampCount, -(ob.location.x), -(ob.location.y), -(ob.location.z),
                        ob.rotation_euler.x, ob.rotation_euler.y, ob.rotation_euler.z))
####################################################################################################
616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322
    def exportRainbows(rainbows):
        for ob in rainbows:
            povdataname = ob.data.name #enough?
            angle = degrees(ob.data.spot_size/2.5) #radians in blender (2
            width = ob.data.spot_blend *10
            distance = ob.data.shadow_buffer_clip_start 
            #eps=0.0000001
            #angle = br/(cr+eps) * 10 #eps is small epsilon variable to avoid dividing by zero
            #width = ob.dimensions[2] #now let's say width of rainbow is the actual proxy height
            # formerly:
            #cz-bz # let's say width of the rainbow is height of the cone (interfacing choice
            
            # v(A,B) rotates vector A about origin by vector B.
            # and avoid a 0 length vector by adding 1
            
            # file.write("#declare %s_Target= vrotate(<%.6g,%.6g,%.6g>,<%.4g,%.4g,%.4g>);\n" % \
                       # (povdataname, -(ob.location.x+0.1), -(ob.location.y+0.1), -(ob.location.z+0.1),
                        # ob.rotation_euler.x, ob.rotation_euler.y, ob.rotation_euler.z))                    
            
            direction = (ob.location.x,ob.location.y,ob.location.z) # not taking matrix into account
            rmatrix = global_matrix * ob.matrix_world
            
            #ob.rotation_euler.to_matrix().to_4x4() * mathutils.Vector((0,0,1))
            # XXX Is result of the below offset by 90 degrees?
            up =ob.matrix_world.to_3x3()[1].xyz #* global_matrix 


            # XXX TO CHANGE: 
            #formerly:
            #tabWrite("#declare %s = rainbow {\n"%povdataname) 
            
            # clumsy for now but remove the rainbow from instancing
            # system because not an object. use lamps later instead of meshes
            
            #del data_ref[dataname]
            tabWrite("rainbow {\n")

            tabWrite("angle %.4f\n"%angle)
            tabWrite("width %.4f\n"%width)
            tabWrite("distance %.4f\n"%distance)
            tabWrite("arc_angle %.4f\n"%ob.pov.arc_angle)
            tabWrite("falloff_angle %.4f\n"%ob.pov.falloff_angle)
            tabWrite("direction <%.4f,%.4f,%.4f>\n"%rmatrix.translation[:])
            tabWrite("up <%.4f,%.4f,%.4f>\n"%(up[0],up[1],up[2]))
            tabWrite("color_map {\n")
            tabWrite("[0.000  color rgbt<1.0, 0.5, 1.0, 1.0>]\n")
            tabWrite("[0.130  color rgbt<0.5, 0.5, 1.0, 0.9>]\n")
            tabWrite("[0.298  color rgbt<0.2, 0.2, 1.0, 0.7>]\n")
            tabWrite("[0.412  color rgbt<0.2, 1.0, 1.0, 0.4>]\n")
            tabWrite("[0.526  color rgbt<0.2, 1.0, 0.2, 0.4>]\n")
            tabWrite("[0.640  color rgbt<1.0, 1.0, 0.2, 0.4>]\n")
            tabWrite("[0.754  color rgbt<1.0, 0.5, 0.2, 0.6>]\n")
            tabWrite("[0.900  color rgbt<1.0, 0.2, 0.2, 0.7>]\n")
            tabWrite("[1.000  color rgbt<1.0, 0.2, 0.2, 1.0>]\n")
            tabWrite("}\n")
            
            
            povMatName = "Default_texture"
            #tabWrite("texture {%s}\n"%povMatName)
            write_object_modifiers(scene,ob,file)
            #tabWrite("rotate x*90\n")
            #matrix = global_matrix * ob.matrix_world
            #writeMatrix(matrix)
            tabWrite("}\n")
            #continue #Don't render proxy mesh, skip to next object
            
################################XXX LOFT, ETC.
    def exportCurves(scene, ob):
        name_orig = "OB" + ob.name
        dataname_orig = "DATA" + ob.data.name

        name = string_strip_hyphen(bpy.path.clean_name(name_orig))
        dataname = string_strip_hyphen(bpy.path.clean_name(dataname_orig))

        global_matrix = mathutils.Matrix.Rotation(-pi / 2.0, 4, 'X')
        matrix=global_matrix*ob.matrix_world
        bezier_sweep = False
        if ob.pov.curveshape == 'sphere_sweep':
            for spl in ob.data.splines:
                if spl.type == "BEZIER":
                    bezier_sweep = True
        if ob.pov.curveshape in {'loft','birail'}:
            n=0
            for spline in ob.data.splines:
                n+=1
                tabWrite('#declare %s%s=spline {\n'%(dataname,n))
                tabWrite('cubic_spline\n')
                lp = len(spline.points)
                delta = 1/(lp)
                d=-delta
                point = spline.points[lp-1]
                x,y,z,w  = point.co[:]
                tabWrite('%.6f, <%.6f,%.6f,%.6f>\n'%(d,x,y,z))
                d+=delta
                for point in spline.points:
                    x,y,z,w  = point.co[:]
                    tabWrite('%.6f, <%.6f,%.6f,%.6f>\n'%(d,x,y,z))
                    d+=delta
                for i in range(2):
                    point = spline.points[i]
                    x,y,z,w  = point.co[:]
                    tabWrite('%.6f, <%.6f,%.6f,%.6f>\n'%(d,x,y,z))
                    d+=delta
                tabWrite('}\n')
            if ob.pov.curveshape in {'loft'}:
                n = len(ob.data.splines)
                tabWrite('#declare %s = array[%s]{\n'%(dataname,(n+3)))
                tabWrite('spline{%s%s},\n'%(dataname,n))
                for i in range(n):
                    tabWrite('spline{%s%s},\n'%(dataname,(i+1)))
                tabWrite('spline{%s1},\n'%(dataname))
                tabWrite('spline{%s2}\n'%(dataname))
                tabWrite('}\n')
            # Use some of the Meshmaker.inc macro, here inlined
            file.write('#macro CheckFileName(FileName)\n')
            file.write('   #local Len=strlen(FileName);\n')
            file.write('   #if(Len>0)\n')
            file.write('      #if(file_exists(FileName))\n')
            file.write('         #if(Len>=4)\n')
            file.write('            #local Ext=strlwr(substr(FileName,Len-3,4))\n')
            file.write('            #if (strcmp(Ext,".obj")=0 | strcmp(Ext,".pcm")=0 | strcmp(Ext,".arr")=0)\n')
            file.write('               #local Return=99;\n')
            file.write('            #else\n')
            file.write('               #local Return=0;\n')
            file.write('            #end\n')
            file.write('         #else\n')
            file.write('            #local Return=0;\n')
            file.write('         #end\n')
            file.write('      #else\n')
            file.write('         #if(Len>=4)\n')
            file.write('            #local Ext=strlwr(substr(FileName,Len-3,4))\n')
            file.write('            #if (strcmp(Ext,".obj")=0 | strcmp(Ext,".pcm")=0 | strcmp(Ext,".arr")=0)\n')
            file.write('               #if (strcmp(Ext,".obj")=0)\n')
            file.write('                  #local Return=2;\n')
            file.write('               #end\n')
            file.write('               #if (strcmp(Ext,".pcm")=0)\n')
            file.write('                  #local Return=3;\n')
            file.write('               #end\n')
            file.write('               #if (strcmp(Ext,".arr")=0)\n')
            file.write('                  #local Return=4;\n')
            file.write('               #end\n')
            file.write('            #else\n')
            file.write('               #local Return=1;\n')
            file.write('            #end\n')
            file.write('         #else\n')
            file.write('            #local Return=1;\n')
            file.write('         #end\n')
            file.write('      #end\n')
            file.write('   #else\n')
            file.write('      #local Return=1;\n')
            file.write('   #end\n')
            file.write('   (Return)\n')
            file.write('#end\n')

            file.write('#macro BuildSpline(Arr, SplType)\n')
            file.write('   #local Ds=dimension_size(Arr,1);\n')
            file.write('   #local Asc=asc(strupr(SplType));\n')
            file.write('   #if(Asc!=67 & Asc!=76 & Asc!=81) \n')
            file.write('      #local Asc=76;\n')
            file.write('      #debug "\nWrong spline type defined (C/c/L/l/N/n/Q/q), using default linear_spline\\n"\n')
            file.write('   #end\n')
            file.write('   spline {\n')
            file.write('      #switch (Asc)\n')
            file.write('         #case (67) //C  cubic_spline\n')
            file.write('            cubic_spline\n')
            file.write('         #break\n')
            file.write('         #case (76) //L  linear_spline\n')
            file.write('            linear_spline\n')
            file.write('         #break\n')
            file.write('         #case (78) //N  linear_spline\n')
            file.write('            natural_spline\n')
            file.write('         #break\n')
            file.write('         #case (81) //Q  Quadratic_spline\n')
            file.write('            quadratic_spline\n')
            file.write('         #break\n')
            file.write('      #end\n')
            file.write('      #local Add=1/((Ds-2)-1);\n')
            file.write('      #local J=0-Add;\n')
            file.write('      #local I=0;\n')
            file.write('      #while (I<Ds)\n')
            file.write('         J\n')
            file.write('         Arr[I]\n')
            file.write('         #local I=I+1;\n')
            file.write('         #local J=J+Add;\n')
            file.write('      #end\n')
            file.write('   }\n')
            file.write('#end\n')


            file.write('#macro BuildWriteMesh2(VecArr, NormArr, UVArr, U, V, FileName)\n')
            #suppressed some file checking from original macro because no more separate files
            file.write(' #local Write=0;\n')
            file.write(' #debug concat("\\n\\n Building mesh2: \\n   - vertex_vectors\\n")\n')
            file.write('  #local NumVertices=dimension_size(VecArr,1);\n')
            file.write('  #switch (Write)\n')
            file.write('     #case(1)\n')
            file.write('        #write(\n')
            file.write('           MeshFile,\n')
            file.write('           "  vertex_vectors {\\n",\n')
            file.write('           "    ", str(NumVertices,0,0),"\\n    "\n')
            file.write('        )\n')
            file.write('     #break\n')
            file.write('     #case(2)\n')
            file.write('        #write(\n')
            file.write('           MeshFile,\n')
            file.write('           "# Vertices: ",str(NumVertices,0,0),"\\n"\n')
            file.write('        )\n')
            file.write('     #break\n')
            file.write('     #case(3)\n')
            file.write('        #write(\n')
            file.write('           MeshFile,\n')
            file.write('           str(2*NumVertices,0,0),",\\n"\n')
            file.write('        )\n')
            file.write('     #break\n')
            file.write('     #case(4)\n')
            file.write('        #write(\n')
            file.write('           MeshFile,\n')
            file.write('           "#declare VertexVectors= array[",str(NumVertices,0,0),"] {\\n  "\n')
            file.write('        )\n')
            file.write('     #break\n')
            file.write('  #end\n')
            file.write('  mesh2 {\n')
            file.write('     vertex_vectors {\n')
            file.write('        NumVertices\n')
            file.write('        #local I=0;\n')
            file.write('        #while (I<NumVertices)\n')
            file.write('           VecArr[I]\n')
            file.write('           #switch(Write)\n')
            file.write('              #case(1)\n')
            file.write('                 #write(MeshFile, VecArr[I])\n')
            file.write('              #break\n')
            file.write('              #case(2)\n')
            file.write('                 #write(\n')
            file.write('                    MeshFile,\n')
            file.write('                    "v ", VecArr[I].x," ", VecArr[I].y," ", VecArr[I].z,"\\n"\n')
            file.write('                 )\n')
            file.write('              #break\n')
            file.write('              #case(3)\n')
            file.write('                 #write(\n')
            file.write('                    MeshFile,\n')
            file.write('                    VecArr[I].x,",", VecArr[I].y,",", VecArr[I].z,",\\n"\n')
            file.write('                 )\n')
            file.write('              #break\n')
            file.write('              #case(4)\n')
            file.write('                 #write(MeshFile, VecArr[I])\n')
            file.write('              #break\n')
            file.write('           #end\n')
            file.write('           #local I=I+1;\n')
            file.write('           #if(Write=1 | Write=4)\n')
            file.write('              #if(mod(I,3)=0)\n')
            file.write('                 #write(MeshFile,"\\n    ")\n')
            file.write('              #end\n')
            file.write('           #end \n')
            file.write('        #end\n')
            file.write('        #switch(Write)\n')
            file.write('           #case(1)\n')
            file.write('              #write(MeshFile,"\\n  }\\n")\n')
            file.write('           #break\n')
            file.write('           #case(2)\n')
            file.write('              #write(MeshFile,"\\n")\n')
            file.write('           #break\n')
            file.write('           #case(3)\n')
            file.write('              // do nothing\n')
            file.write('           #break\n')
            file.write('           #case(4) \n')
            file.write('              #write(MeshFile,"\\n}\\n")\n')
            file.write('           #break\n')
            file.write('        #end\n')
            file.write('     }\n')

            file.write('     #debug concat("   - normal_vectors\\n")    \n')
            file.write('     #local NumVertices=dimension_size(NormArr,1);\n')
            file.write('     #switch(Write)\n')
            file.write('        #case(1)\n')
            file.write('           #write(\n')
            file.write('              MeshFile,\n')
            file.write('              "  normal_vectors {\\n",\n')
            file.write('              "    ", str(NumVertices,0,0),"\\n    "\n')
            file.write('           )\n')
            file.write('        #break\n')
            file.write('        #case(2)\n')
            file.write('           #write(\n')
            file.write('              MeshFile,\n')
            file.write('              "# Normals: ",str(NumVertices,0,0),"\\n"\n')
            file.write('           )\n')
            file.write('        #break\n')
            file.write('        #case(3)\n')
            file.write('           // do nothing\n')
            file.write('        #break\n')
            file.write('        #case(4)\n')
            file.write('           #write(\n')
            file.write('              MeshFile,\n')
            file.write('              "#declare NormalVectors= array[",str(NumVertices,0,0),"] {\\n  "\n')
            file.write('           )\n')
            file.write('        #break\n')
            file.write('     #end\n')
            file.write('     normal_vectors {\n')
            file.write('        NumVertices\n')
            file.write('        #local I=0;\n')
            file.write('        #while (I<NumVertices)\n')
            file.write('           NormArr[I]\n')
            file.write('           #switch(Write)\n')
            file.write('              #case(1)\n')
            file.write('                 #write(MeshFile NormArr[I])\n')
            file.write('              #break\n')
            file.write('              #case(2)\n')
            file.write('                 #write(\n')
            file.write('                    MeshFile,\n')
            file.write('                    "vn ", NormArr[I].x," ", NormArr[I].y," ", NormArr[I].z,"\\n"\n')
            file.write('                 )\n')
            file.write('              #break\n')
            file.write('              #case(3)\n')
            file.write('                 #write(\n')
            file.write('                    MeshFile,\n')
            file.write('                    NormArr[I].x,",", NormArr[I].y,",", NormArr[I].z,",\\n"\n')
            file.write('                 )\n')
            file.write('              #break\n')
            file.write('              #case(4)\n')
            file.write('                 #write(MeshFile NormArr[I])\n')
            file.write('              #break\n')
            file.write('           #end\n')
            file.write('           #local I=I+1;\n')
            file.write('           #if(Write=1 | Write=4) \n')
            file.write('              #if(mod(I,3)=0)\n')
            file.write('                 #write(MeshFile,"\\n    ")\n')
            file.write('              #end\n')
            file.write('           #end\n')
            file.write('        #end\n')
            file.write('        #switch(Write)\n')
            file.write('           #case(1)\n')
            file.write('              #write(MeshFile,"\\n  }\\n")\n')
            file.write('           #break\n')
            file.write('           #case(2)\n')
            file.write('              #write(MeshFile,"\\n")\n')
            file.write('           #break\n')
            file.write('           #case(3)\n')
            file.write('              //do nothing\n')
            file.write('           #break\n')
            file.write('           #case(4)\n')
            file.write('              #write(MeshFile,"\\n}\\n")\n')
            file.write('           #break\n')
            file.write('        #end\n')
            file.write('     }\n')
     
            file.write('     #debug concat("   - uv_vectors\\n")   \n')
            file.write('     #local NumVertices=dimension_size(UVArr,1);\n')
            file.write('     #switch(Write)\n')
            file.write('        #case(1)\n')
            file.write('           #write(\n')
            file.write('              MeshFile, \n')
            file.write('              "  uv_vectors {\\n",\n')
            file.write('              "    ", str(NumVertices,0,0),"\\n    "\n')
            file.write('           )\n')
            file.write('         #break\n')
            file.write('         #case(2)\n')
            file.write('           #write(\n')
            file.write('              MeshFile,\n')
            file.write('              "# UV-vectors: ",str(NumVertices,0,0),"\\n"\n')
            file.write('           )\n')
            file.write('         #break\n')
            file.write('         #case(3)\n')
            file.write('           // do nothing, *.pcm does not support uv-vectors\n')
            file.write('         #break\n')
            file.write('         #case(4)\n')
            file.write('            #write(\n')
            file.write('               MeshFile,\n')
            file.write('               "#declare UVVectors= array[",str(NumVertices,0,0),"] {\\n  "\n')
            file.write('            )\n')
            file.write('         #break\n')
            file.write('     #end\n')
            file.write('     uv_vectors {\n')
            file.write('        NumVertices\n')
            file.write('        #local I=0;\n')
            file.write('        #while (I<NumVertices)\n')
            file.write('           UVArr[I]\n')
            file.write('           #switch(Write)\n')
            file.write('              #case(1)\n')
            file.write('                 #write(MeshFile UVArr[I])\n')
            file.write('              #break\n')
            file.write('              #case(2)\n')
            file.write('                 #write(\n')
            file.write('                    MeshFile,\n')
            file.write('                    "vt ", UVArr[I].u," ", UVArr[I].v,"\\n"\n')
            file.write('                 )\n')
            file.write('              #break\n')
            file.write('              #case(3)\n')
            file.write('                 //do nothing\n')
            file.write('              #break\n')
            file.write('              #case(4)\n')
            file.write('                 #write(MeshFile UVArr[I])\n')
            file.write('              #break\n')
            file.write('           #end\n')
            file.write('           #local I=I+1; \n')
            file.write('           #if(Write=1 | Write=4)\n')
            file.write('              #if(mod(I,3)=0)\n')
            file.write('                 #write(MeshFile,"\\n    ")\n')
            file.write('              #end \n')
            file.write('           #end\n')
            file.write('        #end \n')
            file.write('        #switch(Write)\n')
            file.write('           #case(1)\n')
            file.write('              #write(MeshFile,"\\n  }\\n")\n')
            file.write('           #break\n')
            file.write('           #case(2)\n')
            file.write('              #write(MeshFile,"\\n")\n')
            file.write('           #break\n')
            file.write('           #case(3)\n')
            file.write('              //do nothing\n')
            file.write('           #break\n')
            file.write('           #case(4)\n')
            file.write('              #write(MeshFile,"\\n}\\n")\n')
            file.write('           #break\n')
            file.write('        #end\n')
            file.write('     }\n')
            file.write('\n')
            file.write('     #debug concat("   - face_indices\\n")   \n')
            file.write('     #declare NumFaces=U*V*2;\n')
            file.write('     #switch(Write)\n')
            file.write('        #case(1)\n')
            file.write('           #write(\n')
            file.write('              MeshFile,\n')
            file.write('              "  face_indices {\\n"\n')
            file.write('              "    ", str(NumFaces,0,0),"\\n    "\n')
            file.write('           )\n')
            file.write('        #break\n')
            file.write('        #case(2)\n')
            file.write('           #write (\n')
            file.write('              MeshFile,\n')
            file.write('              "# faces: ",str(NumFaces,0,0),"\\n"\n')
            file.write('           )\n')
            file.write('        #break\n')
            file.write('        #case(3)\n')
            file.write('           #write (\n')
            file.write('              MeshFile,\n')
            file.write('              "0,",str(NumFaces,0,0),",\\n"\n')
            file.write('           )\n')
            file.write('        #break\n')
            file.write('        #case(4)\n')
            file.write('           #write(\n')
            file.write('              MeshFile,\n')
            file.write('              "#declare FaceIndices= array[",str(NumFaces,0,0),"] {\\n  "\n')
            file.write('           )\n')
            file.write('        #break\n')
            file.write('     #end\n')
            file.write('     face_indices {\n')
            file.write('        NumFaces\n')
            file.write('        #local I=0;\n')
            file.write('        #local H=0;\n')
            file.write('        #local NumVertices=dimension_size(VecArr,1);\n')
            file.write('        #while (I<V)\n')
            file.write('           #local J=0;\n')
            file.write('           #while (J<U)\n')
            file.write('              #local Ind=(I*U)+I+J;\n')
            file.write('              <Ind, Ind+1, Ind+U+2>, <Ind, Ind+U+1, Ind+U+2>\n')
            file.write('              #switch(Write)\n')
            file.write('                 #case(1)\n')
            file.write('                    #write(\n')
            file.write('                       MeshFile,\n')
            file.write('                       <Ind, Ind+1, Ind+U+2>, <Ind, Ind+U+1, Ind+U+2>\n')
            file.write('                    )\n')
            file.write('                 #break\n')
            file.write('                 #case(2)\n')
            file.write('                    #write(\n')
            file.write('                       MeshFile,\n')
            file.write('                       "f ",Ind+1,"/",Ind+1,"/",Ind+1," ",Ind+1+1,"/",Ind+1+1,"/",Ind+1+1," ",Ind+U+2+1,"/",Ind+U+2+1,"/",Ind+U+2+1,"\\n",\n')
            file.write('                       "f ",Ind+U+1+1,"/",Ind+U+1+1,"/",Ind+U+1+1," ",Ind+1,"/",Ind+1,"/",Ind+1," ",Ind+U+2+1,"/",Ind+U+2+1,"/",Ind+U+2+1,"\\n"\n')
            file.write('                    )\n')
            file.write('                 #break\n')
            file.write('                 #case(3)\n')
            file.write('                    #write(\n')
            file.write('                       MeshFile,\n')
            file.write('                       Ind,",",Ind+NumVertices,",",Ind+1,",",Ind+1+NumVertices,",",Ind+U+2,",",Ind+U+2+NumVertices,",\\n"\n')
            file.write('                       Ind+U+1,",",Ind+U+1+NumVertices,",",Ind,",",Ind+NumVertices,",",Ind+U+2,",",Ind+U+2+NumVertices,",\\n"\n')
            file.write('                    )\n')
            file.write('                 #break\n')
            file.write('                 #case(4)\n')
            file.write('                    #write(\n')
            file.write('                       MeshFile,\n')
            file.write('                       <Ind, Ind+1, Ind+U+2>, <Ind, Ind+U+1, Ind+U+2>\n')
            file.write('                    )\n')
            file.write('                 #break\n')
            file.write('              #end\n')
            file.write('              #local J=J+1;\n')
            file.write('              #local H=H+1;\n')
            file.write('              #if(Write=1 | Write=4)\n')
            file.write('                 #if(mod(H,3)=0)\n')
            file.write('                    #write(MeshFile,"\\n    ")\n')
            file.write('                 #end \n')
            file.write('              #end\n')
            file.write('           #end\n')
            file.write('           #local I=I+1;\n')
            file.write('        #end\n')
            file.write('     }\n')
            file.write('     #switch(Write)\n')
            file.write('        #case(1)\n')
            file.write('           #write(MeshFile, "\\n  }\\n}")\n')
            file.write('           #fclose MeshFile\n')
            file.write('           #debug concat(" Done writing\\n")\n')
            file.write('        #break\n')
            file.write('        #case(2)\n')
            file.write('           #fclose MeshFile\n')
            file.write('           #debug concat(" Done writing\\n")\n')
            file.write('        #break\n')
            file.write('        #case(3)\n')
            file.write('           #fclose MeshFile\n')
            file.write('           #debug concat(" Done writing\\n")\n')
            file.write('        #break\n')
            file.write('        #case(4)\n')
            file.write('           #write(MeshFile, "\\n}\\n}")\n')
            file.write('           #fclose MeshFile\n')
            file.write('           #debug concat(" Done writing\\n")\n')
            file.write('        #break\n')
            file.write('     #end\n')
            file.write('  }\n')
            file.write('#end\n')
            
            file.write('#macro MSM(SplineArray, SplRes, Interp_type,  InterpRes, FileName)\n')
            file.write('    #declare Build=CheckFileName(FileName);\n')
            file.write('    #if(Build=0)\n')
            file.write('        #debug concat("\\n Parsing mesh2 from file: ", FileName, "\\n")\n')
            file.write('        #include FileName\n')
            file.write('        object{Surface}\n')
            file.write('    #else\n')
            file.write('        #local NumVertices=(SplRes+1)*(InterpRes+1);\n')
            file.write('        #local NumFaces=SplRes*InterpRes*2;\n')
            file.write('        #debug concat("\\n Calculating ",str(NumVertices,0,0)," vertices for ", str(NumFaces,0,0)," triangles\\n\\n")\n')
            file.write('        #local VecArr=array[NumVertices]\n')
            file.write('        #local NormArr=array[NumVertices]\n')
            file.write('        #local UVArr=array[NumVertices]\n')
            file.write('        #local N=dimension_size(SplineArray,1);\n')
            file.write('        #local TempSplArr0=array[N];\n')
            file.write('        #local TempSplArr1=array[N];\n')
            file.write('        #local TempSplArr2=array[N];\n')
            file.write('        #local PosStep=1/SplRes;\n')
            file.write('        #local InterpStep=1/InterpRes;\n')
            file.write('        #local Count=0;\n')
            file.write('        #local Pos=0;\n')
            file.write('        #while(Pos<=1)\n')
            file.write('            #local I=0;\n')
            file.write('            #if (Pos=0)\n')
            file.write('                #while (I<N)\n')
            file.write('                    #local Spl=spline{SplineArray[I]}\n')
            file.write('                    #local TempSplArr0[I]=<0,0,0>+Spl(Pos);\n')
            file.write('                    #local TempSplArr1[I]=<0,0,0>+Spl(Pos+PosStep);\n')
            file.write('                    #local TempSplArr2[I]=<0,0,0>+Spl(Pos-PosStep);\n')
            file.write('                    #local I=I+1;\n')
            file.write('                #end\n')
            file.write('                #local S0=BuildSpline(TempSplArr0, Interp_type)\n')
            file.write('                #local S1=BuildSpline(TempSplArr1, Interp_type)\n')
            file.write('                #local S2=BuildSpline(TempSplArr2, Interp_type)\n')
            file.write('            #else\n')
            file.write('                #while (I<N)\n')
            file.write('                    #local Spl=spline{SplineArray[I]}\n')
            file.write('                    #local TempSplArr1[I]=<0,0,0>+Spl(Pos+PosStep);\n')
            file.write('                    #local I=I+1;\n')
            file.write('                #end\n')
            file.write('                #local S1=BuildSpline(TempSplArr1, Interp_type)\n')
            file.write('            #end\n')
            file.write('            #local J=0;\n')
            file.write('            #while (J<=1)\n')
            file.write('                #local P0=<0,0,0>+S0(J);\n')
            file.write('                #local P1=<0,0,0>+S1(J);\n')
            file.write('                #local P2=<0,0,0>+S2(J);\n')
            file.write('                #local P3=<0,0,0>+S0(J+InterpStep);\n')
            file.write('                #local P4=<0,0,0>+S0(J-InterpStep);\n')
            file.write('                #local B1=P4-P0;\n')
            file.write('                #local B2=P2-P0;\n')
            file.write('                #local B3=P3-P0;\n')
            file.write('                #local B4=P1-P0;\n')
            file.write('                #local N1=vcross(B1,B2);\n')
            file.write('                #local N2=vcross(B2,B3);\n')
            file.write('                #local N3=vcross(B3,B4);\n')
            file.write('                #local N4=vcross(B4,B1);\n')
            file.write('                #local Norm=vnormalize((N1+N2+N3+N4));\n')
            file.write('                #local VecArr[Count]=P0;\n')
            file.write('                #local NormArr[Count]=Norm;\n')
            file.write('                #local UVArr[Count]=<J,Pos>;\n')
            file.write('                #local J=J+InterpStep;\n')
            file.write('                #local Count=Count+1;\n')
            file.write('            #end\n')
            file.write('            #local S2=spline{S0}\n')
            file.write('            #local S0=spline{S1}\n')
            file.write('            #debug concat("\\r Done ", str(Count,0,0)," vertices : ", str(100*Count/NumVertices,0,2)," %")\n')
            file.write('            #local Pos=Pos+PosStep;\n')
            file.write('        #end\n')
            file.write('        BuildWriteMesh2(VecArr, NormArr, UVArr, InterpRes, SplRes, "")\n')
            file.write('    #end\n')
            file.write('#end\n\n')

            file.write('#macro Coons(Spl1, Spl2, Spl3, Spl4, Iter_U, Iter_V, FileName)\n')
            file.write('   #declare Build=CheckFileName(FileName);\n')
            file.write('   #if(Build=0)\n')
            file.write('      #debug concat("\\n Parsing mesh2 from file: ", FileName, "\\n")\n')
            file.write('      #include FileName\n')
            file.write('      object{Surface}\n')
            file.write('   #else\n')
            file.write('      #local NumVertices=(Iter_U+1)*(Iter_V+1);\n')
            file.write('      #local NumFaces=Iter_U*Iter_V*2;\n')
            file.write('      #debug concat("\\n Calculating ", str(NumVertices,0,0), " vertices for ",str(NumFaces,0,0), " triangles\\n\\n")\n')
            file.write('      #declare VecArr=array[NumVertices]   \n')
            file.write('      #declare NormArr=array[NumVertices]   \n')
            file.write('      #local UVArr=array[NumVertices]      \n')
            file.write('      #local Spl1_0=Spl1(0);\n')
            file.write('      #local Spl2_0=Spl2(0);\n')
            file.write('      #local Spl3_0=Spl3(0);\n')
            file.write('      #local Spl4_0=Spl4(0);\n')
            file.write('      #local UStep=1/Iter_U;\n')
            file.write('      #local VStep=1/Iter_V;\n')
            file.write('      #local Count=0;\n')
            file.write('      #local I=0;\n')
            file.write('      #while (I<=1)\n')
            file.write('         #local Im=1-I;\n')
            file.write('         #local J=0;\n')
            file.write('         #while (J<=1)\n')
            file.write('            #local Jm=1-J;\n')
            file.write('            #local C0=Im*Jm*(Spl1_0)+Im*J*(Spl2_0)+I*J*(Spl3_0)+I*Jm*(Spl4_0);\n')
            file.write('            #local P0=LInterpolate(I, Spl1(J), Spl3(Jm)) + \n')
            file.write('               LInterpolate(Jm, Spl2(I), Spl4(Im))-C0;\n')
            file.write('            #declare VecArr[Count]=P0;\n')
            file.write('            #local UVArr[Count]=<J,I>;\n')
            file.write('            #local J=J+UStep;\n')
            file.write('            #local Count=Count+1;\n')
            file.write('         #end\n')
            file.write('         #debug concat(\n')
            file.write('            "\r Done ", str(Count,0,0)," vertices :         ",\n')
            file.write('            str(100*Count/NumVertices,0,2)," %"\n')
            file.write('         )\n')
            file.write('         #local I=I+VStep;\n')
            file.write('      #end\n')
            file.write('      #debug "\r Normals                                  "\n')
            file.write('      #local Count=0;\n')
            file.write('      #local I=0;\n')
            file.write('      #while (I<=Iter_V)\n')
            file.write('         #local J=0;\n')
            file.write('         #while (J<=Iter_U)\n')
            file.write('            #local Ind=(I*Iter_U)+I+J;\n')
            file.write('            #local P0=VecArr[Ind];\n')
            file.write('            #if(J=0)\n')
            file.write('               #local P1=P0+(P0-VecArr[Ind+1]);\n')
            file.write('            #else\n')
            file.write('               #local P1=VecArr[Ind-1];\n')
            file.write('            #end\n')
            file.write('            #if (J=Iter_U)\n')
            file.write('               #local P2=P0+(P0-VecArr[Ind-1]);\n')
            file.write('            #else\n')
            file.write('               #local P2=VecArr[Ind+1];\n')
            file.write('            #end\n')
            file.write('            #if (I=0)\n')
            file.write('               #local P3=P0+(P0-VecArr[Ind+Iter_U+1]);\n')
            file.write('            #else\n')
            file.write('               #local P3=VecArr[Ind-Iter_U-1];\n')
            file.write('            #end\n')
            file.write('            #if (I=Iter_V)\n')
            file.write('               #local P4=P0+(P0-VecArr[Ind-Iter_U-1]);\n')
            file.write('            #else\n')
            file.write('               #local P4=VecArr[Ind+Iter_U+1];\n')
            file.write('            #end\n')
            file.write('            #local B1=P4-P0;\n')
            file.write('            #local B2=P2-P0;\n')
            file.write('            #local B3=P3-P0;\n')
            file.write('            #local B4=P1-P0;\n')
            file.write('            #local N1=vcross(B1,B2);\n')
            file.write('            #local N2=vcross(B2,B3);\n')
            file.write('            #local N3=vcross(B3,B4);\n')
            file.write('            #local N4=vcross(B4,B1);\n')
            file.write('            #local Norm=vnormalize((N1+N2+N3+N4));\n')
            file.write('            #declare NormArr[Count]=Norm;\n')
            file.write('            #local J=J+1;\n')
            file.write('            #local Count=Count+1;\n')
            file.write('         #end\n')
            file.write('         #debug concat("\r Done ", str(Count,0,0)," normals : ",str(100*Count/NumVertices,0,2), " %")\n')
            file.write('         #local I=I+1;\n')
            file.write('      #end\n')
            file.write('      BuildWriteMesh2(VecArr, NormArr, UVArr, Iter_U, Iter_V, FileName)\n')
            file.write('   #end\n')
            file.write('#end\n\n')
            
        if bezier_sweep == False:
            tabWrite("#declare %s =\n"%dataname)
        if ob.pov.curveshape == 'sphere_sweep' and bezier_sweep == False:
            tabWrite("union {\n")
            for spl in ob.data.splines:
                if spl.type != "BEZIER":
                    spl_type = "linear"
                    if spl.type == "NURBS":
                        spl_type = "cubic"
                    points=spl.points
                    numPoints=len(points)
                    if spl.use_cyclic_u:
                        numPoints+=3

                    tabWrite("sphere_sweep { %s_spline %s,\n"%(spl_type,numPoints))
                    if spl.use_cyclic_u:
                        pt1 = points[len(points)-1]
                        wpt1 = pt1.co
                        tabWrite("<%.4g,%.4g,%.4g>,%.4g\n" %(wpt1[0], wpt1[1], wpt1[2], pt1.radius*ob.data.bevel_depth))
                    for pt in points:
                        wpt = pt.co
                        tabWrite("<%.4g,%.4g,%.4g>,%.4g\n" %(wpt[0], wpt[1], wpt[2], pt.radius*ob.data.bevel_depth))
                    if spl.use_cyclic_u:
                        for i in range (0,2):
                            endPt=points[i]
                            wpt = endPt.co
                            tabWrite("<%.4g,%.4g,%.4g>,%.4g\n" %(wpt[0], wpt[1], wpt[2], endPt.radius*ob.data.bevel_depth))

                    
                tabWrite("}\n")
Luca Bonavita's avatar
Luca Bonavita committed

        if ob.pov.curveshape == 'sor':
            for spl in ob.data.splines:
                if spl.type in {'POLY','NURBS'}:
                    points=spl.points
                    numPoints=len(points)
                    tabWrite("sor { %s,\n"%numPoints)
                    for pt in points:
                        wpt = pt.co
                        tabWrite("<%.4g,%.4g>\n" %(wpt[0], wpt[1]))
                else:
                    tabWrite("box { 0,0\n")
        if ob.pov.curveshape in {'lathe','prism'}:
            spl = ob.data.splines[0]
            if spl.type == "BEZIER":
                points=spl.bezier_points
                lenCur=len(points)-1
                lenPts=lenCur*4
                ifprism = ''
                if ob.pov.curveshape in {'prism'}:
                    height = ob.data.extrude
                    ifprism = '-%s, %s,'%(height, height)
                    lenCur+=1
                    lenPts+=4
                tabWrite("%s { bezier_spline %s %s,\n"%(ob.pov.curveshape,ifprism,lenPts))
                for i in range(0,lenCur):
                    p1=points[i].co
                    pR=points[i].handle_right
                    end = i+1
                    if i == lenCur-1 and ob.pov.curveshape in {'prism'}:
                        end = 0
                    pL=points[end].handle_left
                    p2=points[end].co
                    line="<%.4g,%.4g>"%(p1[0],p1[1])
                    line+="<%.4g,%.4g>"%(pR[0],pR[1])
                    line+="<%.4g,%.4g>"%(pL[0],pL[1])
                    line+="<%.4g,%.4g>"%(p2[0],p2[1])
                    tabWrite("%s\n" %line)
            else:
                points=spl.points
                lenCur=len(points)
                lenPts=lenCur
                ifprism = ''
                if ob.pov.curveshape in {'prism'}:
                    height = ob.data.extrude
                    ifprism = '-%s, %s,'%(height, height)
                    lenPts+=3
                spl_type = 'quadratic'
                if spl.type == 'POLY':
                    spl_type = 'linear'
                tabWrite("%s { %s_spline %s %s,\n"%(ob.pov.curveshape,spl_type,ifprism,lenPts))
                if ob.pov.curveshape in {'prism'}:
                    pt = points[len(points)-1]
                    wpt = pt.co
                    tabWrite("<%.4g,%.4g>\n" %(wpt[0], wpt[1]))
                for pt in points:
                    wpt = pt.co
                    tabWrite("<%.4g,%.4g>\n" %(wpt[0], wpt[1]))
                if ob.pov.curveshape in {'prism'}:
                    for i in range(2):
                        pt = points[i]
                        wpt = pt.co
                        tabWrite("<%.4g,%.4g>\n" %(wpt[0], wpt[1]))
        if bezier_sweep:
            spl = ob.data.splines[0]
            points=spl.bezier_points
            lenCur = len(points)-1
            numPoints = lenCur*4
            if spl.use_cyclic_u:
                lenCur += 1
                numPoints += 4
            tabWrite("#declare %s_bezier_points = array[%s]{\n"%(dataname,numPoints))
            for i in range(lenCur):
                p1=points[i].co
                pR=points[i].handle_right
                end = i+1
                if spl.use_cyclic_u and i == (lenCur - 1):
                    end = 0
                pL=points[end].handle_left
                p2=points[end].co
                line="<%.4g,%.4g,%.4f>"%(p1[0],p1[1],p1[2])
                line+="<%.4g,%.4g,%.4f>"%(pR[0],pR[1],pR[2])
                line+="<%.4g,%.4g,%.4f>"%(pL[0],pL[1],pL[2])
                line+="<%.4g,%.4g,%.4f>"%(p2[0],p2[1],p2[2])
                tabWrite("%s\n" %line)
            tabWrite("}\n")
            #tabWrite('#include "bezier_spheresweep.inc"\n') #now inlined
            tabWrite('#declare %s = object{Shape_Bezierpoints_Sphere_Sweep(%s, %s_bezier_points, %.4f) \n'%(dataname,ob.data.resolution_u,dataname,ob.data.bevel_depth))
        if ob.pov.curveshape in {'loft'}:
            tabWrite('object {MSM(%s,%s,"c",%s,"")\n'%(dataname,ob.pov.res_u,ob.pov.res_v))
        if ob.pov.curveshape in {'birail'}:
            splines = '%s1,%s2,%s3,%s4'%(dataname,dataname,dataname,dataname)
            tabWrite('object {Coons(%s, %s, %s, "")\n'%(splines,ob.pov.res_u,ob.pov.res_v))
        povMatName = "Default_texture"
        if ob.active_material:
            #povMatName = string_strip_hyphen(bpy.path.clean_name(ob.active_material.name))
            try:
                material = ob.active_material
                writeObjectMaterial(material, ob)
            except IndexError:
                print(me)
        #tabWrite("texture {%s}\n"%povMatName)
        if ob.pov.curveshape in {'prism'}:
            tabWrite("rotate <90,0,0>\n")
            tabWrite("scale y*-1\n" )
        tabWrite("}\n")
        
#################################################################        
        
            
Luca Bonavita's avatar
Luca Bonavita committed
    def exportMeta(metas):

        # TODO - blenders 'motherball' naming is not supported.
        if comments and len(metas) >= 1:
            file.write("//--Blob objects--\n\n")
Luca Bonavita's avatar
Luca Bonavita committed
        for ob in metas:
            meta = ob.data

            # important because no elements will break parsing.
            elements = [elem for elem in meta.elements if elem.type in {'BALL', 'ELLIPSOID'}]
Luca Bonavita's avatar
Luca Bonavita committed

                tabWrite("blob {\n")
                tabWrite("threshold %.4g\n" % meta.threshold)
Luca Bonavita's avatar
Luca Bonavita committed

                    material = meta.materials[0]  # lame! - blender cant do enything else.
Luca Bonavita's avatar
Luca Bonavita committed

                for elem in elements:
                    loc = elem.co
Luca Bonavita's avatar
Luca Bonavita committed

                    stiffness = elem.stiffness
                    if elem.use_negative:
                        stiffness = - stiffness
Luca Bonavita's avatar
Luca Bonavita committed

                    if elem.type == 'BALL':
Luca Bonavita's avatar
Luca Bonavita committed

                        tabWrite("sphere { <%.6g, %.6g, %.6g>, %.4g, %.4g }\n" % \
                                 (loc.x, loc.y, loc.z, elem.radius, stiffness))
Luca Bonavita's avatar
Luca Bonavita committed

                        # After this wecould do something simple like...
                        # except we'll write the color
Luca Bonavita's avatar
Luca Bonavita committed

                    elif elem.type == 'ELLIPSOID':
                        # location is modified by scale
                        tabWrite("sphere { <%.6g, %.6g, %.6g>, %.4g, %.4g }\n" % \
                                 (loc.x / elem.size_x, loc.y / elem.size_y, loc.z / elem.size_z,
                                  elem.radius, stiffness))
                        tabWrite("scale <%.6g, %.6g, %.6g> \n" % \
                                 (elem.size_x, elem.size_y, elem.size_z))
Luca Bonavita's avatar
Luca Bonavita committed

                if material:
                    diffuse_color = material.diffuse_color
                    if material.use_transparency and material.transparency_method == 'RAYTRACE':
                        povFilter = material.raytrace_transparency.filter * (1.0 - material.alpha)
                        trans = (1.0 - material.alpha) - povFilter
                        povFilter = 0.0
Luca Bonavita's avatar
Luca Bonavita committed

                    material_finish = materialNames[material.name]
                    tabWrite("pigment {rgbft<%.3g, %.3g, %.3g, %.3g, %.3g>} \n" % \
                             (diffuse_color[0], diffuse_color[1], diffuse_color[2],
                              povFilter, trans))
                    tabWrite("finish {%s}\n" % safety(material_finish, Level=2))
Luca Bonavita's avatar
Luca Bonavita committed

                    tabWrite("pigment {rgb<1 1 1>} \n")
                    # Write the finish last.
                    tabWrite("finish {%s}\n" % (safety(DEF_MAT_NAME, Level=2)))
Luca Bonavita's avatar
Luca Bonavita committed

                writeObjectMaterial(material, ob)
Luca Bonavita's avatar
Luca Bonavita committed

                writeMatrix(global_matrix * ob.matrix_world)
                # Importance for radiosity sampling added here
                tabWrite("radiosity { \n")
                tabWrite("importance %3g \n" % importance)
                tabWrite("}\n")
Luca Bonavita's avatar
Luca Bonavita committed

                tabWrite("}\n")  # End of Metaball block
                if comments and len(metas) >= 1:
Luca Bonavita's avatar
Luca Bonavita committed

    def exportMeshes(scene, sel):
#        obmatslist = []
#        def hasUniqueMaterial():
#            # Grab materials attached to object instances ...
#            if hasattr(ob, 'material_slots'):
#                for ms in ob.material_slots:
#                    if ms.material is not None and ms.link == 'OBJECT':
#                        if ms.material in obmatslist:
#                            return False
#                        else:
#                            obmatslist.append(ms.material)
#                            return True
#        def hasObjectMaterial(ob):
#            # Grab materials attached to object instances ...
#            if hasattr(ob, 'material_slots'):
#                for ms in ob.material_slots:
#                    if ms.material is not None and ms.link == 'OBJECT':
#                        # If there is at least one material slot linked to the object
#                        # and not the data (mesh), always create a new, "private" data instance.
#                        return True
#            return False
        # For objects using local material(s) only!
        # This is a mapping between a tuple (dataname, materialnames, ...), and the POV dataname.
        # As only objects using:
        #     * The same data.
        #     * EXACTLY the same materials, in EXACTLY the same sockets.
        # ... can share a same instance in POV export.
        def checkObjectMaterials(ob, name, dataname):
            if hasattr(ob, 'material_slots'):
                has_local_mats = False
                key = [dataname]
                for ms in ob.material_slots:
                    if ms.material is not None:
                        key.append(ms.material.name)
                        if ms.link == 'OBJECT' and not has_local_mats:
                            has_local_mats = True
                    else:
                        # Even if the slot is empty, it is important to grab it...
                        key.append("")
                if has_local_mats:
                    # If this object uses local material(s), lets find if another object
                    # using the same data and exactly the same list of materials
                    # (in the same slots) has already been processed...
                    # Note that here also, we use object name as new, unique dataname for Pov.
                    key = tuple(key)  # Lists are not hashable...
                    if key not in obmats2data:
                        obmats2data[key] = name
                    return obmats2data[key]
            return None

        data_ref = {}
        def store(scene, ob, name, dataname, matrix):
            # The Object needs to be written at least once but if its data is
            # already in data_ref this has already been done.
            # This func returns the "povray" name of the data, or None
            # if no writing is needed.
            if ob.is_modified(scene, 'RENDER'):
                # Data modified.
                # Create unique entry in data_ref by using object name
                # (always unique in Blender) as data name.
                data_ref[name] = [(name, MatrixAsPovString(matrix))]
                return name
            # Here, we replace dataname by the value returned by checkObjectMaterials, only if
            # it is not evaluated to False (i.e. only if the object uses some local material(s)).
            dataname = checkObjectMaterials(ob, name, dataname) or dataname
            if dataname in data_ref:
                # Data already known, just add the object instance.
                data_ref[dataname].append((name, MatrixAsPovString(matrix)))
                # No need to write data
                return None
            else:
                # Data not yet processed, create a new entry in data_ref.
                data_ref[dataname] = [(name, MatrixAsPovString(matrix))]
                return dataname
           
             
        def exportSmoke(smoke_obj_name):
            #if LuxManager.CurrentScene.name == 'preview':
                #return 1, 1, 1, 1.0
            #else:
            flowtype = -1
            smoke_obj = bpy.data.objects[smoke_obj_name]
            domain = None

            # Search smoke domain target for smoke modifiers
            for mod in smoke_obj.modifiers:
                if mod.name == 'Smoke':
                    if mod.smoke_type == 'FLOW':
                        if mod.flow_settings.smoke_flow_type == 'BOTH':
                            flowtype = 2
                        else:
                            if mod.flow_settings.smoke_flow_type == 'SMOKE':
                                flowtype = 0
                            else:
                                if mod.flow_settings.smoke_flow_type == 'FIRE':
                                    flowtype = 1

                    if mod.smoke_type == 'DOMAIN':
                        domain = smoke_obj
                        smoke_modifier = mod

            eps = 0.000001
            if domain is not None:
                #if bpy.app.version[0] >= 2 and bpy.app.version[1] >= 71:
                # Blender version 2.71 supports direct access to smoke data structure
                set = mod.domain_settings
                channeldata = []
                for v in set.density_grid:
                    channeldata.append(v.real)
                    print(v.real)
                ## Usage en voxel texture:
                # channeldata = []
                # if channel == 'density':
                    # for v in set.density_grid:
                        # channeldata.append(v.real)

                # if channel == 'fire':
                    # for v in set.flame_grid:
                        # channeldata.append(v.real)

                resolution = set.resolution_max
                big_res = []
                big_res.append(set.domain_resolution[0])
                big_res.append(set.domain_resolution[1])
                big_res.append(set.domain_resolution[2])

                if set.use_high_resolution:
                    big_res[0] = big_res[0] * (set.amplify + 1)
                    big_res[1] = big_res[1] * (set.amplify + 1)
                    big_res[2] = big_res[2] * (set.amplify + 1)
                # else:
                    # p = []
                    ##gather smoke domain settings
                    # BBox = domain.bound_box
                    # p.append([BBox[0][0], BBox[0][1], BBox[0][2]])
                    # p.append([BBox[6][0], BBox[6][1], BBox[6][2]])
                    # set = mod.domain_settings
                    # resolution = set.resolution_max
                    # smokecache = set.point_cache
                    # ret = read_cache(smokecache, set.use_high_resolution, set.amplify + 1, flowtype)
                    # res_x = ret[0]
                    # res_y = ret[1]
                    # res_z = ret[2]
                    # density = ret[3]
                    # fire = ret[4]

                    # if res_x * res_y * res_z > 0:
                        ##new cache format
                        # big_res = []
                        # big_res.append(res_x)
                        # big_res.append(res_y)
                        # big_res.append(res_z)
                    # else:
                        # max = domain.dimensions[0]
                        # if (max - domain.dimensions[1]) < -eps:
                            # max = domain.dimensions[1]

                        # if (max - domain.dimensions[2]) < -eps:
                            # max = domain.dimensions[2]

                        # big_res = [int(round(resolution * domain.dimensions[0] / max, 0)),
                                   # int(round(resolution * domain.dimensions[1] / max, 0)),
                                   # int(round(resolution * domain.dimensions[2] / max, 0))]

                    # if set.use_high_resolution:
                        # big_res = [big_res[0] * (set.amplify + 1), big_res[1] * (set.amplify + 1),
                                   # big_res[2] * (set.amplify + 1)]

                    # if channel == 'density':
                        # channeldata = density

                    # if channel == 'fire':
                        # channeldata = fire

                        # sc_fr = '%s/%s/%s/%05d' % (efutil.export_path, efutil.scene_filename(), bpy.context.scene.name, bpy.context.scene.frame_current)
                        #               if not os.path.exists( sc_fr ):
                        #                   os.makedirs(sc_fr)
                        #               smoke_filename = '%s.smoke' % bpy.path.clean_name(domain.name)
                        #               smoke_path = '/'.join([sc_fr, smoke_filename])
                        #               with open(smoke_path, 'wb') as smoke_file:
                        #                   # Binary densitygrid file format
                        #                   #
                        #                   # File header
                        #                   smoke_file.write(b'SMOKE')        #magic number
                        #                   smoke_file.write(struct.pack('<I', big_res[0]))
                        #                   smoke_file.write(struct.pack('<I', big_res[1]))
                        #                   smoke_file.write(struct.pack('<I', big_res[2]))
                        # Density data
                        #                   smoke_file.write(struct.pack('<%df'%len(channeldata), *channeldata))
                        #               LuxLog('Binary SMOKE file written: %s' % (smoke_path))

        #return big_res[0], big_res[1], big_res[2], channeldata
                mydf3 = df3.df3(big_res[0],big_res[1],big_res[2])
                sim_sizeX, sim_sizeY, sim_sizeZ = mydf3.size()
                for x in range(sim_sizeX):
                    for y in range(sim_sizeY):
                        for z in range(sim_sizeZ):
                            mydf3.set(x, y, z, channeldata[((z * sim_sizeY + y) * sim_sizeX + x)])

                mydf3.exportDF3(smokePath)
                print('Binary smoke.df3 file written in preview directory')
                if comments:
                    file.write("\n//--Smoke--\n\n")

                # Note: We start with a default unit cube.
                #       This is mandatory to read correctly df3 data - otherwise we could just directly use bbox
                #       coordinates from the start, and avoid scale/translate operations at the end...
                file.write("box{<0,0,0>, <1,1,1>\n")
                file.write("    pigment{ rgbt 1 }\n")
                file.write("    hollow\n")
                file.write("    interior{ //---------------------\n")
                file.write("        media{ method 3\n")
                file.write("               emission <1,1,1>*1\n")# 0>1 for dark smoke to white vapour
                file.write("               scattering{ 1, // Type\n")
                file.write("                  <1,1,1>*0.1\n")
                file.write("                } // end scattering\n")
                file.write("                density{density_file df3 \"%s\"\n" % (smokePath))
                file.write("                        color_map {\n")
                file.write("                        [0.00 rgb 0]\n")
                file.write("                        [0.05 rgb 0]\n")
                file.write("                        [0.20 rgb 0.2]\n")
                file.write("                        [0.30 rgb 0.6]\n")
                file.write("                        [0.40 rgb 1]\n")
                file.write("                        [1.00 rgb 1]\n")
                file.write("                       } // end color_map\n")
                file.write("               } // end of density\n")
                file.write("               samples %i // higher = more precise\n" % resolution)
                file.write("         } // end of media --------------------------\n")
                file.write("    } // end of interior\n")

                # START OF TRANSFORMATIONS

                # Size to consider here are bbox dimensions (i.e. still in object space, *before* applying
                # loc/rot/scale and other transformations (like parent stuff), aka matrix_world).
                bbox = smoke_obj.bound_box
                dim = [abs(bbox[6][0] - bbox[0][0]), abs(bbox[6][1] - bbox[0][1]), abs(bbox[6][2] - bbox[0][2])]

                # We scale our cube to get its final size and shapes but still in *object* space (same as Blender's bbox).
                file.write("scale<%.6g,%.6g,%.6g>\n" % (dim[0], dim[1], dim[2]))

                # We offset our cube such that (0,0,0) coordinate matches Blender's object center.
                file.write("translate<%.6g,%.6g,%.6g>\n" % (bbox[0][0], bbox[0][1], bbox[0][2]))

                # We apply object's transformations to get final loc/rot/size in world space!
                # Note: we could combine the two previous transformations with this matrix directly...
                writeMatrix(global_matrix * smoke_obj.matrix_world)

                # END OF TRANSFORMATIONS

                file.write("}\n")
                #file.write("               interpolate 1\n")
                #file.write("               frequency 0\n")
                #file.write("   }\n")
                #file.write("}\n")                            
                
Luca Bonavita's avatar
Luca Bonavita committed
        for ob in sel:
            ob_num += 1

            # XXX I moved all those checks here, as there is no need to compute names
            if (ob.type in {'LAMP', 'CAMERA', 'EMPTY',
                            'META', 'ARMATURE', 'LATTICE'}):
Luca Bonavita's avatar
Luca Bonavita committed
                continue
            for mod in ob.modifiers:
                if mod and hasattr(mod, 'smoke_type'):
                    smokeFlag=True
                    if (mod.smoke_type == 'DOMAIN'):
                        exportSmoke(ob.name)
                    break # don't render domain mesh or flow emitter mesh, skip to next object.
            if not smokeFlag:    
                # Export Hair
                renderEmitter = True
                if hasattr(ob, 'particle_systems'):
                    renderEmitter = False
                    for pSys in ob.particle_systems:
                        if pSys.settings.use_render_emitter:
                            renderEmitter = True
                        for mod in [m for m in ob.modifiers if (m is not None) and (m.type == 'PARTICLE_SYSTEM')]:
                            if (pSys.settings.render_type == 'PATH') and mod.show_render and (pSys.name == mod.particle_system.name):
                                tstart = time.time()
                                texturedHair=0
                                if ob.active_material is not None:
                                    pmaterial = ob.material_slots[pSys.settings.material - 1].material
                                    for th in pmaterial.texture_slots:
                                        if th and th.use:
                                            if (th.texture.type == 'IMAGE' and th.texture.image) or th.texture.type != 'IMAGE':
                                                if th.use_map_color_diffuse:
                                                    texturedHair=1
                                    if pmaterial.strand.use_blender_units:
                                        strandStart = pmaterial.strand.root_size
                                        strandEnd = pmaterial.strand.tip_size
                                        strandShape = pmaterial.strand.shape 
                                    else:  # Blender unit conversion
                                        strandStart = pmaterial.strand.root_size / 200.0
                                        strandEnd = pmaterial.strand.tip_size / 200.0
                                        strandShape = pmaterial.strand.shape
                                else:
                                    pmaterial = "default"  # No material assigned in blender, use default one
                                    strandStart = 0.01
                                    strandEnd = 0.01
                                    strandShape = 0.0
                                # Set the number of particles to render count rather than 3d view display    
                                pSys.set_resolution(scene, ob, 'RENDER')    
                                steps = pSys.settings.draw_step
                                steps = 3 ** steps # or (power of 2 rather than 3) + 1 # Formerly : len(particle.hair_keys)
                                
                                totalNumberOfHairs = ( len(pSys.particles) + len(pSys.child_particles) )
                                #hairCounter = 0
                                file.write('#declare HairArray = array[%i] {\n' % totalNumberOfHairs)
                                for pindex in range(0, totalNumberOfHairs):

                                    #if particle.is_exist and particle.is_visible:
                                        #hairCounter += 1
                                        #controlPointCounter = 0
                                        # Each hair is represented as a separate sphere_sweep in POV-Ray.
                                        file.write('sphere_sweep{')
                                        if pSys.settings.use_hair_bspline:
                                            file.write('b_spline ')
                                            file.write('%i,\n' % (steps + 2))  # +2 because the first point needs tripling to be more than a handle in POV
                                        else:
                                            file.write('linear_spline ')
                                            file.write('%i,\n' % (steps))
                                        #changing world coordinates to object local coordinates by multiplying with inverted matrix    
                                        initCo = ob.matrix_world.inverted()*(pSys.co_hair(ob, pindex, 0))
                                        if ob.active_material is not None:
                                            pmaterial = ob.material_slots[pSys.settings.material-1].material
                                            for th in pmaterial.texture_slots:
                                                if th and th.use and th.use_map_color_diffuse:
                                                    #treat POV textures as bitmaps
                                                    if (th.texture.type == 'IMAGE' and th.texture.image and th.texture_coords == 'UV' and ob.data.uv_textures != None): # or (th.texture.pov.tex_pattern_type != 'emulator' and th.texture_coords == 'UV' and ob.data.uv_textures != None):
                                                        image=th.texture.image
                                                        image_width = image.size[0]
                                                        image_height = image.size[1]
                                                        image_pixels = image.pixels[:]
                                                        uv_co = pSys.uv_on_emitter(mod, pSys.particles[pindex], pindex, 0)
                                                        x_co = round(uv_co[0] * (image_width - 1))
                                                        y_co = round(uv_co[1] * (image_height - 1))
                                                        pixelnumber = (image_width * y_co) + x_co
                                                        r = image_pixels[pixelnumber*4]
                                                        g = image_pixels[pixelnumber*4+1]
                                                        b = image_pixels[pixelnumber*4+2]
                                                        a = image_pixels[pixelnumber*4+3]
                                                        initColor=(r,g,b,a)                                              
                                                    else:
                                                        #only overwrite variable for each competing texture for now
                                                        initColor=th.texture.evaluate((initCo[0],initCo[1],initCo[2]))
                                        for step in range(0, steps):
                                            co = pSys.co_hair(ob, pindex, step)
                                        #for controlPoint in particle.hair_keys:
                                            if pSys.settings.clump_factor != 0:
                                                hDiameter = pSys.settings.clump_factor / 200.0 * random.uniform(0.5, 1)
                                            elif step == 0:
                                                hDiameter = strandStart
                                            else:
                                                hDiameter += (strandEnd-strandStart)/(pSys.settings.draw_step+1) #XXX +1 or not?
                                            if step == 0 and pSys.settings.use_hair_bspline:
                                                # Write three times the first point to compensate pov Bezier handling
                                                file.write('<%.6g,%.6g,%.6g>,%.7g,\n' % (co[0], co[1], co[2], abs(hDiameter)))
                                                file.write('<%.6g,%.6g,%.6g>,%.7g,\n' % (co[0], co[1], co[2], abs(hDiameter)))                                          
                                                #file.write('<%.6g,%.6g,%.6g>,%.7g' % (particle.location[0], particle.location[1], particle.location[2], abs(hDiameter))) # Useless because particle location is the tip, not the root.
                                                #file.write(',\n')
                                            #controlPointCounter += 1
                                            #totalNumberOfHairs += len(pSys.particles)# len(particle.hair_keys)
                                                 
                                          # Each control point is written out, along with the radius of the
                                          # hair at that point.
                                            file.write('<%.6g,%.6g,%.6g>,%.7g' % (co[0], co[1], co[2], abs(hDiameter)))
                                          # All coordinates except the last need a following comma.
                                            if step != steps - 1:
                                                file.write(',\n')
                                            else:
                                                if texturedHair:
                                                    # Write pigment and alpha (between Pov and Blender alpha 0 and 1 are reversed)
                                                    file.write('\npigment{ color rgbf < %.3g, %.3g, %.3g, %.3g> }\n' %(initColor[0], initColor[1], initColor[2], 1.0-initColor[3]))
                                                # End the sphere_sweep declaration for this hair
                                                file.write('}\n')
                                            
                                          # All but the final sphere_sweep (each array element) needs a terminating comma.

                                        if pindex != totalNumberOfHairs:
                                            file.write(',\n')
                                        else:
                                            file.write('\n')
                                # End the array declaration.
                                file.write('}\n')
Maurice Raybaud's avatar
Maurice Raybaud committed
                                file.write('\n')
                                
                                if not texturedHair:
                                    # Pick up the hair material diffuse color and create a default POV-Ray hair texture.

                                    file.write('#ifndef (HairTexture)\n')
                                    file.write('  #declare HairTexture = texture {\n')
                                    file.write('    pigment {rgbt <%s,%s,%s,%s>}\n' % (pmaterial.diffuse_color[0], pmaterial.diffuse_color[1], pmaterial.diffuse_color[2], (pmaterial.strand.width_fade + 0.05)))
                                    file.write('  }\n')
                                    file.write('#end\n')
                                    file.write('\n')

                                # Dynamically create a union of the hairstrands (or a subset of them).
                                # By default use every hairstrand, commented line is for hand tweaking test renders.
                                file.write('//Increasing HairStep divides the amount of hair for test renders.\n')
                                file.write('#ifndef(HairStep) #declare HairStep = 1; #end\n')
                                file.write('union{\n')
                                file.write('  #local I = 0;\n')
                                file.write('  #while (I < %i)\n' % totalNumberOfHairs)
                                file.write('    object {HairArray[I]')
                                if not texturedHair:
                                    file.write(' texture{HairTexture}\n')
                                else:
                                    file.write('\n')
                                # Translucency of the hair:
                                file.write('        hollow\n')
                                file.write('        double_illuminate\n')
                                file.write('        interior {\n')
                                file.write('            ior 1.45\n')
                                file.write('            media {\n')
                                file.write('                scattering { 1, 10*<0.73, 0.35, 0.15> /*extinction 0*/ }\n')
                                file.write('                absorption 10/<0.83, 0.75, 0.15>\n')
                                file.write('                samples 1\n')
                                file.write('                method 2\n')
                                file.write('                density {\n')
                                file.write('                    color_map {\n')
                                file.write('                        [0.0 rgb <0.83, 0.45, 0.35>]\n')
                                file.write('                        [0.5 rgb <0.8, 0.8, 0.4>]\n')
                                file.write('                        [1.0 rgb <1,1,1>]\n')
                                file.write('                    }\n')
                                file.write('                }\n')
                                file.write('            }\n')
                                file.write('        }\n')
                                file.write('    }\n')
                                
                                file.write('    #local I = I + HairStep;\n')
                                file.write('  #end\n')
                                
                                writeMatrix(global_matrix * ob.matrix_world)
                                
                                file.write('}')
                                print('Totals hairstrands written: %i' % totalNumberOfHairs)
                                print('Number of tufts (particle systems)', len(ob.particle_systems))
                                
                                # Set back the displayed number of particles to preview count
                                pSys.set_resolution(scene, ob, 'PREVIEW')
                                
                                if renderEmitter == False:
                                    continue #don't render mesh, skip to next object.

    #############################################
                # Generating a name for object just like materials to be able to use it
                # (baking for now or anything else).
                # XXX I don't understand that:&nbsp;if we are here, sel if a non-empty iterable,
                #     so this condition is always True, IMO -- mont29
                if sel:
                    name_orig = "OB" + ob.name
                    dataname_orig = "DATA" + ob.data.name
                    name_orig = DEF_OBJ_NAME
                    dataname_orig = DEF_OBJ_NAME
                name = string_strip_hyphen(bpy.path.clean_name(name_orig))
                dataname = string_strip_hyphen(bpy.path.clean_name(dataname_orig))
    ##            for slot in ob.material_slots:
    ##                if slot.material is not None and slot.link == 'OBJECT':
    ##                    obmaterial = slot.material

    #############################################

                if info_callback:
                    info_callback("Object %2.d of %2.d (%s)" % (ob_num, len(sel), ob.name))

                #if ob.type != 'MESH':
                #    continue
                # me = ob.data

                matrix = global_matrix * ob.matrix_world
                povdataname = store(scene, ob, name, dataname, matrix)
                if povdataname is None:
                    print("This is an instance")
                    continue

                print("Writing Down First Occurence")
                                    
############################################Povray Primitives
                # special exportCurves() function takes care of writing
                # lathe, sphere_sweep, birail, and loft
                if ob.type == 'CURVE' and (ob.pov.curveshape in 
                                {'lathe', 'sphere_sweep', 'loft'}):
                    continue #Don't render proxy mesh, skip to next object

                if ob.pov.object_as == 'ISOSURFACE':
                    tabWrite("#declare %s = isosurface{ \n"% povdataname)
                    tabWrite("function{ \n")
                    textName = ob.pov.iso_function_text
                    if textName:
                        node_tree = bpy.context.scene.node_tree
                        for node in node_tree.nodes:
                            if node.bl_idname == "IsoPropsNode" and node.label == ob.name:
                                for inp in node.inputs:
                                    if inp:
                                        tabWrite("#declare %s = %.6g;\n"%(inp.name,inp.default_value))

                        text = bpy.data.texts[textName]
                        for line in text.lines:
                            split = line.body.split()
                            if split[0] != "#declare":
                                tabWrite("%s\n"%line.body)
                    else:
                        tabWrite("abs(x) - 2 + y")
                    tabWrite("}\n")
                    tabWrite("threshold %.6g\n"%ob.pov.threshold)
                    tabWrite("max_gradient %.6g\n"%ob.pov.max_gradient)
                    tabWrite("accuracy  %.6g\n"%ob.pov.accuracy)
                    tabWrite("contained_by { ")
                    if ob.pov.contained_by == "sphere":
                        tabWrite("sphere {0,%.6g}}\n"%ob.pov.container_scale)
                    else:
                        tabWrite("box {-%.6g,%.6g}}\n"%(ob.pov.container_scale,ob.pov.container_scale))
                    if ob.pov.all_intersections:
                        tabWrite("all_intersections\n")
                    else:
                        if ob.pov.max_trace > 1:
                            tabWrite("max_trace %.6g\n"%ob.pov.max_trace)
                    povMatName = "Default_texture"
                    if ob.active_material:
                        #povMatName = string_strip_hyphen(bpy.path.clean_name(ob.active_material.name))
                        try:
                            material = ob.active_material
                            writeObjectMaterial(material, ob)
                        except IndexError:
                            print(me)
                    #tabWrite("texture {%s}\n"%povMatName)
                    tabWrite("scale %.6g\n"%(1/ob.pov.container_scale))
                    tabWrite("}\n")
                    continue #Don't render proxy mesh, skip to next object
                if ob.pov.object_as == 'SUPERELLIPSOID':
                    tabWrite("#declare %s = superellipsoid{ <%.4f,%.4f>\n"%(povdataname,ob.pov.se_n2,ob.pov.se_n1))
                    povMatName = "Default_texture"
                    if ob.active_material:
                        #povMatName = string_strip_hyphen(bpy.path.clean_name(ob.active_material.name))
                        try:
                            material = ob.active_material
                            writeObjectMaterial(material, ob)
                        except IndexError:
                            print(me)
                    #tabWrite("texture {%s}\n"%povMatName)
                    write_object_modifiers(scene,ob,file)
                    tabWrite("}\n")
                    continue #Don't render proxy mesh, skip to next object


                if ob.pov.object_as == 'SUPERTORUS':
                    rMajor = ob.pov.st_major_radius
                    rMinor = ob.pov.st_minor_radius
                    ring = ob.pov.st_ring
                    cross = ob.pov.st_cross
                    accuracy=ob.pov.st_accuracy
                    gradient=ob.pov.st_max_gradient
                    ############Inline Supertorus macro
                    file.write("#macro Supertorus(RMj, RMn, MajorControl, MinorControl, Accuracy, MaxGradient)\n")
                    file.write("   #local CP = 2/MinorControl;\n")
                    file.write("   #local RP = 2/MajorControl;\n")
                    file.write("   isosurface {\n")
                    file.write("      function { pow( pow(abs(pow(pow(abs(x),RP) + pow(abs(z),RP), 1/RP) - RMj),CP) + pow(abs(y),CP) ,1/CP) - RMn }\n")
                    file.write("      threshold 0\n")
                    file.write("      contained_by {box {<-RMj-RMn,-RMn,-RMj-RMn>, < RMj+RMn, RMn, RMj+RMn>}}\n")
                    file.write("      #if(MaxGradient >= 1)\n")
                    file.write("         max_gradient MaxGradient\n")
                    file.write("      #else\n")
                    file.write("         evaluate 1, 10, 0.1\n")
                    file.write("      #end\n")
                    file.write("      accuracy Accuracy\n")
                    file.write("   }\n")
                    file.write("#end\n")
                    ############
                    tabWrite("#declare %s = object{ Supertorus( %.4g,%.4g,%.4g,%.4g,%.4g,%.4g)\n"%(povdataname,rMajor,rMinor,ring,cross,accuracy,gradient))
                    povMatName = "Default_texture"
                    if ob.active_material:
                        #povMatName = string_strip_hyphen(bpy.path.clean_name(ob.active_material.name))
                        try:
                            material = ob.active_material
                            writeObjectMaterial(material, ob)
                        except IndexError:
                            print(me)
                    #tabWrite("texture {%s}\n"%povMatName)
                    write_object_modifiers(scene,ob,file)
                    tabWrite("rotate x*90\n")
                    tabWrite("}\n")
                    continue #Don't render proxy mesh, skip to next object
                    

                if ob.pov.object_as == 'PLANE':
                    tabWrite("#declare %s = plane{ <0,0,1>,1\n"%povdataname)
                    povMatName = "Default_texture"
                    if ob.active_material:
                         #povMatName = string_strip_hyphen(bpy.path.clean_name(ob.active_material.name))
                        try:
                            material = ob.active_material
                            writeObjectMaterial(material, ob)
                        except IndexError:
                            print(me) 
                    #tabWrite("texture {%s}\n"%povMatName)
                    write_object_modifiers(scene,ob,file)
                    #tabWrite("rotate x*90\n")
                    tabWrite("}\n")
                    continue #Don't render proxy mesh, skip to next object
                if ob.pov.object_as == 'BOX':
                    tabWrite("#declare %s = box { -1,1\n"%povdataname)
                    povMatName = "Default_texture"
                    if ob.active_material:
                        #povMatName = string_strip_hyphen(bpy.path.clean_name(ob.active_material.name))
                        try:
                            material = ob.active_material
                            writeObjectMaterial(material, ob)
                        except IndexError:
                            print(me)
                    #tabWrite("texture {%s}\n"%povMatName)
                    write_object_modifiers(scene,ob,file)
                    #tabWrite("rotate x*90\n")
                    tabWrite("}\n")
                    continue #Don't render proxy mesh, skip to next object


                if ob.pov.object_as == 'CONE':
                    br = ob.pov.cone_base_radius
                    cr = ob.pov.cone_cap_radius
                    bz = ob.pov.cone_base_z
                    cz = ob.pov.cone_cap_z
                    tabWrite("#declare %s = cone { <0,0,%.4f>,%.4f,<0,0,%.4f>,%.4f\n"%(povdataname,bz,br,cz,cr))
                    povMatName = "Default_texture"
                    if ob.active_material:
                        #povMatName = string_strip_hyphen(bpy.path.clean_name(ob.active_material.name))
                        try:
                            material = ob.active_material
                            writeObjectMaterial(material, ob)
                        except IndexError:
                            print(me)
                    #tabWrite("texture {%s}\n"%povMatName)
                    write_object_modifiers(scene,ob,file)
                    #tabWrite("rotate x*90\n")
                    tabWrite("}\n")
                    continue #Don't render proxy mesh, skip to next object

                if ob.pov.object_as == 'CYLINDER':
                    tabWrite("#declare %s = cylinder { <0,0,1>,<0,0,-1>,1\n"%povdataname)
                    povMatName = "Default_texture"
                    if ob.active_material:
                        #povMatName = string_strip_hyphen(bpy.path.clean_name(ob.active_material.name))
                        try:
                            material = ob.active_material
                            writeObjectMaterial(material, ob)
                        except IndexError:
                            print(me)
                    #tabWrite("texture {%s}\n"%povMatName)
                    write_object_modifiers(scene,ob,file)
                    #tabWrite("rotate x*90\n")
                    tabWrite("}\n")
                    continue #Don't render proxy mesh, skip to next object


                if ob.pov.object_as == 'HEIGHT_FIELD':
                    data = ""
                    filename = ob.pov.hf_filename
                    data += '"%s"'%filename
                    gamma = ' gamma %.4f'%ob.pov.hf_gamma
                    data += gamma
                    if ob.pov.hf_premultiplied:
                        data += ' premultiplied on'
Loading
Loading full blame...