Creare una connessione tra Revit e Navisworks (con Dynamo)

Ultimo post della serie, per quest’anno: poi ci penseremo. Tra i vari workflow buffi che vi ho proposto in questo periodo, manca solo la connessione a Navisworks e possiamo ottenerla con il package Dynaworks, sviluppato e curato da Adam Sheather. 1. Come funziona? Come Civil Connection di Paolo Serra, il package funziona creando una connessione […]

Ultimo post della serie, per quest’anno: poi ci penseremo. Tra i vari workflow buffi che vi ho proposto in questo periodo, manca solo la connessione a Navisworks e possiamo ottenerla con il package Dynaworks, sviluppato e curato da Adam Sheather.

1. Come funziona?

Come Civil Connection di Paolo Serra, il package funziona creando una connessione diretta con un’istanza di Navisworks. Al contrario di Civil Connection, non richede che l’istanza sia aperta, ma si occupa di aprirla e lo fa con il nodo OpenNavisFile.OpenFile.

Una volta aperto, è possibile interrogare i file in esso contenuti, con NavisNodes.GetFilesInProject.

Possiamo leggere le proprietà dei documenti nel file, ma abbiamo bisogno di GetNavisAttributeFromNodesList…

…e GetPropertyList.

Da un file aperto è poi possibile pescare gli oggetti in esso contenuti, con GetData.GetObjectNames

…e successivamente ne possiamo andare a leggere i valori.

2. Ok, ma come funziona davvero?

Come sempre, per usare Dynamo è necessario aver capito bene come funziona il programma con cui stiamo cercando di interagire. Diamo quindi un’occhiata a quali livelli del Project Tree stiamo interrogando in questa circostanza.

Prendiamo per esempio l’albero di selezione di un modello impiantistico.

Ci troviamo un modello (.rvt) suddiviso per livelli, ciascuno di questi livelli contiene le categorie rilevanti, sotto alle quali troviamo le famiglie, che contengono i tipi, che ne contengono le istanze.

Gli attributi del modello sono quindi le informazioni relative al file…

…gli attributi del livello sono quelli che siamo abituati a considerare in Revit…

…a scendere abbiamo la categoria…

..al cui interno finalmente troviamo la famiglia.

Al di sotto della famiglia, che in questo caso è una famiglia di sistema, troviamo quindi i tipi

…e le istanze.

Dato che sono tutti oggetti, dovremo tenerlo a mente quando proveremo a interrogarli da Revit.

Per quanto riguarda il processo di clash detection, ne ho parlato qui, in un post del 2015 le cui immagini ho trovato più o meno dappertutto, quasi sempre senza credits. Forse qualcuno dovrebbe rileggersi la licenza d’uso di questo blog: il materiale può essere usato anche per scopi commerciali a patto che venga citato l’autore e che il materiale derivante venga condiviso con gli stessi principi. Non mi sembra di chiedere molto.

Hard, Clearance e Workflow: i tre tipi di clash nel BIM
Hard, Clearance e Workflow: i tre tipi di clash nel BIM

Questa immagine è popolarissima, per qualche motivo.


3. Qualche workflow

Vediamo qualche applicazione del nodo, partendo da uno degli elementi più spinosi: l’analisi delle interferenze. Per questo workflow trovate on-line un paio di lezioni veramente ben fatte, tra cui quella di Dieter Vermuellen del 2016. Si tratta di una delle applicazioni che preferisco, mentre trovate tanto altro materiale su una pratica che personalmente considero discutibile, ovvero quella di creare elementi fisici che in Revit evidenzino la presenza di interferenze.

3.1. Aprire il file (ed eventualmente integrarlo)

Il primo passo è scegliere il file nwf con cui si vuole lavorare (possibilmente fatto con lo stesso modello che abbiamo in Revit, altrimenti il risultato sarà davvero buffo). Questo, come abbiamo visto, viene semplicemente fatto con File Path e OpenNavisFile.OpenFile. Suggerisco di mettere la booleana a False, a meno che non si voglia avere aperto il file nwf in faccia ogni volta che si lancia lo script. Fidatevi, non lo si vuole. Laddove invece proprio si voglia che il file rimanga aperto, possiamo mettere la booleana a True oppure usare il nodo OpenNavisFile.StayOpenFile.

Se per qualche motivo non lo si vuole fare direttamente da Navisworks, si può anche usare il package per aggiungere un nuovo file al bundle (ovvero “appendere” un nuovo file, con OpenNavisFile.AppendFile).

Come vedremo alla fine, sarà anche possibile pubblicare un nwd. Bisogna “solo” specificare giusto un paio di parametri.

3.2. Selezionare gli elementi

Le clash non vengono fatte selvaggiamente tutti contro tutti (o, per lo meno, non dovrebbero essere fatte in questo modo). Quello che spesso capita è che si procede sulla base di una matrice. Qui trovate un tutorial di Paul Kawuma su come creare un xml direttamente utilizzabile in Navisworks, a partire dalla matrice, con “un poco” di Python.

L’esempio di matrice nell’articolo di Paul Kawuma.

Con una matrice strutturata in questo modo, indipendentemente dalla creazione automatica del file xml, possiamo usare un pochino di Bumblebee (vedere qui, se vi siete persi quando ne ho parlato) per pescare la riga in cui vengono elencate le categorie rilevanti.

La lista delle categorie ci serve per pescare dal modello di Revit tutti gli elementi che potrebbero essere oggetto di interferenza. Naturalmente tutto questo funziona solamente se nella matrice sono inserite le categorie di Revit esattamente come Revit le nomina: se qualcuno si è fatto venire idee creative, avremo una ben gialla sorpresa.

Degli elementi, ci servirà la geometria. Tanto vale iniziare a prendercela.

3.3. Lanciare i Clash Test

Dal documento aperto, si possono lanciare i test precedentemente preparati: il nodo ClashDetection.GetClashTests restituisce i nomi dei test…

…che ci servono per estrarre tutte le informazioni che ci possono servire, primo fra tutti il risultato della clash che appare in questo modo.

Gli status sono gli stessi che ritroviamo nel pannello Clash Detective di Navisworks:

  • Nuovo;
  • Attivo;
  • Revisionato;
  • Approvato;
  • Risolto.
Questo è ciò che appare come risultato del clash test…
…e questi sono i risultati dei singoli clash test.

Il primo passo è quindi cercare di non occuparsi delle clash che hanno uno status a scelta tra approvato e risolto: potremmo voler gestire solo quelle con status nuovo, ad esempio, oppure quelle con status nuovo e attivo, o magari non ci aspettiamo di avere delle novità ma vogliamo rivedere cosa è stato fatto quando è stato detto che una clash è stata revisionata (magari perché abbiamo il sospetto che il nostro BIM coordinator dica cazzate).

Il risultato si ottiene facilmente verificando l’uguaglianza dello status a una specifica condizione: si può verificare l’uguaglianza esatta oppure possiamo usare il nodo String.Contains, il risultato non cambia.

In entrambi i casi, avremo una lista di risposte alla domanda “sei risolto?” e una lista di risposte alla domanda “sei approvato?”. Dobbiamo semplicemente contare, usando il nodo List.CountTrue, per quali di quei valori esiste almeno un vero, ed eliminarli dalla lista.

Come al solito è una booleana sulla booleana sulla booleana.

Ci interessano quindi solo le clash che non hanno status risolto o approvato (ad esempio) e lavoriamo su quelle.

3.4. Dare un nome alle Clash

Il primo passo è dare alle clash un nome che abbia un senso, in modo da poterci lavorare in Revit sapendo più o meno di che cosa si sta parlando. Lo si fa tranquillamente con il nodo NavisData.GetObjectValues, che useremo moltissimo, cui possiamo aggiungere un suffisso che ad esempio diventa un numero progressivo. In questo modo ci troveremo l’elenco delle clash nominate come “activeclash1, activeclash2, activeclash3” o qualcosa del genere.

Si possono nominare tutte le clash e poi filtrarle con la stessa maschera usata in precedenza (consigliato) oppure si può nominare solo le clash che abbiamo già intenzione di analizzare.

3.5. Identificare gli elementi

Una volta che abbiamo la clash in sé, ci occorre ricavare gli ID degli elementi che fanno interferenza, il che significa ovviamente pescare gli ID degli elementi nella selezione A e nella selezione B (ci vogliono due elementi per fare clash, un elemento da solo non fa clash a meno che non soffra di gravi disturbi).

Con il nodo ClashDetection.GetClashNodes possiamo recuperare l’elenco dei nodi e il valore booleano che daremo a FirstClashItem determinerà se stiamo prendendo la selezione A (vero) o la selezione B (falso).

Se andiamo a sbirciare nelle API, il modo per pescare le informazioni sul nodo richiede di invocare la classe “LcRevitComposite”: dandolo come input a Class Name dentro a NavisNodes.NodeByClassNameList, otteniamo una lista di attributi del nodo… o per lo meno, lo otteniamo una volta aggiunto un ulteriore nodo che ribadisce che sì, grazie, vorrei vedere i dannati attributi. Questo ulteriore nodo è NavisAttributes.GetNavisAttributesFromNodesList.

La lista di attributi equivale un po’ al nostro elemento all’interno di revit: possiamo interrogarla per pescarne il valore. Il nodo che ci occorre in questo caso è NavisProperties.GetValuesAsStringClassUserName e ha bisogno di:

  • sapere qual è il file di Navisworks che stiamo interrogando (sempre lui, in OpenNavisFile);
  • la lista di attributi che abbiamo appena faticosamente ricavato, dentro a NavisAttributesList;
  • la classe in cui guardare (che possiamo immaginare come il tab di parametri all’interno di Navisworks), nel nostro caso “Element ID”;
  • il nome dell’attributo di cui vogliamo conoscere il valore, dentro a PropertyName, ovvero nel nostro caso “Value”.

L’operazione, ripetuta per la selezione A e per la selezione B, ci restituisce due valori che possono essere combinati insieme: posiamo quindi trovarci con un indicatore unico della clash, che contiene per esempio l’ID dell’elemento A e l’ID dell’elemento B.

Non è l’unico uso che faremo dell’ID, ma ci servirà.

3.6. Andare a pesca

La prima cosa che possiamo fare, una volta che abbiamo gli ID (o meglio la seconda, visto che la prima è stata rinominarli) è pescare gli elementi sulla base del loro ID. Questo naturalmente a patto che noi si abbia anche i rile RVT Si consiglia di restringere il campo sulla base degli elementi previsti nella matrice, per non impegnare troppa potenza di calcolo. La cosa si può fare collegandosi direttamente alla matrice oppure semplicemente pescando tutte le istanze delle categorie rilevanti all’interno del modello aperto.

Delle categorie dobbiamo pescare gli elementi (AllElementsOfCategory) e di quegli elementi bisogna pescare l’Id. E’ un lavoro per il nodo Element.Id.

Una volta trovati gli Id degli elementi, è un gioco confrontare la presenza di quegli Id nella lista di Id che abbiamo trovato per la selezione A e per la selezione B: possiamo quindi estrarre solo gli elementi coinvolti in una clash, se lo vogliamo.

3.7. Creare viste

Una volta in possesso degli elementi, è relativamente semplice impostare ad esempio un parametro che ci segnali se l’elemento è soggetto a interferenza o meno: abbiamo gli indici, quindi si possono usare i nodi List.GetItemAtIndex e il suo gemello malvagio List.RemoveItemAtIndex per isolare gli elementi che ci interessano e a quel punto è solo una questione di impostare il parametro con il valore corretto.

Più interessante è invece la possibilità di creare delle specifiche viste per ogni clash (e purtroppo mi è successo). Esistono diversi nodi che consentono di creare viste (sarebbe argomento per una lezione a sé), ma probabilmente il più adatto è Element.Create 3D Cropped view, un nodo di Steam che consente di creare una vista tridimensionale. Non badate al fatto che nel mio esempio sia rosso.

Un modo alternativo per creare le viste è lavorare, anziché intorno agli elementi che potrebbero essere molto estesi e non consentire una visualizzazione di immediata lettura, intorno ai punti delle clash. Il nodo da invocare in questo caso è ClashDetection.GetClashPoint.


Dynaworks: qualche esempio di quello che si può fare.

Questo conclude i miei articoli tecnici, per quest’anno: d’ora in avanti, solo illustratori inglesi, cartoni animati e fiabe norvegesi, almeno fino al 2021.

Good night, and good luck.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.