Modulo 2. Rappresentazione di oggetti 3d. L'ingrediente successivo ad una tecnica di rappresentazione dello spazio 3d per la computer grafica è la descrizione degli oggetti “solidi” all'interno della scena. Questo problema è stato studiato a lungo dai matematici ancor prima dell'avvento della Computer Grafica. Esso ha avuto anche l'attenzione negli anni 60 da parte degli ingegneri manifatturieri: era importante vere modelli che potessero essere “letti” da un torno a controllo numerico per produrre industrialmente parti meccaniche, carrozzerie eccetera. Cosa è un solido 3d? Prima di occuparci di come rappresentare un solido dentro al computer digitale cerchiamo di precisare “cosa” è esattamente nella applicazione che stiamo considerando un solido. Un oggetto 3d è comunemente ed intuitivamente detto un solido. La “topologia matematica” ha elaborato una elegante teoria per definire con precisione e classificare i solidi della quale diamo di seguito qualche cenno. In topologia due insiemi di punti si dicono “omeomorfi” se si può costruire una corrispondenza biunivoca tra i due insiemi che preservi fedelmente le relazioni di “intorno” cioè di “vicinanza” tra punti. Intuitivamente due insiemi in 3d si dicono omeomorfi se, immaginandoli fatti di una gomma estremamente robusta e flessibile, possono essere deformati l'uno nell'altro senza lacerazioni, senza auto-intersezioni e senza saldature. Per esempio un cubo e una sfera sono omeomorfi. Una ciambella “donut” e una tazza da cappuccino sono omeomorfe. Un cubo e una tazzina non sono omeomorfi. Un cubo e una bottiglia... eccetera. Elaborando questa teoria i matematici sanno assegnare ad ogni oggetto “solido orientabile” un numero detto “genere”. Una sfera e qualsiasi oggetto ad essa omeomorfo ha genere 0, un toro ha genere uno, una sfera cui sono stati incollati k manici avrà genere k. Una tazza da cappuccino e una ciambella con un buco avranno allora il medesimo genere. Per gli scopi della computer grafica un solido può essere definito come segue: esso è un insieme di punti S in 3d con la seguente proprietà: per ogni punto x dell'insieme posso sempre trovare una sfera sufficientemente piccola, che contiene x al suo interno (cioè non sulla sua superficie esterna o frontiera), la cui intersezione con i punti dell'insieme S è omeomorfa a una sfera. Esempio: un cubo è un solido. Esempio: un disco 2d matematico nello spazio NON è un solido. Esempio: due cubi disgiunti che si toccano solo in un vertice NON sono solidi. Qualsiasi sfera che contenesse quel vertice produce, intersecandosi con i due cubi una regione dello spazio che non è omeomoforma ad una sfera. Un solido infine può essere connesso o formarsi dalla unione di sottoinsiemi connessi disgiunti. Esempio: se i due cubi disgiunti che si toccano in un solo vertice vengono allontanati di una distanza infinitesima, quanto basto a creare un “vuoto” tra essi, il problema che ci impediva di trattare il caso procedente come un solido, viene meno. Le principali alternative per la descrizione dei modelli. La rappresentazione “matematico-digitale” degli oggetti solidi che intendiamo posizionare dentro una scena 3d può essere effettuata in moltissimi modi diversi. La descrizione di un “oggetto solido 3d” può essere realizzata (in alternativa): 1. descrivendo come “costruire” l'oggetto a partire da “blocchi elementari” o “primitive” (possibilmente controllate da pochi parametri, combinate tra loro mediante operazioni insiemistiche elementari. Si parla in quesot caso di Solid Constructive Geometry (SCG). Tale approccio, storicamente il più antico della computer grafica è stato abbandonato per lungo tempo ed è riapparso di recente in modelli particellari dove le primtive tendono ad essere le “molecole” costituenti un oggetti solido (o una loro macroscopica approssimazione). 2. descrivendo quali punti dello spazio 3d sono pieni (occupati dall'oggetto e dal suo “volume”) o vuoti. Questo approccio richiede un algoritmo che dato un punto “decida” se esso è interno o esterno al volume dell'oggetto. Le varianti di questo approccio prevedono veri e propri algoritmi ad “albero decisionale” (Binary Partition Trees, BPT) o, in alternativa metodi “enumerativi”. I metodi enumerativi richiedono di suddividere lo spazio in una griglia 3d di elementini (usualmente parallelepipedi o cubetti) detti “volume elements” o voxel e di assegnare a ciascun elemento di volume un grado di densità del suo riempimento secondo una scala/palette prestabilita . Il caso più semplice è ovviamente quello della palette 0/1 (pieno/vuoto). Per i modelli enumerativi si pongono i problemi di scelta della risoluzione (e l'apparizione dei relativi artefatti dovuti al limitato campionamento: aliasing) oltre a quello delle importanti quantità di memoria richieste per mantenere modelli anche molto semplici. D’altro canto la possibilità di variare le “densità” di volume rende questo approccio estremamente utile nel caso di modelli grafici costruiti a partire da dati medici (tomografie, risonanze eccetera). Per i modelli ad albero decisionale il limite principale è posto dalla complessità dell'algoritmo che decide se un punto è interno o esterno oltre alla difficoltà di traferire questa informazione in un effettivo algoritmo di resa grafica. 3. descrivendo la geometria della sua “buccia” o “superficie” (Boundary representation, BRep). Questo è il modello più comune e quello maggiormente usato nella grafica 3d (vedi sotto). Le varianti di questo approccio sono relative ai metodi di descrizione di una superficie in 3d: per poligoni, per curve e superficie parametriche, come zeri di funzioni matematiche di varia complessità (funzioni soglia su distribuzioni arbitrarie di densità). Si deve inoltre osservare che è spesso necessario passare dall'una all'altra di queste rappresentazioni a seconda del tipo di applicazione e del motore di rendering che si utilizza. Come esempio di traduzione dal modello voxel a quello poligonale si presenterà più in là in questo corso l'algoritmo dei “marching cube”, che ha enorme popolarità. Di seguito diamo alcuni cenni ed informazioni alle varie rappresentazioni menzionate nella sinossi precedente. Constructive Solid Geometry. Descrivere un oggetto è come fornire un metodo per costruirlo a partire da oggetti elementari di semplice definizione e parametrizzazione e “combinando” con un insieme di operazioni semplici vari oggetti primitivi tra loro. Si tratta quindi di un approccio algoritmico alla costruzione di solidi. L'idea è di fornire un kit di solidi iniziali, detti “primitive”. Tale kit può essere più o meno ricco, ma ciascuna primitiva deve essere descritta per mezzo di pochi parametri, facili da capire e memorizzare sul computer. Esempio: un cubo, basta dare le coordinate di un vertice e del vertice opposto ad esso per avere ogni informazione utile a decidere quali punti sono dentro e fuori dal cubo. In alternativa un cubo sarà descritto dalla posizione in 3d del suo centro, dalla misura del suo spigolo e dall'orientamento nello spazio delle sue facce parallele. Esempio: una sfera, basta dare le coordinate del centro e il raggio. Esempio: la testa di Suzanne, o altri oggetti complessi. Essi sono completamente descrivibili se conosciamo i parametri che descrivono con precisione la loro bounding-box. A partire da queste “forme” base si costruiscono altre forme mediante operazioni quali: a) unione b) intersezione c) differenza d) “sweeping” lungo una curva e) rotazione intorno ad un asse Bisogna però essere molto prudenti: se combiniamo due solidi con una delle operazioni indicate, otteniamo ancora un solido secondo la definizione? La risposta è no. Per ovviare a questo problema si definiscono le versioni “costruttive solide” delle operazioni menzionate che prevedono oltre alla esecuzione della operazione una finale fase di “pulizia” che elimina i punti che violano la proprietà dei solidi o li completa perché tale proprietà sia soddisfatta. Nonostante la semplicità logica e la eleganza di questo approccio esso NON ha avuto molto seguito nella CG moderna. Tuttavia essa è ancora supportata in molte suite 3d moderne. La ragione della sua rilevanza è che essa può essere utilizzata efficientemente per situazioni in cui è importante simulare la collisione e le interazioni tra differenti solidi e nel ray-tracing. In tal caso la CSG si applica alle “bounding boxes” che racchiudono oggetti più complessi. Negli anni recenti ci sono stati diverse proposte di “ritorno” alla CSG. Se infatti le primitive che si possono mettere in gioco possono essere moltissime (cosa impossibile con le architetture degli anni 70-90) si può modellare un solido come l'insieme delle “macro molecole” che lo compongono. Tale approccio rimane però ancora legato a specifiche applicazioni (simulazione di fluidi e medicina) Modello “decisionale” BPT (Binary Partition Tree) In alcune applicazioni tutto quel che occorre sapere di un solido è quando un punto è “interno”, “esterno” o sulla “frontiera” per tale solido. Un settore molto importante della informatica (computational geometry) si è occupato per varie ragioni di questo approccio le cui applicazioni si trovano anche al di fuori della grafica. Una tecnica molto comune quando si deve prendere una decisione è quella di porsi una sequenza ordinata di domande. Esempio: un comune gioco di società chiede ad un giocatore di indovinare un oggetto pensato dagli altri ponendo solo k domande. Egli chiederà cose del tipo: “è vivente o inanimato?”, “è concreto o astratto?”, “E' caldo o freddo?”, eccetera. In pratica ad ogni domanda egli attraversa un albero binario, partendo dalla sua radice e sceglie di seguire l'uno o l'altro dei rami che si dipartono dal nodo in cui si trova. Se è bravo troverà un cammino che in meno di k passi lo conduce ad una foglia (cioè ad un nodo cui corrisponde un unico oggetto corrispondente a quello pensato dagli altri giocatori). Il BPT realizza questo “gioco” con i punti nello spazio. Per illustrarlo tracceremo solo dei disegni nel piano 2d ma l'idea di base è la stessa in 3d. Si osservi anzitutto che data una retta (o in 3d un piano) mediante la sua equazione di primo grado, il tempo richiesto per capire se un punto è a sinistra o a destra della retta è costante. Si tratta di calcolare il segno che la equazione della retta assume in quel punto. Se è positivo si è a derstra, altrimenti si è a sinistra, se è nullo si è sul bordo tra i due semispazi che la retta definisce. Porre una domanda costa dunque un numero costante di operazioni. Supponiamo che si voglia definire l'insieme dei punti interni alla lettera Y maiuscola nel piano disegnata con le proporzioni delle seguenti figure. Se tracciamo tutte le rette che definiscono il bordo della Y (si tratta di 8 rette) resteranno definite 8 “query” lineari (numerate da 1 a 8). Esse definiscono a loro volta 31 regioni del piano (etichettate con le lettere da A,...,Z,a,...,f) di cui 8 IN e 23 OUT.. Se definiamo per le rette orizzontali o diagonali un predicato “sotto” (con valore 1/0) per le rette verticali un predicato “a sinistra” (con valore 1/0), per ogni regione resta definito un codice binario a 8 bit: Esempi: A=00110011, … , S=10111011, eccetera. Si possono proporre “alberi” decisionali che assegnando ad ogni punto gli otto bit del codice della sua regione stabilisce se un punto è dentro o fuori la shape della Y maiuscola. Gli alberi possono avere dimensioni diverse a seconda della strategia che si sceglie nel costruirli. Per esempio nel caso della shape Y, ogni codice che inizi con 01 implica che siamo fuori dalla shape e conviene quindi a iniziare a definire questi due bit di codice. Si osservi come in generale la complessità della forma da codificare può portare a alberi decisionali davvero molto complicati. Questo rende questo approccio, teoricamente molto elegante, in realtà poco applicabile ai problemi della grafica se non in contesti speciali. Infine una nota: il metodo BPT può pensarsi come una derivazione del metodo CSG. Una shape si compone della unione di parti convesse ottenute con la intersezione di numerose “primitive” tutte di tipo “semi-spazio”. Per esempio la nostra Y può pensarsi come la unione delle aree convesse: C1=J+P, C2=N+Q+R+T, C3= W+U. Derivare alberi decisionali per ciascuna di tali regioni è abbastanza diretto. Modelli enumerativi La partizione con semipiani genera regioni di dimensioni variabili e cerca di “adattarsi” alla forma del solido da descrivere. Si può, in alternativa, dividere lo spazio in “celle” regolari, per esempio a forma di “cubetto”, e assegnare a ciascuna cella l'etichetta piena o vuoto. Ogni solido si potrà pensare come un aggregato di questi cubetti. Gli elementini di volume sono detti “volume elements” contratto in “voxel” (parafrasando la contrazione di “picture element” in ”pixel”. Se i cubetti sono di dimensioni grandi ogni solido ci apparirebbe, a causa dell'aliasing, come una costruzione fatta con i “lego”. Solo se i cubetti sono sufficientemente piccoli restano catturati anche i dettagli minuti. Si esamini il piccolo esempio realizzato su Suzanne. Si tratta in pratica di “rasterizzare” un volume così come si fa con una immagine e le problematiche incontrate nello studio della risoluzione, dell'aliasing e del campionamento ottimale di un segnale 1d e 2d si ripropongono eguali in questo caso 3d. I due fattori più importanti per questi modelli sono la forma delle celle e la loro dimensione. Minore la dimensione maggiore sarà la risoluzione che si ottiene. Alte risoluzioni richiedono un prezzo: suddividere un cubo in H cubetti in ogni direzione porta a H 3 cubetti. Se si raddoppia la risoluzione lineare il numero di cubetti aumenterà di 8 volte. Uno svantaggio del modello enumerativo è dovuto al fatto che le cellette sono tutte della stessa dimensione sia in aree del solido ricche di dettaglio che in quelle vuote o molto semplici. Di conseguenza si ha uno spreco di voxel (e di RAM!) nelle aree di poco dettaglio e una insufficienza di precisione nella ricostruzione (aliasing) di zone dettagliate. La forma più popolare delle celle è quella di parallelepipedi o cubi. Sono però anche usate decomposizioni in tetraedi e in piramidi. Un grande vantaggio di questo modello è che ad ogni cubetto può essere associato un valore qualunque tratto da palette opportune scelte a secondo delle applicazioni. Il caso più comune è quello in cui ciascun cubetto porta con se un valore di “densità”. Questa tecnica è utile nelle immagine mediche ottenute da tomografie o nelle simulazioni di eventi gassosi (nubi, fumo). Alla tecnica dei “voxel” si associano algoritmi specializzati di rendering, detti “rendering volumetrico”. Essi sono in grado di “simulare” livelli di trasparenza arbitrari e ci consentono di visualizzare strutture biologiche ed anatomiche complesse in maniera interattiva (si raccomanda a tal proposito di curiosare nei siti web che fanno riferimento al “visible human”). L'esempio che si riporta è stato ottenuto da ricercatori austriaci in “Style Transfer Functions for Illustrative Volume Rendering”, S.Bruckner, E.Groller, Style Transfer Function for Illustrative Volume Rendering. in Computer Graphics Forum, 26(3):715-724, September 2007.