"""
@package CurveReader.rendersetup.py
Holds the object for setting up the render state in the current scene
@author Coen Klosters
@version 1.0
"""

import hou
import os

CAMERA_FOCAL_LENGTH = 32.5
CAMERA_ROT_Y_APPEND = 50

# create the temp path if it doesn't exist
TEMP_IFD_DIR = "%s/exv_renders" % os.environ["TEMP"]
if not os.path.exists(TEMP_IFD_DIR):
    os.mkdir(TEMP_IFD_DIR)

class CurveRenderSetup(object):
    """
    Sets up the scene so it's easy to render out the final image
    """
    
    def __init__(self, inCurveCreator, inCurveLoader):
        """
        @param inCurveCreator: The curve creator used for extracting and building the curves
        @param inCurveLoader: The curve loader used for generating initial set of construction data
        """
        
        self.CurveCreator = inCurveCreator
        self.CurveLoader = inCurveLoader
        
        # The mantra node to render from
        self.MantraNode = None
        # The camera to render from
        self.CameraNode = None
        # The render object to render
        self.RenderObject = None
        # The created shader
        self.Shader = None
        # The output file that is to be rendered
        self.OutputImage = None
        
        
    def CreateSetup(self, inRenderPath, inRenderResX, inRenderResY):
        """
        Creates the entire setup
        @param inRenderPath: The path to render the image to
        """
        
        # create the render object and merge in the curves, set up for render
        self.RenderObject = hou.node("/obj").createNode("geo", "%s_render" % self.CurveLoader.UserInfo.FName)
        for c in self.RenderObject.children():
            c.destroy()
        
        # first create the curve object merger
        curve_merger = self.RenderObject.createNode("object_merge", "merge_curves_%s" % self.CurveLoader.UserInfo.FName)
        curve_merger.parm("xformtype").set(1)
        curve_merger.parm("objpath1").set(self.CurveCreator.CurveMerger.path())
        
        # create the point cloud reader
        point_cloud_reader = self.RenderObject.createNode("liminal_point_cloud_reader", "point_cloud_reader")
        point_cloud_reader.parm("in_xml").set(self.CurveLoader.XmlFile)
        
        # create the merger and connect it up
        liminal_merger = self.RenderObject.createNode("liminal_merger", "liminal_render_settings")
        liminal_merger.setInput(0, point_cloud_reader)
        liminal_merger.setInput(1, curve_merger)
        liminal_merger.setDisplayFlag(True)
        liminal_merger.setRenderFlag(True)
        
        # move 'm to a good position
        self.RenderObject.layoutChildren()
        self.RenderObject.moveToGoodPosition()
        
        # create and assign the shader
        self.Shader = hou.node("/shop").createNode("liminal_constant", "liminal_shader_%s" % self.CurveLoader.UserInfo.FName)
        self.RenderObject.parm("shop_materialpath").set(self.Shader.path())
        self.Shader.moveToGoodPosition()
        
        # create the camera
        self.CameraNode = hou.node("/obj").createNode("cam", "camera_%s" % self.CurveLoader.UserInfo.FName)
        self.CameraNode.parm("tx").set(self.CurveLoader.CamInfo.Position[0])
        self.CameraNode.parm("ty").set(self.CurveLoader.CamInfo.Position[1])
        self.CameraNode.parm("tz").set(self.CurveLoader.CamInfo.Position[2] * -1)
        self.CameraNode.parm("rx").set(self.CurveLoader.CamInfo.Rotation[0])    
        self.CameraNode.parm("ry").set(self.CurveLoader.CamInfo.Rotation[1] + CAMERA_ROT_Y_APPEND)
        self.CameraNode.parm("rz").set(self.CurveLoader.CamInfo.Rotation[2])
        self.CameraNode.parm("near").set(self.CurveLoader.CamInfo.Clipping[0])
        self.CameraNode.parm("far").set(self.CurveLoader.CamInfo.Clipping[1])
        self.CameraNode.parm("aperture").set(self.CurveLoader.CamInfo.FOV)
        self.CameraNode.parm("focal").set(CAMERA_FOCAL_LENGTH)
        self.CameraNode.parm("resx").set(inRenderResX)
        self.CameraNode.parm("resy").set(inRenderResY)
        self.CameraNode.parm("lookatpath").set(self.RenderObject.path())
        
        # move the cam to a good pos
        self.CameraNode.moveToGoodPosition()
        
        # create the render node and set it up
        self.MantraNode = hou.node("/out").createNode("ifd", "render_art_%s" % self.CurveLoader.UserInfo.FName)
        self.MantraNode.parm("vm_samplesx").set(6)
        self.MantraNode.parm("vm_samplesy").set(6)
        self.MantraNode.parm("camera").set(self.CameraNode.path())
        self.MantraNode.parm("vobject").set(self.RenderObject.path())
        self.OutputImage = "%s/%s_art.png" % (inRenderPath.replace("\\","/"), self.CurveLoader.UserInfo.FName)
        self.MantraNode.parm("vm_picture").set(self.OutputImage)
        self.MantraNode.parm("soho_outputmode").set(True)
        self.MantraNode.parm("soho_diskfile").set("%s/%s.ifd" % (TEMP_IFD_DIR, self.CurveLoader.UserInfo.FName))
        self.MantraNode.moveToGoodPosition()