Esplosione blocchi annidati ricorsiva (python)

Hola gente!

Ho un problema da risolvere.

avrei bisogno di creare uno script che mi esplode i blocchi “annidati” lasciandomi intatti i blocchi “principali”

Esempio:

Ho un blocco: (“blocco main 001”)
Annidati dentro “blocco main 001” ci sono altri due blocchi: (“blocco nested 001”, “blocco nested 002”)
A sua volta “blocco nested 002” ha un blocco annidato ( “blocco nested nested 001”)

io vorrei che lo script mi restituisse un solo “blocco main 001” e che nel file non ci siano blocchi annidati.

possibile ? impossibile?

credo che @emilio possa avere una soluzione, ricordo qualcosa di suo ma non ritrovo il post.

Vi lascio uno stupido file di test
block explode example.3dm (68,1 KB)

Non so se ho capito bene: lo script dovrebbe esplodere tutti i blocchi e sottoblocchi per poi ricreare un blocco unico?

mi deve esplodere solo i sotto blocchi, il blocco principale deve avere dentro i sotto blocchi esplosi…

Ok, ma il blocco principale ha delle informazioni che potresti perdere durante l’estrazione o ti basta che il blocco abbia stesso nome e punto di inserimento?
Giusto per capire a che livello deve operare lo script.

nel file che ti metto qui sotto trovi:
una versione del blocco iniziale che si chiama bl_main_001
una versione del blocco come vorrei che diventasse che si chiama bl_main_001_as I want it

block explode example (1).3dm (76,5 KB)

Se lo dici tu, sara’ cosi’ … :slight_smile:
Io ormai la memoria devo averla portata al banco dei pegni … :wink:

Adesso purtroppo non riesco a fare una ricerca … forse nel weekend, ma non so quale … :blush:
Comunque se mi capita sott’occhio qualcosa di simile, mi faccio vivo.

@lucio_zadra

Lucio, credo che tu abbia le idee piu’ chiare a riguardo.
Io con i blocchi mi confondo sempre …
Come si fa a ‘editare’ una definizione di blocco ?
Cioe’ affinche’ le modifiche alla definizione siano applicate a tutte le istanze di un blocco ?

La logica dei blocchi di Rhino la trovo ostica … se mi concentro su un problema forse sul momento capisco qualcosa, ma poi dimentico in fretta. :roll_eyes:

Tra l’altro qui mi sembra che il nome del blocco non importi … ma anche quello e’ un aspetto interessante. Cioe’ se mantenere il nome originale o meno … e come.

Grazie, ciao.

Ciao Emi, avevo cominciato a fare lo script ma poi, per urgenze di lavoro, ho dovuto accantonarlo (anche quello che calcola gli ingombri della rotazione di una polisuperficie l’ho dovuto mettere in pausa).
Tecnicamente, il nome e il punto d’inserimento del blocco te lo estrapoli facilmente dalla block instance selezionata, successivamente devi esplodere il blocco e verificare se l’array contiene oggetti o altre block instance (avevo pensato di utilizzare due array, uno per mettere gli oggetti e l’altro i blocchi da esplodere nuovamente in un ciclo ricorsivo - verifico l’id degli oggetti, se blocco metto in arrayblocchi altrimenti in arrayoggetti loop su ciclo do while arrayblocchi contiene qualcosa).
Alla fine ricreo il blocco con gli oggetti estrapolati dando lo stesso nome e punto di inserimento del blocco iniziale… ovviamente tutto questo con vbscript… magari python ha qualche funzione più potente…

Grazie Lucio !

Si’, infatti quello che sto cercando di capire e’ cosa si puo’ fare (e come) con vbscript/rhinoscriptsyntax.

Se ho ben capito (e questo e’ un “SE” enorme … :smile:), si parla di operare a livello di definizione di blocco.
Cioe’ fare in modo che tutte le istanze di un certo blocco cambino, ma restino istanze di uno stesso blocco.

Lavorare su una singola istanza ovviamente non dovrebbe dare nessun problema, ma non sono sicuro che con vbs/rs sia possibile lavorare a livello di definizione, senza perdere i collegamenti istanza<->definizione.

:confused:

Magari intanto provo con RhinoCommon, li’ definizioni e istanze sono ben separate e trovo piu’ facile ragionarci …

… Scusa la confusione …

Questo e’ un altro problema che mi sembra molto interessante … vorrei avere tempo di gabolarci sopra. :slight_smile:
Ma non ho capito se Kangaroo lo risolve, se e’ cosi’ e’ inutile pensarci ancora …

Grazie, ciao !

Hola @emilio e @lucio_zadra !!

parto da questo script, molto preliminare lo so, che non ci ho lavorato tanto perché ho avuto altro da fare a lavoro:

import rhinoscriptsyntax as rs

for block_name in rs.BlockNames():
    instances = rs.BlockInstances(block_name, 0)
    if len(instances) and rs.IsBlockInstance(instances[0]):
        instance = instances[0]
        point = rs.BlockInstanceInsertPoint(instance)
        objs = rs.ExplodeBlockInstance(instance, True)
        block = rs.AddBlock(objs, "0,0,0", block_name, True)
        rs.InsertBlock(block,point)

Finché lavori su un blocco solo ok, più o meno fa quello che voglio ma ovviamente quando parliamo di svariate istanze di blocco ognuna con sue xform transformations, non serve a nulla.

ma diciamo che il concetto base è corretto, mi esplode il blocchi dentro l’istanza principale e poi la crea nel punto originale.

Ciao Andrea

Beh, dipende … :wink:
Non riusciamo a mantenere il collegamento tra istanze e definizione.

… Sto provando a capirci qualcosa in RhinoCommon ma ho le idee parecchio confuse …
Intanto vorrei capire che fine fanno gli oggetti usati nella definizione di blocco.
:confused:
… Continuo a indagare … :wink:

Dall’help di rhinoscript, quando definisci un blocco con lo stesso nome di uno esistente, la definizione viene applicata a tutte le istanze (praticamente corrisponde ad un block edit).

Non mi interessa mantenere informazioni dei blocchi annidati, voglio mantenere intatte quelle dei blocchi principali.
Il problema è che ciò che voglio è probabilmente impossibile , e me ne rendo conto (colme al solito) ora che cerco di spiegartelo!!
:smiley:

Ah, ecco !
Grazie, questo passaggio mi mancava …
Adesso capisco la procedura che avevi scritto sopra. :grinning:

Thanks again !

1 Mi Piace

Altrimenti, a fine script, devi richiamare il comando replaceblock di rhino che ti sostituisce tutti i blocchi vecchi con quelli nuovi…

Dunque, ragazzi … puf puf … :wink:

Dopo parecchio ravanare, grazie alle spiegazioni di Lucio, forse abbiamo lo script che serve.

A me sembra piu’ utile (anche per eventuale uso personale) poter scegliere quali blocchi semplificare.
Quindi lo script consente di selezionare dei blocchi.
Se non si seleziona niente, lui semplifica tutti i blocchi, come richiesto da Andrea.
… Almeno dovrebbe …

import rhinoscriptsyntax as rs
# import scriptcontext
# import Rhino

def flatten( gid ):
  nam = rs.BlockInstanceName( gid )
  bobs = rs.BlockObjects( nam )
  nes = False
  for bob in bobs:
    if rs.IsBlockInstance( bob ):
      nes = True
      break
  if not nes:
    return False
  xfo = rs.BlockInstanceXform( gid )
  gids = rs.ExplodeBlockInstance( gid, True )
  xfi = rs.XformInverse( xfo )
  rs.TransformObjects( gids, xfi )
  rs.AddBlock( gids, [ 0.0, 0.0, 0.0 ], nam, True )
  rs.InsertBlock2( nam, xfo )
  return True

def main():
  blos = rs.GetObjects( 'Blocks to flatten [Enter => any block] ?', 
      filter = 4096, preselect = True )
  rs.UnselectAllObjects()
  if blos:
    nams = set( [] )
    for blo in blos:
      nam = rs.BlockInstanceName( blo )
      nams.add( nam )
  else:
    nams = rs.BlockNames()
  fnams = []
  rs.EnableRedraw( False )
  for nam in nams:
    gids = rs.BlockInstances( nam )
    if gids:
      if flatten( gids[ 0 ] ):
        fnams.append( nam )
  rs.EnableRedraw( True )
  wrd = 'definition' if len( fnams ) < 2 else 'definitions'
  txt = '%d %s flattened: ' % ( len( fnams ), wrd )
  for fnam in fnams:
    txt += ' %s,' % fnam
  print( txt[ : -1 ] )

main()

Non so se ho capito bene come funziona … pero’ sembra che funzioni … :confused:
Vedete voi … :wink:

3 Mi Piace

Sembra perfetto!
Grandissimo @emilio!! e anche @lucio_zadra per il contributo :slight_smile:

Adesso me lo studio perché ci sono diversi aspetti nuovi per me :smiley:
Ho iniziato a studiare seriamente la materia (scripting python etc) per necessità, davvero da poco, perciò ho molto da imparare…

Fondamentale !
Senza sarei ancora li’ che vago tra la documentazione McNeel … :smile:

Pero’ per riuscirci ho dovuto esplodere i blocchi nello script.
Ho provato anche senza esplodere, come dicevi tu, usando qualcosa di ricorsivo …
ma non ho cavato un ragno dal buco. :confused:

Quindi per ora mi accontento.

Bene !
Chissa’ che tra tutti quanti prima o poi convinciamo anche il grande Lucio ad usare Python ? :grinning:

Lui non trova il tempo per impararlo, OK, ma uno come lui, anche poco per volta, non avrebbe certo delle difficolta’.
Vero che Lucio riesce a fare quello che vuole col VBScript, ma con Python avrebbe molte piu’ possibilita’ … e anche una sintassi piu’ semplice …

… E adesso Lucio mi manda a … stendere, diciamo … :smile:

1 Mi Piace

Lucio, Emilio non si arrende mai e. . . .
:smile: :smile:

1 Mi Piace

Eh, Salvio …
Quando uno nasce zuccone … :roll_eyes: :smile:

1 Mi Piace