Affichage des résultats 1 à 9 sur 9

Discussion: Trier des objets

  1. #1
    Squatteur Avatar de Helium
    Date d'inscription
    novembre 2009
    C4D version
    R13 Broadcast
    OS
    OS X 10.6
    Messages
    179

    Trier des objets

    Salut la compagnie,

    Existe-t-il un moyen de trier automatiquement la hiérarchie des objets dans le gestionnaire en fonction de différents paramètres ?

    Je travaille actuellement avec des grilles de clones mograph assez importantes (aprox. entre 1000 et 10000 clones) avec un seul object source (sphère, cube, parfois spline) dont je fait varier positions et échelles avec différents effecteurs.

    J'aurais besoin de trier ces clones (dans mograph ou après édition du cloner) en fonction de leur taille et / ou volume et / ou surface... voir de leur distance par rapport à un point donné.

    Me retrouver en sortie avec par exemple un groupe d'objet dont le plus volumineux serait en haut de ma hiérarchie, et le moins volumineux en bas. Ou bien avec l'objet le plus proche de ma caméra en haut, et le plus éloigné en bas...

    Une solution potentielle ?

    D'avance merci !
    Dernière modification par Helium ; 29/10/2018 à 17h24.

  2. #2
    Squatteur Avatar de Helium
    Date d'inscription
    novembre 2009
    C4D version
    R13 Broadcast
    OS
    OS X 10.6
    Messages
    179
    J'ai un début de piste qui me fait penser que c'est possible via un script. J'ai trouvé ce morceau de python qui classe les objets du gestionnaire par ordre alphabétique :

    Code:
    # SORT OBJECTS ALPHABETICALLY IN OM
    import c4d
    from c4d import gui
    
    def main():
        obj = doc.GetFirstObject()
        if not obj: return True
        doc.StartUndo()
        olist = []
        while obj:
            olist.append([obj.GetName(),obj])
            obj = obj.GetNext()
        
        olist.sort()
        olist.reverse()
        
        for i,o in enumerate(olist):
            doc.AddUndo(c4d.UNDOTYPE_CHANGE,o[1])
            o[1].Remove()
            doc.InsertObject(o[1],None,None)
    
        c4d.EventAdd()
        doc.EndUndo()
    
    if __name__=='__main__':
        main()
    Je me dit que ça doit être tout à fait transposable à autre chose qu'un ordre alphabétique non ? J'essaie de bricoler l'une ou l'autre ligne, mais je pense que ce n'est pas aussi simple que ça, et de toute évidence je n'ai pas les connaissances requises...

    Discussion à déplacer en section programmation peut être ducoup ?

    Merci
    Dernière modification par Helium ; 31/10/2018 à 11h04.

  3. #3
    Squatteur Niveau 2 Avatar de joecare
    Date d'inscription
    février 2013
    C4D version
    R14 Studio
    OS
    Win 7 64bits
    Messages
    1 219
    Interessant comme sujet...

    Question bête:
    tu n'as pas peur que ça flingue les priorités en cas d'animation.... ??

  4. #4
    Squatteur Avatar de Helium
    Date d'inscription
    novembre 2009
    C4D version
    R13 Broadcast
    OS
    OS X 10.6
    Messages
    179
    Je n'y ai pas pensé, mais c'est pour du statique, pas d'animation en vue. La finalité de tout ça est de récupérer un grand nombre de formes sur illustrator.

    Pour info j'ai essayé de faire ça coté illustrator, j'ai trouvé un script qui ordonne des tracés en fonction de leur surface, mais au dessus d'une centaine d'objets il est dépassé...

  5. #5
    Pilier Avatar de Floc
    Date d'inscription
    novembre 2012
    C4D version
    R15 Studio
    OS
    WindOSX
    Messages
    1 337
    Voici une version modifié de ton code qui classe par "taille".
    Taille est entre guillemet car c'est juste une moyenne des valeurs de la boundingBox.
    Attention que ce script reordonne tout les objets de l'OM.
    il faudrait mettre une gestion de la hierarchie ou au moins une restriction à la selection

    Code PHP:
    # SORT OBJECTS ALPHABETICALLY IN OM
    import c4d
    from c4d import gui

    def main
    ():
        
    obj doc.GetFirstObject()
        if 
    not obj: return True
        doc
    .StartUndo()
        
    olist = []
        while 
    obj:
            
    bb obj.GetRad()
            
    vol int( (bb.bb.bb.z) / 3.0)
            print 
    vol
            olist
    .append([vol,obj])
            
    obj obj.GetNext()
        
        
    olist.sort()
        
    olist.reverse()
        
        
        for 
    i,o in enumerate(olist):
            
    doc.AddUndo(c4d.UNDOTYPE_CHANGE,o[1])
            
    o[1].Remove()
            
    doc.InsertObject(o[1],None,None)

        
    c4d.EventAdd()
        
    doc.EndUndo()

    if 
    __name__=='__main__':
        
    main() 
    Dernière modification par Floc ; 31/10/2018 à 20h28.

  6. #6
    Squatteur Avatar de Helium
    Date d'inscription
    novembre 2009
    C4D version
    R13 Broadcast
    OS
    OS X 10.6
    Messages
    179
    Excellent merci beaucoup Floc !

    Je tricotait au bon endroit mais je suis complètement largué en terme de syntaxe.

    Effectivement à optimiser peut être en mettant une restriction, mais là tout de suite ça fait le taf pour ce que je dois faire. Et de là je devrai arriver avec cette base à adapter à d'autres paramètres.

    Je posterai ça, si j'y arrive !

    Merci encore

  7. #7
    Squatteur Avatar de Helium
    Date d'inscription
    novembre 2009
    C4D version
    R13 Broadcast
    OS
    OS X 10.6
    Messages
    179
    J'ai réussi à adapter le code comme je voulais (en revanche, pour restreindre ça à une sélection ou un groupe d'objet c'est au dessus de mes moyens !)

    C'est surement pas le genre de truc qu'on utilise à tour de bras, mais dans certains cas particuliers ça peut être utile. Je met ça ici, si ça peut servir...

    Pour trier les objets du gestionnaire en fonction de leur "taille" (bounding box), du plus petit au plus grand (j'ai rajouté la prise en compte de l'échelle de l'objet, car en sortie de mograph les objets modifiés par les effecteurs n'ont pas réellement changé de taille mais d'échelle)
    Code:
    # SORT OM OBJECTS : SIZE
    import c4d
    from c4d import gui
    
    def main():
        obj = doc.GetFirstObject()
        if not obj: return True
        doc.StartUndo()
        olist = []
        while obj:
            bb = obj.GetRad()
            scale = obj.GetAbsScale()
            vol = int( bb.x * bb.y * bb.z * scale.x * scale.y * scale.z )
            print vol
            olist.append([vol,obj])
            obj = obj.GetNext()
        
        olist.sort()
        olist.reverse()
        
        
        for i,o in enumerate(olist):
            doc.AddUndo(c4d.UNDOTYPE_CHANGE,o[1])
            o[1].Remove()
            doc.InsertObject(o[1],None,None)
    
        c4d.EventAdd()
        doc.EndUndo()
    
    if __name__=='__main__':
        main()
    Et pour trier les objets en fonction de leur distance avec la caméra active, du plus proche au plus éloigné (vue de l'éditeur si pas de camera objet)
    Code:
    # SORT OM OBJECTS : DISTANCE FROM ACTIVE CAMERA
    import c4d
    from c4d import gui
    
    def main():
        obj = doc.GetFirstObject()
        bd = doc.GetRenderBaseDraw()
        cp = bd.GetSceneCamera(doc)
        if cp is None: cp = bd.GetEditorCamera()
        if not obj: return True
        doc.StartUndo()
        olist = []
        while obj:
            pos1 = obj.GetMg().off
            pos2 = cp.GetMg().off
            dist = (pos2-pos1).GetLength()
            print dist
            olist.append([dist,obj])
            obj = obj.GetNext()
        
        olist.sort()
        olist.reverse()
        
        
        for i,o in enumerate(olist):
            doc.AddUndo(c4d.UNDOTYPE_CHANGE,o[1])
            o[1].Remove()
            doc.InsertObject(o[1],None,None)
    
        c4d.EventAdd()
        doc.EndUndo()
    
    if __name__=='__main__':
        main()
    Merci encore à Floc pour le coup de main
    Dernière modification par Helium ; 01/11/2018 à 17h02.

  8. #8
    Pilier Avatar de xs_yann
    Date d'inscription
    février 2005
    C4D version
    R19 Studio
    OS
    Mac OS X 10.13
    Messages
    1 989
    Salut,

    J'arrive un peu tard mais voilà comment faire un code un peu plus propre pour ceux que ça intéresse :

    Code PHP:
    import c4d

    def sort_objects
    (docsort_keyasc=True):
        
    doc.StartUndo()
        
        
    # Get objects
        
    objects doc.GetActiveObjects(c4d.GETACTIVEOBJECTFLAGS_0)
        if 
    not objects:
            
    objects doc.GetObjects()
        
        
    # Sort objects
        
    objects.sort(key=sort_keyreverse=asc)
        
        
    # Remove and re-insert objects
        
    for obj in objects:
            
    doc.AddUndo(c4d.UNDO_OBJECT_DELobj)
            
    obj.Remove()
            
    doc.InsertObject(obj)
            
    doc.AddUndo(c4d.UNDO_OBJECT_NEWobj)
            
        
    doc.EndUndo()

    def main():
        
    # Sort by name
        
    sort_objects(docc4d.BaseObject.GetName)

        
    c4d.EventAdd()

    if 
    __name__=='__main__':
        
    main() 
    Ce code classe par ordre alphabétique les objets sélectionnés (ou tous si rien n'est sélectionné).
    L'avantage c'est que pour ajouter des nouvelles méthodes de tri, y'a pas besoin de modifier ce qui a déjà été écrit mais simplement de créer une fonction qui retourne une valeur pertinente suivant ce que l'on veut faire :

    Code PHP:
    import c4d

    def sort_objects
    (docsort_keyasc=True):
    [...]

    def get_bounding_box(obj):
        
    bb obj.GetRad()
        
    scale obj.GetAbsScale()
        return 
    int(bb.bb.bb.scale.scale.scale.z)

    def main():
        
    sort_objects(docget_bounding_box)
        
    c4d.EventAdd() 
    Le code complet :

    Code PHP:
    import c4d

    def sort_objects
    (docsort_keyasc=True):
        
    doc.StartUndo()
        
        
    # Get objects
        
    objects doc.GetActiveObjects(c4d.GETACTIVEOBJECTFLAGS_0)
        if 
    not objects:
            
    objects doc.GetObjects()
        
        
    # Sort objects
        
    objects.sort(key=sort_keyreverse=asc)
        
        
    # Remove and re-insert objects
        
    for obj in objects:
            
    doc.AddUndo(c4d.UNDO_OBJECT_DELobj)
            
    obj.Remove()
            
    doc.InsertObject(obj)
            
    doc.AddUndo(c4d.UNDO_OBJECT_NEWobj)
            
        
    doc.EndUndo()

    def get_active_camera(doc):
        
    bd doc.GetRenderBaseDraw()
        
    cp bd.GetSceneCamera(doc)
        return 
    bd.GetEditorCamera() if cp is None else cp

    def get_distance_from_cam
    (objcam):
        
    pos1 obj.GetMg().off
        pos2 
    cam.GetMg().off
        
    return (pos2 pos1).GetLength()

    def get_bounding_box(obj):
        
    bb obj.GetRad()
        
    scale obj.GetAbsScale()
        return 
    int(bb.bb.bb.scale.scale.scale.z)

    def main():
        
    # Sort by name
        
    sort_objects(docc4d.BaseObject.GetName)
        
    # Sort by bounding box
        
    sort_objects(docget_bounding_box)
        
    # Sort by distance from camera
        
    camera get_active_camera(doc)
        
    sort_objects(doclambda objget_distance_from_cam(objcamera))
       
        
    c4d.EventAdd()

    if 
    __name__=='__main__':
        
    main() 
    L'utilisation d'une fonction lambda est nécessaire pour la distance avec la caméra parce que la fonction de tri doit prendre uniquement un élément du tableau en paramètre. Ça permet aussi de récupérer la caméra avant pour ne pas avoir à le faire pour chaque objet.

  9. #9
    Squatteur Avatar de Helium
    Date d'inscription
    novembre 2009
    C4D version
    R13 Broadcast
    OS
    OS X 10.6
    Messages
    179
    Salut,

    Merci pour ces précisions ! Plus pratique en effet !

Discussions similaires

  1. [Problème] help Clothilde , objets qui traversent d'autres objets
    Par alex88500 dans le forum Nouveaux membres
    Réponses: 5
    Dernier message: 20/10/2015, 00h50
  2. Objets plats, or not
    Par zeclubbeur dans le forum Nouveaux membres
    Réponses: 10
    Dernier message: 08/08/2009, 14h14
  3. • Objets par-ci par-là
    Par plarot_1 dans le forum Travaux en cours
    Réponses: 15
    Dernier message: 11/08/2007, 17h12
  4. Modification de 2 objets
    Par sinclairzxfr dans le forum Modélisation
    Réponses: 2
    Dernier message: 26/01/2007, 16h57
  5. WIP multi objets
    Par Moa.Toa.Nous dans le forum Travaux en cours
    Réponses: 26
    Dernier message: 10/12/2004, 14h46

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
  •