Code Vonc

Instances Octane

v 2.0

Script R13+ OSX Win

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

Générer la liste des instances pour Octane
Ouvrez le gestionnaire de scripts, créez un nouveau script (fichier > nouveau) puis copiez-collez-y le code ci-dessous.


Sélectionnez l'objet source ou une de ses instances puis lancer le script. Copiez-collez le texte généré dans le noeud « Scatter » d'Octane.


Attention, l'objet source doit être aux coordonnées globales (0 ; 0 ; 0).

N'oubliez pas d'exporter l'objet source dans un fichier obj à part à l'aide du bouton « Export OBJ/MTL only » de la fenêtre d'exportation vers Octane, puis de l'implémenter dans Octane avec un noeud « Mesh » relié au noeud « Scatter ».


Désactiver ensuite les instances pour ne pas les exporter en même temps que le reste de votre scène dans Octane.


Code inspiré de l'Xpresso créé par Bepeg4D.



import os
import c4d
from c4d import gui, utils
from c4d.modules import mograph as mo

class InstOct() :
    source = None
    ref = False
    ech = 0.01
    code = ""
    erreur = ""
    quantite = 0
    
    def __init__(self, ref, ech) :
        self.ref = ref
        self.source = None
        self.ech = ech
        self.code = ""
        self.quantite = 0
        self.erreur = self.Recup()
    
    def GenereCode(self, obj, matrice = None) :
        ret = ""
        if obj : matrice = obj.GetMg()
        
        matrice *= ~self.source.GetMg()
        
        p = matrice.off
        x = matrice.v1
        y = matrice.v2
        z = matrice.v3
        p *= self.ech
        #x *= self.ech
        #y *= self.ech
        #z *= self.ech
        p.z = -p.z
        z = -z
        x.z = -x.z
        y.z = -y.z
        z.z = -z.z
        ret += str(x.x) + " " + str(y.x) + " " + str(z.x) + " " + str(p.x) + " "
        ret += str(x.y) + " " + str(y.y) + " " + str(z.y) + " " + str(p.y) + " "
        ret += str(x.z) + " " + str(y.z) + " " + str(z.z) + " " + str(p.z) + "\n"
        self.code += ret
        self.quantite += 1
    
    def Recup(self) :
        if not op : return "Veuillez sélectionner un objet."
        if op.CheckType(c4d.Oinstance) : self.source = op[c4d.INSTANCEOBJECT_LINK]
        else : self.source = op
        
        obj = doc.GetFirstObject()
        if not obj : return "Aucun objet trouvé."
        n = 0
        
        if self.ref : self.GenereCode(self.source)
        
        cloneurs = []
        
        while obj :
            objs = [obj]
            for o in objs :
                modon = mo.GeGetMoData(o)
                if modon : cloneurs.append(o)
                
                if o.CheckType(c4d.Oinstance) :
                    if o[c4d.INSTANCEOBJECT_LINK] == self.source :
                        n += 1
                        self.GenereCode(o)
                
                if not modon : objs.extend(o.GetChildren())
            obj = obj.GetNext()
        
        for cloneur in cloneurs :
            objs = cloneur.GetChildren()
            asrc = False
            for o in objs :
                if o.CheckType(c4d.Oinstance) :
                    if o[c4d.INSTANCEOBJECT_LINK] == self.source :
                        asrc = True
                        break
                if o == self.source :
                    asrc = True
                    break
                #objs.extend(o.GetChildren())
            
            if asrc :
                modon = mo.GeGetMoData(cloneur)
                if not modon : continue
                tab = modon.GetArray(c4d.MODATA_MATRIX)
                if not tab : continue
                for i, m in enumerate(tab) :
                    m = cloneur.GetMg() * m
                    self.GenereCode(None, m)
            
        if (self.code == "") : return "Aucun clone trouvé."
        

class Dialogue(gui.GeDialog):
    instoct = None
    
    def sauvegarde(self) :
        dossier = doc.GetDocumentPath()
        titre = self.GetString(11)
        chemin = c4d.storage.SaveDialog(force_suffix = "txt", def_path = dossier)
        if not chemin : return
        chemin = chemin.decode('UTF-8', 'strict')
        
        try : f = open(chemin, "w")
        except IOError :
            gui.MessageDialog("Impossible d'écrire le fichier.\n Vérifiez qu'il ne soit pas utilisé par un autre programme.")
            return
        
        f.write(self.GetString(13))
        
        f.close()
    
    def calcule(self) :
        ech = self.GetReal(22)
        ref = self.GetBool(12)
        self.instoct = InstOct(ref, ech)
        self.SetString(13, self.instoct.code)
        if self.instoct.erreur : self.SetString(13, self.instoct.erreur)
        if self.instoct and  self.instoct.source :
            self.SetString(11, "(" + str(self.instoct.quantite) + ") " + self.instoct.source[c4d.ID_BASELIST_NAME])
    
    def CreateLayout(self) :
        self.SetTitle("Instances Octane v 2.0")
        self.GroupBegin(10, 2, 1)
        self.AddStaticText(11, c4d.BFH_SCALEFIT, 0, 0, "", 2)
        
        self.GroupBegin(20, 1, 2)
        self.AddStaticText(21, c4d.BFH_SCALEFIT, 0, 0, "Échelle : ")
        self.AddEditNumberArrows(22, c4d.BFH_SCALEFIT)
        self.GroupEnd()
        
        self.AddCheckbox(12, c4d.BFH_SCALEFIT, 0, 0, "Inclure référence")
        self.AddMultiLineEditText(13, c4d.BFH_SCALEFIT , 0 , 70 , 0)
        self.AddButton(14, c4d.BFH_SCALEFIT, 300, 20, "Enregistrer sous...")
        self.GroupEnd()
        return True
    
    def InitValues(self) :
        self.SetReal(22, 0.01, min = 0.0000001, step = 0.01)
        self.calcule()
        return True
    
    def Command(self, id, msg) :
        if id == 12 : self.calcule()
        if id == 22 : self.calcule()
        if id == 14 : self.sauvegarde()
        return True

def main():
    dial = Dialogue()
    dial.Open(c4d.DLG_TYPE_MODAL)

if __name__=='__main__':
    main()