#!/usr/bin/env python

# 
# Initial code generated by Softimage SDK Wizard
# 

#----------------------------------------------------------------------------
# Name:         Back_GridPlugin
# Purpose:      Create a grid with a weightmap for volure rendering of a Softimage ICE PointCloud
#
# Author:       Pierre Lalancette
#               www.lalancelot.com
#               lancelot@cgocable.ca
#               lalancelot@hotmail.com
#
# History:      Version 1.0: Executed Thu Feb 7 22:45:01 EST 2013 by Lancelot
#
# Copyright:    Use as you wish, at your own risk.
#              
#
# To Run:       -Copy this file into your pluging directory (Example: C:\Users\Lancelot\Autodesk\Softimage_2010\Application\Plugins)
#               -Restart Softimage
#               -In MODEL menu, GET -> PRIMITIVE -> POLYGON MESH -> BACKGRID
#               *** NOTE: You need the BackGrid.xsicompound in your compound directory in order for this script to work
#               (Example: C:\Users\Lancelot\Autodesk\Softimage_2012\Data\Compounds)
#
#----------------------------------------------------------------------------
import win32com.client
from win32com.client import constants

def XSILoadPlugin( in_reg ):
    in_reg.Author = "Lancelot"
    in_reg.Name = "Back_GridPlugin"
    in_reg.Major = 1
    in_reg.Minor = 0

    in_reg.RegisterCommand("Back_Grid","Back_Grid")
    in_reg.RegisterMenu(constants.siMenuTbGetPrimitiveID,"Back_Grid_Menu",False,False)
    #RegistrationInsertionPoint - do not remove this line

    return True

def XSIUnloadPlugin( in_reg ):
    strPluginName = in_reg.Name
    return True
    
def Back_Grid_Menu_Init( in_ctxt ):
    oMenu = in_ctxt.Source
    oMenu.AddCallbackItem("Back_Grid","Back_Grid_Exe")
    return True

def Back_Grid_Init( in_ctxt ):
    oCmd = in_ctxt.Source
    oCmd.Description = ""
    oCmd.Tooltip = "Create Back Grid Volume Render"
    oCmd.ReturnValue = True

    return True
    
def Back_Grid_Exe(self):
    Back_Grid_Execute()
    return True

def Back_Grid_Execute():

    from win32com.client import constants as c
    import math

    picked_obj = Application.PickObject( 'Pick Camera', 'Pick Camera' )
    button = picked_obj.Value( "ButtonPressed" );
    sel_cam = picked_obj.Value("PickedElement");

    if str(sel_cam) <> "None":
        if sel_cam.type == "camera":
            # Creation.
            back_grid = Application.ActiveSceneRoot.addGeometry("grid", "MeshSurface","back_grid")
            upper_left = Application.ActiveSceneRoot.addGeometry("Null", "","upper_left")
            down_right = Application.ActiveSceneRoot.addGeometry("Null", "","down_right")
            upper_left_gizmo = Application.ActiveSceneRoot.addGeometry("Null", "","upper_left_gizmo")
            down_right_gizmo = Application.ActiveSceneRoot.addGeometry("Null", "","down_right_gizmo")
            Application.AddProp("Custom_parameter_list", back_grid.Name, "", "Grid", "")
            Application.SIAddCustomParameter(back_grid.Name + ".Grid", "Resolution", "siDouble", 120, -1000000000, 1000000000, 2, 5, 0, 240, "Resolution of the Grid", "")
            Application.SIAddCustomParameter(back_grid.Name + ".Grid", "BackGrid", "siDouble", 15, -1000000000, 1000000000, 2, 5, 0, 20, "Position of BackGrid", "")
            Application.SIAddCustomParameter(back_grid.Name + ".Grid", "Limits", "siDouble", 10, -1000000000, 1000000000, 2, 5, 0, 20, "Position of Limits", "")
            # Parent.
            sel_cam.AddChild(back_grid)
            sel_cam.AddChild(upper_left)
            sel_cam.AddChild(down_right)
            sel_cam.AddChild(upper_left_gizmo)
            sel_cam.AddChild(down_right_gizmo)
            # Parameters.
            back_grid.Kinematics.Global.Transform = sel_cam.Kinematics.Global.Transform
            back_grid.ulength = 1
            back_grid.vlength = 1
            Application.AddExpr(back_grid.Name + ".polymsh.geom.subdivv", back_grid.Name + ".polymsh.geom.subdivu * ( 1 /" + sel_cam.Name + ".camera.aspect )", "")
            Application.AddExpr(back_grid.Name + ".kine.local.rotx", "90", "")
            Application.AddExpr(back_grid.Name + ".kine.local.roty", "0", "")
            Application.AddExpr(back_grid.Name + ".kine.local.rotz", "0", "")
            Application.AddExpr(back_grid.Name + ".kine.local.scly", "1", "")
            Application.AddExpr(back_grid.Name + ".kine.local.posz",  "-" + back_grid.Name + ".Grid.BackGrid", "")
            back_grid.Properties("visibility").selectability.Value = 0
            upper_left.primary_icon = 5 # Circle.
            down_right.primary_icon = 5
            upper_left_gizmo.primary_icon = 2 # Ring.
            down_right_gizmo.primary_icon = 2
            upper_left.Kinematics.Global.Transform = sel_cam.Kinematics.Global.Transform
            down_right.Kinematics.Global.Transform = sel_cam.Kinematics.Global.Transform
            upper_left_gizmo.Kinematics.Global.Transform = sel_cam.Kinematics.Global.Transform
            down_right_gizmo.Kinematics.Global.Transform = sel_cam.Kinematics.Global.Transform
            Application.AddExpr(upper_left.Name + ".kine.local.posz", "-ctr_dist( Camera.kine.global.pos, back_grid.kine.global.pos )", "")
            Application.AddExpr(down_right.Name + ".kine.local.posz", "-ctr_dist( Camera.kine.global.pos, back_grid.kine.global.pos )", "")
            Application.AddExpr(upper_left_gizmo.Name + ".kine.local.posz", "-ctr_dist( Camera.kine.global.pos, back_grid.kine.global.pos )", "")
            Application.AddExpr(down_right_gizmo.Name + ".kine.local.posz", "-ctr_dist( Camera.kine.global.pos, back_grid.kine.global.pos )", "")
            Application.AddExpr(upper_left.Name + ".kine.local.posx", "-( ( tan( " + sel_cam.Name + ".camera.fov / 2 ) ) * ctr_dist( " + sel_cam.Name + ".kine.global.pos, " + back_grid.Name + ".kine.global.pos ) )", "")
            Application.AddExpr(upper_left.Name + ".kine.local.posy", "( ( tan( " + sel_cam.Name + ".camera.fov / 2 ) ) * ctr_dist( " + sel_cam.Name + ".kine.global.pos, " + back_grid.Name + ".kine.global.pos ) ) * ( 1 / " + sel_cam.Name + ".camera.aspect )", "")
            Application.AddExpr(down_right.Name + ".kine.local.posx", "( ( tan( " + sel_cam.Name + ".camera.fov / 2 ) ) * ctr_dist( " + sel_cam.Name + ".kine.global.pos, " + back_grid.Name + ".kine.global.pos ) )", "")
            Application.AddExpr(down_right.Name + ".kine.local.posy", "-( ( tan( " + sel_cam.Name + ".camera.fov / 2 ) ) * ctr_dist( " + sel_cam.Name + ".kine.global.pos, " + back_grid.Name + ".kine.global.pos ) ) * ( 1 / " + sel_cam.Name + ".camera.aspect )", "")
            upper_left_gizmo.Kinematics.Global.Transform = upper_left.Kinematics.Global.Transform
            down_right_gizmo.Kinematics.Global.Transform = down_right.Kinematics.Global.Transform
            Application.AddExpr(upper_left_gizmo.Name + ".kine.local.posx", "cond( upper_left_gizmo.kine.local.posx < upper_left.kine.local.posx, upper_left.kine.local.posx, upper_left_gizmo.kine.local.posx )", "")
            Application.AddExpr(upper_left_gizmo.Name + ".kine.local.posy", "cond( upper_left_gizmo.kine.local.posy > upper_left.kine.local.posy, upper_left.kine.local.posy, upper_left_gizmo.kine.local.posy )", "")
            Application.AddExpr(down_right_gizmo.Name + ".kine.local.posx", "cond( down_right_gizmo.kine.local.posx > down_right.kine.local.posx, down_right.kine.local.posx, down_right_gizmo.kine.local.posx )", "")
            Application.AddExpr(down_right_gizmo.Name + ".kine.local.posy", "cond( down_right_gizmo.kine.local.posy < down_right.kine.local.posy, down_right.kine.local.posy, down_right_gizmo.kine.local.posy )", "")
            Application.AddExpr(back_grid.Name + ".kine.local.sclx", down_right_gizmo.Name + ".kine.local.posx - " + upper_left_gizmo.Name + ".kine.local.posx", "")
            Application.AddExpr(back_grid.Name + ".kine.local.sclz", upper_left_gizmo.Name + ".kine.local.posy - " + down_right_gizmo.Name + ".kine.local.posy", "")
            Application.AddExpr(back_grid.Name + ".kine.local.posx", upper_left_gizmo.Name + ".kine.local.posx + (( " + down_right_gizmo.Name + ".kine.local.posx - " + upper_left_gizmo.Name + ".kine.local.posx) / 2 )", "")
            Application.AddExpr(back_grid.Name + ".kine.local.posy", down_right_gizmo.Name + ".kine.local.posy + (( " + upper_left_gizmo.Name + ".kine.local.posy - " + down_right_gizmo.Name + ".kine.local.posy) / 2 )", "")
            Application.AddExpr(back_grid.Name + ".polymsh.geom.subdivu",  "( " + back_grid.Name + ".Grid.Resolution / (" + down_right.Name + ".kine.local.posx - " + upper_left.Name + ".kine.local.posx)) * ( " + down_right_gizmo.Name + ".kine.local.posx - " + upper_left_gizmo.Name + ".kine.local.posx)", "")
            Application.AddExpr(back_grid.Name + ".polymsh.geom.subdivv",  "((" + back_grid.Name + ".Grid.Resolution * ( 1 / " + sel_cam.Name + ".camera.aspect )) / (" + upper_left.Name + ".kine.local.posy - " + down_right.Name + ".kine.local.posy)) * ( " + upper_left_gizmo.Name + ".kine.local.posy - " + down_right_gizmo.Name + ".kine.local.posy)", "")
            # Front's limits
            limits = Application.SICreateCurve("limits", 1, 1)
            Application.SIAddPointOnCurveAtEnd(limits.FullName, 0, 0, 0, False, 0, "")
            Application.SIAddPointOnCurveAtEnd(limits.FullName, 0, 1, 0, False, 0, "")
            Application.SIAddPointOnCurveAtEnd(limits.FullName, 1, 1, 0, False, 0, "")
            Application.SIAddPointOnCurveAtEnd(limits.FullName, 1, 0, 0, False, 0, "")
            Application.ApplyTopoOp("CrvOpenClose", limits.FullName, 3, "siPersistentOperation", "")
            center_limits = Application.ActiveSceneRoot.addGeometry("Null", "","center_limits")
            center_limits.primary_icon = 0 # None.
            limits.Kinematics.Global.Transform = sel_cam.Kinematics.Global.Transform
            center_limits.Kinematics.Global.Transform = sel_cam.Kinematics.Global.Transform
            limits.Properties("visibility").selectability.Value = 0
            sel_cam.AddChild(center_limits)
            center_limits.AddChild(limits)
            Application.AddExpr(center_limits.Name + ".kine.local.roty", "0", "")
            Application.AddExpr(center_limits.Name + ".kine.local.rotz", "0", "")
            Application.AddExpr(center_limits.Name + ".kine.local.rotx", "0", "")
            Application.AddExpr(center_limits.Name + ".kine.local.posz",  "-" + back_grid.Name + ".Grid.Limits", "")
            Application.AddExpr(center_limits.Name + ".kine.local.posx", "0", "")
            Application.AddExpr(center_limits.Name + ".kine.local.posy", "0", "")
            Application.AddExpr(limits.FullName + ".kine.local.posx", "-( ( tan( " + sel_cam.Name + ".camera.fov / 2 ) ) * ctr_dist( " + sel_cam.Name + ".kine.global.pos, " + center_limits.Name + ".kine.global.pos ) )", "")
            Application.AddExpr(limits.FullName + ".kine.local.posy", "-( ( tan( " + sel_cam.Name + ".camera.fov / 2 ) ) * ctr_dist( " + sel_cam.Name + ".kine.global.pos, " + center_limits.Name + ".kine.global.pos ) ) * ( 1 / " + sel_cam.Name + ".camera.aspect )", "")
            Application.AddExpr(limits.FullName + ".kine.local.sclx", " 2 * (tan( " + sel_cam.Name + ".camera.fov / 2 ) * ctr_dist( " + sel_cam.Name + ".kine.global.pos, " + center_limits.Name + ".kine.global.pos ))", "")
            Application.AddExpr(limits.FullName + ".kine.local.scly", " 2 * (tan( " + sel_cam.Name + ".camera.fov / 2 ) * ctr_dist( " + sel_cam.Name + ".kine.global.pos, " + center_limits.Name + ".kine.global.pos )) * ( 1 / " + sel_cam.Name + ".camera.aspect )", "")

            back_grid_icetree = Application.ApplyOp("ICETree", "back_grid", "siNode", "", "", 0)
            back_grid_node = Application.AddICECompoundNode("BackGrid", back_grid_icetree)
            Application.ConnectICENodes(str(back_grid_icetree) + ".port1", str(back_grid_node) + ".Execute")
            gd1 = Application.AddICENode("GetDataNode", back_grid_icetree)
            Application.SetValue(str(gd1) + ".reference", sel_cam.Name, "")
            Application.ConnectICENodes(str(back_grid_node) + ".Camera", str(gd1) + ".outname")
            gd2 = Application.AddICENode("GetDataNode", back_grid_icetree)
            Application.SetValue(str(gd2) + ".reference", center_limits.Name, "")
            Application.ConnectICENodes(str(back_grid_node) + ".Limits", str(gd2) + ".outname")
            weight_map = Application.CreateWeightMap("", back_grid.Name, "", "", "")

            #obj.ActivePrimitive.ConstructionHistory
            #if op.type = "ICETree"
            
            
            