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

Discussion: Python Scripts phidek

  1. #1

    Python Scripts phidek

    Hello la French

    Etant rookie j'ouvre ce post pour partager mes avancées dans le monde merveilleux de Python, en espérant pouvoir me faire aider et corriger parfois.
    J'ai commencé il y a quelques semaines et pour vous donner une idée je vous post mon premier script...

    Il renomme chaque enfants de l'objet sélectionné en leur donnant le nom du parent principal + le chiffre correspondant à leur place dans la hiérarchie.
    Pratique pour renommer une chaîne de joints par exemple.


    Code PHP:
    import c4d

    def main
    ():
      
    pass

    counter 
    0
    end_Counter 
    50 #*
    const_Selec doc.GetActiveObject()

    while 
    counter<=end_Counter:
     
    selec doc.GetActiveObject()
     
    new_Selec selec.GetDown()
     
    le_Nom const_Selec.GetName()
     
    chiffre str(counter)
     
    new_Selec.SetName(le_Nom+chiffre)
     
    doc.SetActiveObject(new_Selec)
     
    counter counter +1


    if __name__=='__main__':
        
    main() 
    *J'ai définit la valeur de end_Counter à 50, à défaut d'avoir trouver un moyen de renvoyer le nombre total de sous-objets .GetChildren() ne renvoyant pas les grandchilds.


    N'hésitez pas à me corriger.
    Merci au post de oli_d qui m'ont permis d'y voir un peu plus clair.

  2. #2
    Gourou Avatar de valkaari
    Date d'inscription
    mai 2009
    C4D version
    Autre
    OS
    OSX / windows
    Messages
    2 949
    il faut revoir ton indentation qui n'est pas bonne à mon sens.

    Ton code s'exécutes bien mais pas via la fonction Main. Ce n'est pas forcement un problème (la preuve ça fonctionne) autant prendre de bonnes habitudes.

    La fonction Main est au même niveau que ton while. Tu dois virer le pass de ta fonction main et mettre tout ton code en dessous avec une. De la même façon que tout ce qui vas dans le while doit être en dessous avec une tabulation.

    Pour ce qui est du "tant qu'il y a un enfant" je ne suis pas certain en python mais normalement tu dois faire un while enfant
    et dans la boucle enfant = enfant.GetDown().

    Si la fonction GetDown() ne renvoit pas d'objet, elle doit renvoyer none ce qui arrêtera la boucle.

    (enfin en c++ c'est comme ça qu'on fait)

    Regarde également les fonctions récursive pour ce genre d'exercice, valable dans tous les langages de programmation, c'est diaboliquement puissant et rapide.

    edit : j'ai testé ceci et ça fonctionne. J'ai rajouté le c4d.EventAdd() pour que c4d mette à jours l'objet manager après le changement des noms. Par rapport à ton code, pas besoin de récupérer dans la boucle tout ce qui ne change pas.

    Code:
    import c4d
    
    def main():
        counter = 0
        le_Nom = doc.GetActiveObject().GetName()
        enfant = doc.GetActiveObject().GetDown()
        while enfant :
             chiffre = str(counter)
             enfant.SetName(le_Nom + " " + chiffre)
             counter += 1
             enfant = enfant.GetDown()
        c4d.EventAdd()
    
    if __name__=='__main__':
        main()

    edit 2 :

    en générale on préfère écrire counter +=1 plutôt que counter = counter + 1 même si les deux sont identiques.
    ça marche également avec les autres opérations.

    voir dans d'autres langages tu pourra voir directement counter ++
    Ne pas trop abuser quand même, à force ça devient illisible.
    un autre abus, c'est les opérations comme j'ai mis genre
    enfant = doc. GetActiveObject().GetDown()
    si t'as 4km de fonction, autant faire des pointeurs (surtout si tu dois réutiliser d'autre fonction d'un objet ciblé.
    Dernière modification par valkaari ; 12/05/2011 à 23h10.

  3. #3
    TOP Val une fois de plus

    Parfaites explications.
    Comme tjrs.
    Je vais revoir ma manière de faire, suite à tes conseils avisés.
    En espérant poster quelque chose d'un peu plus propre prochainement.

  4. #4
    Pilier Avatar de oli_d
    Date d'inscription
    avril 2004
    C4D version
    Autre
    OS
    MacOS X
    Messages
    707
    Bravo pour ton code, ça fait plaisir de voir qu'il y a du monde qui se lance dans le python et ça me motive pour un tuto ...

    Je plussoie avec Val qui t'a donné d'excellents conseils.

    Pour les bases du python je te conseille 2 excellents outils :




    Regarde en tous cas jusqu'au chapitres sur la récursion des pythonneries.

    Bon dans ton cas si tu veux réellement que le premier enfant pas forcément besoin de la récursion.

    Mais si tu veux par exemple parcourir tous les objets de ta scène :
    Code PHP:
    import c4d

    def parcourir_objs
    (obj,stop None):
        
    """fonction recursive pour parcourir tous les objets
           si stop = None tous les objets depuis obj
           si stop = obj, uniquement les objets en enfants de obj"""

        
    while obj :
            print 
    obj.GetName() #mettre ce que l'on a besoin ici
            
    parcourir_objs(obj.GetDown())# recursion : la fonction s'appelle elle-meme
            
    if stop and obj == stop : return
            
    obj obj.GetNext()

    if 
    __name__=='__main__':
        
    obj doc.GetFirstObject()#on trouve le premier element de notre scene...
        
    if obj parcourir_objs(obj)#...si il y en a un on parcourt tout 
    Avec la même fonction pour parcourir tous les enfants de l'objet actif :

    Code PHP:
    import c4d

    def parcourir_objs
    (obj,stop None):
        while 
    obj :
            print 
    obj.GetName()
            
    parcourir_objs(obj.GetDown())
            if 
    stop and obj == stop : return
            
    obj obj.GetNext()

    if 
    __name__=='__main__':
        
    obj doc.GetActiveObject()#on recupere l'objet actif...
        
    if obj parcourir_objs(obj,stop=obj)#...si il existe et on parcourt tous les enfants et sous-enfants 
    Dans ce cas je ne fais qu'imprimer le nom des objets dans la console, mais tu peux remplacer la ligne où il y a le print par ce que tu veux pour interagir avec tes objets
    Dernière modification par oli_d ; 13/05/2011 à 06h35.

  5. #5
    Super Oli_d

    Merci pour tes liens, j'espère qu'après leur lecture je ne ressentirai plus cette étrange douleur au cerveau en lisant tes scripts ..
    « Pour moi, la programmation est plus qu'un art appliqué important. C'est aussi une ambitieuse
    quête menée dans les tréfonds de la connaissance. »

    Ok
    ca attaque fort en page 1...

  6. #6
    Hello à tous en particulier à Val et Oli_d

    Après une semaine intensive de pythonnerie je reviens, comme promis, poster mes avancées sur le reptile.
    Voici un nouveau script qui m'a couté pas mal de plantage machine et de surchauffe neuronal ...

    Il regroupe chaque objets au sein du même parent en fonction de leur type (cube, plane, sphere, disc etc...)

    Code PHP:
    import c4d
    from c4d import 
    *


    def main():
        
    obj doc.GetObjects()
        
    len_objlen(obj)
        
    n=0
        
    while n<len_obj:
            
    i=0
            
    while i<len_obj:
                if 
    i==n:                # ne rien faire (évite le plantage machine)
                    
    print 'false'                 
                
    elif obj[i].GetType()==obj[n].GetType():
                    
    obj[i].InsertUnder(obj[n])
                    
    obj doc.GetObjects()      # Réinforme la machine sur la taille du chutier une fois modifée.
                    
    len_objlen(obj)
                    
    i=i-1
                i
    =i+1
            n
    =n+1
    c4d
    .EventAdd()


    if 
    __name__=='__main__':
        
    main() 
    Je pense qu'il existe un moyen plus simple d'atteindre le même but (en dehors d'un glisser déposer avec la souris ).
    Si vous en avez une idée je suis impatient de la connaitre...
    Dernière modification par phidek ; 22/05/2011 à 03h10.

  7. #7
    Pilier Avatar de oli_d
    Date d'inscription
    avril 2004
    C4D version
    Autre
    OS
    MacOS X
    Messages
    707
    N'hésites pas à utiliser les boucles for in surtout quand tu récupères une liste :

    la fonction doc.GetObjects() renvoie une liste avec tous les objets du premier niveau, donc pour les parcourir tu peux simplement faire :

    Code PHP:
    for obj in doc.GetObjects():
            print 
    obj.GetName() 
    Les plantages que tu avais était probablement dû à ta fonction InsertUnder() quand tu essaies de mettre un objet en enfant de lui-même (c'est pire que l'inceste !).

    Je te mets une variante qui copie tous les objets et les classes dans un null "Regroupement" (à par ça il y a déjà une fonction qui te permet d'isoler tes éléments par type quand tu cliques sur le petit œil dans la palette objets)

    Code PHP:
    import c4d

    def liste_obj
    (obj,stop None):
        
    """fonction recursive pour récupérer tous les objets sous forme de liste
           si stop = None tous les objets depuis obj (donc si premier objet d'un doc -> tous les objets)
           si stop = obj, uniquement les objets en enfants de obj"""
        
    liste = []
        while 
    obj :
            
    liste.append(obj#on ajoute l'objet a la liste
            
    liste +=liste_obj(obj.GetDown())# recursion : la fonction s'appelle elle-meme et on ajoute la liste
            
    if stop and obj == stop : return
            
    obj obj.GetNext()
        return 
    liste



    if __name__=='__main__':
        
        
    obj doc.GetFirstObject()
        
    objs liste_obj(obj,stop None# fonction en dessus pour récupérer tous les objets sous forme de liste
        
    null c4d.BaseObject(c4d.Onull)
        
    null.SetName('Regroupement')

        
    dic_type = {} #on crée un dictionnaire pour stocker nos null object par type
        
    for o in objs
            
    typ o.GetTypeName() #on récupère le nom du type
            
    nul_obj dic_type.get(typ,None#on regarde si on a déjà stocké un null object correspondant au type ...
            
    if not nul_obj# si il n'existes pas ...
                
    nul_obj=c4d.BaseObject(c4d.Onull#...on le crée
                
    nul_obj.SetName(typ)
                
    nul_obj.InsertUnder(null)
                
    dic_type[typ]=nul_obj ## et on l'ajoute à notre dictionnaire

            
    o2 o.GetClone(flags=c4d.COPYFLAGS_NO_HIERARCHY)# on copie chaque objet sans les enfants
            
    o2.InsertUnder(nul_obj#et on le met dans notre null object

        
    doc.InsertObject(null)
        
    c4d.EventAdd() 
    Dernière modification par oli_d ; 24/05/2011 à 20h10.

  8. #8
    Merci Oli_d.

    J'avais fais pas mal d'essais avec les boucles for in.
    J'avais eu des plantages à cause d' obj[x].InsertUnder(obj.[x]) et aussi à cause des boucles infinies... Bref

    Merci pour ton code Il y à encore des zones que j'ai du mal à comprendre, je vais me pencher dessus ...
    Merci

  9. #9

    EWalk

    Un autre petit script qui facilite le processus d'animation d'un cycle de marche.
    J'essayerai de le develloper un peu plus dans le futur en esperant en sortir un petit plug

    Code PHP:
    import c4d
    from c4d import gui
     
    def main
    ():
        
    Objs=doc.GetActiveObjects(False)
     
        
    a=0
        
    for i in Objs:
            
    a+=1
     
        
    if a!=3:
            
    gui.MessageDialog("Please select the 3 following elements: \n - L.Foot \n - R.Foot \n - Control Object")
        else:
            
    c4d.CallCommand(12410# Insert KeyFrames 
            
    Obj1V=Objs[0].GetRelPos()
            
    Obj2V=Objs[1].GetRelPos()
            
    Obj3V=Objs[2].GetRelPos()
     
            
    # Fonction definissant quel pied est le pied arriere
            
    def lepiedarriere():
                if 
    Obj1V.z<Obj2V.z:
                    
    lePiedArr=Objs[1
                else:
                    
    lePiedArr=Objs[0]
                return 
    lePiedArr
     
            
    """ Determine la taille du pas a effectuer en fonction
            de l'ecart principal"""
     
            
    Ecart=Obj1V.z-Obj2V.z   
            
    if Ecart<0:
                
    Ecart=0-Ecart
     
            PiedsV
    =lepiedarriere().GetRelPos()
            if 
    PiedsV==Obj1V:
                
    PiedsV.z=0+(Obj2V.z-Ecart)
            else:
                
    PiedsV.z=0+(Obj1V.z-Ecart)
     
            
    lepiedarriere().SetRelPos(PiedsV)
     
            
    #Determine l'amplitude de l'avancement de l'objet controleur
            
    Obj3V.z=Obj3V.z-Ecart
            Objs
    [2].SetRelPos(Obj3V)
     
            
    #InsertKey toutes les x Frames Message d'erreur "out of timeline"
            
    def nbrsDeFrames(c):
                
    fps doc.GetFps()
                
    currentFrame doc.GetTime().GetFrame(fps)
                
    endTime doc.GetMaxTime().GetFrame(fps)
                if 
    currentFrame>=endTime-(c-1):
                     
    gui.MessageDialog("Out of timeline")
                else:
                    
    doc.SetTime(c4d.BaseTime(currentFrame+,fps))
                    
    c4d.CallCommand(12410#insert la key
     
            # Modifie l'interpolation de chaque keys
            
    def interpolation(d):
                for 
    n in range(len(Objs)):
                    
    track Objs[n].GetCTracks() #List de CTrack
                    
    b=0
                    key_Count
    track[1].GetCurve().GetKeyCount()
                    while 
    b<=key_Count-1:
                        for 
    i in range(len(track)):
                            
    curve track[i].GetCurve()
                            
    lacle=curve.GetKey(b)
                            
    test=lacle.SetInterpolation(curved)   
                        
    b+=1
     
            nbrsDeFrames
    (20)#Soi 20 frames pour un pas
            
    c4d.EventAdd()
            
    interpolation(2#Type d'interpolation 2 soi lineaire
     
     
    if __name__=='__main__':
        
    main() 
    Les 3 objets doivent être sélectionnés dans cet ordre "les 2 pieds puis l'objet contrôleur".
    La grandeur des pas est déterminée en fonction de la pose de départ.
    Il ne reste plus qu'à placer la valeur "Y" entre chaque pas.



    Vue que je suis débutant les corrections sont tjrs le bienvenues
    Merci pour les retours...
    Dernière modification par phidek ; 23/06/2011 à 18h45.

Discussions similaires

  1. Scripts divers python by oli_d
    Par oli_d dans le forum Programmation
    Réponses: 48
    Dernier message: 14/05/2011, 08h37
  2. MDD Reader python
    Par valkaari dans le forum Programmation
    Réponses: 6
    Dernier message: 21/02/2011, 00h41
  3. Py4D : le language python dans C4D
    Par oli_d dans le forum Xpresso/Programmation
    Réponses: 47
    Dernier message: 27/09/2010, 11h18
  4. Petit scripts d'acceuil (pour se connecter)
    Par kyoshiro dans le forum Le site
    Réponses: 10
    Dernier message: 21/03/2005, 16h41
  5. Quelques scripts de COFFEE
    Par blazouf dans le forum Xpresso
    Réponses: 6
    Dernier message: 05/08/2002, 17h10

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