Sei sulla pagina 1di 165

Introduzione

Benvenuto nel meraviglioso mondo GrassHopper (ndt GH_Cavalletta, quell'insetto verde con le ali che saltella nell'erba e ne mangia in quantit). Questa la seconda edizione di un breve manuale, che non sarebbe potuto nascere senza il fondamentale contributo di Rajaa Issa. Rajaa un tecnico SW alla Robert McNeel and Associates, oltre che autrice di parecchi altri plug-in di Rhino, tra cui ArchCut ed il sempre pi diffuso PanelingTools. Questa revisione fornisce una guida molto pi comprensibile rispetto alla prima edizione, con oltre 70 nuove pagine dedicate alla creazione di componenti di scripting personalizzati. L'uscita di questo versione coincide con due eventi; il primo l'uscita della versione 0.6.0007 di aggiornamento di GH, che si appresta ad essere un grosso contributo di miglioramento rispetto alla gi robusta piattaforma GH. Chi gi ha usato la versione precedente, trover sottili, a volte anche sostanziali, differenze nel modo in cui i dati sono gestiti, al punto da rendere alcune definizioni precedenti superate e persino inutilizzabili. Si spera che questo manuale possa aiutare utenti nuovi e vecchi a districarsi nelle molte novit del software (SW). Il secondo evento che coincide con questa pubblicazione la conferenza dal titolo FLUX:Architettura in Ambiente Parametrico, che si tiene al California College of the Arts. Questo evento esplora l'architettura contemporanea ed il design attraverso la loro relazione con i recenti progressi nelle tecnologie CAD, quali la modellazione Parametrica, la fabbricazione additiva digitale e lo scripting. Tra le altre cose, sar presente una mostra e si terranno una serie di workshop dedicati ai sistemi SW Parametrici. Avr l'onore di tenere una conferenza su Introduzione alla modellazione con GrassHopper, mentre Rajaa Issa e Gil Akos gestiranno i workshop Modellazione avanzata con GH e VB.Net Scripting (programmazione con interfaccia VisualBasic). Abbiamo incluso in questa edizione molte nuove spiegazioni e speriamo che essa possa continuare ad essere una fondamentale risorsa per quanti vogliono apprendere l'uso del plug-in. Tuttavia, il suo contenuto di maggior valore sei tu utente, perch pi gente si accosta a ed impara la modellazione Parametrica, pi vantaggi ne trae l'intera comunit di utenti. Per questo incoraggio ciascun lettore di questo manuale ad aderire alla crescente comunit online e a postare domande nel forum, poich c' quasi sempre qualcuno pronto a fornire risposte. Per maggiori dettagli, visita http://www.grasshopper.rhino3d.com Grazie buona fortuna Andrew Payne LIFT architects www.liftarchitects.com Rajaa Issa Robert McNeel and Associates www.rhino3d.com

INDICE
Introduzione Indice 1. 2. 3. 4. 5. 6. Come iniziare Interfaccia Oggetti GrassHopper Gestione dei dati permanenti Eredit dei dati volatili Coordinamento del flusso di dati 1 2 8 11 13 18 21 21 23 25 27 29 32 36 40 43 46 48 53 55 56 61 67 72 74 76 79 84 89 92 93 93 93 95 96 97

7. Tipi di componente Scalare 7.1 Operatori 7.2 Dichiarazioni condizionali 7.2 Confronto tra Range-Series-Interval 7.3 Funzioni ed operazioni Booleane 7.4 Dati numerici e Funzioni 7.5 Curve trigonometriche 8. Il giardino dei sentieri che si dividono 8.1 Liste e Gestione dati 8.2 Intrecciare i dati 8.3 Spostare i dati 8.4 Esportare i dati in Excel 9. Nozioni di base sui Vettori 9.1 Manipolazione di Punti e Vettori 9.2 Uso della matematica dei Vettori/Scalari con Punti attrattori (scalatura di cerchi) 9.3 Uso della matematica dei Vettori/Scalari con Punti attrattori (scalatura di rettangoli) 10. Tipi di Curve 10.1 Elementi di Analisi delle Curve 11. Tipi di Superficie 11.1 Interazione con Superfici 11.2 Strumenti di pannellatura (Plug-in PanelingTools) 11.3 Griglie a diamante su Superfici 11.4 Griglie a diamante su Superfici irregolari 12. Introduzione alla programmazione (scripting) 13. Interfaccia di programmazione 13.1 Dove trovare gli strumenti di programmazione 13.2 Parametri in Input 13.3 Parametri in Output 13.4 Informazioni fuori interfaccia e di Debug 13.5 Dentro il componente Script

pag5 14. Visual Basic DotNET 14.1 Introduzione 14.2 Commenti 14.3 Variabili 14.4 Array e Liste 14.5 Operatori 14.6 Dichiarazioni condizionali 14.7 Iterazioni (Loops) 14.8 Iterazioni annidate 14.9 Subroutine e Funzioni 14.10 Ricorsione (ripetizione) 14.11 Processamento delle Liste in GrassHopper 14.12 Processamento dell'Albero di costruzione in GrassHopper 14.13 File di Input/Output 15. Rhino.NET SDK 15.1 15.2 Capire le NURBS (NonUniformRationalBSplines) 15.3 Gerarchia degli oggetti OpenNURBS 15.4 Struttura della Classe 15.5 Confronto tra istanze Costanti e Non-costantI 15.6 Punti e Vettori 15.7 Curva OnNURBS (su superficie) 15.8 Classi di Curve non derivate da OnCurve 15.9 Superficie OnNURBS 15.10 Classi di Superfici non derivate da OnSurface 15.11 OnBRep (Boundary Representation=oggetto descritto dai limiti geometrici) 15.12 Trasformazione di Geometria 15.13 Funzioni di utilit globale 16. Aiuto

100 100 100 100 101 103 104 104 106 107 110 113 114 116 118 118 118 121 123 124 124 126 130 132 137 138 147 148 155

1 Come iniziare
Installazione di GrassHopper Per scaricare il plug-in GH, visita il sito http://www.grasshopper3d.com/. Clicca sul link Download nell'angolo in alto a sinistra e quando invitato nella finestra di dialogo, fornisci il tuo indirizzo e-mail. Poi, clicca sul link di download con il tasto destro e scegli l'opzione Salva Oggetto con nome. Seleziona una cartella sul tuo hard drive dove salvare il file eseguibile (nota:il file non pu esser caricato da una connessione network, perci deve essere presente fisicamente sul PC che lo utilizza).

Seleziona Run dalla finestra di dialogo e segui le istruzioni di installazione (devi avere Rhino 4.0 con SR4b o successiva gi installato ed avere i diritti di amministratore, per OS Vista o Win7).

2 L'Interfaccia*
La finestra di interfaccia principale Una volta caricato il plug-in, scrivi "Grasshopper" sulla riga di comando di Rhino per far apparire la finestra principale del programma:

Questa interfaccia contiene molti elementi, buona parte dei quali familiari all'utente Rhino: A. La barra principale del men Il men del tutto simile a quelli di Windows, con l'eccezione del controllo per la ricerca dei file sull'estremit destra B. Con questo menu a tendina puoi scorrere velocemente tra i file caricati. Attenzione se usi comandi da tastiera (shortcuts), poich sono gestiti dalla finestra attualmente attiva, che pu essere quella principale di Rhino, quella di GrassHopper o qualsiasi altra finestra di dialogo all'interno di Rhino. Dal momento che il comando non pu essere annullato, attento in particolare ai comandi Ctrl-X, Ctrl-S e Del. B. Ricerca dei files Come anticipato, questo men a tendina viene usato per passare tra un file e l'altro di quelli caricati. * provenienza: RhinoWiki
http://en.wiki.mcneel.com/default.aspx/McNeel/ExplicitHistoryPluginInterfaceExplained.html

C. Pannello dei Componenti Questo pannello mostra tutte el categorie di componenti, ognuno dei quali appartiene ad una certa categoria (tipo "Params" per tutti i tipi di dati primitivi, o "Curves" per tutti gli strumenti che hanno a che fare con le curve). Ogni categoria ha il suo specifico pannello. Larghezza e lunghezza delle barre possono essere personalizzate, consentendo di tenere visibili pi o meno pulsanti per categoria. I pannelli di categoria contengono tutti i componenti che appartengono a quella categoria. Poich potenzialmente il loro numero pu essere molto elevato, vengono mostrati solo quelli usati pi di recente, mentre per visualizzare gli altri necessario premere sulla freccia nera nell'angolo in basso a sinistra della barra: Si apre il pannello di categoria, contenente l'intera collezione di componenti. Puoi selezionare il componente desiderato e trascinarlo sul canvas (la parte dove si compone il progetto). La sola selezione del componente lo rende disponibile nel men chiuso, ma per usarlo comunque necessario trascinarlo sul canvas.

Puoi anche trovare i componenti, facendo doppio click sul canvas e scrivendo il nome nella finestra che appare: vedrai una lista di componenti che rispondono al criterio di ricerca (che contengono la parola scritta).

D. Barra del nome Windows Questa barra dell'Editor ha un comportamento diverso dalla solita analoga di MS Windows. Se la finestra non minimizzata o massimizzata, facendo doppio click sulla barra del nome aprir o chiuder il resto dell'interfaccia. E' un buon modo per passare dal plug-in a Rhino, perch minimizza l'interfaccia del plug-in senza muoverla in fondo allo schermo o dietro altre finestre. Nota che se chiudi l'Editor, le geometrie mostrate in preview nei viewport di Rhino spariranno, ma i relativi file non
3

verranno chiusi. Alla prossima istanza del comando _Grasshopper, la finestra torner com'era, con gli stessi file caricati in precedenza. E. La barra degli strumenti Canvas Questa barra consente un accesso rapido ad una serie di funzioni usate di frequente. Tutti questi strumenti sono anche accessibili attraverso i menu a tendina della barra principale, se vuoi nascondere questa barra per massimizzare l'area di lavoro (pu essere riattivata dal menu View).

La barra degli strumenti Canvas riporta i seguenti pulsanti (da sinistra a destra): 1. Editor delle propriet 2. Sketch Tool, Strumento di disegno a mano libera Questo matita funziona come la maggior parte degli analoghi Photoshop o Windows Paint. I controlli di default della matita consentono di definirne dimensione, tipo e colore. Comunque tracciare linee diritte o sagome precise non facile. Per supplire a questa carenza, traccia una sagoma qualsiasi nel Canvas, selezionala con il tasto destro e scegli l'opzione "Load from Rhino", seleziona quindi una sagoma 2D costruita in precedenza in Rhino (es. rettangolo, cerchio, stella, ecc). Una volta selezionata la sagoma di riferimento, premi Enter e nel Canvas apparir la geometria Rhino. 3. Livelli di Zoom 4. Mappa di navigazione: apre una piccola finestra con lo schema complessivo, che ti permette di spostarti a piacere senza doverlo fare direttamente sul Canvas. Questo strumento simile al Navigator di Photoshop. 5. Zoom Extent: resetta il fattore di zoom per includere tutto lo schema 6. Focus Corners: consente di spostare la vista (focus) in corrispondenza di ognuno dei quattro spigoli del canvas (comodo per tornare all'inizio o alla fine dello schema) 7. Salva Viste: consente di salvare e richiamare definizioni di schemi (comodo per esplorare alternative) 8. Abilita/Disabilta Preview della selezione: consente di vedere la preview in Rhino del componente selezionato 9. Abilita/Disabilta la selezione 10. Ricostruisci la definizione: forza la completa ricostruzione dell'History 11. Abilita/disabilita il Solver: consente di vedere l'effetto delle modifiche apportate alla definizione man mano oppure farlo a definizione completa (utile per non perdere tempo in ri-calcolo di geometrie complesse) 12. Bake: letteralmente "cuoci", crea effettivamente in Rhino la geometria selezionata nella definizione (fino ad ora si trattava di un semplice preview)

13. Modalit di visualizzazione della preview (Wireframe, Shaded o nessuna)


NDT: alcuni punti della lista precedente sono diversi dal testo originale, perch aggiornati all'ultima versione GH

F. Canvas Questo lo spazio dove definisci e disegni lo schema dell'History. Il canvas (letteralmente la tela su cui dipinge il pittore) ospitasia gli oggetti che compongono la definizione che alcuni Widgets di interazione con l'utente G. Gli oggetti sul canvas hanno una codifica di colore che ne indica lo stato:

A) Parameter. Un Parametro che contiene avvisi mostrato in arancio. La maggior parte dei Parametri inizialmente appaiono di questo colore, perch non ancora connessi a dati. B) Parameter. Un Parametro che non contiene errori n avvisi (colore nero) C) Component. Un componente sempre un oggetto pi complesso, contenendo Parametri di input e di output. Questo specifico componente ha associato almeno un avviso (colore arancio). Si pu individuare qual' il Parametro che genera avvisi ed errori attraverso il men contestuale degli oggetti (tasto Dx su corpo o input/output dell'oggetto) D) Component. Un componente che non contiene errori n avvisi (colore nero) E) Component. Un componente che contiene almeno un errore (colore rosso). L'errore pu derivare sia dal componente stesso o da uno dei Parametri di input/output. Ne sapremo di pi nei prossimi capitoli sulle Strutture dei componenti. Tutti gli oggetti al momento della selezione vengono mostrati con un sovra-colore verde.

G. UI Widgets Al momento l'unico widget disponibile il Compasso, mostrato nell'angolo inferiore destro del canvas. Il Compasso consente di indirizzare la navigazione nel canvas in modo visivo, indicando la direzione da seguire per raggiungere gli elementi della definizione (i selezionati in rosso). Il widget pu essere disabilitato dal men View. H. La barra di Stato La barra di stato (parte inferiore) fornisce il feedback sugli eventi relativi al plug-in e sulle selezioni. Informazioni chiave sulla presenza o assenza di errori ed avvisi verranno mostrate qui. L'icona quadrata arancio nell'angolo di sinistra un lettore di live RSS del forum GH. Selezionandola si aprir una lista delle discussioni pi recenti trattate nel sito degli utenti GH. Scegliendone una, verrai indirizzato direttamente al sito ed alla pagina relativa. Visita il sito degli utenti GrassHopper al: http://grasshopper3d.com Il pannello di Controllo Remoto Poich la finestra di GH piuttosto voluminosa, potresti non volerla sullo schermo per tutto il tempo. Naturalmente puoi minimizzarla o collassarla sul posto, ma in questi casi non puoi interagire per cambiare i dati. Se desideri un'interfaccia minimalista alla definizione che ti consenta l'accesso ai dati, puoi abilitare il Pannello remoto. Si tratta di una finestra che possibile spostare dove fa comodo, in cui si possono trovare tutti i valori contenuti negli slider e negli attuatori booleani (possibilmente anche altri dati nelle prossime release):

Il Pannello remoto consente anche una preview di base, controllo degli eventi e dello scambio dei file di definizione. Puoi attivare il Pannello remoto dal men View della finestra principale, o attraverso il comando _GrasshopperPanel sulla barra di comandi Rhino.

Preview del risultato in Rhino:

A) Blu geometria in blu della preview che stai selezionando con il mouse (obsoleta) B) Verde geometria appartenente ad un componente GH selezionato (in GH) C) Rosso geometria appartenente ad un componente GH non selezionato D) Punto viene disegnato come una crocetta per distinguerlo dal corrispondente quadratino di Rhino

3 Oggetti Grasshopper*
Oggetti della definizione di Grasshopper Una definizione GH si compone di molti tipi di oggetti, ma per iniziare hai bisogno di impararne un paio: Parametri Componenti

I Parametri contengono dati, nel senso che immagazzinano cose. I componenti contengono azioni, nel senso che svolgono cose. L'immagine seguente mostra alcuni degli oggetti che probabile incontrerai in una definizione GH:

A) Un Parametro che contiene dati. Dal momento che non c' alcuna connessione sul lato sinistro dell'oggetto, significa che esso non eredita i suoi dati da qualcos'altro. I Parametri che non contengono errori o avvisi sono blocchetti sottili di colore nero con dicitura orizzontale. B) Un Parametro che non contiene alcun dato. Qualsiasi oggetto che non contiene dati considerato sospetto in una definizione di History (storia di costruzione) esplicita, poich non se ne vede l'utilit. Per conseguenza, tutti i Parametri (appena aggiunti) sono di colore arancio, ad indicare che non contengono (ancora) dati e non hanno alcun effetto tangibile sul risultato della soluzione dell'History. Nel momento in cui un Parametro eredita o gli viene attribuito un dato, diventa nero. C) Un componente selezionato. Tutti gli oggetti selezionati presentano una sovra-colorazione verde. D) Un componente regolare E) un componente che contiene avvisi(o). Poich probabile che un componente abbia diversi input ed output, ad occhio non si pu vedere quale abbia generato l'avviso. Ce ne possono essere anche pi d'uno. Devi usare il men contestuale (vedi sotto) per individuare le cause. Nota che gli avvisi non devono necessariamente essere risolti. Possono essere perfettamente regolari.

* provenienza: RhinoWiki
http://en.wiki.mcneel.com/default.aspx/McNeel/ExplicitHistoryPluginObjectsExplained.html

pag15(9)
8

F) Un componente che contiene almeno un errore. Come per gli avvisi, non possibile vedere a prima vista qual' l'origine dell'errore.. Dovrai usare il men contestuale (vedi sotto). Nota che un componente contenente sia errori che avvisi sar di colore rosso, perch il colore dell'errore ha prevalenza su quello dell'avviso. G) Una connessione. Le connessioni sono sempre tra un Parametro di output ed uno di input. non esiste alcun limite al numero di connessioni che un Parametro pu avere, ma non possibile creare una definizione con connessioni cicliche/ricorsive. Questo tipo di ricorsione viene individuato e l'intera soluzione cortocircuitata, con l'emissione di un errore nel primo componente o Parametro che viene individuato come appartenente alla ricorsione. Per maggiori informazioni sulle connessioni, vedi il capitolo riguardante l'Eredit dei Dati. Parti di un componente Un componente normalmente richiede dati per svolgere la sua azione, che di solito produce un risultato. Questa la ragione per cui gran parte dei componenti hanno un set di Parametri annidati, a cui ci si riferisce come Parametri di Input e di Output. Gli Input si trovano sul lato sinistro del componente, mentre gli Output sono sul lato destro:

A) I tre Parametri di input del componente Divisione. Di default, i nomi dei Parametri sono abbreviati. Puoi rinominarli come ti fa comodo. B) L'area del componente Divisione (di solito contenente il suo nome) C) I tre Parametri di output del componente Divisione Quando ti fermi con il mouse sopra ciascuna parte di un oggetto componente, vedrai dei tooltips che descrivono il particolare tipo di sub-componente su cui siete. I tooltips sono assai utili perch precisano sia il tipo che il valore di ciascun Parametro:

Uso del Men contestuale a pop-up Tutti gli oggetti sul canvas (area di disegno) hanno il loro men contestuale (Tasto destro), che illustra gran parte delle informazioni su quel particolare oggetto. I Componenti sono un pochino pi insidiosi, perch mostrano a cascata anche tutti i men contestuali dei sub-componenti che contengono. Per esempio, se un componente diventa arancio significa che esso o qualche suo Parametro, ha generato un avviso. Se vuoi scoprirne la fonte, devi usare il men contestuale:

Nell'immagine puoi vedere il men del componente principale, con il men a cascata del Parametro di input "R". La prima riga del men di solito editabile e contiene il nome dell'oggetto in questione. Puoi cambiare il breve nome di default con qualcosa di pi significativo, compatibilmente con lo spazio a disposizione. Il secondo articolo del men (Preview abilita/disabilita) indica se la geometria prodotta/definita da questo componente sar visibile nel viewport di Rhino. Disabilitando la preview di oggetti che non contengono informazioni essenziali, possibile sia accelerare il refresh in Rhino che il calcolo della soluzione in GH (specialmente nel caso sia coinvolta un'operazione di meshatura). Se la preview di un Parametro o di un componente disabilitata, esso sar disegnato con una sfumatura grigiastra. Non tutti i Parametri/componenti possono venir rappresentati nel viewport di Rhino (ad esempio i numeri) ed in questo caso l'articolo di men relativo alla Preview non c'. Il men contestuale per il Parametro di input "R" contiene un'icona arancio di avviso, che a sua volta contiene una lista (in questo caso solo uno) di avvisi generati da questo Parametro.

10

4 Gestione dei dati permanenti*


Tipi di Dati I Parametri vengono usati solo per immagazzinare informazione, ma la maggio parte di essi ne pu contenere di due tipi: Permanenti e Temporanei. I dati temporanei sono derivati da uno o piParametri sorgente e vengono distrutti (es.: ri-campionati) ogni volta che inizia una nuova soluzione. I dati permanenti sono invece quelli specificamente impostati dall'utente. Ogni volta che un Parametro viene connesso ad un oggetto sorgente, il dato permanente viene ignorato , ma non distrutto. Un'eccezione a questa definizione rappresentata da Parametri di output che non possono n contenere valori permanenti n definire un insieme di sorgenti. Questi Parametri di output sono completamente controllati dal componente cui appartengono. I dati permanenti sono accessibili attraverso il men contestuale, e in relazione alla natura del Parametro hanno gestione differente.. I Parametri Vettore ad esempio ti consentono di specificare sia un singolo che pi vettori all'interno del men. Torniamo indietro un attimo e vediamo come un Parametro Vettore di default si comporta. Una volta che l'hai trascinato sul canvas dal pannello Parameter, vedrai l'immagine seguente:

Il Parametro arancio, a significare che contiene un avviso. Niente di preoccupante, l'avviso serve solo ad avvertirti che il Parametro vuoto (non contiene dati permanenti, n eredita dati temporanei) e pertanto non ha alcun effetto sulla soluzione dell'History. Il men contestuale del Parametro presenta due modalit di introdurre dati permanenti: singolo o multiplo:

* provenienza: RhinoWiki
http://en.wiki.mcneel.com/default.aspx/McNeel/ExplicitHistoryPersistentDataRecordManagement.html

11

Una volta selezionata un'opzione, la finestra GH si chiude e ti viene chiesto di selezionare un vettore in uno dei viewport di Rhino:

Quando hai finito di scegliere tutti i vettori che ti servono, premi Enter ed essi diverranno parte del Record dei dati permanenti del Parametro. Ci significa che esso non pi vuoto e pertanto passa da arancio a nero:

A questo punto puoi usare il Parametro per "inseminare" tutti gli oggetti che desideri con vettori identici.

pag19(13)
12

5 Eredit di dati temporanei*


Come si ereditano i dati I dati sono immagazzinati nei Parametri (sia in forma temporanea che permanente) ed usati nei componenti. Quando i dati non sono immagazzinati nella raccolta permanente dei dati sei Parametri, essi devono essere derivati da qualche altra fonte. Ciascun Parametro (eccetto quelli di output) indica da dove prende i dati e la maggior parte dei Parametri non hanno niente si strano. Puoi connettere un Parametro Double (che significa semplicemente che si tratta di un numero decimale) ad una fonte Integer (solo numeri interi) e sar il Parametro ad occuparsi della conversione. Il plug-in definisce molti schemi di conversione, ma se non esiste una procedura codificata di trasformazione, il Parametro ricevente genera un errore. Per esempio, se fornisci una Superficie quando richiesto un Punto, il Parametro punto genera un messaggio d'errore (accessibile attraverso il men contestuale del Parametro stesso) e diventa rossa. Se il Parametro appartiene ad un componente, questa situazione anomala si propaga su per la scala gerarchica, colorando di rosso l'intero componente, anche se non contiene errori di per s. Gestione delle connessioni Poich i Parametri gestiscono i propri dati d'origine, puoi accedervi attraverso il Parametro in oggetto. Ipotizziamo di aver preparato una piccola definizione contenente tre Componenti e due Parametri:

A questo punto, nessun oggetto connesso e dobbiamo iniziare a farlo. Non ha molta importanza in che ordine lo facciamo, ma cominciamo da sinistra verso destra. Se premi il pulsante Sx del mouse vicino ad uno dei piccoli semicerchi sui lati degli oggetti (quello che noi chiamiamo una maniglia) e trascini, si former un cordone che segue il movimento del mouse:

Nel momento il cui il pointer del Mouse (con il Sx sempre premuto) arriva in vicinanza di un Parametro potenziale bersaglio, il cordone vi si attaccher e diventer una connessione stabile, solo nel momento in cui rilasci il pulsante: * provenienza: RhinoWiki
http://en.wiki.mcneel.com/default.aspx/McNeel/ExplicitHistoryVolatileDataInheritance.html

13

Si pu fare la stessa cosa con il Parametro "Y" del componente PtGrid e per i Parametri "A" e "B" del componente Line: Click+trascina+rilascia....

__________________________________________________________________________________

___________________________________________________________________________________

___________________________________________________________________________________

14

Nota che possiamo fare connessioni in entrambi i sensi. Ma attento, una nuova connessione cancella un'eventuale connessione preesistente nella stessa posizione. Poich abbiamo supposto che la maggior parte delle volte useremo solo connessioni singole, devi fare qualcosa di particolare per definire origini multiple. Se tieni premuto il tasto Shift mentre effettui la connessione, il pointer del mouse cambier, indicando una connessione che si aggiunge a quella esistente:

___________________________________________________________________________________

Se il cursore "ADD" attivo nel momento in cui rilasci il tasto Sx del mouse su un'origine, il Parametro verr aggiunto alla lista delle origini. Se cerchi di riconnettere la stessa origine, non accade nulla, come ovvio. Con la stessa logica, se premi il tasto Ctrl, diventa visibile il cursore "REM" e la sorgente che stai puntando verr rimossa dalla lista (disconnessa). Se il bersaglio non connesso, non accade nulla.

15

___________________________________________________________________________________

Puoi anche eliminare connessioni (ma non aggiungerne) dal men contestuale del Parametro:

16

Grasshopper ha anche la capacit di trasmettere le informazioni in modalit senza filo per mezzo di un ricevitore, che possibile reperire nella sub-cartella Primitive del tab Params. Puoi effettuare la connessione al ricevitore, nello stesso modo di prima, ma allena rilasci il pulsante, il cordone scompare. Questo perch l'impostazione di default del ricevitore tale da mostrare la connessione tratteggiata solo quando esso viene selezionato. Puoi cliccare Dx sullo stesso per cambiare tale impostazione per rendere evidente la connessione "sempre" o "mai". Puoi connettere l'output del ricevitore a tanti Componenti quanti te ne servono.

Qui la connessione tratteggiata visibile perch il ricevitore selezionato

Il numero 1 prima dell'input al ricevitore indica che esiste una sola connessione senza filo a questo input. Tuttavia, dal momento che il ricevitore non selezionato, la connessione non pi visibile (ma i dati vengono comunque trasferiti).

17

6 Combinazione dei flussi di dati*


La corrispondenza dei dati Combinare tra loro i dati un problema senza soluzione univoca. Succede quando un componente ha accesso a dati Input di diversa dimensione. Immagina un componente che crea segmenti di linea tra punti. Avr due parametri di Input, ognuno dei quali fornisce le coordinate di punto (flusso A e Flusso B). E' irrilevante da dove provengono questi dati, dal momento che un componente non pu "vedere" oltre il limite dei suoi parametri di input ed output:

Come puoi vedere, ci sono diversi modi di connettere con linee i punti contenuti in ciascun flusso. Il plugin GH al momento supporta tre algoritmi combinatori, ma ce ne sono molti altri possibili. Il metodo pi semplice quello di connettere gli input uno a uno fino a quando uno dei flussi viene completato. Questo si chiama algoritmo della lista pi breve (Shortest List):

L'algoritmo della lista pi lunga (Longest List) continua a connettere input fino a completo esaurimento di tutti i flussi. Questo il comportamento di default:

In fine, l'algoritmo di combinazione incrociata (Cross Reference) consente tutte le possibili combinazioni:

Questo potenzialmente pericoloso, perch la mole di dati di output potrebbe diventare enorme. Il problema diventa sempre pi complesso quando sono coinvolti sempre pi parametri e quando l'eredit di dati temporanei continua a moltiplicare nuovi dati, ma la logica di funzionamento rimane la stessa. * provenienza: RhinoWiki
http://en.wiki.mcneel.com/default.aspx/McNeel/DataStreamMatchingAlgorithms.html

18

Immagina di avere un componente Point che eredita i suoi valori X,Y e Z da parametri remoti che contengono i seguenti dati: coordinate X: [0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0] coordinate Y: [0.0, 1.0, 2.0, 3.0, 4.0] coordinate Z: [0.0, 1.0]

Se combiniamo i dati con il metodo "Shortest List", otteniamo solo 2 punti perch la lista delle coordinate Z contiene solo 2 valori. La lista pi piccola determina l'estensione della soluzione:

Il metodo "Longest List" creer 10 punti, riutilizzando i valori pi alti delle liste Z e Y, fino ad esaurire anche la lista pi lunga X:

19

Il metodo "Cross Reference", connettera ogni valore di ciascuna lista a tutti i valori delle altre, con il risultato di creare 10x5x2 = 100 punti:

Ogni componente pu essere configurato per seguire uno di questi metodi (nel men contestuale del componente, accessibile con il tasto Dx). Nota l'unica notevole eccezione a questo comportamento. Alcuni Componenti si attendono di ricevere una lista di dati in uno o pi campi di input. Il componente Polyline, per esempio, crea una polilinea per mezzo di una serie di punti di input. Pi punti nel Parametro di input si traducono in una polilinea pi complessa, non in pi segmenti di linea. I Parametri di input che si suppone debbano fornire pi valori sono chiamati List Parameters e non sono presi in considerazione dal metodo di combinazione dei dati.

20

7 Tipi di componente Scalare


La tipologia dei Componenti Scalari di solito usta per varie operazioni matematiche ed composta da A) Costanti Forniscono il valore di costanti quali Pi, Sezione Aurea, ecc.. B) Intervalli Usati per dividere domini numerici in parti pi piccole in intervalli di valori. Ci sono nel rispettivo tab molti tipi di Componenti adatti a creare e scomporre diversi tipi di intervalli C) Operatori Usati in operazioni matematiche come Somma, Sottrazione, moltiplica, ecc... D) Polinomiali Usati per elevare a potenza un valore numerico E) Trigonometrici Forniscono tipici valori trigonometrici, quali Seno, Coseno, Tangente, ecc... F) Utilit (Analisi) Usati per controllare due o pi valori numerici 7.1 Operatori Come accennato in precedenza gli Operatori sono un insieme di Componenti che usano funzioni algebriche con due valori in input, per un unico valore di output. Per capire meglio gli Operatori, creeremo un semplice definizione che analizza i vari tipi di Operatori.

Per creare questa definizione da zero: Params/Special/Numeric Slider - Trascina un componente Slider sul canvas Doppio click sullo slider per configurare:

-limite inferiore: 0.0

21

-limite superiore: 100.0 -valore: 50.0 (nota: questo valore arbitrario e pu essere modificato con qualsiasi altro all'interno dell'intervallo tra minimo e massimo) Seleziona lo slider e da tastiera premi Ctrl+C (Copia) poi CTRL+V (Incolla) in modo da crearne un duplicato Params/Primitive/Integer - Trascina due Componenti Integer sul canvas Connetti lo slider 1 al primo componente Integer Connetti lo slider 2 al secondo componente Integer

Il tipo di valore di default dello slider settato su Floating Point (che significa un valore numerico decimale). Connettendo lo slider al componente Integer, possiamo trasformare i valori decimali in interi. Se connettiamo un componente Post-it (Params/Special/Panel) al valore di output di ciascun componente Integer, possiamo vedere la conversione in tempo reale. Muovi uno degli slider a destra o sinistra e nota che il valore decimale dello slider viene convertito in numero intero (leggi sul post-it). Naturalmente avremmo potuto semplificare tutto ci settando lo slider come Integer. Scalar/Operator/Add - Trascinaun componente Add sul canvas Connetti il primo componente Integer all'input A del componente Add Connetti il secondo componente Integer all'input B del componente Add Params/Special/Panel - Trascina un Post-it sul canvas Connetti l'output R del componente Add all'input del Post-it Trascina sul canvas ciascuno degli altri Scalar Operators

Puoi ora vedere sul Post-it il risultato della somma dei due Integer - Subtraction - Multiplication - Division - Modulus - Power Connetti il primo componente Integer all'input A di ciascun Operatore Connetti il secondo componente Integer all'input B di ciascun Operatore Trascina sul canvas altri cinque Post-it e connettili agli output di ciascun altro Operatore

La definizione completa e quando cambi il valore di ciascun slider vedrai il risultato della rispettiva operazione nel Post-it di riferimento.

22

7.2 Dichiarazioni Condizionali Avrai notato che alcuni dei Componenti contenuto nella sotto-categoria del tab Scalar non sono stati descritti nell'ultima sezione. La spiegazione che ci sono quattro componenti (nuovi nella versione 0.6.0007) che si comportano in qualche modo diversamente dagli operatori matematici, nel senso che essi confrontano due liste di dati anzich compiere un'operazione algebrica. I quattro Componenti sono Equality (Eguaglianza), Similarity (Somiglianza), Larger Than (Maggiore di) e Smaller than (Minore di) e sono spiegati in maggior dettaglio di seguito. Nota: per vedere la versione finale di questa definizione, apri il file Conditional Statements.ghx che si trova nella cartella Source Files che accompagna questo documento. Ecco qui sotto un'immagine della definizione completa:

A) Equality prende due liste e confronta il primo elemento della lista A con il primo elemento della lista B. Se i due valori sono uguali, viene creato un valore booleano True (vero), mentre se i due valori sono diversi, viene creato un valore booleano False (falso). Il componente scorre la lista seguendo l'algoritmo di confronto specificato (per default Longest List). Per questo componente esistono 2 output. Il primo d per risultato un elenco di valori booleani che mostrano quali elementi delle liste erano uguali. Il secondo output riporta l'elenco dei valori diversi nelle liste, ovvero una lista complementare alla prima. B) Similarity valuta due liste di dati e misura la somiglianza tra due valori. Lavora in modo analogo ad Equality, con l'eccezione di avere un input che specifica una percentuale di differenza ammessa tra i valori in confronto, entro la quale viene garantita la somiglianza. Il componente Similarity genera un output aggiuntivo che specifica il valore assoluto di differenza tra le due liste di input.

23

C) Larger Than prende due liste di dati e calcola se il primo della lista A maggiore del primo della lista B, ecc. Gli output consentono all'utente di effettuare il confronto con l'unica condizione "maggiore di (>) o con le condizioni "maggiore di" + "uguale a" (>=) insieme. D) Smaller Than effettua il confronto inverso. Il componente Smaller Than confronta ogni dato della lista A con il corrispondente della lista B e produce una lista di valori booleani (True_False). Analogamente, si ha la possibilit sia di confrontare solo per "Minore di" (<), sia per "Minore di" e "Uguale a" (<=) insieme.

24

7.2 Confronto tra Range, Series, Interval I Componenti Range (schiera), Series (sequenza), Interval (intervallo) creano tutti un set di valori tra due estremi numerici, pur operando in modi diversi. Nota: Per vedere la versione completa degli esempi seguenti, Apri il file Scalar_Interval-ghx che trovi nella solita cartella Souce Files di accompagnamento a questo tutorial.

Il componente Range crea una lista di numeri distanziati l'uno dall'altro in modo costante tra un valore minimo ed uno massimo, chiamati dominio della schiera numerica. Nell'esempio mostrato sopra, due slider numerici sono connessi agli input del componente Range. Il primo slider specifica il dominio della serie. In questo caso il dominio (gli estremi minore e maggiore) della schiera sono 0 e 1, giacch lo slider puntato su 1. Il secondo slider specifica in quanti intervalli uguali dividere il dominio, in questo caso 10. Di conseguenza l'output costituito da 11 valori numerici regolarmente intervallati che coprono il dominio 0-1 (nota che il secondo slider specifica il numero di "intervalli", 10, che richiedono appunto 10+1 valori).

Il componente Series crea un set di numeri discreti a partire da un numero iniziale, il valore di intervallo tra un numero ed il successivo ed il numero di valori richiesti nella serie. L'esempio qui sopra mostra tre slider numerici connessi al componente Series. Il primo, connesso all'input S, specifica il valore iniziale della serie, il secondo, connesso all'input N, specifica l'intervallo tra i valori della serie. Dal momento che il numero iniziale 1 e l'intervallo 10, il secondo numero della serie sar 11. Il terzo slider specifica il numero totale di valori contenuti nella serie. Con l'impostazione a 10, il risultato di output sar costituito da 10 valori, che iniziano con 1 ed aumentano di 10 ad ogni passaggio.

25

Il componente Intervallo crea una schiera di possibili numeri tra un valore minimo ed uno massimo. E' simile al Range. La differenza principale costituita dal fatto che, mentre Range crea un dominio numerico di default tra il valore 0 (minimo) e qualsiasi altro numero (massimo, anche se potrebbe essere inferiore a 0), per il componente Interval possono essere definiti sugli input A e B entrambi i valori minimo e massimo. Nell'esempio qui sopra, abbiamo derivato una schiera di tutti i possibili valori tra 10 e 20, specificati nei due slider. L'output del componente Interval mostra sul post-it 10.0 To 20.0, che rispecchia il nostro nuovo dominio numerico. Se connettiamo l'output I di Interval all'input D di un componente Range, possiamo creare una schiera di numeri tra i valori di Interval. Se, come nel caso precedente, specifichiamo con un terzo slider il numero di passaggi a 10, vedremo come output di Range 11 valori distanziati in modo uniforme tra il minimo 10.0 ed il massimo 20.0 di Interval. (Nota: ci sono svariati modi di definire un intervallo, ne vedrai alcuni altri nel tab Scalar/Interval. Abbiamo solo mostrato un componente Interval semplice, ma discuteremo altri metodi di Interval nei prossimi capitoli)

26

7.3 Funzioni & Booleane Praticamente tutti i linguaggi di programmazione hanno metodi per elaborare dichiarazioni condizionali. Gran parte delle volte il programmatore crea un pezzo di codice che pone questa semplice domanda "Che succede, se...?" Che succederebbe se gli attacchi terroristici del 11 settembre non fossero mai successi? Che succederebbe se un gallone di benzina costasse 10 $? Sono domande importanti che richiedono un livello superiore di pensiero astratto. I programmi software hanno la capacit di analizzare questioni tipo "What, if?", ed agire sulla base della risposta che ne si ottiene. Vediamo di dare un'occhiata ad una dichiarazione condizionale molto semplice che un programma sia in grado di interpretare. Se l'oggetto una curva, cancellalo. Questo frammento di codice controlla un oggetto ed emette un singolo valore booleano sul suo essere o meno una curva (vero o falso). Non esiste via di mezzo. Il valore booleano True se l'oggetto una curva, oppure False se l'oggetto qualcosa d'altro. La seconda parte del codice compie un'azione conseguente alla risposta data alla prima parte, in questo caso, se l'oggetto una curva, lo cancella. Questa dichiarazione condizionale viene dichiarazione If/Else (Se.., altrimenti...). Se lpoggetto risponde a certi criteri, compie una determinata azione; altrimenti, compie un'azione diversa (o nessuna azione, come in questo caso). Grasshopper possiede la stessa capacit di analizzare una dichiarazione condizionale usando i Componenti Function (funzione).

Nell'esempio qui sopra, abbiamo connesso uno slider all'input X di un componente Funzione ad una sola variabile (Logic/Script/F1). In aggiunta, un componente dichiarazione condizionale stato connesso all'input F della Function, che chiede: "X maggiore di 5?". Se il valore dello slider viene portato sopra 5, l'output della Funtion diventa vero -True-, mentre se il valore viene spostato sotto 5, l'output diventa falso -False-. Una volta ricavato il valore booleano della funzione, lo possiamo usare come input in un componente Dispatch (Logic/List/Dispatch) per svolgere una determinata azione.

27

Il componente Dispatch (spedisci) funziona usando una lista di dati (nel nostro esempio abbiamo connesso il dato dello slider con l'input L del Dispatch) e filtra questa informazione sulla base del risultato della funzione booleana ad una sola variabile. Se tale risultato risulta True, il valore viene passato all'output A del Dispatch, mentre se il risultato False, il valore viene passato all'output B. In questo esempio, abbiamo deciso di creare un cerchio SOLO se il valore dello slider maggiore di 5. Abbiamo connesso un componente Circle (Curve/Primitive/Circle) all'output A del Dispatch, in modo che sia generato un cerchio di raggio pari al valore dello slider solo se il risultato della funzione booleana True. Poich all'output B di Dispatch non connesso alcun componente, quando il valore booleano risulta False, non succede niente e non si genera alcun cerchio.

Possiamo portare questa definizione un p oltre, attivando anche l'output B del Dispatch con un componente N-sided Polygon (poligono a n lati)(Curve/Primitive/Polygon), mediante la connessione all'input R del Polygon, per definirne il raggio. Adesso, quando il valore dello slider scende oltre il limite della funzione booleana, viene creato un poligono a cinque lati di raggio pari al valore dello slider. Se portiamo tale valore oltre 5, viene invece creato un cerchio. Con questo sistema, possiamo iniziare a produrre tante dichiarazioni If/Else quante ce ne servono per incanalare il flusso d'informazione nella nostra definizione.

Nota: Per vedere la definizione completa di questo esempio, Apri il file If_Else test.ghx nella cartella che correda questo tutorial.

28

7.4 Funzioni e Dati Numerici Il componente Function molto flessibile; vale a dire che pu essere usato in una molteplicit di situazioni. Abbiamo gi visto come una Function pu essere usata per valutare una dichiarazione condizionale e fornire un valore booleano. Tuttavia possiamo anche usare Function per risolvere complessi algoritmi matematici e mostrare come output il risultato. Nell'esemopio che segue, creeremo una spirale matematica simile a quella dell'esempio che David Rutten ha fornito nel suo manuale Rhinoscript 101. Per maggiori dettagli su Rhinoscript o per scaricare una copia del manuale, visita http://en.wiki.mcneel.com/default.aspx/McNeel/RhinoScript101.html Nota: Per vedere la definizione completa dell'esempio della spirale, Apri il file Function_spiral.ghx dalla cartella Source Files che correda questo tutorial. Ecco qui un'immagine della definizione completa:

Per creare la definizione da zero: Logic/Set/Range- trascina sul canvas un componente Range Params/Special/Slider- trascina sul canvas due slider Con il Dx sul primo slider, imposta i seguenti valori

- Name (nome): Crv L - Slider Type (tipo di slider): Foating Point (a virgola mobile, gi di default) - Lower Limit (limite inferiore): 0.1 - Upper Limit (limite superiore): 10.0 - Value (valore): 2.5 Con il Dx sul secondo, imposta i seguenti valori: - Name : Num Pts su Crv - Slider Type : Integer (interi) - Lower Limit : 1 - Upper Limit : 100 - Value : 100 Connetti lo slider Crv L con l'input D del componente Range Connetti lo slider Num Pts su Crv all'input N di Range

29

Abbiamo giusto creato una serie di 101 numeri regolarmente spaziati tra 0.0 e 2.5, che possiamo usare come input nei nostri Componenti Function. Logic/Script/F1- trascina sul canvas una Function a singola variabile Connetti l'output R di Range all'input x di Function Tasto Dx sull'input F della Function e apri Espression Editor Nella finestra di dialogo dell'editor, scrivi la seguente equazione:

x*sin(5*x) Se non hai commesso errori di battitura, dovresti vedere il messaggio "No syntax errors detected in expression" nella riga degli errori in fondo alla finestra Conferma con OK per accettare la formula

Seleziona il componente Function, Ctrl+C (copia) e Crtl+V (incolla) per crearne un duplicato Taso Dx su input F della copia, apri Espression Editor e correggi con questa formula:

x*cos(5*x) Nota: l'unica differenza di questa formula la sostituzione della funzione seno con coseno Conferma con OK Abbiamo in questo modo fornito i 101 numeri generati da Range ai componenti Function, che elaborano una algoritmo matematico e generano una seconda serie di valori. Puoi soffermarti sull'output r di ciascuna funzione per vedere i risultati delle equazioni. Vector/Point/PointXYZ- trascina sul canvas un componente Point XYZ Connetti l'output r della prima Function con l'input X del Point Connetti l'output r della seconda Function con l'input Y del Point Connetti l'output R di Range all'input Z del Point

Ora, se controlli nel viewport di Rhino, vedrai una serie di punti che formano una spirale. Puoi modificare attraverso i due slider il numero di punti e la lunghezza della spirale.

30

Curve/Spline/Curve- trascina sul canvas un componente Curve Connetti l'output Pt del Point all'input V del Curve

Abbiamo generato una singola curva che passa da ciascuno dei punti della spirale. Possiamo usare il Dx sull'input D della Curve, per definirne il grado; grado 1 genera una poli-linea tra tutti i punti. Grado 3 creer invece una curva di Bezier regolare dove i punti ungono da controllo della curva, che ci passa solo vicino, ma inizia e finisce rispettivamente sup primo e sull'ultimo.

Nota: Per vedere un video-tutorial di questo esempio, visita il blog di Zach Downey al: http://www.designalyze.com/2008/07/07/generating-a-spira-in-rhinos-grasshopper-plugin/

31

7.5 Curve Trigonometriche Abbiamo gi visto che possibile usare il componente Function per elaborare formule complesse per la generazione di curve matematiche, ma Grasshopper possiede anche un suo set di componenti trigonometrici contenuti nella famiglia dei componenti Scalar. Le funzioni trigonometriche come Seno, Coseno e Tangente sono strumenti importanti per matematici, scienziati ed ingegneri perch esse rappresentano il rapporto tra i due lati di un triangolo rettangolo formanti uno specifico angolo, detto Theta. Queste funzioni sono importanti nell'analisi dei Vettori, di cui parleremo nei capitoli successivi. Inoltre possiamo usare queste funzioni per descrivere fenomeni periodici, come per l'appunto le onde sinusoidali che si incontrano spesso in natura sotto forma di onde marine, onde sonore, onde luminose. Nel 1822, Joseph Fourier, un matematico Francese, scopr che le onde sinusoidali possono essere usate come mattoni elementari per "costruire" e spiegare qualsiasi fenomeno ondulatorio periodico. In suo onore il processo chiamato analisi di Fourier. Nell'esempio seguente, creeremo una geometria ad onda sinusoidale dove il numero di punti della curva, la lunghezza d'onda, la frequenza e l'ampiezza possono essere controllate da un set di slider. Nota: Per vedere la definizione completa usata per generare la curva sinusoidale mostrata, Apri il file Trigonometric_curves.ghx dalla cartella Source Files che correda questo tutorial.

Per creare la definizione da zero: Params/Special/Slider- trascina sul canvas 3 slider Seleziona Dx il primo slider e imposta i seguenti parametri:

-Name: NumPts on Crv -Slider Type: Integers -Lower Limit: 1 -Upper Limit: 50 -Value: 40 Imposta sul secondo slider i seguenti parametri: -Name: L d'onda -Slider Type: Integers -Lower Limit: 0 -Upper Limit: 30 -Value: 10

32

Imposta sul terzo slider i seguenti parametri:

-Name: Frequenza -Slider Type: Integers -Lower Limit:0 -Upper Limit: 30 -Value: 12 Logic/Sets/Range - trascina sul canvas 2 componenti Range Connetti lo slider L d'onda all'input D del primo Range Connetti lo slider Frequenza all'input D del secondo Range Connetti lo slider NumPts on Crv all'input N di entrambi i Range

La tua definizione dovrebbe avere circa questo aspetto, a parte la lingua. Abbiamo dunque creato 2 liste di valori; la prima una schiera di numeri equamente distribuiti tra 0 e 10, la seconda una schiera di numeri equamente distribuiti tra 0 e 12. Scalar/Trigonometric/Sine - trascina sul canvas un componente Sine Connetti l'output del secondo Range all'input x del Sine Vector/Point/PointXYX (attenzione a non fare confusione) - trascina sul canvas un Point XYZ Connetti l'output R del primo Range all'input X del Point XYZ Connetti l'output y del componente Sine all'input Y del componente Point XYZ

Se controlli il viewport di Rhino, dovresti vedere una serie di punti in forma sinusoidale. Poich l'output del primo Range viene direttamente fornito all'input X del Point XYZ, senza passare da alcun componente di funzione trigonometrica, i valori sull'asse X dei nostri punti sono costanti ed equamente distribuiti. Tuttavia, il componente Sine che alimenta l'input Y del Point XYZ fa in modo che il valore sull'asse Y dei punti vari in modo ondulatorio. Puoi ora provare valori diversi sugli slider per vedere cambiare di conseguenza lunghezza d'onda, frequenza ed estensione della forma sinusoidale. Curve/Spline/Interpolate- trascina sul canvas un componente Interpolated Curve Connetti l'output del Point XYZ all'input V del componente Curve

A questo punto, la tua definizione dovrebbe avere l'aspetto dell'immagine qui sotto. Abbiamo preparato la nostra definizione per controllare numero di punti, frequenza e lunghezza d'onda, ma potremmo aggiungere un ulteriore slider per controllare l'ampiezza della curva sinusoidale.

33

Parms/Special/Slider - trascina sul canvas uno slider Imposta i seguenti parametri:

-Name: Ampiezza -Slider Type: Floating Point -Lower Limit:0.1 -Upper Limit: 5.0 -Value: 2.0 Scalar/Operators/Multiplication- trascina sul canvas un componente Multiplication Connetti lo slider Ampiezza all'input A del Multiplication Connetti l'output y del Sine all'input B del Multiplication Connetti l'output r di Multiplication all'input Y del Point XYZ

Quest'azione dovrebbe rompere la connessione esistente e sostituirvisi. Lo slider Ampiezza sta solo moltiplicando i valori di Sine per un fattore di scala. Poich lo slider interviene sul valore della coordinata Y dei punti, quando aumenti il valore della slider Ampiezza, vedrai la curva aumentare i suoi picchi. Vector/Point/Point XYZ - trascina sul canvas un altro Point XYZ Curve/Primitive/Line - trascina sul canvas un componente Line Connetti l'output Pt del primo Point XYZ all'input B del Line

Nell'ultima parte della definizione abbiamo creato un secondo set di punti equamente distribuiti lungo la'sse X, aventi le stesse coordinate X di quelli della curva sinusoidale. Il componente Line crea un segmento di linea tra la prima lista di punti, quella sinusoidale e la seconda sull'asse X. Queste ultime linee forniscono un riferimento visivo dello spostamento verticale della forma ondulatoria. La tua definizione dovrebbe essere come nell'immagine sotto.

34

Abbiamo spiegato come costruire una curva sinusoidale, ma possibile generare analogamente anche altre curve trigonometriche con coseno o tangente. Provate a sostituire le connessioni di Sine con quelle corrispondenti dei componenti Cos o Tan , che trovate sempre nel tab Scalar/Trigonometry. Nota: Per vedere un video-tutorial di questo esempio, visita il blog di David Fano al: http://designereform.net/2008/06/01/rhino-3d-sine-curve-explicit-history/

35

8 Il Giardino dei Sentieri Ramificati


Nelle versioni di Grasshopper fino alla 0.6.00xx, i dati di un parametro venivano inseriti in ununica lista; non cera quindi necessit di avere un indice delle liste. Tuttavia c stata una completa riorganizzazione della gestione dati in Grasshopper, e ora possibile avere liste multiple di dati allinterno dello stesso parametro. Da quando le liste multiple sono state rese possibili, c stata la necessit di trovare un metodo per identificare ogni singola lista. Qui sotto riportiamo unimmagine, creata da David Rutten, che rappresenta un diagramma ad albero complesso ma ben strutturato.

Nellimmagine abbiamo un singolo ramo principale nel percorso a indice 0. Questo ramo non contiene dati, ma solamente altre 3 ramificazioni. Ognuna di queste eredita, nella propria nomenclatura, lindice del ramo da cui provengono (in questo caso 0) e aggiungono il loro sotto-indice (ripettivamente 0, 1, 2). Sarebbe sbagliato riferirsi a queste nuove ramificazioni con una sola cifra, in quanto non riusciremmo a identificare la ramificazione da cui provengono. E molto meglio riferirsi alle ramificazioni come a sentieri, simili alla struttura a cartelle utilizzata nei dischi fissi. Ognuna di queste tre ramificazioni contiene a sua volta 2 nuove ramificazioni, senza alcun dato. Ovviamente lo stesso metodo di nomenclatura viene utilizzato per le ogni ramificazione e sottoramificazione appartenente alla struttura. Una volta raggiunto il sottolivello 4, abbiamo la presenza di dati (nel grafico le liste dati sono rappresentate da linee colorate molto spesse, i dati invece da pallini colorati). Ogni sotto-sotto-sotto-ramificazione (o sottolivello 4) un ramo terminale, ovvero non si suddivide in nessunaltra ramificazione.

36

Ogni lista di dati parte di una (e solo una) ramificazione del nostro diagramma ad albero, ed ogni elemento ha un indice che specifica la sua posizione allinterno della lista; cos come ogni ramificazione ha una denominazione che specifica la sua posizione allinterno del diagramma ad albero. Per esaminare ancora meglio questo tipo di strutture, prendiamo lesempio seguente. Partiamo da 2 curve che colleghiamo a Grasshopper. Utilizzeremo poi un unico elemento Dividi Curva (Curve/Division/Divide Curve) per divider entrambe le curve in 20 segmenti; otterremo cos 21 punti per ogni curva, in una lista di 42 punti. Ora colleghiamo questi punti a un componente Polilinea (Curve/Spline/Polyline), che creer una nuova linea passante per i punti precedentemente rilevati. Se

avessimo usato Grasshopper versione 0.5 o precedente, il comando Polilinea avrebbe disegnato solamente 1 curva passante per tutti e 42 I punti della lista. Questo perch nella versione precedente tutti i punti venivano salvati allinterno della stessa singola lista (senza ramificazioni). Usando Grasshopper versione 0.5 la lista dei punti e la polilinea risultante sarebbero stati molto simili allesempio qui sotto: Dal

momento che sappiamo che Grasshopper ha la possibilit di incorporare ramificazioni di dati, possiamo ora usare questi indici per controllare il comportamento del componente Polilinea. Se seguiamo esattamente i passi mostrati nellesempio, utilizzando, Grasshopper versione 0.6.00xx o superiore, il nostro componente Polilinea creer 2 curve perch riconosce la presenza di 2 ramificazioni di dati, ognuna contenente 20 segmenti (21 valori). Possiamo controllare la struttura ad albero utilizzando il

37

Parameter Viewer (Params/Special/Param Viewer). Qui sotto riportato uno screenshot dove viene mostrata la struttura a 2 ramificazioni (0;0) e (0;1) aventi, ciascuna, una lista dati al loro interno. L i n d i c e

dei punti di ogni polilinea e le curve risultanti assomigliano al risultato di seguito:

Sappiamo che la nostra definizione possiede 2 ramificazioni, ma come dobbiamo fare se volessimo 1 solo insieme di dati e ununica polilinea? Grasshopper possiede un gran numero di nuovi componenti dedicati alla gestione delle strutture ramificata di dati; si trovano allinterno della sotto-categoria Tree, nella sezione Logics, e possono aiutare a controllare lorganizzazione della struttura dati. Possiamo, ad esempio, usare un componente Flatten Tree (Logic/Tree/Flatten Tree) per collassare unintera struttura in una sola lista, similmente a come Grasshopper si sarebbe comportato nella versione 0.5 o precedente. Nellimmagine seguente si pu notare che, quando si appiattiscono delle ramificazioni, la struttura risultante consiste in una sola ramificazione, con ununica lista dati contenuta alla sua fine... la stessa unica lista dati che avrebbe restituito una qualsiasi versione di Grasshopper precedente a quella in questione.

38

Potete ottenere lo stesso risultato collassando la struttura all'interno del componente Polilinea,

bypassando il componente Flatten. Per fare ci cliccate con il tasto destro sull'ingresso V-input del componente Polyline e scegliere "Flatten" dal menu. In questa maniera la struttura ad albero (visibile attraverso il Parameter Viewer) viene fusa da 2 ramificazioni a solamente 1.

Nota: Per vedere la definizione usata per creare questo esempio, Apri il file Curve Paths.ghx che trovi nella cartella Source Files che accompagna questo documento. Dovrai inoltre aprire il corrispondente file di Rhino, che si trova nella stessa cartella, di nome Curve Paths_base file.3dm.

8.1 Liste & Organizzazione Dati Pensare a Grasshopper in termini di flusso di dati pu aiutare molto, in quanto l'interfaccia grafica progettata per avere flussi di informazioni in entrata e in uscita da ogni specifico componente. In ogni caso, sono i DATI (come liste di punti, curve, superfici, stringhe, booleane, numeri ecc

39

etc) che definiscono il flusso di informazioni in entrata e in uscita dai componenti; un passaggio fondamentale per comprendere Grasshopper quindi capire come manipolare le liste dati. Ecco un esempio di come si pu controllare una lista di dati numerici utilizzando alcuni componenti appartenenti alla sottocategoria List nel menu Logic. Nota: Per vedere la definizione usata per creare questo esempio, Apri il file List

Management.ghx che trovi nella cartella Source Files che accompagna questo documento. Per prima cosa abbiamo creato un componente Serie, con un valore iniziale di 0.0, passo 1.0 e contatore 10. Il pannello Post-it connesso all'output Series-S mostra la seguente lista di numeri in uscita: 0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, e 9.0. Nota: Il pannello Post-it mostra l'indice di ogni elemento in lista prima del valore numerico dell'elemento stesso, come in figura:

40

L'indice degli elementi pu essere disattivato cliccando con il tasto destro sul pannello Post-it e modificando la Entry Numbers Preview in attivo o disattivo. Per questo esempio lasceremo l'indice degli elementi attivo, perch ci permette di vedere esattamente che indice associato a ogni valore numerico della lista. A) I dati numerici sono inseriti nel componente List Item (Logic/List/List Item), che usato per estrarre uno specifico elemento dalla lista. Quando si accede a elementi individuali di una lista, occorre utilizzare un indice come riferimento. Il primo elemento di qualsiasi lista sempre localizzato a indice zero, il secondo elemento a indice 1, e cos via. Se si prova ad estrarre da una lista un elemento con indice -5 verr restituito un errore, in quanto quell'indice non esiste. Abbiamo connesso l'uscita di Series-S con l'entrata di List Item-L. In aggiunta, abbiamo inserito un numero intero nell'entrata List Item-i, che definisce l'indice del valore che vogliamo estrarre. Siccome abbiamo fissato questo valore a 5, l'uscita del List Item ci mostrer il valore numerico associato all'indice 5, in questo caso proprio 5.0. B) Il componente List Length (Logic/List/List Length) essenzialmente conta il numero di elementi all'interno di una lista, restituendo la lunghezza della lista in termini di numero di valori. In questo esempio abbiamo connesso l'uscita di Series-S all'entrata di List Length-L, e ci viene mostrato che la lista possiede 10 valori. C) Possiamo invertire l'ordine di una lista utilizzando il componente Reverse List (Logic/List/Reverse List). Abbiamo inserito una lista di valori crescenti nel componente Reverse List, ottenendo in uscita una serie di valori decrescente da 9.0 a 0.0. D) Il componente Shift (Logic/List/Shift List) trasla la lista verso l'alto o verso il basso di un numero di incrementi dipendente dal valore attribuito a shift offset. Abbiamo connesso l'uscita di Series-S all'ingresso di Shift-L, e uno slider numerico all'entrata di Shift-S. Abbiamo settato la tipologia di slider a integers in maniera che l'incremento avvenga per numeri interi. Se settiamo lo slider a -1, la lista si muover verso il basso di un valore di indice. Al contrario, settando lo slider a +1, tutti I valori della lista saranno traslati verso lalto di un valore di indice. Possiamo inoltre settare un valore di wrap nell'ingresso Shift-W, che pu essere True o False (per impostarlo basta cliccarci sopra con il tasto destro, e scegliere Set Boolean). In questo esempio abbiamo attribuito a shift offset un valore di +1; dobbiamo quindi decidere come vogliamo che il primo valore (indice 0) venga trattato. Se settiamo il valore di wrap a True, la prima entrata verr traslata all'ultimo posto della lista. Invece se settiamo il valore di wrap a False, il primo valore verr traslato verso l'alto e al di fuori della lista, in pratica eliminando il

41

dato dalla lista stessa. E) Il componente Split List divide la lista in due liste pi piccole. Il parametro splitting index, non altro che un numero intero indicante l'indice dove la lista verr divisa. In questo caso abbiamo detto al componente Split List di dividere la lista dopo la quinta entrata, quindi la nostra uscita sar: List A - 0.0, 1.0, 2.0, 3.0, 4.0 List B - 5.0, 6.0, 7.0, 8.0, 9.0. F) Il componente Cull Nth (Logic/Sets/Cull Nth) rimuover ogni dato Nesimo dalla lista, dove N definito da un numero intero. In questo esempio abbiamo connesso uno slider numerico all'ingresso di Cull Nth-N. Abbiamo settato lo slider a 2.0, in modo che il componente Cull Nth rimuova ogni altra entrata a cadenza 2 dalla lista. L'uscita di Cull Nth-L mostra dati in uscita dove ogni entrata a indice dispari della precedente lista stata eliminata: 0.0, 2.0, 4.0, 6.0, e 8.0. Se impostassimo il numeric slider a 3.0, il componente Cull Nth rimuoverebbe ogni terzo numero dalla lista, con risultato: 0.0, 1.0, 3.0, 4.0, 6.0, 7.0, and 9.0. G) Il componente Cull Pattern (Logic/Sets/Cull Pattern) simile al componente Cull Nth, in quanto rimuove elementi da una lista basandosi su un valore definito. La differenza dal precedente che, invece di utilizzare un valore numerico, Cull Pattern usa un set di valori booleani che formano un pattern. Se il valore booleano settato in True, il valore rimarr nella lista; un valore di False rimuover invece l'elemento dalla lista. In questo esempio abbiamo settato il pattern booleano a: True, True, False, False. Dal momento che abbiamo 4 valori booleani, e che la lista ha 10 elementi, il pattern verr ripetuto fino al termine della stessa. Con questo pattern la lista in uscita sar: 0.0, 1.0, 4.0, 5.0, 8.0, and 9.0. Il componente Cull Pattern ha mantenuto I primi due elementi (0.0 e 1.0) rimuovendo I due seguenti (2.0 and 3.0), ripetendo il pattern fino al raggiungimento dell'ultimo termine della lista.

8.2 Mescolare Dati (Weaving data) Nell'ultima sezione abbiamo spiegato come usare alcuni componenti per gestire le liste in Grasshopper, ma possiamo utilizzare anche il componente Weave per organizzare l'ordine di una lista. Il componente Weave pu essere trovato nella sottocategoria Lists dentro al menu Logics (Logics/Lists/Weave). Nota: Per vedere la definizione in esempio, Apri il file Weave Pattern.ghx localizzato nella cartella Source Files che accompagna questo documento.

42

Per ricreare la definizione: Logic/List/Weave Trascinare un componente Weave nello spazio di lavoro Noterai immediatamente 3 entrate. La prima, P, il pattern di weaving, e determiner l'ordine in cui I dati saranno mescolati. Le altre due entrate, rispettivamente 0 e 1, ci permetteranno di collegare in ingresso due liste che verranno mescolate insieme. Come fare se vogliamo mescolare insieme pi di due liste? Cliccando con il tasto destro nel centro del componente Weave, si pu aprire l'Input Manager e aggiungere quante liste in input si voglia. All'apertura dell'Input Manager cliccare sul tasto verde con il + per aggiungere un'altra lista. Similarmente la X rossa localizzata vicino a ogni lista la rimuover dal componente.

43

Aprire l'Input Manager e cliccare il bottone con il + verde per aggiungere una lista al componente. L'Input Manager dovrebbe assomigliare all'immagine sopra. Params/Primitive/Integer Trascinare un parametro Integer sull'area di lavoro Cliccare con il tasto destro sul parametro Integer e scegliere "Manage Integer Collection" Cliccando sul tasto con il + verde, nella parte alta, si pu aggiungere un numero intero alla collezione. Aggiungere 3 numeri al pattern e cambiare I valori in modo che siano: 0, 1, 2.

Questa collezione di numeri interi determiner il nostro pattern di mescolamento. Cambiando l'ordine di questi numeri, possiamo velocemente modificare l'ordine del nostro set di valori. Params/Primitive/String Trascinare un componente String nello spazio di lavoro Cliccare con il tasto destro sul componente String e scegliere "Manage String Collection" Similarmente a ci che abbiamo fatto con la collezione di numeri interi, stiamo per aggiungere una lista di stringhe che vogliamo mescolare insieme. Questa sar la nostra prima lista di dati, ma la copieremo e incolleremo per 2 volte, in maniera da avere 3 liste da mescolare assieme. Aggiungere 5 stringhe alla collezione, in maniera da avere: L0:A, L0:B, L0:C, L0:D, L0:E. Il prefisso L0: ci indicher che queste stringhe sono nella lista zero e ci aiuter a rintracciare I valori una volta che li avremo mescolati insieme.

44

Scegliere il parametro String e premere Ctrl+C (copia) e Ctrl+V (incolla) per duplicare altri 2 parametri String nello spazio di lavoro Cliccare col destro sul secondo parametro String e aprire il String Collection Manager. Cambiare la collezione in maniera che I valori siano: L1:A, L1:B, L1:C, L1:D, L1:E. Cliccare col destro sul terzo parametro String e aprire il String Collection Manager. Cambiare la collezione in maniera che I valori siano: L2:A, L2:B, L2:C, L2:D, L2:E. Connettere il parametro Integer che definir il nostro pattern di mescolamento all'ingresso P del componente Weave Connettere il primo parametro String parameter all'ingresso 0 del componente Weave Connettere il secondo parametro String parameter all'ingresso 1 del componente Weave Connettere il terzo parametro String parameter all'ingresso 2 del componente Weave Params/Special/Post-it Panel Trascinare un pannello Post-it nello spazio di lavoro Connettere l'uscita Weave-W al pannello Post-it Panel in maniera da poter vedere il risultato. Il pannello Post-it dovrebbe mostrare una lista di dati che sono stati mescolati secondo la nostra collezione di interi. Il primo elemento nella lista dovrebbe essere il primo elemento della lista 0. Similarmente, il secondo elemento della lista sar il primo elemento dell lista 1. E cos via fino alla fine della lista. Provare a cambiare l'ordine degli interi, per modificare il pattern di mescolamento.

8.3 Traslare Dati (Shifting Data) Abbiamo discusso, nella sezione 8.1, di come usare il componente Shift per traslare tutti i valori di una lista verso l'alto o verso il basso di un valore definito. Qui sotto abbiamo un esempio, creato da David Rutten, che ci mostra come possiamo usare il componente shift su due liste di punti appartenenti a una circonferenza. Altre informazioni su questo esempio possono essere trovate al link:

http://en.wiki.mcneel.com/default.aspx/McNeel/ExplicitHistoryShiftExample.html
Nota: Per la definizione usata nel seguente esempio, Apri il file Shift Circle.ghx che potete trovare nella cartella Source Files che accompagna questo documento. Qui sotto riportiamo la definizione utilizzata per generare l'esempio dei cerchi traslati.

45

Per creare la definizione:: Curve/Primitive/Circle CNR trascinare un Circle CNR (Centro, Normale, e Raggio) nello spazio di lavoro Cliccare con il tasto destro sull'entrata Circle-C e scegliere Set One Point Nella casella di dialogo di Rhino digitare 0,0,0 e premere invio Cliccare con il tasto destro sull'entrata Circle-R e impostare Set Number a 10.0 Vector/Constants/Unit Z Trascinare un vettore Unit Z nello spazio di lavoro Cliccare con il tasto destro sul'entrata F del componente Unit Z e settare Set Number to 10.0 X Form/Euclidean/Move Trascinare un componente nello spazio di lavoro Connettere l'uscita Unit Z-V all'entrata Move-T Connettere l'uscita Circle-C all'entrata Move-G E' stato appena creato un cerchio con centro 0,0,0 e raggio 10.0 unit. In seguito abbiamo usato il componente Move per copiare il cerchio e muovere il duplicato di 10 unit lungo asse Z. Curve/Division/Divide Curve Trascinare due componenti Divide Curve nello spazio di lavoro Connettere l'uscita Circle-C all'ingresso del primo Divide-C Connettere l'uscita Move-G all'ingresso del secondo Divide-C Params/Special/Slider Trascinare uno slider numerico nel piano di lavoro Selezionare lo slider e settare I seguenti parametri: o Slider Type: Integers o Lower Limit: 1.0

46

Upper Limit: 30.0 Value: 30.0 Connettere lo slider numerico a entrambi gli ingressi dei componenti Divide Curve-N Dovrebbero apparire 30 punti equamente spaziati su ogni circonferenza Logic/List/Shift List Trascinare un componente Shift List sul piano di lavoro Connettere l'uscita del secondo Divide Curve-P all'ingresso di Shift List-L Params/Special/Slider Trascinare uno slider numerico sul piano di lavoro Selezionare il nuovo slider e settare I seguenti parametri: o Slider Type: Integers o Lower Limit: -10.0 o Upper Limit: 10.0 o Value: 10.0 Connettere lo slider numerico all'ingresso di Shift List-S Cliccare con il tasto destro sull'ingresso di Shift List-W e settare il valore booleano di wrap su True Abbiamo traslato I punti disposti lungo la circonferenza superiore di 10 incrementi. Settando il valore di wrap su True, abbiamo creato un loop chiuso di dati nella lista. Curve/Primitive/Line Trascinare un componente Line sullo spazio di lavoro Connettere la prima uscita Divide Curve-P all'ingresso Line-A Connettere l'uscita di Shift-L all'ingresso di Line-B Abbiamo cos creato una serie di linee che connettono la lista di punti (non traslati) della circonferenza inferiore agli stessi punti (traslati) della circonferenza superiore. Possiamo cambiare il valore dello slider numerico che controlla lo Shift Offset per vedere le linee che si modificano seguendo la traslazione dei punti appartenenti alle due circonferenze
o o

8.4 Esportare Dati su Excel Ci sono molte situazioni in cui diventa utile esportare dati da Grasshopper per poi importarli in altri software per analisi approfondite. Nota: Per vedere la definizione dell'esempio seguente, Apri il file Stream Contents_Excel.ghx situato nella cartella Source Files che accompagna questo documento.

Per partire abbiamo trascinato un componente Range (Logic/Sets/Range) nello spazio di lavoro, settandone il dominio da 0.0 a 10.0. Cliccando con il tasto destro sull'ingresso RangeN, abbiamo settato il numero di steps a 100, in modo che la nostra uscita riporti 101 valori equamente spaziati tra 0.0 e 10.0.

47

Abbiamo poi trascinato un componente Graph Mapper (Params/Special/Graph Mapper) sullo spazio di lavoro. Cliccare con il tasto destro sul componente Graph Mapper per settare il Graph Type su Linear. Ora connettere l'uscita di Range-R all'ingresso del Graph Mapper. Come ultima cosa trascinare un componente pannello Post-it sullo spazio di lavoro e connettere l'uscita del Graph Mapper all'ingresso del pannello Post-it. Dal momento che la tipologia del Graph Mapper impostata in Linear, la lista restituita (visibile nel Post-it Panel) mostra un set di dati crescenti linearmente da 0.0 a 10.0. Se per clicchiamo con il tasto destro sul componente Graph Mapper e scegliamo come Graph Type il Square Root (radice quadratica), vedremo una nuova lista di dati ce rappresenta la funzione logaritmica.

Per esportare questa lista di dati dal Post-it Panel, dobbiamo semplicemente cliccare con il tasto destro sul pannello, e scegliere Stream Contents. Quando richiesto, indicare nome e ubicazione del file per salvarlo sull'hard disk. Nel nostro esempio salveremo il file nella posizione: C:/Tutorials/Exporting Data/Stream_Contents.csv. Esistono svariati tipi di file che possono essere usati per esportare dati, come file di testo (.txt), valori separati da virgola (.csv), files di dati (.dat) per citarne alcuni. Personalmente tendo a usare il formato valori separati da virgola (.csv) perch stato progettato per il contenimento di dati strutturati sottoforma di tabella, comunque molti formati possono essere importati in Excel. Ogni linea di dati nel formato CSV corrisponde a una linea di tabella. Su ogni linea, I campi sono a loro volta separati da virgole. Il nostro esempio possiede un solo valore per ogni linea, quindi non utilizzeremo le funzioni multi-colonna di questo formato, ma possibile la creazione di vaste quantit di dati, se questi sono esportati correttamente.

48

Possiamo ora importare I dati in Microsoft Excel 2007. Per prima cosa lanciamo l'applicazione e selezioniamo la categoria Data. Scegliere Get External Data from Text e trovare il file Stream_Contents.csv salvato sull'hard disk. Sarai ora guidato dal Text Import Wizard che ti porr alcune domande sul come tu voglia importare I dati. Assicurarsi che il bottone radiale Delimited sia selezionato, e procedere al passo 2.

Il secondo step del Text Import Wizard ci permette di definire quale tipologia di Delimitatori separer I nostri dati. Un Delimitatore un carattere (come una virgola o un punto) inserito in un file CSV che indica dove il dato debba essere spostato in una colonna adiacente. Dal

49

momento che in ogni linea del file CSV abbiamo solamente dati numerici, non necessitiamo di scegliere un particolare tipo di Delimitatore. Scegliere Next per procedere allo step 3.

Lo Step 3 del Text Import Wizard ci permette di definire come vogliamo che i dati siano formattati in Excel. Il metodo General converte le stringhe numeriche in numeri; Data converte tutti i valori in date (Giorno/Mese/Anno); tutti i valori rimanenti sono formattati come Testo. Per il nostro esempio scegliere General e cliccare Finish.

Verr ora richiesto da quale cella si voglia iniziare l'importazione dei dati. Noi useremo il valore di default, ovvero cella A1. Vediamo quindi 101 valori nella colonna A che corrispondono a quelli riportati nel pannello Post-It di Grasshopper. La definizione di Grasshopper un flusso continuo di dati, perci ogni cambiamento che faremo alla lista di dati andr automaticamente ad aggiornare il file CSV. Tornare a Grasshopper e cambiare il tipo di Graph Mapper in Sine. Notare il cambiamento dei dati nel Pannello Post-it.

50

Tornare a Microsoft Excel e, sotto al menu Data, prestare attenzione al tasto Refresh All. Premere il tasto e, quando richiesto, scegliere il file CSV precedentemente aperto in Excel. La lista di dati nella colonna A verr cos aggiornata. Ora selezionare le celle dalla A1 alla A101 e cliccare il menu Insert nella parte alta. Ora cliccare Grafico a linea e selezionare la prima icona Grafico a linea 2D.

Vedrai un grafico a linea che riflette la stessa forma mostrata dal componente Graph Mapper in Grasshopper. Potete fare quante modifiche vogliate in Grasshopper, e dopo avere cliccato Refresh All, vedrete i cambiamenti riportati su Excel.

51

52

9 Informazioni di base sui Vettori


Dalla fisica, sappiamo che un vettore un oggetto geometrico che possiede lunghezza, direzione e senso (orientamento lungo la direzione). Un vettore spesso rappresentato con un segmento di retta con una direzione definita(per mezzo di una freccia), che connette un punto iniziale A con un punto finale B. L'ampiezza del vettore data dalla sua lunghezza e la direzione indica lo scostamento di B rispetto ad A: di quanto si deve "spostare" A per portarlo a B.

In Rhino, i vettori sono indistinguibili dai punti. Sono entrambi rappresentati come terne di numeri decimali, dove ogni variabile rappresenta le coordinate X, Y e Z dello spazio Cartesiano. L'unica differenza che i punti sono rappresentati in modo assoluto, mentre i vettori in modo relativo. Quando abbiamo a che fare con un array (schiera) di di tre coordinate come punto, esso rappresenta le coordinate spaziali del punto rispetto all'origine degli assi cartesiani. Quando invece si tratta di un array di vettore, esso rappresenta una direzione. I vettori sono considerati relativi, perch indicano solo la differenza (di coordinate) tra punto iniziale e punto finale della freccia, vale a dire i vettori non sono vere entit geometriche, ma solo informazione. Ci significa che in Rhino non viene creato alcun oggetto visibile, ma possiamo comunque usare l'informazione associata al vettore per guidare alcune operazioni di trasformazione sulle geometrie reali, come spostamento, rotazione, ecc.

53

Nell'esempio mostrato sopra, creiamo prima un punto all'origine 0,0,0 usando il componente Point XYZ (Vector/Point/PointXYZ). Poi connettiamo l'output Pt del Point XYZ all'input G di un componente Move, per spostare il punto in qualche altro posto. Per farlo, trasciniamo sul canvas un componente UnitX, un UnitY e un UnitZ (Vector/Constant). Ognuno di questi componenti specifica una direzione sugli assi ortogonali X,Y e Z del sistema di riferimento (spazio Cartesiano). Possiamo definirne l'ampiezza, collegando all'input di ciascuno uno slider. Tenendo premuto il tasto Shift siamo in grado di connettere i tre output di ciascuna unit vettoriale all'input T del componente Move. Se controlli nel viewport di Rhino, vedrai un punto all'origine 0,0,0 ed altri tre nuovi punti, uno per asse. Prova a cambiare i valori degli slider per vedere lo spostamento (cambio di ampiezza) del vettore. Per dare un'immagine visiva del vettore, come quando si disegna una freccia, possiamo creare un segmento di linea che congiunge l'origine con ciascuno dei tre nuovi punti. Per farlo, trascina sul canvas un componente Line (Curve/Primitive/Line). Connetti l'output G del Move all'input A del Line e l'output Pt del Point XYZ all'input B del Line. Qui sotto puoi vedere il risultato in Rhino.

Nota: Per vedere la definizione completa di questo esempio, Apri il file Unit Vectors.ghx che trovi nella cartella Source Files allegata a questo tutorial.

54

9.1 Manipolazione di Punti/Vettori


Componente Posizione Descrizione Esempio

Vector/Point/Distance

Calcola la Distanza tra due punti (input A e B)

Vector/Point/Decompose

Scompone un punto nei suoi componenti X, Y eZ

Vector/Vector/Angle

Calcola l'angolo tra due vettori Output reso in Radianti

Vector/Vector/Length

Calcola la lunghezza(ampiezza) del vettore

Vector/Vector/Decompose

Scompone un vettore nelle sue componenti X,Y,Z

Vector/Vector/Summation

Somma due vettori e ne calcola la risultante: primo vettore su input A, secondo su input B

Vector/Vector/Vector2pt

Crea un vettore da due punti definiti

Vector/Vector/Reverse

Inverte di segno tutte le componenti del vettore per invertire la direzione. L'ampiezza resta uguale

Divide tutte le componenti per l'inverso della lunghezza del vettore. Il vettore risultante ha Vector/Vector/Unit Vector lunghezza unitaria 1.0 e viene definito Unit Vector. Questa operazione si chiama a volte Normalizzazione Vector/Vector/Multiply Moltiplica le componenti del vettore per un fattore specificato

55

9.2 Uso della Matematica dei Vettori con i Punti Attrattori (scalare cerchi) Adesso che sappiamo qualcosa sulla matematica dei vettori e delle grandezze scalari, diamo un'occhiata ad un esempio che scala una griglia di cerchi in modo proporzionale alla distanza tra il centro di ciascun cerchio ed uno o pi punti.

Nota: Per vedere la definizione completa di questo esempio, Apri il file Attractor_2pt_circles.ghx che trovi nella cartella Source Files allegata a questo tutorial. Sopra un'immagine della definizione che genera la serie di cerchi scalati qui sotto.

56

Per creare la definizione da zero:


Params/Special/Numeric Slider - trascina sul canvas tre slider Taso Dx su tutti per impostare: - Slider Type: Integers - Lower Limit: 0.0 - Upper Limit: 10.0 - Value: 10.0 Vector/Point/Grid Rectangular - trascina sul canvas un componente Rectangular Point Grid Connetti il primo slider all'input X del Pt Grid Connetti il secondo slider all'input Y del Pt Grid Connetti il terzo slider all'input S del Pt Grid Il Rectangular Point Grid crea una griglia di punti che ha origine, attraverso l'input P, in 0,0,0 (default). Il componente crea il numero di punti, lungo l'asse X e l'asse Y, specificato dai rispettivi slider, che abbiamo impostato entrambi a 10. Se conti le file e le colonne, vedrai che ce ne sono 20 su ciascun asse. Questo succede perch il componente crea la griglia a partire da un punto centrale che viene copiato in entrambi i sensi lungo l'asse il numero di volte specificato dallo slider. L'input S specifica la distanza a cui il punto viene copiato ogni volta dal precedente. Params/Geometry/Point - trascina sul canvas un componente Point Questo componente considerato di tipo implicito perch usa dati permanenti come input (vedi il capitolo 4 per maggiori informazioni sui dati permanenti). Questo componente diverso da quello che abbiamo usato finora (Point XYZ), perch non crea un punto in Rhino, bens referenzia un punto gi esistente, che ovviamente deve gi essere stato creato. Questo sar il nostro punto attrattore. In ambiente Rhino, digita Point sulla riga di comando ( o usa la specifica icona sulla barra degli strumenti) e piazzalo dove ti pare. Nel nostro caso lo creiamo nella vista Top, in modo che sia sul piano XY. Ora che abbiamo creato il punto attrattore, possiamo referenziarlo al componente Point che abbiamo in GH Tasto Dx sul componente Point e seleziona "Set One Point" Sparisce GH e sei invitato a selezionare il punto in Rhino A questo punto abbiamo creato una griglia di punti e referenziato un punto attrattore. Possiamo usare un poco di matematica vettoriale per determinare la distanza di ciascun punto della griglia dal punto attrattore. Vector/Point/Distance - trascina sul canvas un componente Distance Connetti l'outpunt del Point attrattore all'input A del componente Distance Connetti l'output G del Grid all'input B del componente Distance

57

La prima parte della nostra definizione dovrebbe avere questo aspetto. Se ci soffermiamo con il mouse supra ciascun output D del Distance vedremo una lista di numeri che corrispondono alla distanza dal punto attrattore. Useremo questi valori per pilotare il raggio dei cerchi, ma prima dobbiamo scalarle questi numeri per ottenere delle dimensioni dei cerchi pi approppriate. Scalar/Operator/Division - trascina sul canvas un operatore Division Connetti l'output D di Distance all'input A di Division Params/Special/Numeric Slider - trascina sul canvas uno slider Tasto Dx ed imposta i seguenti parametri: - Name: Pt Attrazione - Slider Type: Floating Point - Lower Limit: 0.0 - Upper Limit: 100.0 - Value: 25.0 Connetti lo slider all'input B del Division Dal momento che i valori di distanza erano assai grandi, ci serve un fattore di scala per riportarli a dimensione pi congrua. Usiamo lo slider per dosare questo fattore in modo da ottenere un secondo set di valori per il raggio dei cerchi. Potremmo usare questo set direttamente come input di un componente Circle, ma per rendere la nostra definizione un p pi robusta, possiamo usare ancora la matematica scalare per limitare l'effetto della distanza. Ci significa definire una dimensione massima dei cerchi accettabile, all'aumentare della loro distanza dal punto attrattore. Scalar/Utility/Minimum - trascina sul canvas un componente Minimum Connetti l'output R del Division all'input A del Minimum Parms/Special/Numeric Slider - trascina uno slider sul canvas Tasto Dx ed imposta i seguenti parametri: - Name: Attenuazione - Slider Type: Floating Point

For plugin version 0.6.0007

58

- Lower Limit: 0.0 - Upper Limit: 30.0 - Value: 5.0 Connetti lo slider Attenuazione all'input B del Minimum Curve/Primitive/Circle CNR - trascina sul canvas un Circle CNR (Centro, Normale, Raggio) Vogliamo che il centro di ogni cerchio coincida con ciascuno dei punti della griglia. Connetti l'output G del Rectangulat Point Grid all'input C del Circle (parametro posizione) Connetti l'output R di Minimum all'input R di Circle (parametro raggio) Tasto destro sul componente Rectangular Point Grid e disattiva la sua Preview

La tua definizione dovrebbe essere cos. Abbiamo dunque creato un set di cerchi la cui dimensione varia in funzione della distanza del loro centro da un punto attrattore. Che succederebbe se volessimo aggiungerne un secondo? Giacch abbiamo gi la definizione per un punto attrattore, dobbiamo semplicemente copiare ed incollare un certo numero di componenti, per attivare il secondo. Seleziona (con finestra o tenendo premuto Shift) i seguenti componenti: Pt attrattore, Distance, gli slider Attrazione e Attenuazione, il Minimum e premi Ctrl+C (copia), poi Ctrl+V (incolla) per duplicarli

Sposta i componenti duplicati un poco sotto, in modo che non siano sovrapposti agli originali

59

Dobbiamo referenziare un secondo punto attrattore, naturalmente dopo averlo creato in Rhino. In Rhino digita "Point" nella riga di comando e piazza un punto dove vuoi, sempre sul viewport Top come prima, in modo che sia sul piano XY. Tasto Dx sul duplicato Point e seleziona "Set One Point" Sparisce la finestra GH e vi si chiede di selezionare il punto in Rhino. A questo punto abbiamo due gruppi di componenti ognuno dei quali calcola la distanza di una griglia rettangolare di punti da ciascun attrattore e ce la rende disponibile per controllare il diametro dei cerchi incentrati su quella griglia. Dobbiamo combinare i due flussi di informazione che escono dai componenti Minimum in un'unica lista. Per farlo usiamo un componente scalare Addition. Scalar/OPeration/Addition - trascina sulla griglia un componente Addition Connetti l'output R del primo Minimum all'input A del componente Addition Connetti l'output R del secondo Minimum all'input B di Addition Ora, connetti l'output R di Addition all'input R di Circle (Nota:questa connessione va a sostituire quella esistente)

Se completata correttamente, la tua definizione dovrebbe apparire cos. Noterai che ho eliminato uno degli slider Attenuazione e controllo entrambi i Minimum con lo stesso slider. Gioca un poco con gli slider Attrazione ed Attenuazione, per sistemare secondo i tuoi gusti il diametro dei cerchi scalato per la distanza.

Nota: Per vedere un video tutorial di questo esempio, visita il blog di David Fano al: http://designreform.net/2008/07/08/grasshopper-patterning-with-2-attractor-points/

60

9.3 Utilizzo della Matematica Vettoriale e Scalare con i Punti Attrattori (scalatura di cubi) Abbiamo gi visto come poter usare la matematica vettoriale e scalare per regolare il diametro di cerchi in relazione alla loro distanza da alcuni punti, ma possiamo sostanzialmente usare gli stessi componenti per per scalare degli oggetti o per definirne la colorazione per mezzo dei componenti Shader di GH. La definizione mostrata qui sotto stata usata per generare l'immagine successiva, ma cominciamo dall'inizio e costruiamo la definizione un passo alla volta.

Nota: Per vedere la definizione completa di questo esempio, Apri il file Color Boxes.ghx che trovi nella cartella Source Files allegata a questo tutorial.

Prima parte: Comincia con il creare una griglia tridimensionale

For plugin version 0.6.0007

63

61

Params/Special/Numeric Slider - trascina sul canvas 2 slider Tasto Dx sul primo e imposta questi parametri: Slider Type: Integer Lower Limit: 0.0 Upper Limit: 10.0 Value: 3.0 Tasto Dx sul secondo e imposta questi parametri: Slider Type: Floating Point Lower Limit: 0.0 Upper Limit: 25.0 Value: 25.0 Vector/Point/Grid Rectangular - trascina sul canvas un componente Grid Connetti il primo slider ad ENTRAMBI gli input X e Y del Grid Connetti il secondo slider all'input S del Grid

Nota del traduttore: nelle versioni di GH successive alla 0.6.0007, alcuni componenti, la loro collocazione nei tab ed il loro comportamento sono cambiati. Per questo alcune delle spiegazioni possono risultare non pi attuali o applicabili. Eventuali cambi nella logica di comportamento sono evidenti al primo impiego. Dovresti vedere in Rhino una griglia di punti, dove il primo slider controlla il numero di punti sia nella direzione dell'asse X che nella direzione dell'asse Y (ricordati che il numero di righe e colonne risulta essere doppio del valore impostato, perch l'operazione parte da un punto centrale e procede in entrambi i sensi). La distanza tra i punti controllata dal secondo slider. Ci resta da copiare questa griglia bidimensionale sull'asse Z per ottenerne una tridimensionale. Logic/Set/Series - trascina sul canvas un componente Series Connetti il secondo slider all'input N di Series Connetti il primo slider all'input C di Series Il nostro componente Series conter il numero dicopie della griglia XY che faremo in Z; tuttavia avrai notato che i conti non tornano. Come spiegato in precedenza, la griglia XY stata creata a partire da un punto centrale in entrambi i sensi, sicch pur avendo il primo slider impostato a 3, abbiamo ottenuto realmente 7 righe e 7 colonne. Se vogliamo avere una griglia cubica, dobbiamo dunque creare altre 6 copie della griglia XY originale. Per avere questo risultato, dobbiamo scrivere una semplice formula per raddoppiare il conteggio di Series. Tasto Dx sull'input C di Series e vai gi fino alla riga Expression Nell'editor , digita la seguente espressione: (C*2)+1 Abbiamo cos specificato che l'input a C deve essre moltiplicato per 2 ed il risultato incrementato di 1. Poich l'impostazione 3, il conteggio finale sar 7, ci che ci serve.
Vector/Connstants/Unit Z - trascina un componente Unit Z sul canvas Connetti l'output S di Series con l'input F di Unit Z Se ti soffermi con il mouse sopra l'output V di Unit Z, vedrai che abbiamo in uscita 7 valori locali, il cui incremento dall'uno all'altro di 25, il valore impostato sul secondo slider. Useremo questo valore vettoriale per fissare la distanza dall'originale delle copie di griglia XY in Z.

X Form/Euclidean/Move - trascina un componente Move sul canvas Connetti l'output G di Grid all'input G di Move Connetti l'output V di Unit Z all'input T di Move

Se osservi ci che successo in Rhino, vedrai che i nostri punti non sembrano

62

affatto una griglia cubica. Assomigliano pi ad una rampa che sale verso un piano di punti. Ci dovuto al fatto che l'algoritmo di combinazione dei dati di default impostato su "Longest List". Se selezioni con tasto Dx il componente Grid, puoi impostare invece "Cross Reference". Se guardi adesso i punti sembrano davvero una griglia regolare a tre dimensioni (Torna al Capitolo 6 per informazioni su Combinazione di flussi di dati).
Surface/Primitive/Center Box - trascina un componente Center Box sul canvas Connetti l'output G di Move con l'input B di Center Box Tasto Dx sui componenti Grid e Move ed annullane la Preview

Qui sotto un'immagine di come dovrebbe essere la prima parte della nostra definizione.

Seconda Parte: Applicare la Matematica Vettoriale e Scalare


Params/Geometry/Point - trascina sul canvas un componente Point Selezionalo con tasto Dx e rinominalo come "Attrattore" Come nell'esempio dei cerchi scalati, dovremo referenziare il Point ad un punto reale in Rhino, per cui prima generiamolo. In Rhino, digitiamo "Point" sulla riga di comando e posizioniamolo dove ci pare Torniamo a GH, tasto Dx su Attrattore e seleziona "Set One Point" Sparisce la finestra Gh e vieni invitato a selezionare il punto in Rhino Dovresti adesso vedere una crocetta, per confermare che hai referenziato l'Attrattore a quel punto. Se muovi il punto Rhino, vedrai che la crocetta GH lo segue. Vector/Point/Distance -trascina sul canvas un componente Distance Connetti l'output Pt di Attrattore all'input A di Distance Connetti l'output G di Move all'input B di Distance Se ti soffermi con il mouse sopra l'output d di Distance, vedrai una lista di valori numerici indicanti la distanza di ciascun punto della griglia da Attrattore. Per poterli usare come fattore di scala per i nostri cubi, dovremo dividerli per un certo valore, per renderli proporzionati nel nostro esempio.

63

Scalar/Operators/Division - trascina un componente Division sul canvas Connetti l'output D di Distance all'input A di Division Params/Special/Numeric Slider - trascina sul canvas uno slider Tasto Dx sullo slider ed imposta: - Name: Fattore Scala - Slider Type: Integer - Lower Limit: 0 - Upper Limit: 25 - Value: 25 Connetti Fattore Scala all'input B di Division XForm/Affine/Scale - trascina sul canvas un componente Scale Connetti l'output B di Center Box all'input G di Scale Connetti l'output R di Division all'input F di Scale Tasto Dx su Center Box e disattiva la Preview Qui sotto un'immagine della definizione fin qui. Se guardi in Rhino, dovresti vedere che tutti i nostri cubetti sono stati scalati proporzionalmente alla loro distanza dal punto attrattore. Possiamo andare ancora oltre aggiungendo il colore per evidenziare meglio il processo di scalatura progressiva.

Terza Parte: Associare una gradazione di colore ai cubetti

Logic/List/Sort List - trascina sul canvas un componente Sort List Per associare un codice di colore basato sulla distanza di ciascun cubetto dall'attrattore, dobbiamo conoscere due informazioni: la distanza minore e quella maggiore. Dobbiamo quindi riordinare dal minore al maggiore tutti i valori di distanza, per poter prendere il primo e l'ultimo della lista. Logic/List/List Item - trascina sul canvas un componente List Item Connetti l'output L di Sort List all'input L di List Item Tasto Dx sull'input i di List Item ed imposta il valore Integer a 0 Questo ha l'effetto di prendere dalla lista il primo valore, cio quello della distanza minore Logic/List/List Length - trascina sul canvas un componente List Length Connetti loutput L di Sort List all'input L di List Length

64

Il componente List Length ci dice quante voci ci sono nella nostra lista, in modo che possiamo usare questo dato in un secondo List Item per beccare l'ultima voce. Logic/List/List Item - trascina sul canvas un altro List Item (o Copia/Incolla quello esistente) Connetti l'output L di List Length all'input i del secondo List Item Se ti soffermi con il mouse sopra l'output E del secondo List Item, vedrai che il componente non ha affatto beccato l'ultimo valore della lista, perch GH archivia i valori a partire dalla posizione 0, per cui una lista di 100 valori non finisce con il numero 0 ma con 99. Dobbiamo quindi aggiungere una piccola espressione, che tiene conto di questa particolarit (che ha una sua logica) e sottrae 1 dalla lunghezza della lista (output di List Length). Tasto Dx sull'input i del secondo List Item ed apri Espression Editor Nella finestrella di dialogo, scrivi questa equazione: i-1 Ora, se guardi l'output E, vedrai un valore numerico che corrisponde alla massima distanza di un cubetto dall'attrattore. Parms/Special/Gradient - trascina sul canvas un componente Gradient Connetti l'output E del primo List Item (quello della distanza minore) all'input L0 di Gradient Connetti l'output E del secondo List Item (quello della distanza maggiore) all'input L1 di Gradient L'input L0 determina qual' il valore numerico inferiore della sfumatura di colore, nel nostro esempio la colorazione della parte sinistra di Gradient corrisponder alle distanze minori. L'input L1 invece determina il valore numerico superiore della sfumatura di colore, nel nostro caso la colorazione della parte destra di Gradient corrisponder alle distanze maggiori. L'input t di Gradient rappresenta la lista di valori che desideri mappare sull'intera estensione della sfumatura. Abbiamo deciso di usare tutti i valori del fattore di scala, in modo che ciascun blocchetto abbia un suo proprio colore all'interno dei limiti del gradiente. Vector/Color/Create Shader - trascina un componente Create Shader sul canvas Connetti l'output di Gradient all'input Kd di Create Shader Il componente shader ha un certo numero di input per aiutarti a definire come vuoi che appaia la tua opera. Qui sotto, una breve descrizione di ci che fa ciascun input ed il suo effetto: Kd: stabilisce il valore di Diffuse Color. In pratica il codice del colore primario dell'oggetto, definito da tre numeri interi compresi tra 0 e 255, che rappresentano il Rosso, il Verde ed il Blu nel sistema codificato RGB (in binario questi 256 valori sono racchiusi in 8 bit, curioso?) Ks: stabilisce il valore di Specular Highlight (colorazione accentuata?), definito anch'esso da tre valori interi della codifica RGB Ke: stabilisce il valore di Emissivity, ovvero il colore di auto-illuminazione dello shader T: stabilisce il livello di Transparency (trasparenza) dello shader S: stabilisce il valore di Shininess (brillantezza, riflettanza) dello shader, dove il valore 0 indica che l'oggetto non riflette, mentre il valore 100 indica che l'oggetto ha massima riflettanza

65

Abbiamo connesso lo slider del gradiente all'input Diffuse del componente Shader in modo che il colore primario dei nostri cubetti sia rappresentato da una scala graduata di colore. Puoi cambiare i colori della scala graduata selezionando uno dei piccoli cerchietti bianchi nell'area di Gradient, per cambiare il valore Color In e quello Color Out, oppure trascinarli a destra ed a sinistra per cambiare le proporzioni tra i vari calori. In aggiunta, ci sono alcuni set precostituiti in Gradient che puoi attivare con il tasto Dx, selezionandone uno. Il nostro esempio usa il preset Spectrum. Parms/Special/Custom Preview - trascina sul canvas un componente Custom Preview Connetti l'output G di Scale all'input G di Custom Preview Connetti l'output S si Shader all'input S di Custom Preview Tasto Dx su Scale e disattiva il suo preview Qui sotto un'immagine della definizione completa dopo la terza parte. Se muovi in Rhino il punto attrattore, vedrai che sia la dimensione che il colore dei blocchetti si aggiorna.

66

10 Tipi di Curve
Dal momento che le curve sono oggetti geometrici, possiedono un certo numero di caratteristiche o propriet che possibile usare per descriverle ed analizzarle. Ad esempio, ogni curva ha una coordinata di inizio ed una di fine. Quando la distanza tra queste due coordinate nulla, la curva chiusa. Inoltre, ogni curva ha un certo numero di punti di controllo, se tutti questi punti giacciono sullo stesso piano (vale a dire hanno tutti una delle tre coordinate uguale), l'intera curva planare. Alcune propriet si applicano alla curva nel suo insieme, altre solo a posizioni specifiche della curva. Ad esempio, la planarit una propriet globale della curva, mentre la tangenza una propriet locale. Ancora, alcune propriet sono applicabili solo a certi tipi di curva. Per adesso abbiamo analizzato solo alcuni dei componenti GH di Curve Originali, quali: rette, cerchi, ellissi ed archi.

Grasshopper possiede anche una serie di strumenti adatti a descrivere tipi pi complessi di curve Rhino., quali le Nurbs e le curve composite. Pi oltre troverai un esempio che ti guider attraverso la conoscenza di alcuni dei Componenti Spline di GH, ma dovremo creare un set di punti che definiranno il controllo della curva.

Nella cartella Source Files a corredo di questo manuale, Apri il file Curve Types.3dm. Vi troverai 6 punti piazzati sul piano XY. Li ho numerati da Sx a Dx come nell'immagine sopra, perch For plugin version 0.6.0007 questo sar l'ordine in cui dovranno essere selezionati nella procedura di GH.

67

file Curve Types.ghx sempre nella stessa cartella Source Files. Vedrai un componente Point connesso a diversi componenti Curve, ognuno dei quali controlla la curva con un metodo diverso. Analizzeremo ad uno a d uno i componenti, ma prima dobbiamo referenziare i punti di Rhino al nostro componente Point in GH. Per farlo, tasto Dx sul Point in Gh e seleziona l'opzione Set Multiple Points. La finestra GH sparisce e sei invitato a selezionare ciascuno dei punti, facendo attenzione a farlo nell'ordine in cui sono numerati, da Sx a Dx. Man mano che selezioni i punti, una connessione implicita di colore blu confermer la selezione. Dopo aver selezionato i 6 punti, conferma con Invio per tornare a GH. Tutti i 6 punti avranno una crocetta rossa, ad indicare che sono stati referenziati ad un componente Grasshopper. A) Curve NURBS (Curve/Spline/Curve)

Le Non-Uniform-Rational-Basic-Splines, o NURBS, sono uno dei molti tipi di definizione disponibili in Rhino. In aggiunta ai punti di controllo che servono a guidare la curva (i sei punti selezionati in Rhino come referenze), le curve NURBS hanno altre propriet come grado, vettori di nodo e peso di nodo. Sono stati scritti tomi ponderosi (o almeno lunghi trattati) per spiegare la matematica sottesa a questa entit, pertanto non mi dilungher sulla materia. Se tuttavia vuoi saperne di pi, vai al sito: http://en.wikipedia.org/wiki/NURBS L'input V di Curve specifica i punti di controllo, che possono essere descritti implicitamente

68

selezionando dei punti esistenti da Rhino, oppure ottenuti per eredit di dati temporanei da altri componenti. L'input D di Curve stabilisce il grado della curva. Il grado di una curva sempre un intero positivo tra 1 e 11, entrambi inclusi. Sostanzialmente, il grado di una curva regola l'estensione di influenza di ciascun punto di controllo sull'andamento della curva; maggiore il grado, maggiore l'estensione dell'influenza del punto. La tavola nella pagina seguente dal manuale di David Rutten, Rhinoscript 101, illustra come la variazione di grado influisce sulla curva risultante. pag75(69)

Nel nostro esempio, abbiamo connesso uno slider all'input D di Curve, in modo da poter variare il grado della nostra curva. Trascinando il cursore verso Dx e Sx possiamo vedere in diretta la variazione dell'influenza dei punti e di conseguenza della forma della curva. L'input P di Curve usa un valore booleano per stabilire se la curva debba essere periodica o meno. Un valore False genera una curva NURBS aperta, mentre un valore True ne crea una chiusa. I tre output del componente Curve sono abbastanza autoesplicativi; l'output C rappresenta l'entit curva, l'output L ne fornisce la lunghezza, infine l'output D specifica il dominio della curva (ovvero l'intervallo tra 0 ed il valore numerico del grado della curva). B) Curve Interpolate (Curve/Spline/Interpolate)

Le curve interpolate si comportano in modo leggermente diverso dalle curve NURBS, perch

69

passano esattamente dai punti di controllo. Come sapete, assai difficile far passare una NURBS da coordinate specifiche. Anche se spostiamo a mano ad uno ad uno ciascun punto di controllo, estremamente difficile riuscire a far passare la curva esattamente da una coordinata stabilita. Eccoti qui dunque, Curva Interpolata. L'input V di Interpolate simile a quello di Curve, richiedendo un set di punti per creare la curva. Tuttavia con il metodo della Curva Interpolata, la curva generata passa proprio da quei punti , indipendentemente dal suo grado. pag76(70) Nel componente (NURBS)Curve, siamo riusciti a far questo solo ponendo il grado a 1. Analogamente al componente Curve, l'input D di Interpolate specifica il grado della curva risultante. Con questo metodo per si possono assegnare come input su D solo interi dispari tra 1 e 11, perci impossibili generare una curva Interpolata di grado 2. L'input P come prima specifica se la curva Periodica o aperta. Credo che stia diventando evidente un pattern prevedibile negli output di molti tipi di curva, poich C, L e D generalmente specificano rispettivamente per l'entit geometrica, la lunghezza ed il dominio. C) Curve Spigolo (Curve/Splines/Kinky Curve)

Nonostante il suo nome, una curva spigolo altro non che una Curva Interpolata particolare. Possiede gran parte delle caratteristiche spiegate nel paragrafo precedente, con un'unica piccola differenza. Il componente Curva Spigolo ti permette di decidere uno specifico angolo limite oltre il quale essa passer da spigolosa a morbida. Abbiamo connesso uno slider all'input A del componente Kinky Curve per vedere in tempo reale la variazione dell'angolo limite ed il conseguente effetto sulla curva. Nota che l'input di A deve essere in Radianti. Nel nostro esempio, c' un'equazione che converte il valore dell'input A, espresso in gradi, in radianti (rad=360/2Pi greco). D) Curve Polilinea (Curve/Spline/Polyline) Una polilinea forse la curva pi adattabile ed universale di Rhino. Infatti essa costituita da segmenti di retta, segmenti di polilinea, curve NURBS di grado1, o la combinazione tra questi tipi. Specifichiamone i fondamentali. In sostanza, una polilinea come una schiera di punti. L'unica differenza che noi consideriamo i punti della polilinea come una serie, il che ci consente di tracciare una linea

70

sequenziale tra di essi. Come menzionato, una curva NURBS di grado 1 si comporta a tutti gli effetti come una polilinea. dal momento che una polilinea una collezione di segmenti di retta che uniscono due o pi punti, la curva risultante passer sempre attraverso i suoi punti di controllo, rendendola simile in qualche modo alla curva interpolata. Come i tipi di curve visti finora, l'input V di Polyline specifica un set di punti che pag77(71) costituiscono gli estremi dei segmenti componenti la polilinea. L'input C di Polyline stabilisce se essa aperta o chiusa. Nel caso il valore booleano sia True, quando la coordinata del primo punto non coincide con quella dell'ultimo, verr automaticamente creato un ultimo segmento che unisce questi due punti. L'output di Polyline leggermente diverso da quello degli esempi precedenti, perch l'unico risultato la polilinea stessa. Devi usare uno degli altri componenti di analisi delle curve di GH per ricavare altri attributi di Polyline.

E)Poli-Arco (Curve/Spline/Poly Arc)

Una Poly Arc praticamente identica per natura alla Polyline, eccetto che, invece di segmenti di retta, usa una serie di archi che connettono i punti. Poly Arc univoca, nel senso che calcola la tangenza richiesta in ciascun punto per ottenere una curva fluida, dove il passaggio tra un arco e quello successivo privo di variazioni brusche. Non ci sono altri input, oltre alla serie di punti iniziale, e l'unico output la curva risultante.

71

10.1 Analisi dell Curve Sarebbe molto complesso creare un tutorial che copra tutto lo spettro degli strumenti di analisi disponibili in Grasshopper, perci ho incluso una tavola che illustra un buon numero dei componenti pi usati.
Component Posizione Descrizione Esempio

Curve/Analysis/Center

Trova il centro ed il raggio di archi e cerchi

Curve/Analysis/Closed

Controlla se la curva chiusa o periodica

Curve/Analysis/Closest Point

Trova il punto pi vicino appartenente alla curva rispetto ad un punto dato

Curve/Analysis/End Points Ricava le coordinate degli estremi della curva

Curve/Analysis/Explode

Scompone la curva nei suoi elementi

Curve/Utility/Join Curves

Unisce tutti i segmenti di curva possibili

Curve/Analysis/Length

Computa la lunghezza di una curva

Curve/Division/Divide Curve

Divide la curva in parti di uguale lunghezza

Curve/Division/Divide Distance

Distribuisce sulla curva punti a distanza prededefinita

72

Curve/Division/Divide Length

Divide la curva in segmenti di lunghezza predefinita

Curve/Utility/Flip

Inverte il senso di una curva, usando opzionalmente una curva guida

Curve/Utility/Offset

Offsetta una curva a distanza specificata

Curve/Utility/Fillet

Raccorda gli spigoli di una curva con raggio impostato

Curve/Utility/Project

Proietta la curva su una BRep (un set di superfici unite simile alla poli-superficie di Rhino)

Intersect/Region/Split with BRep(s)

Spezza una curva con una o pi BRep

Taglia una curva con una o pi BRep. Gli Intersect/Region/Trim with output Ci (Curva interna) e Co (Curva esterna) BRep(s) specificano quello che vuoi tenere della curva Taglia una curva con uno o pi profili planari chiusi. Gli output Ci (Curva interna) e Co (Curva esterna) specificano quello che vuoi tenere della curva

Intersect/Region/Trim with Region(s)

Intersect/Boolean/Region Computa il profilo di unione di due o pi curve Union chiuse planari

Intersect/Boolean/Region Intersection

Computa il profilo comune di intersezione di due o pi curve chiuse planari

73

Intersect/Boolean/Region Difference

Computa il profilo di differenza tra due o pi curve chiuse planari

11 Tipi di Superficie*
A parte alcuni tipi di superfici primitive come la sfera, il cono, i piani ed i cilindri, Rhino supporta tre tipologie di superfici free form (a forma libera), di cui il pi usato la NURBS. Analogamente a quanto succede per le curve, qualsiasi forma di superficie pu essere rappresentata con una NURBS e questo il metodo di default di Rhino. Si tratta anche della definizione di superficie di gran lunga pi utile e di quella su cui ci concentreremo pi a lungo.

Le superfici NURBS sono molto simili alle curve NURBS. Per calcolare la forma, le normali, le tangenti le curvature ed altre propriet vengono usati gli stessi algoritmi, ma ci sono alcune differenze. Ad esempio, sulle curve si hanno vettori tangenti e piani normali(che formano un angolo di 90 con la curva nel punto di intersezione), mentre sulle superfici si hanno vettori normali e piani tangenti. Ci significa che alle curve manca orientazione, mentre alle superfici manca direzione. Questa una propriet generalizzata per qualsiasi curva e superficie e dovrai imparare a conviverci. Spesso, mentre scriverai codice che ha a che fare con curve o superfici, dovrai scegliere a caso orientamento e direzione ed a volte (molto pi spesso della media!!!) queste assunzioni si dimostreranno sbagliate. le superfici NURBS son griglie rettangolari di curve {U} e {V}. Anche se la loro direzione spesso arbitraria, finiamo per usarle ugualmente perch ci facilitano tanto la vita. Grasshopper trata le superfici
NURBS allo stesso modo in cui lo fa Rhino perch costruito sulle stesse operazioni di base necessarie a generare la superficie. Tuttavia, poich GH mostra una copia virtuale della sua superficie sovrapposta alla geometria nativa di Rhino (ragione per cui non puoi selezionarla fino a quando non attivi al sua creazione con il pulsante Bake), le impostazioni della mesh per la visualizzazione sono meno strette, in modo da mantenere la velocit di aggiornamento dei risultati ragionevolmente alta. Potrai vedere delle sfaccettature, ma solo il risultato di queste impostazioni in Grasshopper. Una volta "cotta", la geometria reale creata in For plugin version 0.6.0007 76 Rhino riprender per la visualizzazione le tue impostazioni di meshatura.

74

* Origine: Rhinoscript 101 by David Rutten http://en.wiki.mcneel.com/default.aspx/McNeel/RhinoScript101

Grasshopper tratta le superfici in due modi. Il primo, come abbiamo appena visto, attraverso l'uso di NURBS. In linea di massima tutti i componenti di Analisi della Superficie possono essere applicati alle entit NURBS, tipo calcolare l'area o la curvatura di una superficie. Questo calcolo, pur essendo pesante dal punto di vista computazionale, relativamente semplice, perch il computer non deve prendere in considerazione la terza dimensione di un volume, come profondit o spessore. Ed allora, come fa GH a lavorare sulle superfici tridimensionali? Beh, gli sviluppatori di McNeel ci hanno dato un contentino, creando un secondo metodo con cui possiamo controllare oggetti solidi allo stesso modo in cui lo faremmo in Rhino. Avanti con la BRep, ovvero Boundary Representation (descrizione del contorno limite). La BRep pu essere indifferentemente immaginata come un solido 3D o come una polisuperficie di Rhino. Si tratta comunque di un insieme di superfici NURBS, unite insieme a formare un oggetto solido pieno, mentre una superficie singola NURBS teoricamente non ha spessore. Dal momento che le BRep sono essenzialmente superfici NURBS unite tra loro, alcuni strumenti di analisi che funzionano per le NUBS potranno continuare a farlo per le BRep, altri invece no. Questo dovuto al fatto che Grasshopper corredato di un algoritmo di trasposizione che tenta di trasformare gli oggetti in input accettabili. Se un componente ha bisogno di una BRep come input e gli dai una superficie, essa verr trasformata in una BRep al volo. Lo stesso si applica al caso di Numeri ed Interi, Colori e Vettori, Archi e Cerchi. Ci sono persino alcune trasformazioni assai curiose, ad esempio: Curve diventa Number (esce la lunghezza della curva) Curve diventa Interval (esce il dominio della curva) Surface diventa Interval2D (esce il dominio UV della superficie) String diventa Number (computa la schiera, anche se si tratta di un'espressione completa) Interval2D diventa Number (esce l'area dell'Interval2D) Ci sono altre trasformazioni automatiche e sono in continuo aumento, man mano che il SW cresce. Dovresti avere un'infarinatura sufficiente per iniziare a trattare qualche esempio di operazioni con superficie.

75

11.1 Connetti alla superficie L'esempio che segue, creato da David Fano di Design Reform, un ottimo tutorial che mostra una gran variet di tecniche di manipolazione di superfici. In questo esempio tratteremo i componenti Swepp2Rail (superficie 2 binari), Surface Offset e Surface Division, per creare il modello mostrato sotto. Per iniziare, Apri in Rhino il file SurfaceConnect.3dm, che trovi nella cartella Source Files a corredo di questo manuale. Il file contiene 3 curve (due binari ed una curva di sezione) che ci forniscono gli elementi di partenza per l'esempio.

Nota: per vedere la definizione completa di questo esempio, Apri il file Grasshopper SurfaceConnect.ghx dalla solita cartella.

76

77

Per creare la definizione da zero: Surface/Free Form/Sweep2Rail - trascina sul canvas un elemento Sweep2Rail Tasto Dx sull'input R1 e seleziona l'opzione "Set one Curve" Sparisce la finestra GH e puoi selezionare la prima delle curve binario in Rhino (vedi immagine qui sopra) Tasto Dx sull'input R2 e seleziona l'opzione "Set one Curve" Sparisce la finestra GH e puoi selezionare la seconda delle curve binario in Rhino Tasto Dx sull'input S e seleziona l'opzione "Set one Curve" Puoi infine selezionare la curva di sezione trasversale Se le curve sono state selezionate nel giusto ordine, dovresti vedere in Rhino una superficie che si estende tra le tre curve Surface/Free Form/Offset - trascina sul canvas un elemento Offset Connetti l'output S di Sweep2Rail all'input S di Offset Params/Special/Number Slider - trascina sul canvas uno slider Tasto Dx sullo slider ed imposta: - Name: Offset - Slider Type: Floating Point - Lower Limit: 0.0 - Upper Limit: 10.0 - Value: 10.0 Connetti lo slider all'input D del componente Offset

78

Dovresti a questo punto vedere una seconda superficie spostata di 10 unit rispetto all'originale Surface/Utility/Divide Surface - trascina sul canvas due componenti Surface Divide Connetti l'output S di Sweep2Rail all'input S del primo Surface Divide Dovresti osservare immediatamente una griglia di punti sulla superficie originale. Questo perch i valori di default del componente Divide Surface sia per U che per V sono impostati a 10. Sostanzialmente Divide divide la superficie in 10 parti uguali in ciascuna direzione, creando una griglia regolare di punti sulla stessa. Se dovessi connetterli, ti ritroveresti con le "isocurve" che formano l'armatura interna della superficie. Connetti l'output S di Surface Offset con l'input S del secondo Divide Surface Un analogo set di punti appare sulla superficie di offset. Params/Special/Number Slider - Trascina sul canvas due slider Tasto Dx sul primo ed imposta: - Name: Divisioni U - Slider Type: Integer - Lower Limit: 0 - Upper Limit: 100 - Value: 15 Tasto Dx sul secondo ed imposta: - Name: Divisioni V - Slider Type: Integer - Lower Limit: 0 - Upper Limit: 100 - Value: 25 Connetti lo slider Divisioni U agli input U di entrambi i componenti Divide Surface Connetti lo slider Divisioni V agli input V di entrambi i componenti Divide Surface I due slider adesso controllano (disattivando temporaneamente il dato permanente di default) il numero di divisioni in ciascuna direzione di entrambe le superfici. Poich esse hanno lo stesso numero di divisioni, ogni loro punto corrispondente avr lo stesso numero di indice, il che ci consente di creare tra ogni coppia di punti una linea, connettendo le due superfici. Curve/Primitive/Line - trascina un componente Line sul canvas Connetti l'output P del primo Divide Surface all'input A di Line Connetti l'output P del secondo Divide Surface all'input B di Line E' cos facile! Adesso dovresti vedere una serie di segmenti che vanno dalla prima alla seconda superficie in corrispondenza dei punti. Possiamo andare oltre e dare alle linee un p di sostanza. Surface/Free Form/Pipe - trascina sul canvas un componente Pipe Connetti l'output L di Line all'input C di Pipe Params/Special/Number Slider - trascina sul canvas un Number Slider Tasto Dx sullo slider ed imposta: - Name: Raggio tubo - Slider Type: Floatin Point - Lower Limit: 0.0 - Upper Limit: 2.0 - Value: 0.75 Connetti lo slider Raggio tubo all'input R di Pipe ed osserva il risultato finale pag85(79) 11.2 Strumenti di Pannellatura (divisione di superfici in parti regolari) Poco tempo fa la McNeel ha diffuso un ottimo plug-in gratuito di Rhino dal nome Paneling

79

Tools. Tra l'altro, il plug-in consente di rivestire in modo regolare una superficie con una geometria data. Grasshopper possiede alcuni componenti che possono riprodurre questo metodo ed il tutorial che segue mostra come usare un componente Interval per suddividere una superficie ed anche alcuni dei componenti di Morphing (modifica della forma) di GH. Per maggiori informazioni sul plug-in Paneling Tools, visita:
http://en.wiki.mcneel.com/default.aspx/McNeel/PanelingTools.html Qui sotto un'immagine della definizione per rivestire in modo regolare una torre con un infisso vetrato.

Nota: per vedere la definizione completa di questo esempio, Apri il file PanelingTool.ghx dalla cartella Source Files a corredo di questo manuale.

Per creare la definizione da zero, ci serve prima un set di curve con cui creare la torre con lo strumento Loft. In Rhino, Apri il file PanelingTool_base.3dm che trovi nella stessa cartella. Ci trovi 4 ellissi, che useremo per la torre ed altra geometria 2D predefinita.

80

Cominciamo la definizione creando una superficie di Loft: Params/Geometry/Curve - trascina sul canvas un componente Curve Tasto Dx sul componente e seleziona l'opzione "Multiple Curves" Sparisce la finestra GH ed in Rhino puoi selezionare ad una ad una le 4 ellissi, partendo dal basso Conferma con Enter alla fine della selezione Come abbiamo gi visto in precedenza, abbiamo cos referenziato (stabilito un legame) geometria di Rhino in Grasshopper Surface/Free Forma/Loft - trascina un componente Loft sul canvas Connetti l'output di Curve all'input S di Loft Se selezioni con il Dx l'input O di Loft, vedi che appaiono le tipiche opzioni di Loft del corrispondente comando Rhino. Nel nostro caso ci accontentiamo delle impostazione di default, ma nulla vieta che si verifichi in futuro il caso in cui necessario cambiarle. Step Opzionale: praticamente impossibile prevedere se la superficie di Loft guarda verso l'esterno, come dovrebbe o verso l'interno. Per tentativi, ho verificato che statisticamente (la legge di Murphy!!) la superficie spesso guarda verso l'interno, con il risultato che i pannelli vanno a finire sulla faccia interna. Possiamo allora usare un componente Flip per ribaltare la normale della nostra superficie, in modo che guardi verso l'esterno. Noi ce lo mettiamo, ma se ti accorgi che i pannelli vengono piazzati all'interno, non devi far altro che cancellarlo dalla definizione e riconnettere in modo corretto i fili. Surface/Utility/Flip - trascina sul canvas un componente Flip Connetti l'output L di Loft all'input S di Flip Params/Geometry/Surface - trascina un componente Surface sul canvas Connetti l'output S di Flip all'input di Surface Tasto Dx su Surface e metti un segno di spunta sulla casella Reparameterize In questo momento la nostra superficie ha un dominio che va da zero (alla base della torre) ad un numero che rappresenta la cima. Non sappiamo n ce ne importa quale sia il limite superiore, perch possiamo normalizzarla, vale a dire, reimpostare il dominio in modo che i suoi limiti siano da 0 a 1, dove 0 in corrispondenza della base mentre 1 della sommit. Questo un passaggio cruciale, perch la nostra superficie non si dividerebbe correttamente se non normalizzata tra 0 e 1.

Scalar/Interval/Divide Interval - trascina sul canvas un componente Divide Two Dimensional Interval (che vagonata di nome) Prima di suddividere la superficie, dobbiamo specificare l'estensione di intervallo Tasto Dx sull'input I del componente Interval e selezionare l'opzione "Manage Interval Collection"

81

Fai click sul pallino verde con il + per aggiungere un intervallo alla collezione Di default, l'intervallo esistente ha valori: U{0.0 To 0.0}, V{0.0 To 0.0}, ma a noi serve un intervallo da 0 a 1 per entrambe le direzioni. Cambia il valore finale di U in 1.0 Cambia il valore finale di V in 1.0

Il Collection Manager dell'Intervallo dovrebbe avere questa impostazione. Conferma con OK. Ora se ti soffermi con il mouse sull'input I di Divide Inteval, vedrai che sia l'intervallo U che il V vanno da 0 a 1, in perfetta corrispondenza alla nostra superficie normalizzata. Params/Special/Number Slider - trascina sul canvas due slider Tasto Dx sul primo ed imposta: - Name: Intervallo U - Slider Type: Integer - Lower Limit: 5 - Upper Limit: 30 - Value: 10 Tasto Dx sul secondo ed imposta: pag88(82) - Name: Intervallo V - Slider Type: Integer - Lower Limit: 5 - Upper Limit: 30 - Value: 10 Connetti lo slider Intervallo U all'input U di Divide Interval

82

Connetti lo slider Intervallo V all'input V di Divide Interval XForm/Morph/SurfaceBox - trascina sul canvas un componente Surface Box Connetti l'output di Surface all'input S si Surface Box Connetti l'output S di Divide Interval all'input D di Surface Box Tasto destro su ciascuno dei componenti Curve, Loft e Surface, disattiva la Preview

A questo punto abbiamo diviso la nostra superficie in cento porzioni quadrangolari basate sugli slider che pilotano Interval. Quel che succede che, avendo impostato un intervallo tra 0 e 1 che corrisponde a quello della superficie, abbiamo potuto dividere quell'intervallo 10 volte in direzione U e 10 volte in direzione V, ottenendo 100 cento combinazioni U-V univoche all'interno del nostro intervallo. Puoi cambiare l'impostazione degli slider Intervallo U e V, per controllare il livello di suddivisione della superficie in ciascuna direzione.

Facciamo un passo indietro per creare un disegno geometrico che ci sia possibile applicare alla suddivisione che abbiamo fatto. In Rhino trovi il disegno di un sistema di finestratura, consistente in un pannello di tamponamento, una cornice ed il vetro. Useremo queste tre entit geometriche per creare la pannellatura esterna sulla nostra superficie. Params/Geometry/Geometry - trascina sul canvas un componente Geometry Tasto Dx su Geometry e seleziona "Set Multiple Geometries" In Rhino seleziona il pannello, la cornice ed il vetro Premi Invio per confermare, dopo aver selezionato le 3 entit Surface/Primitive/Bounding Box -trascina un componente Bounding Box sul canvas Connetti l'output di geometry con l'input C di Bounding Box Usiamo il componente Bounding Box per due ragioni. La prima, perch Bounding Box ci fornisce l'altezza del nostro assemblato. Dal momento che abbiamo usato per il nostro disegno dei componenti rettangolari, sarebbe facile misurarne l'altezza, ma nel caso avessimo scelto una forma pi organica da spalmare sulla superficie, la sua altezza sarebbe stata assai pi difficile da calcolare. Useremo l'informazione di altezza come valore di input per il componente Surface Box. La seconda ragione, perch useremo Bounding Box come BRep di riferimento per il componente BoxMorph che vedremo tra poco. pag89(83) Tasto Dx sull'input U di Bounding Box e impostare il valore booleano a True (vero) Questo importante perch consentir di raggruppare le tre entit in un unico bounding box (contenitore minimo) Surface/Analysis/Box Components - Trascina sul canvas un Box Components Connetto l'output B di Bounding Box con l'input B di Box Components Connetti l'output Z di Box Components con l'input H di Surface Box Siamo in dirittura d'arrivo. XForm/Morph/Box Morph - trascina siul camvas un componente Box Morph Connetti l'output di Pattern Geometry con l'input G di Box Morph

83

Connetti l'output B di Bounding Box con l'input R di Box Morph Connetti l'output B di Surface Box all'input T di Box Morph Tasto Dx su Box Morph ed imposta l'algoritmo di confronto dei dati su Cross Reference Tasto Dx su Surface Box e disattiva la Preview Accidenti! Se il tuo cervello non sta per dare forfait, cerco di spiegarti il significato dell'ultima parte. Abbiamo fornito come input a Morph Box la geometria di riferimento, in modo che sia in grado di replicarla su ciascuna suddivisione. Abbiamo usato il Bounding Box sull'insieme dei nostri componenti Rhino come geometria di riferimento, ed abbiamo usato le 100 suddivisioni quadrangolari come bersaglio su cui replicare la nostra geometria. Se non hai commesso errori, dovresti essere in grado di cambiare la superficie di base, la geometria da replicare (il sistema finestra), la suddivisione nelle due direzioni U e V della superficie da rivestire, avendo il controllo completo di quanti elementi usare.

11.3 Suddivisione a Diamante della Superficie Abbiamo visto come usare la definizione Paneling Tools per creare il rivestimento esterno di una superficie, ma il prossimo esempio ti insegner a manipolare il flusso di informazioni in modo da creare una griglia strutturale a diamante (romboidale) su una qualsiasi superficie. Per iniziare, Apri il file Rhino Surface Diagrid.3dm. Ci trovi due curve trigonometriche, di cui una specchiata rispetto all'altra, che useremo per la superficie di Loft.

84

Nota: Per vedere la definizione completa di questo esempio, Apri il file Surface Diagrid.ghx che trovi nella cartella Source Files a corredo di questo tutorial.

Costruiamo la definizione da zero: Params/Geometry/Curve - trascina sul canvas due componenti Curve Tasto Dx sul primo e rinominalo "CRV 1" Tasto Dx sull'input di CRV1 ed imposta "Set One Curve" Sparisce GH e puoi selezionare la prima curva in Rhino

85

Rinomina il secondo componente Curve come "CRV2" Tasto Dx sull'input di CRV2 ed imposta "Set One Curve" Sparisce GH e puoi selezionare l'altra curva in Rhino Surface/Free Forma/Loft - trascina sul canvas un componente Loft Connetti l'output di CRV1 all'input S di Loft Tenendo premuto il tasto Shift (Maiusc), connett l'output di CRV2 all'input S di Loft Dovresti vedere una superficie di Loft in Rhino Params/Geometry/Surface - trascina sul canvas un componente Surface Connetti l'output L di Loft all'input di Surface Scalar/Interval/Divide Interval - trascina sul canvas un Divide two Dimensional Interval Attenzione! Nelle versioni pi recenti la famiglia Interval si chiama Domain Come nell'esempio precedente, suddividiamo la superficie in porzioni pi piccole. Per farlo, abbiamo bisogno di creare un intervallo univoco sia lungo la direzione U sia lungo la V. Connetti l'output di Surface all'input di Divide Interval Params/Special/Number Slider - trascina sul canvas un Number Slider Tasto Dx su Number Slider ed imposta: - Name: Numero Divisioni - Slider Type: Integer - Lower Limit: 0 - Upper Limit: 20 - Value: 12 Connetti lo slider ad entrambi gli input di Divide Interval Surface/Utility/Isotrim - trascina sul canvas un componente Isotrim Connetti l'output di Surface all'input S di Isotrim (Subsrf) Connetti l'output S di Divide Interval all'input D di Isotrim Tasto Dx sui componenti Loft e Surface e disattiva le rispettive Preview Dovresti vedere una serie di piccole superfici che suddividono quella di Loft, in numero corrispondente a quanto impostato sullo slider. Poich abbiamo connesso un solo slider ad entrambi gli input di direzione U e V di Interval, otteniamo lo stesso numero di divisioni nei due sensi. Se vuoi controllare la suddivisione in modo indipendente, aggiungi un secondo slider. Surface/Analysis/Explode (ex BRep Components) - trascina sul canvas un componente BRep Questo componente divider ogni BRep nei suoi elementi costitutivi, quali faccia, spigolo, vertice. In questo caso, abbiamo bisogno di sapere la posizione di ciascun vertice, per poter fare delle connessioni diagonali all'interno della suddivisione. Connetti l'output S di Isotrim all'input B di Explode

La nostra definizione a questo punto dovrebbe essere cos. Abbiamo in sostanza

86

diviso la superficie di Loft in sub-superfici pi piccole, le abbiamo esplose per ottenere la posizione dei vertici. Nel prossimo passaggio, daremo un'occhiata alla struttura ad albero dei componenti ed indicizzeremo i vertici. Params/Special/Parameter Viewer - trascina sul canvas un componente Parameter Viewer Connetti l'output V di Explode all'input di Parameter Viewer Parameter Viewer consente di esaminare la struttura dei componenti. Nel nostro caso abbiamo la struttura ad albero contiene 144 ramificazioni, con ogni terminale contenente 4 set di dati (nel nostro caso si tratta dei quattro spigoli di ciascuna sub-superficie). Possiamo usare List Item per analizzare ciascuna ramificazione e recuperare una specifica informazione. Per il nostro scopo, vogliamo sapere la posizione nello spazio Cartesiano del primo, secondo, terzo e quarto spigolo di ciascuna sub-superficie.

Logic/List/List Item - trascina sul canvas quattro componenti List Item Connetti l'output V di Explode all'input L di tutti i List Item (tieni premuto Maiusc) Tasto Dx sull'input i del primo List Item ed imposta Integer a 0 (zero) Tasto Dx sull'input i del secondo List Item ed imposta Integer a 1 Tasto Dx sull'input i del terzo List Item ed imposta Integer a 2 Tasto Dx sull'input i del quarto List Item ed imposta Integer a 3 Avrai notato che abbiamo aumentato l'indice dei List Item di 1 ogni volta. Dal momento che la nostra struttura completa e GH sa che abbiamo 144 ramificazioni, ognuna con 4 elementi finali...tutto quel che dobbiamo fare prendere i valori che ci servono nel giusto ordine da ciascun elemento finale. I 4 List Item raggruppano uno specifico spigolo di tutte le subsuperfici, il che ci consente di connetterne ognuno con quello che gli sta opposto, ovvero tracciare la diagonale e creare il nostro diamante.

pag93(87) Curve/Primitive/Line - trascina sul canvas due componenti Line Connetti l'output E del primo List Item all'input A del primo Line Connetti l'output E del terzo List Item all'input B del primo Line Connetti l'output E del secondo List Item all'input A del secondo Line Connetti l'output E del quarto List Item all'input B del secondo Line A questo punto sulla superficie suddivisa vedrai un set di segmenti diagonali. Surface/Free Form/Pipe - trascina sul canvas un componente Pipe Connetti l'output L del primo Line all'input C di Pipe Tenendo premuto Shift (Maiusc), connetti l'output L del secondo Line allo stesso input C di Pipe Per poter controllare la dimensione della struttura, usiamo uno slider per specificare il raggio

87

di Pipe. Params/Special/Number Slider - trascina sul canvas un Number Slider Tasto Dx sullo slider ed imposta: - Name: Raggio tubo - Slider Type: Floating Point - Lower Limit: 0.0 - Upper Limit: 1.0 - Value: 0.05 Connetti lo slider all'input R di Pipe Da ultimo, creeremo una superficie piana tra i 4 spigoli di ciascuna sub-superficie. Lo facciamo perch esse sono curve, mentre noi abbiamo bisogno di usare elementi strutturali piani per la facciata (ad esempio vetro). Surface/Free Form/4Point Surface - trascina sul canvas un componente 4Point Surface Connetti l'output E del primo List Item all'input A di 4Point Surface Connetti l'output E del secondo List Item all'input B di 4Point Surface Connetti l'output E del terzo List Item all'input C di 4Point Surface Connetti l'output E del quarto List Item all'input D di 4Point Surface Assicurati di disattivare la Preview di tutti i componenti ad eccezione di 4Point Surface e Pipe.

88

L'ultima parte della definizione dovrebbe essere cos. Questa definizione funziona su qualsiasi superficie singola e puoi sostituire la parte di definizione inerente la creazione della superficie Loft con uno strumento di creazione di superficie a tua scelta (purch generi una superficie singola!)

11.4 Suddivisione irregolare a diamante di Superfici Nell'ultimo esempio abbiamo mostrato come suddividere una superficie per creare una struttura reticolare e regolare a diamante. La suddivisione della superficie era regolare perch abbiamo creato un intervallo a sua volta regolare.... possiamo anche usare alcuni componenti aggiuntivi ed un Graph Mapper (grafico dinamico) per modificare localmente la collezione dell'intervallo e di conseguenza variare la spaziatura della suddivisione. Questo esempio user una parte di ci che abbiamo preparato per il precedente, per cui si ipotizza che tu abbia gi costruito la struttura regolare a diamante. Sotto trovi un'immagine della definizione completa di suddivisione irregolare, con evidenziati in verde i componenti aggiuntivi. Nota: Per avere a disposizione la definizione completa di questo esempio, Apri il file Uneven Surface Diagrid.ghx che trovi nella cartella Source Files che correda questo tutorial.

89

Nell'ultima definizione, abbiamo connesso il componente Divide Interval al componente Isotrim (SubSrf). Cominciamo il nostro intervento disconnettendo questo collegamento. Tasto Dx sull'input D di Isotrim (SubSrf) e seleziona "Disconnect All" Dal momento che dobbiamo inserire dei nuovi componenti dopo questo punto, ti consiglio di spostare tutto quello che segue della definizione originale un p a destra. Scalar/Interval(Domain)/Interval(Domain) Components - trascina sul canvas un componente Interval Components (quello che suddivide l'intervallo nei 4 dati) Connetti l'output S di Divide Interval all'input I di Interval Components Params/Special/Graph Mapper - trascina sul canvas un componente Graph Mapper Connetti l'output U0 di Interval al Graph Mapper Tenedo premuto Shift (Maiusc), connetti l'output U1di Interval al Graph Mapper
Tasto Dx su Graph Mapper e scegli un tipo di grafico Penso che il grafico tipo Bezier sia ideale in questa situazione, permettendo di agire sui punti di controllo per modificare la curva del grafico, ma ognuno pu scegliere quello di suo gusto. Ti starai chiedendo perch facciamo tutto questo. Beh, abbiamo fino a questo punto decomposto il nostro intervallo in una lista di valori ed abbiamo alimentato la lista di valori U nel grafico, nel quale possiamo modificarne la spaziatura, da regolare qual'era, nel modo che desideriamo. All'uscita dal Graph Mapper otteniamo una nuova lista di valori U riorganizzata da rimettere insieme in un Interval ed usare (come prima) nel componente Isotrim. Logic/List/List Length - trascina sul canvas un componente List Length Connetti l'output U1 di Interval all'input L di List Length Logic/Lista/Split List - trascina sul canvas un componente Split List Connetti l'output di Graph Mapper all'input L di Split List Connetti l'output L di List length all'input i di Split List Scalar/Interval(Domain)/Interval2d(Domain) - trascina sul canvas un componente Interval a due dimensioni (quello che ricompone) Connetti l'output A di Split List all'input U0 di Interval2d Connetti l'output B di Split List all'input U1 di Interval2d Connetti gli output V0 e V1 dell'Interval di decomposizione(il primo aggiunto) direttamente ai rispettivi input di Interval2d di ricomposizione Nel Graph Mapper abbiamo alimentato tutti i valori di U, dal minore al maggiore, per poter controllare la suddivisione in direzione U attraverso la curva di grafico. Invece abbiamo connesso direttamente i valori della direzione V dall'Interval di decomposizione all'Interval 2d, in modo da lasciare inalterata la distribuzione della suddivisione in questa direzione. Naturalmente, si pu fare lo stesso anche per V, aggiungendo una seconda serie di componenti. Tutto quel che ci resta da fare connettere la nostra nuova collezione di intervalli al componente Isotrim (SubSrf). Connetti l'output I di Interval2d all'input D di Isotrim (SubSrf) Poich il resto della definizione uguale a prima, la curva di grafico controller unicamente la

90

suddivisione in direzione U della superficie, e di conseguenza la creazione della struttura a diamante. Prova a modificare la curva di Bezier per vedere in diretta il risultato nella suddivisione. La parte centrale della nuova definizione dovrebbe apparire cos.

Nota del traduttore: I nomi che trovate qua e l tra parentesi sono in genere quelli che lo stesso componente cui si riferisce il tutorial ha assunto in versioni pi recenti. Potrebbe anche darsi che alcune funzioni specifiche siano cambiate. Si prega quindi di prestare la massima attenzione nella scelta di componenti apparentemente uguali, ma con caratteristiche e risultati diversi.

91

12 Introduzione allo Scripting


Le funzionalit di Grasshopper possono essere estese utilizzando componenti di scripting per generare codici nei linguaggi di programmazione VB DotNET o C#. Probabilmente in futuro saranno supportati anche altri linguaggi. Il codice scritto dall'utente inizialmente inserito in una template generata dinamicamente che viene poi compilata in un assemblato, usando il compilatore CRL incluso nel framework DotNET. Questo linguaggio incluso nella memoria del computer, e non verr eliminato fintanto che Rhino esister. Il componente script, in Grasshopper, ha accesso alle funzioni e variabili Rhino DotNET, che sono le stesse utilizzate dagli sviluppatori di plugin per Rhino per accedere alle varie funzioni. Di fatto Grasshopper una plugin per Rhino, completamente scritta nel linguaggio DotNET utilizzando lo stesso SDK per accedere ai componenti di script! Come mai entrambi utilizzano dei componenti script di partenza? Normalmente non ci sar bisogno di utilizzare componenti script, ma pu capitare il caso in cui questi siano utili. Per esempio se si volessero ottenere funzionalit che altrimenti non sarebbero supportate da altri componenti di Grasshopper. Oppure se si sta scrivendo un codice che utilizzi funzioni reiterate, come i frattali. Questo manuale propone una descrizione generale di come utilizzare il componente scripting in Grasshopper, utilizzando il linguaggio di programmazione VB DotNET. Include tre sezioni. La prima a proposito dell'interfaccia del componente di scripting. La seconda include un riassunto veloce del linguaggio di programmazione VB DotNET. L'ultima illustra invece l'SDK di Rhino DotNET, le classi di geometrie e le funzioni. Alla fine troverete una lista di dove reperire materiale di ulteriore aiuto.

92

13 L'interfaccia di Scripting
13.1 Dove trovare i componenti di Script Il componente VB DotNet Script si trova sotto il menu logic. Sono presenti due componenti script. Uno usato per scrivere codice Visual Basic, l'altro per C#. Sicuramente in futuro verranno supportati altri linguaggi di programmazione. Per aggiungere un componente script sull'area di lavoro, trascinare l'icona del componente.

Il componente script di default possiede due input e due output. L'utente pu cambiare nome, tipologia e numero di input e output.

X: primo input generico (oggetto). Y: secondo input generico (oggetto). Out: stringa di output con messaggi di feedback di compilazione. A: output di tipo oggetto.

13.2 Parametri di Input

93

Ci sono due parametri di input di default: x e y. E' possibile editare il nome dei parametri, eliminarli, aggiungerli ed assegnarne una tipologia. Cliccando con il tasto destro del mouse su un parametro di input, verr mostrata la seguente lista di opzioni:

Parameter name: cliccare per inserire un nuovo nome. Run time message: errori ed avvisi. Disconnect e Disconnect All. funziona nello stesso modo degli altri componenti Grasshopper. Flatten: per appiattire i dati. In caso di una lista multipla, viene convertito in una singola serie di elementi. List: indica se l'input una lista di dati. Type hint: i parametri di input sono settati de default alla tipologia generica object. E' sempre meglio specificare una tipologia per rendere il codice pi leggibile ed efficiente. Le tipologie il cui nome inizia per On appartengono al genere OpenNURBS.

93

I parametri di input possono anche essere gestiti dal menu principale del componente. Cliccando con il tasto destro del mouse nel centro del componente, apparir un menu con dettagli dell'input e dell'output. Puoi usare questo menu per aprire l'input manager e cambiare i nomi dei parametri, aggiungerne o eliminarne, come mostrato nell'immagine. Notare che la firma della funzione scripting (parametri di input e loro tipologie) possono essere modificati solamente attraverso questo menu. Una volta che si inizia a modificare il codice, solo il corpo della funzione pu essere modificato, non i parametri.

93

13.3 Parametri di Output Usando il menu del componente si possono impostare quanti output si desidera. A differenza dei parametri di input, non ci sono tipologie da assegnare ai parametri di output. Sono infatti definiti come tipologia generica object e la funzione pu assegnare qualsiasi testo, lista variabile, a ogni output. La seguente immagine mostra come impostare gli output, utilizzando l'output manager. Nota che il parametro out non pu essere eliminato, in quanto contiene le stringhe di debug.

95

13.4 Finestra Out e informazioni di Debug La finestra di output, di default chiamata out, mostra informazioni di debug: errori di compilazione e avvisi. L'utente pu stamparne i valori nel codice, per aiutarsi nel debug. E' molto utile attentamente leggere i messaggi di compilazione, quando il codice non funziona correttamente.

E' una buona idea connettere l'output a un componente testo, in maniera da vedere direttamente i messaggi di compilazione e le informazioni di debug.

96

13.5 Dentro al Componente Script Per aprire il componente script, fare dopio click al suo centro o scegliere Edit Source... dal menu del componente. Il componente script consiste in due parti: A: Importazioni B: Grasshopper_Script. C: Link A Microsoft developer network help su VB.NET. D: Check box per attivare la funzione out of focus.

A: Imports Le Imports sono dll esterne che possono essere utilizzate nel codice. La maggior parte di loro appartengono a DotNET, ma ce ne sono anche due appartenenti a Rhino: RMA.openNURBS e RMA.Rhino. Queste includono tutte le geometrie di Rhino e le funzioni di utilit. Ce ne sono anche alcune specifiche di Grasshopper.

97

B: Definizioni Grasshopper_Custom_Script Una definizione Grasshopper_Custom_Script cos costituita:

98

1. Members: Includono due riferimenti: il primo alla applicazione in uso (Rhino,


app)e il secondo al documento attivo (doc). Si pu accedere direttamente a entrambe, l'applicazione (Rhino) e il documento, usando RhinoUtil. Alla regione Members appartengono anche i valori di ritorno e l'output della funzione di script. I valori di ritorno, Return, sono definiti come tipo generico di sistema, e l'utente non pu cambiarne la tipologia.

2. RunScript: Questa la funzione principale scritta dall'utente. 3. Additional methods and type declarations: qui dove possono essere inseriti
funzioni e tipologie addizionali. Il seguente esempio mostra due maniere di accesso a un documento. La prima avviene usando il riferimento al documento, integrato nello script, la seconda invece avviene attraverso RhUtil (Rhino Utility Functions). Notare che quando viene restituita la tolleranza nella finestra di output, entrambe le funzioni mostrano lo stesso risultato. Notare anche che in questo esempio ci sono due output (MyOutput1 e myOutput2). Questi sono listati nella regione members della finestra di definizione.

99

14 Visual Basic DotNET


14.1 Introduzione Vi sono una moltitudine di riferimenti a proposito di VB.NET , che potete trovare in internet e in libreria. Riportiamo qui un riassunto degli essenziali di cui avrete bisogno per creare un codice. 14.2 Commenti E' molto importante integrare il pi possibile commenti nel codice. Sarete sorpresi di vedere quanto velocemente potete dimenticare ci che avete programmato! Nel linguaggio VB.NET potete usare l'lapostrofo ( ' ) per segnalare che il resto della linea di codice un commento, e che quindi il compilatore dovr ignorare. In Grasshopper i commenti vengono visualizzati in colore grigio, ad esempio:
Questo un commento posso scrivere qualsiasi cosa! Davvero qualsiasi cosa... io amo Inno :)

14.3 Variabili Si pu pensare alle variabili come a dei contenitori di dati. Ci sono diversi tipi di variabile, e ognuna ha differenti dimensioni, a seconda ella tipologia di dati che possono contenere. Per esempio, una variabile int32 occupa 32 bit di memoria oltre al nome della variabile ed il nome del contenitore. Una volta che una variabile stata definita, il codice pu leggerne il contenuto richiamandone il nome. Definiamo ora una variabile, o contenitore, chiamata x, di tipo int32 e fissiamone il contenuto al valore 10. Ora assegnamo alla variabile x un nuovo valore, sempre un numero intero, questa volta 20. Ecco come risulter il codice in VB DotNET:
Dim x as Int32 = 10 Se chiediamo il valore della variabile x a questo punto, otterremo in risposta il valore 10 x = 20 Da ora in poi x ha valore 20

Ecco qui altri esempi di tipologie di variabili comunemente usate:


Dim x as Double = 20.4 Dim b as Boolean = True Dim name as String = Joe Dim qualscosa significa che stiamo definendo una variabile Double, Boolean e String sono tutti esempi di basi, o tipologie definite di sistema

Il seguente esempio utilizza 3 variabili: x: un variabile a numero intero, definito all'interno del codice. y: un'altra variabile a numero intero, utilizzato dalla funzione come input. A: una variabile di putput. L'esempio restituisce i valori di output della variabile, attraverso una finestra di codice. Come gi detto, questo un buon metodo per vedere cosa sta accadendo all'interno del codice per eseguire un debug in tempo reale e, si spera, minimizzare la necessit di un editor di codice esterno.

100

Assegnare alle variabili un nome che pu essere riconosciuto istantaneamente render il codice molto pi leggibile e semplice da correggere. In questo capitolo cercheremo di mostrare alcune buone pratiche di programmazione attraverso i numerosi esempi. 14.4 Matrici e Liste Ci sono molti metodi per definire le matrici in VB.NET. Ci sono matrici singole e multi dimensionali. Si pu definire la dimensione di una matrice, oppure utilizzare matrici dinamiche. Se si conosce in anticipo il numero di elementi della matrice, la sua dimensione pu essere definita nel seguente modo:
Matrice a una dimensione Dim myArray(1) As Integer myArray (0) = 10 myArray (1) = 20 Matrice a due dimensioni Dim my2DArray (1,2) As Integer my2DArray (0, 0) = 10 my2DArray (0, 1) = 20 my2DArray (0, 2) = 30 my2DArray (1, 0) = 50 my2DArray (1, 1) = 60 my2DArray (1, 2) = 70 Dichiarazione e assegnazione dei valori Dim my2DArray(,)As Integer = {{10,20,30},{40,50,60}}

Dichiarazione e assegnazione dei valori Dim myArray() As Integer = {10,20}

101

Tieni a mente che le matrici in VB.NET sono base zero, quindi quando si dichiarer che la dimensione di una matrice sar (9) significher che contiene 10 elementi (dall'uno al 9, pi lo 0). Lo stesso vale per matrici multidimensionali. Per matrici dinamiche a una dimensione, si pu dichiarare una nuova Lista, come mostrato nell'esempio seguente, e iniziare a aggiungere elementi.

Si possono utilizzare Liste annidate o ArrayList per dichiarare matrici dinamiche multidimensionali delle stesse o differenti tipologie. Eccone un esempio:

102

14.5 Operatori Ci sono molti operatori preimpostati in VB.NET. Essi funzionano tramite uno o pi operandi Ecco una tabella di operatori comuni:
Type Operatori Aritmetici Operator ^ * / \ Mod + Operatori Assegnativi = ^= *= /= \= += Description Eleva un numero a potenza di un altro numero. Moltiplica due numeri. Divide due numeri restituendo il risultato compresi i decimali. Divide due numeri restituendo il risultato a numero intero. Divide due numeri e riporta solamente il resto dell'operazione. Addiziona due numeri o restuisce il valore positivo di una espressione numerica. Sottrae due numeri o restuisce il valore negativo di una espressione numerica. Assegna un valore a una variabile Eleva a potenza il valore di una variabile e ne assegna il nuovo risultato alla variabile stessa. Moltiplica il valore della variabile e ne assegna il nuovo risultato alla variabile stessa. Divide il valore di una variabile, e ne assegna il nuovo risultato (decimali compresi) alla variabile stessa. Divide il valore di una variabile, e ne assegna il nuovo risultato (solo la parte intera) alla variabile stessa. Addiziona il valore di una variabile a una espressione numerica, e ne assegna il nuovo risultato alla variabile stessa. Pu anche essere utilizzata per concatenare una stringa a una variabile stringa, assegnandone il nuovo contenuto alla variabile stessa. Sottrae il valore di una espressione dal valore della variabile, e ne assegna il nuovo risultato alla variabile stessa. Concatena una stringa a una variabile stringa (o propriet) e ne assegna il risultato alla variabile stessa (o propriet). Minore di Minore o uguale Maggiore di Maggiore o uguale Uguale diverso Genera una concatenazione a stringa di due espressioni. Concatena due stringhe. Esegue una congiunzione logica tra due espressioni Booleane Esegue una negazione logica tra due espressioni Booleane Esegue una disgiunzione logica tra due espressioni Booleane Esegue una esclusione logica tra due espressioni Booleane

-= &= Operatori Comparativi < <= > >= = <> Operatori Concatenativi Operatori Logici & + And Not Or Xor

103

14.6 Espressioni condizionali Si pu pensare alle espressioni condizionali come a blocchi di codice con degli stop che permettono l'esecuzione del codice al loro interno solo se all'avverarsi di alcune condizioni. L'espressione condizionale maggiormente utilizzata if, e ha il seguente formato: IF<condizione> Then <codice> End IF.
Una espressione if a linea singola non necessita End If: condizione=(x<y), codice=(x=x+y)

If x < y Then x = x + y
Linee multiple di espressione if necessitano End If per chiudere il blocco di codice

If x < y Then x=x+y End If

E' anche possibile utilizzare Else If Then e Else per scegliere un blocco di codice alternativo da utilizzare, alla presenza di altre condizioni. Per esempio:
If x < y Then x=x+y esegui questa linea, poi vai alla parte di codice che segue il End If Else If x > y Then x=xy esegui questa linea, poi vai alla parte di codice che segue il End If Else x = 2*x esegui questa linea, poi vai alla parte di codice che segue il End If End If

C' anche l'espressione Select Case (scegli tra i casi). Viene usata per eseguire blocchi di codice differenti, basandosi sul valore di una espressione (nell'esempio, l'espressione index) :
Select Case index Case 0 Se index=0 il codice esegue la linea x = x * x, altrimenti controlla se Case=1 x=x*x o Case=2 andando a scegliere il blocco di codice relativo Case 1 x=x^2 Case 2 x = x ^ (0.5) End Select

14.7 Loops I Loop consentono di ripetere l'esecuzione di un blocco di codice fino a quando la condizione di loop sia stata soddisfatta. Ci sono differenti tipologie di Loop. Illustreremo i due tipi pi comunemente utilizzati. Loop di tipo For Next Questo il Loop pi comune. La struttura la seguente:
For < indice = valore di partenza> To <valore di fine> [Step <incremento>]
Il corpo del Loop For inizia qui

[ espressione/codice che deve essere eseguito all'interno del Loop]

104

[ Exit For ]

Opzionale: per uscire dal Loop in qualsiasi momento

[ altre dichiarazioni ] [ Continue For ] [ altre dichiarazioni]


Il corpo del Loop For finisce qui (subito prima di Next) Next significa: torna indietro all'inizio del Loop per controllare se l'indice ha superato il valore di fine, poi esci dal Loop ed esegui il codice che segue Next Altrimenti aumenta il valore indice dell'incremento prefissato (Step) Opzionale: per saltare l'esecuzione delle altre dichiarazioni di Loop

Next [ dichiarazioni che seguono il Loop ]

I seguenti esempi utilizzano un Loop per iterare una matrice di luoghi:


Matrice di luoghi Dim places_list As New List( of String ) places_list.Add( Paris ) places_list.Add( NY ) places_list.Add( Beijing ) indice del Loop Dim i As Integer Dim place As String Dim count As Integer = places_list.Count() Loop partendo da 0 fino a -1 (counteggio = 3, ma l'ultimo indice della place_list = 2) For i=0 To count-1 place = places_list(i) Print( place ) Next

Per eseguire Loop tra oggetti in una matrice, si pu anche utilizzare For...Nex per iterarne gli elementi senza usare un indice. L'esempio riportato sopra, pu essere riscritto come segue:
Dim places_list As New List( of String ) places_list.Add( Paris ) places_list.Add( NY ) places_list.Add( Beijing ) For Each place As String In places_list Print( place ) Next

Loop di tipo While End While Anche questo un tipo di Loop molto utilizzato. La struttura questa:
While < le condizioni sono Vere >
il corpo del Loop While inizia qui

[ dichiarazioni da eseguire all'interno del loop]

104

[ Exit While ] [ altre dichiarazioni]

Opzionale per uscire dal Loop

[ Continue While ] optzionale, per saltare l'esecuzione del resto di codice di Loop [ altre dichiarazioni]
Il corpo del Loop While finisce qui Torna indietro all'inizio del Loop per controllare se la condizione ancora Vera, poi esegue il corpo del Loop. Se la condizione non vera, allora esce dal Loop ed esegue il codice che 'segue il End While

End While [ dichiarazioni che seguono il Loop While ]

Questo l'esempio precedente dei luoghi, riscritto utilizzando il Loop While:


Dim places_list As New List( of String ) places_list.Add( Paris ) places_list.Add( NY ) places_list.Add( Beijing ) Dim i As Integer Dim place As String Dim count As Integer = places_list.Count() i=0 While i < count place = places_list(i) Print( place ) i=i+1 End While

(i<count) considerazione di tipo Vero o Falso

14.8 Loop annidati I Loop annidati, sono Loop che ne includono altri al proprio interno. Per esempio avendo una griglia di punti, se vogliamo ottenere ogni punto della lista, dobbiamo usare un Loop annidato. L'esempio seguente mostra come trasformare una matrice a una dimensione di punti, in una griglia bidimensionale. Il codice processa poi la griglia per trovare il punto centrale di ogni cella.

Il codice ha due parti:

106

Primo, converte una matrice a una dimensione in una matrice a 2 dimensioni, che chiamiamo Grid (griglia). Secondo, processa la griglia cos ottenuta per trovare il punto centrale di ogni cella.

In entrambe le parti abbiamo usato Loop annidati. Ecco la definizione in Grasshopper:

14.9 Sottofunzioni e Funzioni RunScript la funzione base che viene utilizzata da tutti i componenti. Questo ci che si vedr aprendo un componente script di default in Grasshopper:
Sub RunScript(ByVal x As Object, ByVal y As Object) <il tuo codice> End Sub

Sub End Sub: Sono parole chiave che includono blocchi di codice della funzione RunScript: il nome della sottofunzione (): Le parentesi dopo il nome della Sottofunzione includono i parametri di input ByVal x As Object,: Sono i parametri di input Ogni parametro di input necessita di essere definito nel seguente modo:

ByRef o ByVal: Specifica se un parametro definito per valore o per riferimento. Name: nome del parametro Tipo di parametro, preceduto da As come parola chiave.

Notare che i parametri di input nelle Sottofunzioni RunScript di Grasshopper sono tutti definiti da valore (parola chiave ByVal). Questo significa che sono copie degli input originali, e ogni variazione di questi parametri all'interno dello script non modificher in nessun modo l'input originale. Per, se vengono definite altre Sottofunzioni o funzioni all'interno del componente script, i parametri possono essere definiti come riferimento (ByRef). Definire i parametri come riferimento significa che ogni variazione di questi parametri all'interno della funzione cambier anche il valore originale da cui questi hanno preso riferimento. Non sempre necessario includere tutto il codice all'interno del corpo RunScript, anche possibile definire, se necessario, sottofunzioni e funzione esterne da richiamare. Perch usare funzioni esterne? Per semplificare il codice della funzione principale. Per rendere il codice pi leggibile. Per isolare e riusare funzionalit comuni. Per definire funzioni specializzate, come iterazioni. Qual' la differenza tra Sottofunzioni e Funzioni? Si utilizzano Sottofunzioni se non si ha necessit di valori di ritorno. Le funzioni permettono di ritornare un risultato. Basicamente si assegna un valore al nome della funzione. Per esempio:
Function AddFunction( ByVal x As Double, ByVal y As Double ) AddFunction = x + y End Function

Come gi stato detto, non c' necessit di avere una Funzione per avere un valore di ritorno. Anche le Sottofunzioni possono compiere lo stesso processo attraerso parametri di input definiti come ByRef. Nel seguente, rc usato per ritornare il risultato:
Sub AddSub( ByVal x As Double, ByVal y As Double, ByRef rc As Double )

107

rc = x + y End Sub

Ecco qui la struttura della funzione di richiamo utilizzando Function e Sub:


Dim x As Double = 5.34 Dim y As Double = 3.20 Dim rc As Double = 0.0 Si pu utilizzare uno qualsiasi dei seguenti per avere lo stesso risultato rc = AddFunction( x, y ) Assegna il valore della funzione a rc AddSub( x, y, rc ) rc definito come reference, e avr al suo interno il risultato

Nella sezione dei Loop annidati, abbiamo illustratp un esampio che creava una griglia a partire da una lista di punti, per poi calcolarne il centro di ogni cella. Ognuna di queste due funzionalit abbastanza distinta da poter essere separata in una Sottofunzione a s stante che potr poi essere utilizzata in codici futuri. Ecco una riscrittura dell'esempio della griglia, utilizzando funzioni esterne:

Ecco come ognuna delle due sottofunzioni appare, quando espansa:

108

14.10 Recursioni Le funzioni recursive sono una tipologia particolare di funzioni, che richiamano loro stesse fino a quando una particolare condizione di stop sia soddisfatta. Le recursioni sono comunemente utilizzate per la ricerca di dati, e per sistemi di suddivisione e genertivi. Discuteremo un esempio che illustra come funziona la recursione. Per altri esempi sulla recursione vi indirizziamo alla wiki di Grasshopper e alla pagina della Galleria. L'esempio seguente prende la pi piccola parte di una linea di input, e la ruota di un angolo dato. Continua a ruotarla fino a quando la lunghezza della linea diventa minore di una lunghezza minima prefissata. I parametri di input sono: Linea di partenza (C).

109

Angolo in radianti (A). Lo slider mostra l'angolo in gradi, convertito in radianti dallo script Lunghezza minima (L) Come condizione di stop.

L'output : Matrice di linee.

Risolveremo lo stesso esempio sia in maniera iterativa, sia in maniera recursiva, per paragonare i due metodi. Soluzione recursiva. Notare che all'interno della sottofunzione DivideAndRotate vi sono:

Condizione di stop per uscire dalla Sottofunzione. Richiamo alla stessa funzione (le funzioni recursive richiamano s stesse). AllLines (matrice di linee) definita come riferimento, in maniera da potere sempre aggiungere nuove linee alla lista.

110

Qui riportiamo la stessa funzionalit, usando per una soluzione iterativa utilizzando un Loop While:

111

14.11 Processare Liste in Grasshopper Il componente script di Grasshopper pu processare liste di input in due maniere:

112

1. Processare un valore di input alla volta (il componente richiamato un numero di volte uguale al numero di valori nella matrice di input). 2. Processare tutti i valori di input contemporneamente (il componente richiamato una sola volta). Se dovete processare ogni elemento in una lista in maniera indipendente da tutti gli altri, allora utilizzare il primo approccio pi semplice. Per esempio, se avete una lista di numeri e volete incrementare ognuno di 10, allora potete utilizzare il primo approccio. Ma se avete bisogno di una funzione somma per addizionare tutti gli elementi fra loro, allora avrete bisogno di seguire il secondo approccio, e definire l'intera lista come input. L'esempio seguente mostra come processare una lista di dati usando il primo metodo, processando un valore di input alla volta. In questo caso la funzione RunScript richiamata 10 volte (una volta per ogni numero). Il punto chiave da notare che il parametro di input Number definito come Double, perch appartenente a una List(of Double) come vedremo nell'esempio a seguire.

113

Nel seguente esempio inseriamo come input una lista di numeri. Il settaggio pu essere ottenuto cliccando con il tasto destro del mouse sul parametro di input, e selezionando List. La funzione RunScript richiamata una sola volta.

14.12 Processare Ramificazioni di dati in Grasshopper Le ramificazioni di dati (o dati multidimensionali) possono essere processati un elemento alla volta o una ramificazione alla volta, o tutti contemporaneamente. Per esempio, se dividiamo tre curve in 10 segmenti ognuna, otterremo una struttura dati data da tre ramificazioni, ognuna con 11 punti. Se usiamo questi dati come input, avremo: A: Se entrambi Flatten e List sono selezionati, allora il componente richiamato una sola volta, e viene processata l'intera lista (Flat, appiattita, tutti i dati in fila senza pi ramificazioni) di tutti i punti.

114

B: Se l'unico selezionato List, allora il componente richiamato tre volte e ogni volta processa una lista di 11 punti:

C: Se nulla selezionato, allora la funzione richiamata una volta per ogni punto di divisione (33 volte in questo caso). La stessa cosa accade se solo Flatten sar selezionato:

115

Questo il codice all'interno del componente VB. In pratica scrive la parola inside ogni volta che il componente viene richiamato:

14.13 File I/O Ci sono molti modi di leggere da e scrivere sui file in VB.NET, e molti di questi metodi sono trattati in materiale reperibile in internet e in libreria. In generale, leggere un file una operazione in relazione con: Aprire il file. Generalmente necessario il percorso verso il file da aprire. Leggere una stringa (stringa completa, o linea per linea). Spezzettare la stringa usando caratteri di delimitazione. Processare ogni parte. Salvare il risultato.

Illustreremo un semplice esempio che analizza dei punti a partire da un file di testo. Usando il seguente formato di file testuale, leggeremo ogni linea come un punto singolo, il primo valore come coordinata x, il secondo come y e il terzo come z. Useremo poi questi punti, come punti di controllo di una curva.

116

Il componente VB accetta come input una stringa che non altro che il percorso del file da leggere, e da come output On3dPoints.

Questo il codice all'interno del componente script. Ci sono un paio di codici salvaerrore, per essere sicuri che il file esista ed abbia contenuto:

117

117

15 Rhino.NET SDK 15.1 Sommario Rhino .NET SDK fornisce accesso alle funzioni di utilit ed alla geometria OpenNURBS. Insieme con il file .NET SDK viene scaricato anche un file help, una grossa risorsa cui fare affidamento. Ecco da dove scaricare: http://en.wiki.mcneel.com/default.aspx/McNeel/Rhino4DotNetPlugIns.html In questo capitolo, ci concentreremo espressamente sulla parte di SDK (Software Development Kit_strumento di sviluppo software) che ha a che fare con i tipi di geometria Rhino e con le funzioni di utilit. Mostreremo esempi sulla creazione e modifica di geomtria usando il componente VB Script di Grasshopper. 15.2 Capire le NURBS Rhino un modellatore NURBS che descrive la geometria di curve e superfici usando Non-Uniform Rational Basis Spline (NURBS). La NURBS una rappresentazione matematica accurata di curve e superfici molto intuitiva da modificare. Per coloro che fossero interessati ad approfondire l'argomento NURBS, esistono molte pubblicazioni (http://en.wikipedia.org/wiki/NURBS). Tuttavia per tutti necessaria almeno un'infarinatura, per riuscire ad usare con profitto le categorie e le funzioni di SDK. Ci sono quattro elementi che definiscono una curva NURBS: Grado, Punti di controllo, Nodi e Regola di valutazione. Grado Si tratta di un numero intero positivo solitamente uguale a 1,2,3 o 5. Rhino consente di lavorare con gradi da 1 a 11. Di seguito alcuni esempi di curve e rispettivi gradi:
Segmenti e polilinee sono curve di grado 1. Ordine = 2 (ordine = grado + 1)

Cerchi ed ellissi sono esempi di curve NURBS di grado 2. Sono anche curve razionali o non uniformi. Ordine = 3.

Le curve a forma libera sono di solito descritte da Nurbs di grado 3. Ordine = 4 Anche il grado 5 abbastanza frequente, ma i successivi sono puramente ipotetici.

118

Punti di controllo I punti di controllo di una curva NURBS sono una lista di almeno grado+1 punti (vedi ordine). Il modo pi usuale di modificare la forma di una curva NURBS quello di spostare i suoi punti di controllo. I punti di controllo hanno associato un valore detto Peso. Tranne alcune eccezioni, il Peso un numero positivo. Quando i punti di controllo hanno tutti lo stesso peso (di solito 1), la curva viene definita nonrazionale. Vedremo un esempio di come modificare interattivamente il peso dei punti in GH. Nodi o Vettore di nodo Ogni curva NURBS possiede una lista di valori specifica detta Vettore di nodo. Il concetto di nodo un p pi complicato da capire ed applicare, ma per fortuna le funzioni di SDK lo fanno per noi. Tuttavia, alcune cose sar bene impararle: Pluralit del nodo Viene cos definito il numero di volte che il valore di un nodo viene duplicato. Qualsiasi valore di nodo non pu essere ricorrente pi volte del grado della curva. Ecco di seguito alcune informazioni utili su questo aspetto. Nodo a pluralit piena la situazione in cui il nodo replicato un numero di volte pari al grado della curva. Curve tronche hanno nodi a pluralit piena alle estremit e questo spiega perch punti di inizio e fine della curva coincidono con i punti di controllo iniziale e finale. Se esistesse un nodo a pluralit piena nel mezzo della curva, essa dovrebbe passare per il punto di controllo, formando una cuspide. Nodo semplice un nodo il cui valore appare solo una volta. Vettore di nodo uniforme soddisfa 2 condizioni: 1. Numero di nodi= numero di punti di controllo+grado-1 2. I nodi iniziano con uno a pluralit piena, seguito da nodi semplici, a chiudere da un altro a pluralit piena, con valori crescenti e spaziati in modo uniforme. tipico delle curve tronche. Le curve periodiche (chiuse) hanno caratteristiche differenti, come vedremo in seguito. Ecco qui 2 curve con un numero uguale di punti di controllo , ma con vettori di nodo diversi:
Grado = 3 Numero di punti di controllo = 7 vettore di nodo = (0,0,0,1,2,3,5,5,5)

Grado = 3 Numero di punti di controllo = 7 vettore di nodo = (0,0,0,1,1,1,4,4,4) Nota: la pluralit piena nel mezzo crea una cuspide e la curva cotretta a passare per il corrispondente punto di controllo.

Regola di Valutazione La regola di valutazione usa una formula matematica che accetta un numero e assegna un punto. La

119

formula usa grado, punti di controllo e nodi. Utilizzando questa formula, le funzioni SDK possono accettare un parametro della curva e produrre il punto corrispondente sulla curva stessa. Un parametro un numero compreso nel dominio della curva. Il dominio descritto da due parametri: un minimo (m_t(0)) dove inizia la curva ed un massimo (m_t(1)) dove finisce. Superfici NURBS Dovete immaginare le superfici NURBS come una griglia bidimensionale di curve NURBS. La forma di una superficie NURBS definita da un certo numero di punti di controllo e dal grado della superficie in ciascuna delle due direzioni ( U e V). Per maggiori dettagli, fate riferimento al Glossario dell'Help di Rhino (F1).

Le superfici NURBS possono essere ritagliate o non ritagliate. Pensate ad una superficie ritagliata come alla sua corrispondente integra ed a una curva chiusa che ne delimita una porzione. Qualsiasi superficie possiede un perimetro esterno chiuso (bordo esterno) e pu avere al suo interno molte altre curve chiuse che non si intersecano e delimitano dei fori (bordi interni). Viene definita superficie non ritagliata quella il cui bordo esterno identico alla sua integra corrispondente e che non ha fori al suo interno.

La superficie a sinistra non ritagliata. Quella a destra la stessa superficie ritagliata da un foro ellittico. Notate che la struttura della superficie non cambia per effetto del ritaglio.

120

Poli-superfici Una poli-superficie consiste in una pluralit di superfici (di solito ritagliate) unite tra loro. Ciascuna superficie ha la sua specifica parametrizzazione e le direzioni UV non devono necessariamente essere corrispondenti. Le poli-superfici e le superfici ritagliate sono di solito rappresentate usando ci che viene comunemente definita Boundary Representation (BRep, rappresentazione per mezzo del bordo di confine). Il BRep in sostanza descrive le superfici, gli spigoli ed i vertici della geometria attraverso i dati di ritaglio e le relazioni tra parti diverse. Per esempio, descrive ogni faccia, i suoi lati e le curve che la tagliano, la normale alla superficie, la relazione con le facce confinanti e cos via. Descriveremo in dettaglio la variabile BRep e come unirla al resto pi avanti. OnBRep probabilmente la struttura di dati pi complessa nel campo delle OpenNURBS e non sarebbe certo facile da assimilare, ma per fortuna L'SDK di Rhino possiede un buon numero di strumenti e funzioni globali che aiutano nella creazione e manipolazione delle BReps.

15.3 Gerarchia degli oggetti OpenNURBS Il file di Help di SDK mostra la gerarchia di tutte le classi di oggetti. Ecco qui la sezione di un sub-set di classi relativo alla creazione e manipolazione di geometria che potrebbe servirvi per scriptare. Vi avverto, la lista del tutto parziale. Per maggiori dettagli, fate riferimento al file di Help. OnObject (tutte le classi in Rhino derivano da OnObject) - OnGeometry (classe derivata da o che eredita da OnObject) OnPoint OnBRepVertex OnAnnotationDot OnPointGrid OnPointCloud OnCurve (classe generica) OnLineCurve OnPolylineCurve OnArchCurve OnNurbsCurve

121

OnCurveOnSurface OnCurveProxi OnBrepTrim OnBrepEdge OnSurface (classe generica) OnPlaneSurface OnRevSurface OnSumSurface OnNurbsSurface OnProxiSurface OnBrepFace OnOffsetSurface OnBrep OnMesh OnAnnotation

- Punti e Vettori (non derivati da OnGeometry) On2dPoint (usato per punti nello spazio parametrico) On3dPoint On4dPoint (utile per rappresentare punti di controllo con x,y,z e w per il peso) On3dVector - Curve (non derivate da OnGeometry) OnLine OnPolyline (derivato in realt da OnPointArray) OnCircle OnArc OnEllipse OnBezierCurve - Superfici (non derivate da OnGeometry) OnPlane OnSphere OnCylinder OnCone OnBox OnBezierSurface - Miscellanea OnBoundingBox (per calcolare il bounding box di oggetti) OnInterval (per calcolare il dominio di curve e superfici) OnXForm (per le trasformazioni di geometria: muovi, ruota, scala, ecc.) OnMassProperties (per il calcolo di volume, area, centroide, ecc.)

122

15.4 Struttura delle Classi Una classe tipica (una struttura di dati definita dall'utente) composta da quattro parti funzionali: Costruzione - usato per creare l'oggetto istanza dello script Variabili della parte pubblica - dove vengono memorizzati i dati relativi alla classe. Le variabili OpenNURBS di solito iniziano con "m_", in modo da essere facilmente individuate Funzioni della parte pubblica - dove sono contenute tutte le funzioni di classe da creare, per aggiornare e modificare le variabili dei membri della classe, oltre che adempiere a specifiche funzionalit Membri della parte privata - sono funzioni di utilit e variabili per uso interno (in genere non modificabili) Nel momento in cui inizializzate una classe, sarete in grado di accedere a tutte le funzioni o variabili dei membri attraverso la funzione di auto-completamento. Notate che se passate sopra a ciascuna funzione o variabile, appare la sua firma. Quando iniziate ad introdurre parametri di funzione, vi verr mostrato di che tipo di parametro si tratta. Questo un ottimo modo di scoprire le funzioni disponibili per una determinata classe. Ecco qui sotto un esempio dalla classe On3dPoint:

E' possibile copiare dati da una classe ad un'altra nuova in diversi modi, in funzione della classe. Per esempio, creiamo una nuova classe On3dPoint e copiamoci dentro i dati di un punto esistente. Ecco come fare:
Usate Costruzione per inizializzare l'istanza della classe Dim new_pt as New On3dPoint (input_pt) Usate "=operator" se la classe ne fornita Dim new_pt as New On3dPoint new_pt= input_pt

123

Potete usare la funzione "New", se disponibile Dim new_pt as New On3dPoint new_pt.New(input_pt) A volte esiste una funzione "Set" Dim new_pt as New On3dPoint new_pt.Set(input_pt) Copiate le variabili di membro una alla vota. Un p laborioso, ma pazienza Dim new_pt as New On3dPoint new_pt.x = input_pt.x new_pt.y = input_pt.y new_pt.z = input_pt.z Le classi della geometria OpenNURBS possiedono la funzione "Duplicate", molto facile da usare Dim new_crv as New OnNurbsCurve new_crv=input_crv.DuplicateCurve()

15.5 Istanze Costanti e Non-costanti Il .NET SDK di Rhino fornisce due set di classi. Il primo set costante ed i nomi delle sue classi sono preceduti da una "I", ad esempio IOn3dPoint. La classe corrispondente Non-costante ha lo stesso nome senza la "I", ad esempio On3dPoint. Potete duplicare una classe costante, vedere le variabili dei suoi membri ed alcune altre funzioni, ma non cambiarne i valori. Il .NET SDK di Rhino basato sull'SDK di Rhino C++. Il linguaggio di programmazione C++ contmpla la possibilit di fornire istanze costanti di classe e viene usato estesamente per le funzioni SDK. D'altra parte invece, il .NET non possiede un simile concetto e da qui la necessit di una versione per ciascuna classe. 15.6 Punti e Vettori Ci sono molte classi che potrebbero essere usate per memorizzare e manipolare punti e vettori. Prendete ad esempio i punti a doppia precisione. Ci sono tre tipi di punti:
Nome Classe On2dPoint Variabili del membro x come Double y come Double Note Usato soprattutto per punti dello spazio piano parametrico. Il d nel nome della classe sta per numero in virgola mobile a doppia precisione. Esistono altre classi per i punti che hanno una f nel nome, perch usano precisione singola. Comunemente usato per rappresentare punti nello spazio a coordinate tridimensionali. Usato per rappresentare punti di controllo, che hanno un dato relativo al peso, oltre ai tre delle coordinate.

On3dPoint On4dPoint

x come Double y come Double x come Double y come Double z come Double w come Double

124

Le operazioni su punti e vettori includono: Addizione di Vettori


Dim add_v AsNew On3dVector=v0+v1

Sottrazione di Vettori
Dim subtract_vector AsNew On3dVector=v0-v1

Vettore tra due punti


Dim dir_vector AsNew On3dVector=p1-p0

Prodotto di Vettori decimali (se il risultato positivo, i vettori sono nella stessa direzione):
Dim dot_product As Double = v0 * v1

Prodotto incrociato tra Vettori (il risultato un vettore normale all'input dei due vettori in input)
Dim normal_v As New On3dVector = OnUtil.ON_CrossProduct( v0, v1)

Scalare un vettore:
Dim scaled_v As New On3dVector = factor * v0

Spostare un punto lungo un vettore:


Dim moved_point As New On3dPoint = org_point + dir_vector

Distanza tra due punti:


Dim distance As Double = pt0.DistanceTo( pt1)

Normalizza Vettore (poni la lunghezza del vettore pari a 1)


v0.Unitize()

Calcola lunghezza Vettore:


Dim length As Double = v0.Length()

L'esempio seguente mostra come calcolare l'angolo tra due vettori:

125

15.7 OnNurbsCurve (curva su superficie Nurbs) Per creare una curva Nurbs, dovete fornire i seguenti parametri: Dimensione(grado), tipicamente =3 Ordine, Grado+1 Punti di controllo (l' array (schiera)dei punti) Vettori di Nodo (un array di numeri) Tipo di curva (tronca o chiusa) Esistono funzioni specifiche per generare il vettore di nodo, come vedremo tra breve, per cui sostanzialmente dovete solo decidere il grado e disporre di una lista di punti di controllo. L'esempio che segue crea una curva tronca.

126

Per ottenere curve chiuse uniformi, dovete usare le curve periodiche. Usando lo stesso grado e punti di controllo dell'esempio precedente, ecco qui come creare una curva chiusa.

Curve NURBS tronche o chiuse Le curve tronche sono generalmente curve aperte che hanno punti di inizio e fine coincidenti con il primo ed ultimo punto di controllo. Le curve periodiche sono curve chiuse uniformi (senza cuspidi). Il modo migliore per capire la differenza quello di confrontare i rispettivi punti di controllo.

127

L'esempio seguente crea curve NURBS tronche e genera quel che vedete in verde:

Ecco invece una curva periodica ottenuta usando gli stessi input (punti di controllo e grado):

Notate che la curva periodica ha trasformato i 4 punti di controllo in input in 7 punti di controllo (4+grado), mentre la curva tronca ha usato solo i 4 punti originali. Il vettore di nodo della curva periodica usa solo nodi semplici, mentre i nodi di inizio e fine di quella tronca sono del tipo a pluralit piena. Ecco alcuni altri esempi, ma con curve di grado 2. Come potete aver intuito, il numero di punti di controllo e di nodi cambia con il grado della curva.

128

Ecco lo script per accedere ai punti di controllo ed ai nodi degli esempi precedenti:

Peso Il peso dei punti di controllo in una curva NURBS uniforme impostato a 1, ma pu essere diverso nelle curve NURBS razionali. L'esempio seguente mostra come modificare il peso dei punti di controllo interattivamente in GH.

129

Dividi Curva NURBS Dividere una curva NURBS in un certo numero di segmenti comporta i seguenti passaggi: conoscere il dominio della curva, vale a dire il parametro dell'intervallo della curva preparare una lista di parametri che dividono la curva in segmenti di ugual lunghezza

130

trovare questi punti sulla curva 3d

L'esempio seguente mostra come farlo. Notate che esiste una funzione globale in RhUtil che divide una curva in un certo numero di segmenti o di archi che potete usare direttamente, come spiegheremo in seguito.

15.8 Classi di curve non derivate da OnCurve Bench tutte le curve possano essere rappresentate con NURBS, qualche volta utile lavorare con altri tipi di geometria. Una delle ragioni che il loro costrutto matematico pi semplice da capire e sono spesso pi leggere da manipolare. E' relativamente facile alla bisogna trasformare queste curve non derivate da OnCurve nelle corrispondenti NURBS. In sostanza c' unicamente da trasformare nella classe corrispondente. La tavola seguente mostra le corrispondenze.

130

Tipi di Curve OnLine OnPolyline OnCircle OnArc OnEllipse OnBezierCurve

Tipi derivati da OnCurve OnLineCurve OnPolylineCurve OnArcCurve o OnNurbsCurve (usa la funzione GetNurbsForm() ) OnArcCurve or OnNurbsCurve (usa la funzione GetNurbsForm()) OnNurbsCurve (usa la funzione GetNurbsForm()) OnNurbsCurve (usa la funzione GetNurbsForm())

15.9 OnNurbsSurface In modo analogo a quanto spiegato per la classe OnNurbsCurve, per creare una OnNurbsSurface serve conoscere: Dimensione (grado), che tipicamente = 3 Ordine nelle direzioni U e V= grado+1 Punti di controllo
131

Vettori di nodo nelle direzioni U e V Tipo di superficie (tronca o periodica)

L'esempio seguente crea una superficie NURBS da una griglia di punti di controllo:

132

Un'altra esigenza frequente, suddividere il dominio di una superficie, viene mostrato qui sotto, dove la superficie viene suddivisa in parti contenenti un identico numero di punti di controllo (il numero di punti deve essere>1, perch questo abbia senso), compiendo queste operazioni: - normalizza il dominio della superficie (impostando l'intervallo del dominio tra 0 e 1) - calcola il valore di passo in base al numero di punti - usa un'operazione ricorsiva annidata per calcolare i punti della superficie usando i parametri U eV

133

La classe OnSurface dotata di molte funzioni utili per manipolare superfici. L'esempio che segue mostra come tirare una curva sulla superficie. Nel componente di scripting di GH (VB) ci sono due output. Il primo il parametro curva bidimensionale (rappresenta la proiezione della curva 3d sul piano XY), limitatamente al dominio della superficie. Il secondo output l'effettiva curva 3d giacente sulla superficie, che abbiamo ottenuto "tirando" la curva bidimensionale sulla superficie.

134

Usando un esempio precedente, calcoleremo il vettore normale ai punti iniziale e finale della curva tirata sulla superficie. Ecco due diversi modi per farlo: - Usare i parametri 2D degli estremi della curva tirata, che saranno i punti iniziale e finale sulla superficie spianata (bidimensionale) - Oppure usare i parametri 3D dei punti iniziale e finale della curva tirata, trovare i punti pi vicini della superficie 3D ed usare i loro parametri per trovare la normale alla superficie

135

Qui sotto l'immagine del canvas di GH, che mostra l'output del valore dei parametri agli estremi della curva usando entrambi i metodi. Notate che i risultati, come previsto, sono identici.

136

137

15.11 OnBRep Boundary representation (BRep, descrizione attraverso i dati limite) viene usato per descrivere in modo univoco oggetti per mezzo dei loro componenti esterni (di confine). Potete immaginare una BRep come composta da tre parti distinte: Geometria: dati 3D delle curve e delle superfici NURBS, oltre che dati 2D di curve piane o di curve di ritaglio Topologia 3D: facce, spigoli e vertici. Ogni faccia codifica per una superficie Nurbs ed i suoi dati descrivono anche tutte le possibili interazioni. Gli spigoli codificano per le curve 3D. Ogni spigolo possiede una lista di curve di ritaglio, oltre che dei parametri 3D relativi al punto iniziale e finale. I vertici codificano per i punti 3D. Ogni vertice possiede la lista degli spigoli che hanno uno dei loro estremi coincidente con il vertice stesso. Topologia 2D: proiezione 2D di facce e spigoli. Nello spazio 2D parametrico, le curve di ritaglio 2D hanno direzione oraria o antioraria a seconda che facciano parte di un'operazione esterna o interna alla faccia. Ogni faccia valida dovr avere un'unica operazione di ritaglio esterna, ma pu avere un numero illimitato di ritagli interni (fori). Ogni ritaglio codificato da uno spigolo, 2 vertici (estremi), l'operazione di ritaglio stessa (immaginatela come un percorso circolare che parte ed arriva nello stesso punto), e la curva di ritaglio 2D Il diagramma che segue mostra le tre parti e le loro interrelazioni. La parte superiore mostra i componenti della geometria 3D che definiscono una singola faccia BRep con un foro. La parte inferiore rappresenta la topologia 3D che include la faccia BRep, i suoi spigoli esterni ed interni (che circondano il foro) ed i vertici. Sul lato la rappresentazione in piano (spazio parametrico 2D) delle operazioni e della loro sequenza/verso.

138

Variabili di OnBrep Le variabili dei membri della classe OnBrep includono tutte le informazioni relative alla geometria ed alla topologia 2D e 3D. Quando create un'istanza BRep, potete accedere a tutte le funzioni e variabili dello specifico membro della classe. L'immagine seguente mostra le funzioni di un membro in modalit auto-completamento. La tavola elenca i tipi di dati con la loro descrizione.

Membri della Topologia: descrive le relazioni tra diverse parti BRep OnBrepVertexArray m_V OnBrepEdgeArray m_E OnBrepTrimArray m_T OnBrepFaceArray m_F OnBrepLoopArray m_L Array di vertici BRep (OnBrepVertex) Array di spigoli BRep (OnBrepEdge) Array di curve di ritaglio (OnBrepTrim) Array di facce BRep (OnBrepFace) Array di operazioni (OnBrepLoop)

Membri della Geometria: dati geometrici di curve e superfici 3D di curve di ritaglio 2D OnCurveArray m_C2 CnCurveArray m_C3 ONSurfaceArray m_S Array di curve di ritaglio (curve 2D) Array di curve di spigolo (curve 3D) Array di superfici

Notate che ciascuna funzione dei membri della categoria OnBrep sostanzialmente un array di altre classi. Per esempio m_F un array di riferimenti alla OnBrepFace. OnBrepFace una classe derivata da OnSurfaceProxi e possiede variabili e funzioni sue proprie. Ecco qui le variabili delle classi OnBrepFace, OnBrepEdge, OnBrepVertex, OnBrepTrim e OnBrepLoop :

139

Il diagramma che segue mostra le variabili OnBrep e come interagiscono tra loro. Potete usare questa informazione per accedere ad ogni specifica parte di Brep. Per esempio, ogni faccia possiede le informazioni relative alle operazioni coinvolte nella sua creazione, ciascuna operazione ha una lista di curve di ritaglio, da una curva di ritaglio potete ottenere l'informazione sullo spigolo che genera e sui due vertici che determina, e cos via.

140

Ecco qui uno schema pi dettagliato delle interrelazioni tra le parti costitutive delle BRep e del percorso da seguire per passare dall'una all'altra.

Useremo i prossimi esempi per spiegare come creare un'istanza OnBrep, come muoversi all'internio di esse e come ottenere le relative informazioni. Vedremo anche l'uso di alcune funzioni specifiche della classe ed anche di alcune funzioni globali. Creazione di OnBrep Esistono diversi modi di creare una nuova istanza della classe OnBrep: Duplicare una OnBrep esistente Duplicare o estrarre una faccia da una OnBreop esistente Usare la funzione Create che usa come parametro di input una istanza OnSurface Esistono funzioni diverse per ogni tipo di superfici: Da SumSurface Da RevSurface Da PlanarSurface Da OnSurface Usare funzioni globali di utilit: Da OnUtil come ON_BrepBox, ON_BrepCone, ecc. Da RhUtil come RhinoCreateEdgeSurface o RhinoSweep1 e molte altre

Questo un esempio di come creare una BRep dai punti di vertice.


141

Muoversi attraverso i dati OnBrep L'esempio seguente mostra come estrarre i punti di vertice da una superficie chiusa BRep.

Questo mostra come ottenere il numero di parti della geometria e della topologia in una superficie
142

chiusa BRep (facce, spigoli, curve di ritaglio, vertici, ecc.).

Trasformazione di OnBrep Tutte le classi derivate da OnGeometry ereditano quattro funzioni di trasformazione. Le prime sono quelle usate pi di frequente e sono Rotate (ruota), Scale (scala) e Transform (trasforma). Esiste anche una generica funzione "Trabsform" che opera con una matrice di trasformazione 4x4 definita dalla classe OnXform. Parleremo di questa classe nella prossima sezione.

Modifica di OnBrep La maggior parte delle funzioni dei membri della classe OnBrep sono strumenti ad uso di esperti per creare e modificare le BRep. Ci sono per anche molte funzioni globali per compiere operazioni Booleane o spezzare le BRep, come vedremo in un'apposita sezione. Nel Wiki DotNET di McNeel disponibile un esempio eccellente e dettagliato che crea un'istanza BRep da zero e dovrebbe fornirvi un'idea di quel che bisogna fare per ottenere un risultato valido. Ecco qui invece un esempio che estrae le facce OnBrep e le sposta lontano dal centro dell'entit OnBrep, usando il centro del bounding box.

143

Altre funzioni dei membri OnBrep La classe OnBrep possiede molte altre funzioni che sono ereditate da altre classi o specifiche di OnBrep. Tutte le classi di geometria, inclusa OnBrep, hanno una funzione detta "BoundingBox()". Una delle classi di OpenNURBS appunto OnBoundingBox, che fornisce utili informazioni sull'estensione della geometri. Vedete l'esempio seguente, che calcola il bounding box di una BRep, il suo centro e la lunghezza della diagonale.

144

Un altro argomento che si rivela utile conoscere quello delle propriet fisiche della geometria. La classe OnMassProperties ed alcune delle sue funzioni sono illustrate nell'esempio seguente:

145

Esistono alcune funzioni che iniziano con "Is", che di solito ritorna un valore Booleano (vero o falso). Queste funzioni interrogano l'istanza BRep a cui si riferiscono. Ad esempio, se volete sapere se una BRep una poli-superficie chiusa, usate la funzione OnBrep.IsSolid(). E' utile anche verificare se una BRep valida o composta da geometria valida. Ecco una lista di queste funzioni diinterrogazione sulla classe OnBrep:

L'esempio seguente controlla se un punto dato all'interno di una BRep:

Ecco il codice per verificare se il punto interno:

146

15.12 Trasformazioni di Geometria OnXform una classe che serve a memorizzare e manipolare matrici di trasformazione. Ci comprende, ma non limitato a, definire una matrice per muovere, ruotare, scalare o distorcere oggetti. Il membro m_Xform di OnXform una matrice 4x4 di numeri in doppia precisione. La classe comprende anche funzioni che supportano le operazioni matriciali, come inversione e trasposizizione. Ecco alcune funzioni di membri della classe collegate con l'esecuzione di diverse trasformazioni:

Una bella utilit di auto-completamento (per altro disponibile per tutte le funzioni) quella che all'atto della selezione mostra tutte le funzioni collegate. Per esempio, Translation (spostamento) accetta sia tre coordinate numeriche che un vettore, come mostrato in figura.

Di seguito alcune altre funzioni OnXform:

Il prossimo esempio accetta come input un cerchio e genera tre cerchi. Il primo una copia scalata dell'originale, il secondo una copia ruotata ed il terzo una copia spostata.

147

15.3 Funzioni di utilit globali A parte le funzioni specifiche dei membri di ciascuna classe, Rhino.NET SDK fornisce una serie di funzioni globali nei gruppi OnUtil e RhUtil. Faremo degli esempi usando alcune di queste funzioni.

148

OnUtil Ecco qui un sommario delle funzioni disponibili, in OnUtil, che si riferiscono a geometria:

Intersezioni OnUtil La funzione di utilit globale ON_Intersect ha ben 11 funzioni collegate. Ecco qui una lista di geometria intersecante ed i valori in uscita (la "I" che precede come in "IOnLine" significa che viene generata un'istanza costante):

Geometria Intersecante IOnLine con IOnArc IOnLine con IOnCircle IOnSphere con IOnShere IOnBoundingBoc con IOnLine IOnLine con IOnCylinder IOnLine con IOnSphere IOnPlane con IOnSphere IOnPlane con IOnPlane with IOnPlane

output Parametri della linea (t0 & t1) e punti dell'arco (p0 & p1) Parametri della linea (t0 & t1) e punti del cerchio (p0 & p1) OnCircle Parametri della linea (OnInterval) 2 punti (On3dPoint) 2 punti (On3dPoint) OnCircle On3dPoint

149

151

Funzione Dividi curva di RhUtil E' possibile dividere una curva, in un determinato numero di segmenti oppure in segmenti di una determinata lunghezza, usando la funzione di utilit RhUtil.RhinoDivideCurve. Ecco uno elenco dei parametri della funzione: RhinoDivideCurve: nome della funzione Curve: curva costante da dividere Num: numero di segmenti in cui dividerla Len: lunghezza dei segmenti con cui dividerla False: spuntare per invertire la direzione della curva (pu essere impostata a True o False) True: include la creazione degli estremi della curva (pu essere impostata a True o False) crv_p: lista dei punti che dividono la curva crv_t: lista dei parametri dei punti di divisione sulla curva Esempio di divisione della curva per numero di segmenti:

Esempio di divisione di una curva per lunghezza di archi:

152

Utilit Interpola curva tra punti RhinoInterpCurve: nome della funzione 3: grado della curva pt_array: punti da interpolare Nothing: Tangente all'inizio della curva Nothing: Tangente alla fine della curva 0: nodi uniformi (nessuna cuspide) L'esempio che segue prende come input una lista di punti da On3dPoints e crea una curva NURBS che passa dagli stessi.

153

Utilit RhUtil Crea una superficie da spigoli L'input nell'esempio seguente una lista di quattro curve e l'output una superficie da spigoli.

154

16 Aiuto
Dove trovare maggiori informazioni su Rhino DotNET SDK
Nel Wiki McNeel potete trovare un sacco di informazioni e di esempi. Gli sviluppatori di Rhino continuano ad aggiungere nuovo materiale. E' una grande risorsa da usare, la trovate a questo indirizzo:
http://en.wiki.mcneel.com/default.aspx/McNeel/Rhino4DotNetPlugIns.html

Forum e Gruppi di discussione


La comunit di Rhino molto attiva e pronta ad aiutare. Il forum di discussione di GrassHopper il posto giusto per iniziare: http://grasshopper.rhino3d.com/ Potete anche porre domande nel Rhino Developer Newsgroup (il newsgroup degli sviluppatori) accessibile alla pagina di McNeel: http://www.rhino3d.com/developer.htm

Debugging con Visual Studio


Per codice pi complesso che sarebbe difficile debuggare all'interno del componente script di GH, potete usare il programma Visual Studio Express, fornito gratuitamente da MicroSoft, oppure la versione professionale a pagamento per sviluppatori. Dettagli per scaricare il programma gratuito e per come usarlo si possono trovare qui: http://en.wiki.mcneel.com/default.aspx/McNeel/DotNetExpressEditions Se disponete della versione professionale di Visual Studio, ancora meglio. Controllate al link seguente per ricevere aiuto ad installarlo ed usarlo: http://en.wiki.mcneel.com/default.aspx/McNeel/Rhino4DotNetPlugIns.html

Esempi di scrip in GrassHopper


La galleria di GrassHopper ed i forum contengono molti esempi di componenti scriptati che troverete molto utili.

155

Note