Undo Script Python

Forum per: Modellazione, Texturing, Animazione, Composting e tutto quello che riguarda il normale utilizzo di Cinema4D.

Moderators: Arkimed, natas, visualtricks, cappellaiomatto

Post Reply
  • Advertising
IoAro
Posts: 51
Joined: Fri Jul 30, 2010 1:06 pm

Undo Script Python

Post by IoAro »

Buon pomeriggio a tutte/i,
facendo seguito ad una mia richiesta postata ieri, aggiungo un'altra domanda per un eventuale buon samaritano che potesse/volesse aiutarmi in questa improbabile impresa di scripting in cui mi sono imbarcato. Improbabile perché, ovviamente, non conosco praticamente nulla di Python ma pretendo di fare cose.
Un tipico italiano medio, insomma.
La mia finalità è avere uno script che generi un'estrusione con alcune specifiche. Innanzitutto di generare una semplice estrusione sul punto zero se non c'è nessuna spline selezionata e fin qui, nulla di impossibile.
La parte difficile è la successiva: se sono selezionate una o più spline vorrei generare un'estrusione per ogni singola spline, posizionarla in corrispondenza del centro della spline di riferimento e rinominarla secondo il nome della spline.
E anche qui, contro ogni pronostico, utilizzando pezzi di script da destra e da sinistra trovati nel web sono riuscito a realizzare questa azione ma mi manca un solo punto da risolvere: far sì che tornando indietro di un passaggio mi possa ritrovare alla situazione iniziale (con solo le spline, insomma). Con lo script che ho "compilato" devo tornare indietro di cinque passaggi per ritrovare la situazione originale e non riesco a capire come bypassare i quattro ctrl+z di troppo.
O meglio... so benissimo perché ci sono, ma non so come liberarmene.
Come si può notare dallo script c'è un punto in cui per risolvere alcuni passaggi sono ricorso ad accrocchi che hanno incasinato la situazione:

Code: Select all

import c4d
from c4d import gui

def main():

    obj = doc.GetActiveObjects(0)

    # Generare Estrusione Senza Spline Selezionate

    if not obj:
        extrude = c4d.BaseObject(c4d.Oextrude) 
        doc.InsertObject(extrude)
        extrude[c4d.EXTRUDEOBJECT_HIERARCHIC] = True
        extrude[c4d.EXTRUDEOBJECT_MOVE] = c4d.Vector(0,0,0)
        c4d.EventAdd()
        return

    # Generare Estrusione Con Spline Selezionate

    if obj:

        doc.StartUndo()
        extrudem = obj[0].GetMg()
        extrude = c4d.BaseObject(c4d.Oextrude)
        extrude.SetName('{0}'.format(obj[0].GetName()))
        extrude[c4d.EXTRUDEOBJECT_HIERARCHIC] = True
        extrude[c4d.EXTRUDEOBJECT_MOVE] = c4d.Vector(0,0,0)
        doc.InsertObject(extrude)
        extrude.InsertBefore(obj[0])
        doc.AddUndo(c4d.UNDOTYPE_NEW, extrude)
        extrude.SetBit(c4d.BIT_ACTIVE)
        extrude.SetMg(extrudem)
        
    for ob in obj:
        m = ob.GetMg()
        doc.AddUndo(c4d.UNDOTYPE_CHANGE, ob)
        ob.InsertUnderLast(extrude)
        ob.DelBit(c4d.BIT_ACTIVE)
        ob.SetMg(m)

    c4d.CallCommand(12236)    # Rendi modificabile

    c4d.CallCommand(100004773)    # Espandi Gruppo Oggetti

    ActiveObject = doc.GetActiveObject()    # Selezionare Oggetto Successivo
    NextObject = ActiveObject.GetNext()
    ActiveObject.DelBit(c4d.BIT_ACTIVE)
    NextObject.SetBit(c4d.BIT_ACTIVE)

    c4d.CallCommand(100004773)    # Espandi Gruppo Oggetti

    ActiveObject = doc.GetActiveObject()    # Selezionare Oggetto Precedente
    PrevObject = ActiveObject.GetPred()
    PrevObject.SetBit(c4d.BIT_ACTIVE)

    c4d.CallCommand(100004787)    # Cancella


    doc.EndUndo()
    c4d.EventAdd()

if __name__=='__main__':
    main()
Infatti fino a "ob.SetMg(m)" tutto bene, ma poi ho dovuto arrangiarmi con dei CallCommand e altre robe per completare l'operazione: se si elimina il codice da "Rendi modificabile" in poi, l'Undo funziona correttamente.
Tutte le operazioni seguenti sono per trasformare l'estrusione in tot estrusioni singole, poi "scorporare" uno degli oggetti nulli generati, selezionare il nullo successivo, scorporare nuovamente le estrusioni, selezionare il nullo precedente ed eliminare entrambi gli oggetti nulli.
Tutta 'sta roba perché non sono riuscito, nella parte precedente dello script, a generare singole estrusioni che prendessero posizione e nome delle spline selezionate.
Infatti la cosa si potrebbe risolvere anche così, mettendo diversamente la parte precedente, ma anche lì non riesco a capire dove e come mettere le mani.

Chi è riuscito ad arrivare a leggere fin qui merita già tutta la mia stima ed il mio apprezzamento, detto questo, riassumendo, vorrei capire se fosse possibile risolvere la questione in uno dei seguenti modi:

- Generare singole estrusioni con posizione e nome presi dalle spline selezionate (probabilmente la soluzione più pulita e giusta)

oppure

- Lavorare su questo script aggiungendo correttamente l'Undo che permetta di tornare daccapo in un unico passaggio.

Come sempre grazie e buon fine settimana a tutte/i!

P.s. Per chi volesse, ecco direttamente lo script:

https://drive.google.com/file/d/1sb9smC ... sp=sharing
User avatar
Caleidos4D
Posts: 72
Joined: Tue Sep 27, 2011 4:48 pm

Re: Undo Script Python

Post by Caleidos4D »

Ciao IoAro, ho dato una ripulita veloce al tuo script.
Adesso dovrebbe fare quello che avevi in mente, undo/redo compresi:

Se non hai selezionato nulla, ti crea l'oggetto estrusione,
Se hai oggetti selezionati, per ogni oggetto ti crea il genitore estrusione con lo stesso nome dell'oggetto figlio. Inoltre, il genitore avrà la stessa posizione del figlio, sia nella scena che sull'object manager.

EDIT: Ho eliminato il file, usa quello del mio post successivo
Last edited by Caleidos4D on Sat Jun 01, 2019 9:26 pm, edited 1 time in total.
User avatar
Caleidos4D
Posts: 72
Joined: Tue Sep 27, 2011 4:48 pm

Re: Undo Script Python

Post by Caleidos4D »

Usa questo al posto di quello di prima:
Estrusione.rar
(572 Bytes) Downloaded 132 times
c'erano 2 righe di codice ridondante
IoAro
Posts: 51
Joined: Fri Jul 30, 2010 1:06 pm

Re: Undo Script Python

Post by IoAro »

Caleidos che dire...
Grazie! ;)

Semplice e pulito, esattamente come immaginavo e come avrei voluto saper fare!
Tanto più che continuando a cercare informazioni in merito, ho trovato un paio di post in cui si dice che il CallCommand non può essere gestito con un Undo personalizzato dato che genera degli Undo "automatici" derivati dal fatto che si va a richiamare proprio un comando di Cinema e quindi non possono essere bypassati.
Non so se sia realmente così, ma poco importa e soprattutto molto meglio così che con quel guazzabuglio medievale (cit.) che avevo impostato io!

Grazie ancora del supporto Caleidos, ancora una volta preciso e decisivo!
  • Advertising
Post Reply