Boutique Cinema 4D
Affichage des résultats 1 à 10 sur 10

Discussion: Mon premier script Python. J'ai besoin d'aide pour le tester.

  1. #1
    Touriste
    Date d'inscription
    janvier 2016
    C4D version
    R17 Studio
    Messages
    2

    Mon premier script Python. J'ai besoin d'aide pour le tester.

    Bonjour à tous.

    Après avoir lu un tweet de Patrick Letourneau : https://twitter.com/PolygonSandwich/...37946457239553,
    j'ai décidé de me coller à la programmation d'un script pour résoudre ce problème.

    Voici donc ce qu'il est censé réaliser:

    Pour chaque objet sélectionné :
    - Effacer les doublons de tags de texture
    - Effacer les tags de sélection vide
    - Effacer les tags de texture restreint à des tag de sélection qui n'existe pas

    C'est sûrement très mal programmé, je débute totalement en python, mais si vous avez l'occasion de le tester, je suis avide de retours...

    Code:
    import c4d
    from c4d import gui
    
    
    ### For selected polygon objects
    ###    - remove empty selection tags
    ###    - remove texture tags restricted to non-existing selection tag
    ###
    
    
    
    
    
    
    def nettoie_polygon_tag(t,anciens_tags):
        """ on s'occupe des selections de polygones """
        
        s = t.GetBaseSelect()
        if s.GetCount() == 0:
            t.Remove()        
            
    def nettoie_texture_tag(t,anciens_tags):
        """ on s'occupe des textures """
        
        flag_a_garder = False
    
    
        if t[c4d.TEXTURETAG_RESTRICTION]:
            la_restriction = t[c4d.TEXTURETAG_RESTRICTION]
            
            # verifie si restriction existe dans selectiontag
            for tt in anciens_tags:
                if type(tt) is c4d.SelectionTag:
                    
                    if tt.GetName() == str (la_restriction):
                        flag_a_garder = True
                        
        else:
            flag_a_garder = True
    
    
        if not flag_a_garder:
            t.Remove()
    
    
    def nettoie_doublon_texture_tag(tag,anciens_tags):
        """ on ne garde que la derniere texture """
        
        tags_tex_liste = []
        for tt in anciens_tags:
            if type(tt) is c4d.TextureTag:
                if not tt[c4d.TEXTURETAG_RESTRICTION]:
                    tags_tex_liste.append(tt)
                    ## tt.Remove()
        
        ## remet le dernier
        print tags_tex_liste
        print (len (tags_tex_liste) )
            
        
    def nettoie_tags(o):
        """
        Nettoyage des Tags
        """
        
        
    
    
        ### Passe 1 : virer tag textures doublons
        anciens_tags = o.GetTags()
        for tag in anciens_tags:
            if type(tag) is c4d.TextureTag:        
                tags_tex_liste = []
                for tag in anciens_tags:
                    if type(tag) is c4d.TextureTag:
                        if not tag[c4d.TEXTURETAG_RESTRICTION]:
                            tags_tex_liste.append(tag)
                            tag.Remove()
        
        c4d.EventAdd()            
        
        ##  Passe 2 : remetre le dernier tag texture
        if len (tags_tex_liste) > 0:
            le_dernier_tag = tags_tex_liste[len(tags_tex_liste) - 1]
            print le_dernier_tag
        
            o.InsertTag(le_dernier_tag)
        
            c4d.EventAdd()
    
    
        ### Passe 3 : virer selection polygones vides
        anciens_tags = o.GetTags()
        for tag in anciens_tags:
            if type(tag) is c4d.SelectionTag:        
                nettoie_polygon_tag(tag,anciens_tags)
        c4d.EventAdd()
        
        ### Passe 4 : virer tag textures dont la restriction n'existe pas
        anciens_tags = o.GetTags()
        for tag in anciens_tags:
            if type(tag) is c4d.TextureTag:        
                nettoie_texture_tag(tag,anciens_tags)
        c4d.EventAdd()
        
    
    
    def main():
        ledoc = c4d.documents.GetActiveDocument() ## type : c4d.documents.BaseDocument
        laselection = ledoc.GetActiveObjects(0)   ## type : list
        
    
    
        
        ledoc.StartUndo()
        for ob in laselection:                    ## type: c4d.PolygonObject
            doc.AddUndo(c4d.UNDOTYPE_CHANGE,ob)
            nettoie_tags(ob)
            
        ledoc.EndUndo()
        c4d.EventAdd()
            
    if __name__=='__main__':
        main()

  2. #2
    Pilier Avatar de oli_d
    Date d'inscription
    avril 2004
    C4D version
    R19 Studio
    OS
    MacOS X
    Messages
    669
    Salut et bienvenue !

    Tout d'abord pour un premier script je trouve que tu t'en sors vraiment très bien. Plutôt que d'essayer de corriger tout ton code je te montre comment j'aurais abordé le problème, si tu ne comprends pas des trucs n'hésites pas à demander:

    Code PHP:
    import c4d

    def main
    ():
        
        
    doc.StartUndo()
        
        for 
    o in doc.GetActiveObjects(c4d.GETACTIVEOBJECTFLAGS_0):
            
    doc.AddUndo(c4d.UNDOTYPE_CHANGE,o)
            
            
    #################################################
            #suppression des tags de sélection de polygones vides
            
    for t in o.GetTags():
                if 
    t.CheckType(c4d.Tpolygonselection):
                    
    bs t.GetBaseSelect()
                    if 
    not bs.GetCount(): t.Remove()
                    
            
    #liste des noms des tags de sélection qui restent par une ompréhension de liste
            
    sel_names = [t.GetName() for t in o.GetTags() if t.CheckType(c4d.Tpolygonselection)]
            
            
    #################################################
            #suppression des tags texture avec restriction qui n'existent pas
            
    for t in o.GetTags():
                if 
    t.CheckType(c4d.Ttexture):
                    
    restrict t[c4d.TEXTURETAG_RESTRICTION]
                    if 
    restrict and restrict not in sel_namest.Remove()
            
            
    #################################################
            #suppression de tous les tags texture sans restriction sans le dernier
            
            #liste de tous les tags texture qui n'ont pas de restriction
            
    tags_tex = [for t in o.GetTags() if t.CheckType(c4d.Ttexture) and not t[c4d.TEXTURETAG_RESTRICTION]]
            
            
    #on supprime tout sauf le dernier
            
    for t in tags_tex[:-1] : t.Remove()
        
        
    doc.EndUndo()
        
        
    c4d.EventAdd()
            
    if 
    __name__=='__main__':
        
    main() 
    Explications dans l'ordre :
    • hors plugin tu peux utiliser la variable doc pour remplacer c4d.documents.GetActiveDocument(), c'est plus court à écrire
    • j'utilise souvent les compréhensions de liste, c'est vachement pratique en python
    • dans une liste si tu veux le dernier élément tu peux écrire list[-1] si tu veux tous les éléments sauf le dernier list[:-1] (voir d'autres combines ici)


    En ce qui concerne les fonctions, je suis toujours un peu partagé. Pour les scripts courts je préfére taper le code à la suite, je trouve ça plus lisible. Mon critère pour utiliser une classe ou une fonction, c'est dès que tu commences à copier/coller des portions de code c'est qu'il faut créer soit une classe soit une fonction. Pour les codes plus long, c'est une autre problématique.

    Il y a évidemment toujours 40 manières d'arriver au même résultat. J'ai appris sur le tas et je fais sûrement des trucs pas très catholiques. Il y a des plus pro sur le forum, comme xsYann, Valkaari et César qui me corrigeront si j'ai dit des conneries.

    En tous cas bravo, ça fait toujours plaisir de voir pointer des nouveaux codeurs par ici.

    PS :Si il y a un modo qui passe, je vote pour qu'on le désensable et que l'on bouge ce sujet dans la section programmation
    Dernière modification par oli_d ; 22/01/2016 à 21h51.

  3. #3
    Vieux Croûton Avatar de Aurety
    Date d'inscription
    juillet 2002
    C4D version
    R17 Studio
    OS
    Mac
    Messages
    14 310
    Billets dans le blog
    3
    ouaip je fais ça !
    kenavo !! // Pinterest KAMIGAZ®

  4. #4
    Pilier Avatar de oli_d
    Date d'inscription
    avril 2004
    C4D version
    R19 Studio
    OS
    MacOS X
    Messages
    669
    ça c'est du rapide, merci Aurety !

  5. #5
    Touriste
    Date d'inscription
    janvier 2016
    C4D version
    R17 Studio
    Messages
    2
    Merci beaucoup Oli_d pour ta réponse super détaillée et Aurety pour ta promptitude.
    Ca va me prendre un peu de temps de bien comprendre ton code, mais c'est super interessant d'avoir le corrigé !



    Bon je vais déjà potasser :




    Et merci pour les conseils.




  6. #6
    Gourou Avatar de valkaari
    Date d'inscription
    mai 2009
    C4D version
    Autre
    OS
    OSX / windows
    Messages
    2 856
    j'avais complètement raté ce post tient.


    tags_tex = [t for t in o.GetTags() if t.CheckType(c4d.Ttexture) and not t[c4d.TEXTURETAG_RESTRICTION]]

    En plus d'être pratique c'est d'une élégance folle.

  7. #7
    Touriste
    Date d'inscription
    mai 2019
    C4D version
    R19 Studio
    OS
    Windows 10
    Messages
    2

    Besoin d'aide sur un problème du même genre je pense

    Bonjour,

    Je suis sur c4d r20 et ça fait plus de 6 heures que je cherche désespérément à écrire un script python qui sélectionne tous tags de texture assignés aux objets de scène, puis qui change la valeur de restriction (TEXTURETAG_RESTRICTION) à "0".

    Ca désactiverait toutes les textures, également dans le live viewport d'octane.
    Pour le moment, je débute et ça m'a donc pris des lustres pour comprendre un peu le language et écrire cela :

    Code:
    import c4dfrom c4d import gui
    
    
    def main():
        c4d.CallCommand(300001025) # Select All
        c4d.CallCommand(16370, 16370) # Select Texture Tags/Objects
        s = doc.GetActiveTags()
        
        for i in s:
            tag(i)[c4d.TEXTURETAG_RESTRICTION] = "off#"
    
        c4d.EventAdd()
    
    
    if __name__=='__main__':
        main()
    Quand j’exécute, ça sélectionne tous tags de texture assignés aux objets de scène mais impossible de changer les valeurs de restriction sur tous en même temps.

    Auriez-vous une solution ?

    Merci d'avance !

    Antoka
    Dernière modification par Antoka ; 25/08/2019 à 12h33.

  8. #8
    Gourou Avatar de César Vonc
    Date d'inscription
    avril 2006
    C4D version
    R19 Studio
    OS
    Windows 10
    Messages
    2 456
    Salut,

    Essaie ça plutôt :

    Code:
        for i in s:
            i[c4d.TEXTURETAG_RESTRICTION] = "off#"

    Ce serait plus joliment écrit comme ceci :

    Code:
        tags = doc.GetActiveTags()
        
        for tag in tags:
            tag[c4d.TEXTURETAG_RESTRICTION] = "off#"
    Dernière modification par César Vonc ; 25/08/2019 à 11h10.

  9. #9
    Touriste
    Date d'inscription
    mai 2019
    C4D version
    R19 Studio
    OS
    Windows 10
    Messages
    2
    Merci BEAUCOUP César Vonc.
    J'étais pas si loin, merci encore. Le chemin va être long avant de maîtriser ce langage.

    Aussi j'aurais une nouvelle question, je ne sais pas c'est approprier de la poser à la suite.
    Je cherche à écrire un script qui sélectionne puis fusionne tous les shaders ayant le même "MATERIAL_COLOR_SHADER"

    Pour l'instant j'ai ça qui me permet de fusionner les shaders sélectionnés manuellement :

    Code:
    import c4d
    
    def main():
            mats = doc.GetActiveMaterials()
            list_tags = list()
    
    
            for mat in mats:
                obj_link = mat[c4d.ID_MATERIALASSIGNMENTS]
    
    
                for i in xrange(obj_link.GetObjectCount()):
                    list_tags.append(obj_link.ObjectFromIndex(doc, i))
    
    
            doc.StartUndo()
            for tag in list_tags:
                doc.AddUndo(c4d.UNDOTYPE_CHANGE, tag)
                tag[c4d.TEXTURETAG_MATERIAL] = mats[0]
    
    
            for mat in mats[1:]:
                doc.AddUndo(c4d.UNDOTYPE_DELETE, mat)
                mat.Remove()
    
    
            doc.EndUndo()
            c4d.EventAdd()
    
    
    if __name__=='__main__':
        main()
    Maintenant je n'ai aucune idée de ce que je pourrait écrire devant afin de ça trouve et sélectionne les doublons. Ce scripts me serait très utiles quand j'importe des persos en fbx issue de DAZ. Il y a toujours 1000 shaders dupliqué à fusionner ça prend du temps. Peut-être qu'un script existe déjà, mais je n'ai rien trouvé pour l'instant.

    Merci encore !
    Antoka
    Dernière modification par Antoka ; 25/08/2019 à 12h33.

  10. #10
    Gourou Avatar de César Vonc
    Date d'inscription
    avril 2006
    C4D version
    R19 Studio
    OS
    Windows 10
    Messages
    2 456
    Pour ça, il faut regrouper tes matériaux dans un dictionnaire avec comme clef le nom de la texture, par exemple :

    Code PHP:
        mats doc.GetMaterials()
        
        
    dico = {}
        
        for 
    mat in mats :
            
    clef 'vide'
            
    tex mat[c4d.MATERIAL_COLOR_SHADER]
            if 
    mat[c4d.MATERIAL_USE_COLOR] and tex and tex[c4d.BITMAPSHADER_FILENAME] : clef tex[c4d.BITMAPSHADER_FILENAME]


            if 
    clef in dico :
                
    dico[clef].append(mat)
            else :
                
    dico[clef] = [mat]
        
        
    groupes dico.values()
        
        for 
    mats in groupes :
            print 
    mats # Et là tu peux appeler ta fonction de dédoublonnage 

    Après, est-ce que la fonction de C4D ne ferait pas l'affaire ? Dans le gestionnaire de matériaux : Fonction > Supprimer les matériaux en double.

Discussions similaires

  1. script python pour compter les pass dans un post effects
    Par phobos34 dans le forum Programmation
    Réponses: 4
    Dernier message: 11/01/2016, 09h08
  2. j'ai un mini truc à faire... j'ai besoin d'aide !
    Par benjam1 dans le forum Nouveaux membres
    Réponses: 12
    Dernier message: 04/06/2009, 12h23
  3. Bonjour a tous...J'ai besoin d'aide !
    Par Mork dans le forum Nouveaux membres
    Réponses: 2
    Dernier message: 27/07/2008, 18h25
  4. Bonsoir a tous ) j'ai besoin d'aide...
    Par DeadSoul dans le forum Nouveaux membres
    Réponses: 7
    Dernier message: 25/08/2005, 17h33
  5. Je suis nouveau salut et j'ai besoin d'aide.
    Par Kage2 dans le forum Général Cinema 4D
    Réponses: 20
    Dernier message: 15/07/2004, 19h26

Les tags pour cette discussion

Règles de messages

  • Vous ne pouvez pas créer de nouvelles discussions
  • Vous ne pouvez pas envoyer des réponses
  • Vous ne pouvez pas envoyer des pièces jointes
  • Vous ne pouvez pas modifier vos messages
  •  
Mediaworks - Logiciels 3D | Design Internet - Creation site internet