Code Vonc

Importer un fichier OCS

v 1.2

Script Python pour Cinéma 4D R13.

TéléchargerDownload
Faire un donMake a donation
Comment installer ?How to install ?
CommentairesComments


Lancez le script et sélectionnez votre fichier OctaneRender (1.0 beta 2.57) pour importer dans C4D :

Caméra
- Position
- Rotation
- Angle de champ
- Décalage
- Mise au point

Résolution

Soleil
- Rotation



import c4d
import xml
import math
from xml.dom.minidom import parse, Node
from math import pi
from c4d import Vector, gui
from c4d.utils import VectorToHPB, Rad, VectorAngle, GetAngle

# v1.2
# http://code.vonc.fr

class Dialogue(gui.GeDialog) :
    annuler = True
    camera = True
    reso = True
    soleil = True
    
    def CreateLayout(self) :
        self.SetTitle("Importeur OCS v1.2")
        self.GroupBegin(10, c4d.BFH_CENTER, 1, 3)
        self.AddCheckbox(20, c4d.BFH_SCALEFIT, 0, 0, "Caméras")
        self.AddCheckbox(21, c4d.BFH_SCALEFIT, 0, 0, "Résolution")
        self.AddCheckbox(22, c4d.BFH_SCALEFIT, 0, 0, "Soleil")
        self.GroupEnd()
        self.AddSeparatorV(11)
        self.AddDlgGroup(c4d.DLG_OK|c4d.DLG_CANCEL)
        return True
    
    def InitValues(self) :
        self.SetBool(20, True)
        self.SetBool(21, True)
        self.SetBool(22, True)
        return True
    
    def Command(self, id, msg) :
        if id == 1 :
            self.annuler = False
            self.camera = self.GetBool(20)
            self.reso = self.GetBool(21)
            self.soleil = self.GetBool(22)
            self.Close()
        if id == 2 :
            self.Close()
        return True

class OCSCamera :
    nom = "Camera"
    position = Vector()
    cible = Vector()
    angledechamp = 50
    haut = Vector()
    decalage = Vector()
    miseaupoint = 10
    
    Rot = Vector(1, 1, -1)
    Ech = 100
    
    def __init__(self, nom = "Camera", pos = Vector(), cib = Vector(), hau = Vector(), ang = 0, dec = Vector(), map = 10) :
        if nom : self.nom = nom
        if pos : self.position = pos
        if cib : self.cible = cib
        if ang : self.angledechamp = ang
        if hau : self.haut = hau
        if dec : self.decalage = dec
        if map : self.miseaupoint = map
    
    def Axe(self, v) :
        vec = Vector()
        vec.x = v.x * self.Rot.x * self.Ech
        vec.y = v.y * self.Rot.y * self.Ech
        vec.z = v.z * self.Rot.z * self.Ech
        return vec
    
    def C4DCamera(self) :
        camera = c4d.BaseObject(c4d.Ocamera)
        camera[c4d.ID_BASELIST_NAME] = self.nom
        camera[c4d.ID_BASEOBJECT_REL_POSITION] = self.Axe(self.position)
        camera[c4d.ID_BASEOBJECT_REL_ROTATION] = VectorToHPB(self.Axe(self.cible - self.position))
        
        vh = self.Axe(self.haut)
        m = camera.GetMl()
        if vh.y < 0 :
            vech = (GetAngle(vh.Cross(m.v3), m.v2) + pi/2) *-1
        else :
            vech = GetAngle(vh.Cross(m.v3), m.v2) - pi/2
        
        camera[c4d.ID_BASEOBJECT_REL_ROTATION,c4d.VECTOR_Z] = vech
        camera[c4d.CAMERAOBJECT_FOV] = Rad(self.angledechamp)
        camera[c4d.CAMERAOBJECT_FILM_OFFSET_X] = self.decalage.x
        camera[c4d.CAMERAOBJECT_FILM_OFFSET_Y] = self.decalage.y
        camera[c4d.CAMERAOBJECT_TARGETDISTANCE] = self.miseaupoint * self.Ech
        
        return camera

class OCSRendu :
    nom = "Rendu"
    resolution = None
    
    def __init__(self, reso) :
        if reso : self.resolution = reso
    

class OCSSoleil :
    nom = "Soleil"
    cible = Vector()
    
    Rot = Vector(-1, -1, 1)
    
    def __init__(self, cible) :
        if cible : self.cible = cible
    
    def Axe(self, v) :
        vec = Vector()
        vec.x = v.x * self.Rot.x
        vec.y = v.y * self.Rot.y
        vec.z = v.z * self.Rot.z
        return vec
    
    def C4DSoleil(self) :
        soleil = c4d.BaseObject(c4d.Olight)
        soleil[c4d.LIGHT_TYPE] = c4d.LIGHT_TYPE_DISTANT
        soleil[c4d.LIGHT_SHADOWTYPE] = c4d.LIGHT_SHADOWTYPE_HARD
        soleil[c4d.ID_BASEOBJECT_REL_ROTATION] = VectorToHPB(self.Axe(self.cible))
        
        return soleil

class XmlOCS :
    chemin = None
    fichier = None
    cameras = []
    rendu = None
    soleil = None
    ValCam = True
    ValRes = True
    ValSol = True
    
    def __init__(self, cam = True, res = True, sol = True) :
        self.ValCam = cam
        self.ValRes = res
        self.ValSol = sol
        self.ouvrir()
    
    def ouvrir(self) :
        chemin = c4d.storage.LoadDialog()
        self.chemin = chemin
        if chemin is None : return
        chemin = chemin.decode('UTF-8', 'strict')
        self.chemin = chemin
        
        try:
            self.fichier = xml.dom.minidom.parse(chemin)
        except IOError :
            print "Fichier introuvable"
            return
        
        self.lire()
        self.fermer()
    
    def fermer(self) :
        if self.fichier is not None :
            self.fichier.unlink()
    
    def texte(self, txt) :
        txt = txt.encode('UTF-8', 'strict')
        return str(txt)
        
    def texteDuNoeud(self, noeud) :
        return noeud.childNodes[0].nodeValue
    
    def noeudParNom(self, noeud, genre, nom, requis, i = 0) :
        if not noeud : return None
        j = 0
        snoeuds = noeud.getElementsByTagName(genre)
        for n in snoeuds :
            n_nom = n.getElementsByTagName(nom)
            if len(n_nom) > 0 :
                n_nom = n_nom[0]
                val = self.texteDuNoeud(n_nom)
                if val == requis :
                    if i == j : return n_nom.parentNode
                    j += 1
        
        return None
    
    def paramValeur(self, noeud) :
        if not noeud : return None
        
        parametres = noeud.getElementsByTagName("parameters")
        paramtype = noeud.getElementsByTagName("typename")
        paramtype = self.texteDuNoeud(paramtype[0])
        
        if paramtype == "float" :
            valeur = parametres[0].getElementsByTagName("value")
            valeur = self.texteDuNoeud(valeur[0])
            return float(valeur)
        
        elif paramtype == "float2" :
            valeur = parametres[0].getElementsByTagName("valuexy")
            valeur = self.texteDuNoeud(valeur[0])
            valeur = valeur.split(" ")
            return Vector(float(valeur[0]), float(valeur[1]), 0)
        
        elif paramtype == "float3" or paramtype == "float3daylightsystem" :
            valeur = parametres[0].getElementsByTagName("valuexyz")
            valeur = self.texteDuNoeud(valeur[0])
            valeur = valeur.split(" ")
            return Vector(float(valeur[0]), float(valeur[1]), float(valeur[2]))
        
        elif paramtype == "int2resolution" :
            valeur = parametres[0].getElementsByTagName("valuexy")
            valeur = self.texteDuNoeud(valeur[0])
            valeur = valeur.split(" ")
            return Vector(int(valeur[0]), int(valeur[1]), 0)
        
        return None
    
    def lire(self) :
        if self.ValCam is True : self.recCamera()
        if self.ValRes is True : self.recRendu()
        if self.ValSol is True : self.recSoleil()
    
    def recRendu(self) :
        n_ren = self.noeudParNom(self.fichier, "Node", "typename", "int2resolution", 0)
        n_ren_res = self.paramValeur(n_ren)
        
        self.rendu = OCSRendu(n_ren_res)
    
    def recSoleil(self) :
        n_sol = self.noeudParNom(self.fichier, "Node", "typename", "daylight", 0)
        if n_sol is None :
            self.soleil = None
            return
        
        n_sol_cib = self.paramValeur(self.noeudParNom(n_sol, "Node", "name", "sundir"))
        
        self.soleil = OCSSoleil(n_sol_cib)
    
    def recCamera(self) :
        i = 0
        n_cam = self.noeudParNom(self.fichier, "Node", "typename", "thinlens", i)
        
        while n_cam is not None :
            n_cam_nom = self.texte(self.texteDuNoeud(n_cam.getElementsByTagName("name")[0]))
            n_cam_foc = self.paramValeur(self.noeudParNom(n_cam, "Node", "name", "fov"))
            n_cam_pos = self.paramValeur(self.noeudParNom(n_cam, "Node", "name", "pos"))
            n_cam_cib = self.paramValeur(self.noeudParNom(n_cam, "Node", "name", "target"))
            n_cam_hau = self.paramValeur(self.noeudParNom(n_cam, "Node", "name", "up"))
            n_cam_dec = self.paramValeur(self.noeudParNom(n_cam, "Node", "name", "lensShift"))
            n_cam_map = self.paramValeur(self.noeudParNom(n_cam, "Node", "name", "focalDepth"))
            
            camera = OCSCamera(n_cam_nom, n_cam_pos, n_cam_cib, n_cam_hau, n_cam_foc, n_cam_dec, n_cam_map)
            self.cameras.append(camera)
            
            i += 1
            n_cam = self.noeudParNom(self.fichier, "Node", "typename", "thinlens", i)

def importOCS() :
    dial = Dialogue()
    dial.Open(c4d.DLG_TYPE_MODAL)
    if dial.annuler is True : return
    
    ocs = XmlOCS(dial.camera, dial.reso, dial.soleil)
    if ocs.chemin is None : return
    doc.StartUndo()
    
    bd = doc.GetActiveBaseDraw()
    rd = doc.GetActiveRenderData()
    
    # Caméras
    if dial.camera is True :
        ocs.cameras.reverse()
        for camera in ocs.cameras :
            camera = camera.C4DCamera()
            bd.SetSceneCamera(camera)
            doc.InsertObject(camera)
            doc.AddUndo(c4d.UNDOTYPE_NEW, camera)
    
    # Résolution
    if dial.reso is True :
        doc.AddUndo(c4d.UNDOTYPE_CHANGE_SMALL, rd)
        rd[c4d.RDATA_XRES] = ocs.rendu.resolution.x
        rd[c4d.RDATA_YRES] = ocs.rendu.resolution.y
    
    # Soleil
    if dial.soleil is True and ocs.soleil is not None :
        soleil = ocs.soleil.C4DSoleil()
        doc.InsertObject(soleil)
        doc.AddUndo(c4d.UNDOTYPE_NEW, soleil)
    
    c4d.EventAdd()
    doc.EndUndo()

if __name__=='__main__':
    importOCS()