[export ply|off|stl] Per quanto riguarda il salvataggio per questi tre formati viene richiamata la funzione exporter appartenente alla libreria vcg, che provvede a sua volta ad invocare la funzione corretta per il salvataggio del formato. [export_obj.h] AllÂinterno di questo file viene definita la funzione per il salvataggio della mesh in formato obj. Tale funzione ha più firme, ma di seguito viene descritta solamente quella principale. LÂalgoritmo è diviso in quattro fasi: 1. Inizializzazione variabili + controlli 2. Salvataggio vertici + normali per vertice 3. Salvataggio facce + coordinate texture 4. Salvataggio materiali 1. controllo dellÂesistenza vertici e facce. 2. Vengono salvate su file le coordinate del vertice nel seguente forma: v x,y,z. Per quanto riguarda le normali viene prima controllato se esse sono state selezionate dalla dialog utilizzata per decidere quali informazioni salvare della mesh, in tal caso la normale viene passata alla funzione AddNewNormalVertex() come parametro la quale restituisce false se la normale è già presente nella map o true se essa è una nuova normale e in tal caso viene salvata nella seguente forma: vn x,y,z. 3. Questa fase può essere divisa in tre sottofasi: selezione o creazione del materiale della faccia; salvataggio delle coordinate di texture e come ultima fase viene assemblato il tutto per salvare tutte le facce, dove ognuna delle quali è composta da: lÂindice del vertice(parte da 1 non da 0), lÂindice di coordinata di texture, lÂindice della normale. Il salvataggio delle coordinate di texture avviene analogamente come nel punto 2 per le normali. 4. Viene richiamata la funzione WriteMaterials la quale salva tutti i materiali presenti nel vector Materials. [export_3ds.h] CÂè da precisare che il salvataggio dei file 3ds è stato implementato utilizzando la libreria lib3ds. Questa funzione è divisibile in cinque fasi distinte: 1. controlli correttezza mesh 2. generazione vertici duplicati, se necessario 3. salvataggio dei vertici 4. salvataggio facce, texture e materiali. 5. salvataggio del file 3ds mediante la chiamata della funzione della libreria lib3ds 1. nella prima fase viene controllato oltre allÂesistenza di vertici,facce e se il numero di vertici presenti nella mesh non sia superiore a 65535, numero massimo consentito dal formato 3DS. 2. questa fase viene eseguita solamente quando viene deciso di salvare le coordinate di texture della mesh, sempre che essa le abbia. Il concetto che sta alla base è il seguente: si tiene in considerazione una mappa ListOfDuplexVert<Key,int>, alla quale gli viene associato il seguente significato: Key:è una coppia (int,TexCoord) formata da un int che rappresenta l'indice del vettore nella mesh originale e la sua coordinata di texture. tale coppia rappresenta una chiave, essendo univoca in tutta la mesh. non è possibile che si incontrino due vertici che hanno solita coordinata di vertice e solite coordinate di texture, se un vertice di questo tipo esistesse allora i due vertici rappresenterebbero lo stesso vertice. int:è l'indice del vertice inserito all'interno del vettore VectorOfVertexType<VertexType>. Nel vertice VectorOfVertexType vengono inseriti tutti i vertici appartenenti alla mesh + i k vertici dublicati. la scelta di tali vertici va in base alla seguente regola: se un vertice con indice i(originale) ha più di una coordinata di texture allora tale vertice viene duplicato e inserito in ListOfDuplexVert e in VectorOfVertexType(in VectorOfVertexType, l'inserimento del doppio vertice non sarebbe necessario, però viene fatto per comodità , in caso contrario dovremmo cercare il vertice dentro il vettore). 3. Il salvataggio dei vertici può esser fatto in due modi distinti: il primo nel caso in cui si trattano le coordinate di texture, il secondo in cui la mesh non ha texture o lÂutente decide di non salvarle. Nel primo caso i vertici da salvare sono quelli presenti nel vettore VectorOfVertexType e quindi comprendenti anche i vertici duplicati, nel secondo caso i vertici sono quelli della mesh e quindi non abbiamo bisogno dei vertici duplicati. I vertici da salvare vengono inseriti allÂinterno la struttura dati presente in lib3ds. 4. Per il salvataggio delle facce viene fatto un ciclo for su tutte le facce, per ogni faccia vengono presi gli indici dei vertici che la compongono. LÂassegnamento dei vertici alla faccia viene fatto in due modi: il primo considerando le coordinate di texture, quindi lÂindice da assegnare è lÂindice del vertici allÂinterno dei vertici duplicati, nel secondo modo, senza texture, vengono considerati gli indici dei vertici appartenenti alla mesh. Successivamente vengono salvate, cioè inserire allÂinterno della mesh della lib3ds, le informazioni che lÂutente ha selezionato, in ordine : texture, normali e materiali. 5. Appena finito la creazione della mesh della libreria lib3ds, viene aggiunto il nodo rappresentante tale mesh, dopodichè viene chiamata la funzione della libreria lib3ds per salvare la mesh su file. Il risultato ti tale operazione viene restituito al chiamante. [material.h] Il questo file viene definita la struttura dati del materiale. La funzione CreateNewMaterial() crea un nuovo materiale aggiungendolo al vector passato come argomento, sotto condizione che esso sia effettivamente un nuova materiale. Nel caso in cui il materiale sia nuovo viene restituito un intero rappresentante la dimensione del valore del vector, altrimenti viene restituito lÂindice del materiale allÂinterno del vettore. [savemaskexporter.h/cpp/ui] à la dialog mediante la quale lÂutente può selezionare cosa salvare di una mesh. Le informazioni selezionabili sono quelle presenti allÂinterno dellÂenumerazione nel file sf\wrap\io_trimesh\io_mask.h appartenente alla libreria vcg. La dialog ha il seguente funzionamento: a priori sappiamo quale informazioni, sotto forma di maschera, sono presenti nella mesh caricata. Ogni tipo di exporter ha una funzione, GetExportMaskCapability, la quale restituisce una capability(maschera) contenente le informazioni che il formato può salvare. A questo punto viene fatto il merge delle due maschere, così facendo le informazioni che possono essere selezionate sono quelle che sono presenti sia nella mesh che nella capability. à possibile dalla dialog appena descritta selezionare, se presenti, i nomi dei file delle texture e modificarne il valore. La modifica non fa nessun controllo ne che il file esista ne che le coordinate di texture siano consone a quel tipo di file. [changetexturename.h/cpp/ui] à la dialog con quale lÂutente seleziona/modifica il nome del nuovo file della texture. Tale interfaccia grafica viene richiamata da savemaskexporter. [meshio.h/cpp] Raggruppa tutti i salvataggi dei vari formati. AllÂinterno vi è un membro save( ) il quale permette di salvare la mesh in tutti i formati disponibili. Per ogni formato viene eseguita la seguente procedura: viene richiamata la funzione Save( ) dellÂexporter la quale restituisce un interno >= 0 rappresentante il codice di errore. 0 rappresenta NOERROR. Se il salvataggio restituisce un errore viene visualizzata un dialog contenente la stringa di errore associata allÂintero. Vi sono altre tre funzioni presenti in questo codice: importFormats( ) che restituisce la lista delle estensioni dei file supportati per importazione; exportFormats( ) restituisce la lista delle estensioni dei file supportati per lÂesportazione; GetExportMaskCapabilty( )restituisce la capability relativa allÂestensione passata come argomento. [glarea.h/cpp] definita un funzione che restituisce una stringa del tipo VC, FC,WT . contenente le informazioni caricate da file della mesh. Le informazioni prese in considerazione sono quelle allÂinterno di MeshModel. [mainwindow.h/cpp] Implementata la funzione Saveas( ) il cui funzionamento è il seguente: 1. vengono caricati i filtri, ovvero i vari formati supportati 2. viene aperta la dialog con la quale è possibile selezionare/digitare il nome e il formato con cui salvare la mesh 3. viene ricavato il pluing in base allÂestensione del file 4. viene prelevata la capability del formato 5. viene prelevata la maschera che lÂutente ha scelto di salvare 6. viene eseguita la funzione Save relativa al plugin passangohli lÂestensione del file e la maschera presa al punto 5. [interface.h] modificata l'interfaccia MeshIOInterfaces. [vecchia dialog obj export] creata una dialog personalizzata per esportazione del formato obj, devenuta in un secondo momento obsoleta e quindi eliminata dal progetto! [Trasparenza intermediazione plugin IO] Adattamento della mainWindow di meshLab in modo da supportare in maniera del tutto trasparente all'utente il meccanismo di import/export realizzato tramite l'intermediazioni di plugin. A tale proposito e' stata modificata la modalita' di caricamento dei plugin di IO, che ora provvede a conservare i puntatori ai plugin di io all'interno di un vettore presente in mainWindow; e sono stati adattati i metodi open e saveAs di mainwindow in modo da rendere accessibili, nelle usuali finestre di open e save, tutti i formati resi disponibili dai plugin. Entrambe le funzioni invocano un apposito metodo che si occupa di popolare una map che conserva l'associazione <estensione format, indice plugin corrispondente>. In questo modo data l'estensione del file e' possibile delegare al plugin corrispondente il compito di importare/esportare il file specificato. [import] - import STL e OFF vengono semplicemente invocati i metodi open delle rispettive classi ImportSTL e ImportOFF e in caso di errore viene mostrato il messaggio di errore corrispondente. Se invce tutto va' a buon fine vengono calcolate le normali per faccia. - import ply ci si limita ad invocare la loadmask, abilitare le coordinate di texture per wedge se presetni e viene invocato il metodo open. Opportuni messaggi in caso di errore. - import obj Per quanto riguarda l'importazione dei file di tipo obj, il compito e' eseguito principalmente dalla classe ImportOBJ, che fornisce i metodi Open e LoadMask. Entrambe le funzioni prevedono come parametro in ingresso una struttura di tipo ObjInfo, che contiene le seguenti informazioni: - numero di vertici - numero di facce - maschera di bit relativa alle informazioni presenti nel file - puntatore alla callback utilizzata per informare l'esterno riguardo lo stato di avanzamento del processo, e per rendere il processo interrompibile. Lo stesso oggetto viene dapprima passato alla loadMask che provvede a riempirne i campi significativi e in seguito e' passato alla stessa procedura open. La loadmask, a seconda di quanto trovato nel file, andra' a settare i bit relativi a normali per wedge, coordinate di texture per wedge, colore per faccia, colore per vertice. La open si occupa di riempire i campi della struttura dati del modello in base alle informazioni esistenti nel file: coordinate dei vertici, coordinate di texture per vertice, normali per vertice, facce, colore. In particolare, per quanto riguarda le normali per faccia si distinguono due casi: - se e' presente la normale per wedge si ottiene la normale per faccia facendo la media delle normali per wedge - altrimenti si calcola la normale per faccia con il prodotto vettore (si invoca la face::ComputeNormalizedNormal). Inoltre riguardo alle facce, se queste corrispondono a poligoni con piu' di tre vertici, nell'importer si provvede a suddividerle in triangoli ottenuti considerando il primo vertice come vertice comune a tutte le facce generate, mentre gli altri due vertici corrispondono agli ultimi due vertici incontrati tra quelli enumerati all'interno della faccia. I questo modo si ottiene una "triangolrizzazione" a ventaglio. Nel caso in cui nel file siano presenti degli errori, a seconda della gravita' degli stessi ci si comporta in due diverse modalita'. Nel caso in cui l'errore sia di una certa criticita', e quindi tale da non permettere il caricamento corretto delle caratteristiche geometriche del modello, il processo di lettura viene interrotto e viene restituito il corrispondente codice di errore, in base al quale verra poi mostrato l'oportuno messaggio. Nel caso in cui l'errore riscontrato non sia di una eccessiva gravita', e comunque tale da non pregiudicare il caricamento della strutura geometrica del modello (es: definizione di materiale mancante, texture non trovata), il processo di caricamento non viene interrotto. ma ci si limita a fornire un opportuno messaggio di errore. Lo stesso avviene anche quando nella definizione di un modello vi sono triangoli in cui vi e' piu' di un vertice con lo stesso indice. - import 3ds Anche per quanto riguarda l'importazione dei file di tipo 3ds, il processo prevede l'invocazione dei due metodi LoadMask ed open. Anche in questo caso i due metodi condivinono come parametro in ingresso una struttura chiamata 3dsInfo, che in sostanza contiene gli stessi membri visti nella struttura corrispondente per i file obj. Oltre a questa struttura, nel caso dei file 3ds, dato che il caricamento di questo tipo di file e' quasi totalmente delegato alla libreria Lib3ds, i due metodi condividono anche un ulteriore parametro, ossia un puntatore ad una struttura di tipo Lib3dsFile, in modo da caricare questa struttura una sola volta e condividerla tra i due metodi. La lettura dei file 3ds avviene in maniera ricorsiva sui nodi (chunk) del file 3ds, l'importer si occupa della lettura di coordinate dei vertici, facce, colore per faccia, normale per faccia e normale per wedge, coordinate di texture. L'importer legge correttamente anche files contenenti piu' meshes in nodi diversi, in tal caso vengono effettuate delle opportune operazioni matriciali affinche tutte le mesh compaiano nella loro corretta posizione le une rispetto alle altre. Dato che le operazioni sopra elencate consistono a meno di semplificazioni in una semplice traslazione, l'applicazione di tali operazioni viene effettuata solo nei confronti delle coordinate dei vertici e non delle normali.