vcglib/vcg/complex/trimesh/create
Paolo Cignoni 7befff7bec make point2 derived Eigen's Matrix, and a set of minimal fixes to make meshlab compile
with both old and new version. The fixes include:
- dot product: vec0 * vec1 => vec0.dot(vec1) (I added .dot() to the old Point classes too)
- Transpose: Transpose is an Eigen type, so we cannot keep it if Eigen is used. Therefore
  I added a .tranpose() to old matrix classes, and modified most of the Transpose() to transpose()
  both in vcg and meshlab. In fact, transpose() are free with Eigen, it simply returns a transpose
  expression without copies. On the other be carefull:  m = m.transpose() won't work as expected,
  here me must evaluate to a temporary: m = m.transpose().eval(); However, this operation in very
  rarely needed: you transpose at the same sime you set m, or you use m.transpose() directly.
- the last issue is Normalize which both modifies *this and return a ref to it. This behavior
  don't make sense anymore when using expression template, e.g., in (a+b).Normalize(), the type
  of a+b if not a Point (or whatever Vector types), it an expression of the addition of 2 points,
  so we cannot modify the value of *this, since there is no value. Therefore I've already changed
  all those .Normalize() of expressions to the Eigen's version .normalized().
- Finally I've changed the Zero to SetZero in the old Point classes too.
2008-10-28 00:59:46 +00:00
..
advancing_front.h added missing std:: 2008-04-08 09:51:15 +00:00
ball_pivoting.h Port to eigen2: state of the mess: 2008-10-27 19:35:17 +00:00
emc_lookup_table.h minor changes to comply gcc compiler 2005-03-30 17:18:13 +00:00
extended_marching_cubes.h big replacement .Zero => .SetZero, and start of Eigen's compatibilities (currently disabled by default) 2008-10-27 14:48:14 +00:00
marching_cubes.h Removed updating of normal when computing 'C' vertex: it should not be done here and could be dangerours if vertex type has not the normal. 2005-07-26 06:10:28 +00:00
mc_lookup_table.h added missing license info 2008-05-29 20:54:34 +00:00
platonic.h added facegrid method to build just the faces 2008-04-24 04:44:48 +00:00
readme.txt Initial commit 2005-01-24 09:49:16 +00:00
resampler.h make point2 derived Eigen's Matrix, and a set of minimal fixes to make meshlab compile 2008-10-28 00:59:46 +00:00

readme.txt

MARCHING CUBES & EXTENDED MARCHING CUBES
===================================================================================
In breve le classi coinvolte sono 3 e sono:
	* MerchingCubes ed ExtendedMarchingCubes
			processano una cella alla volta, aggiungendo per ogni chiamata a ProcessCell 
			l'insieme di triangoli approssimante la superficie che interseca la cella
	* Walker
			gestisce l'attraversamento del volume, servendo le chiamate effettuate dagli
			algoritmi di estrazione della superficie al volume e cachandone i risultato
	*	Volume
			conosce come calcolare il campo scalare all'interno del volume da processare 
			e come calcolare le intersezioni superficie/segmenti.
			

DESCRIZIONE
====================================================================================
	Le classi che implementano gli algoritmi MarchingCubes ed ExtendedMarchingCubes
sono state implementate così da risultare quanto più generiche possibile: ogni chiamata
al metodo ProcessCell(Point3i p1, Point3i p2) analizza la cella del volume individuata 
dai due punti p1 e p2 e l'analisi di questa cella si conclude esattamente al ritorno da questa 
chiamata: nel caso infatti la superficie da estrarre attraversi questa cella, all'interno 
di questa stessa chiamata la mesh viene aggiornata con un opportuno insieme di triangoli.
L'assunzione alla base di questa astrazione è l'esistenza di altri due entità, il Walker
ed il Volume; sebbene sulla loro implementazione è lasciata la più completa libertà, è utile
precisare in quale relazione essi stiano rispetto agli algoritmi di estrazione di superfici.

Un esempio che riassume quanto qui esposto è incluso nella libreria: vd. vcg/apps/test/extractors.
	
VOLUME
====================================================================================
	Gli algoritmi di estrazione di superfici risalgono alla superficie utilizzando i valori
di un campo scalare definito sul volume da processare campionato sui vertici di una qualche 
griglia. Questo campo scalare sarà generalmente diverso a seconda del tipo di applicazione.
Il Volume è appunto quella classe che racchiude il campo scalare e di cui ne conosce le proprietà.
In realtà, all'interno dell'algoritmo di estrazione di superfici, non esiste alcun collegamento
esplicito con il Volume: tutte le sue chiamate sono rivolte al Walker. Questo perché
(per motivi che saranno esposti successivamente a proposito del Walker) il Walker potrebbe già 
possedere il valore del campo calcolato in un dato punto, che evita così di farselo ricalcolare 
nuovamente dal Volume: Similmente, quando viene chiesto di calcolare il punto di intersezione 
della superficie con un segmento, se il Walker dispone già di questa informazione, la restituisce
all'algoritmo di estrazione di superfici, altrimenti il calcolo verrà effettuato dal Volume: il 
punto ottenuto verrà restituito al Walker che potrà quindi soddisfare la richiesta iniziale. 
Il motivo per cui si è scelto di frapporre un Walker fra gli algoritmi di estrazione di superfici
ed il Volume è esclusivamente di ottimizzazione. L'idea di fondo è che il Walker è quell'oggetto
attrverso cui avviene la visita del volume: per ogni cella del volume, esso effettua la chiamata
ProcessCell. Conoscendo l'ordine di visita, il Walker è anche la classe candidata ad implementare
le politiche di caching, in quanto sa esattamente da che momento può essere utile una certa 
informazione e per quanto a lungo può essere conveniente mantenerla prima di liberarsene.

WALKER
====================================================================================
Poiché la politica di visita del volume è realizzata all'interno del walker, 
è opportuno che sempre all'interno del walker vengano realizzate le politiche 
di caching rivolte ad ottimizzare l'esecuzione degli algoritmi MC ed EMC. Durante
il processing di ogni cella questi algoritmi possono chiamare le seguenti funzioni
del Walker:
																						MC		 EMC
							------------------------------------------
							V(i, j, k)										X				X
							GetXIntercept(p1, p2, v)			X				X
							GetYIntercept(p1, p2, v)			X				X
							GetZIntercept(p1, p2, v)			X				X
							Exist(p1, p2, v)							X

const float V(int i, int j, int k) const 
	La superficie che attraversa ogni cella viene ricavata dall'algoritmo di estrazione
	analizzando il valore del campo sugli otto spigoli di ogni voxel del volume; 
	per ogni voxel, il valore del campo sui suoi otto spigoli vengono richiesti 
	dall'algoritmo di estrazione al walker: se questo valore è già stato calcolato 
	e cachato, il walker restituisce direttamente tale valore; altrimenti il valore 
	del campo in questo spigolo viene calcolato (eventualmente cachato) e restituito
	al walker. In questo modo il valoro del campo ad ogni punto viene calcolato una
	sola volta anziché 8, questo puo' essere molto utile nel caso si utilizzi dataset 
	volumetrici mantenuti implicitamente.

void GetXIntercept(Point3i p1, Point3i p2, VertexPointer v)
void GetYIntercept(Point3i p1, Point3i p2, VertexPointer v)
void GetZIntercept(Point3i p1, Point3i p2, VertexPointer v)
	Dall'analisi del valore del campo agli spigoli di un dato voxel, l'algoritmo di 
	estrazione ha rilevato che la superficie interseca lo spigolo avente estremi p1 
	e p2(a seconda dell'orientazione di questo spigolo, viene chiamato uno dei tre 
	metodi): al termine di una di queste chiamate, v deve puntare al vertice della
	mesh (di coordinate comprese fra p1 e p2) attraverso cui passa la superficie. 
	Se questo vertice è stato già calcolato ed inserito nella mesh, il walker deve 
	risalire a tale vertice e memorizzarne in v il suo puntatore. Altrimenti deve provvedere
	ad aggiugnere un nuovo vertice ed a calcolare la sua posizione; v deve puntare 
	in questo caso al vertice appena inserito.
	Il motivo per cui questo calcolo non viene implementato direttamente negli algoritmi
	di estrazione (possibile per es. attraverso interpolazione lineare del valore 
	del campo nei punti p1 e p2) è che questo calcolo può essere fatto in maniere
	molto più precisa conoscendo come il campo viene calcolato, essendo infatti ciò 
	dipendente dall'applicazione.
	
bool Exist(Point3i p1, Point3i p2, VertexPointer v)
	Questo metodo viene chiamato solamente all'interno dell'algoritmo MarchingCubes.
	A differenza dei tre motodi precedenti, in questo caso si vuole sapere solamente
	se esiste già un vertice tra i punti p1 e p2: nel caso tale vertice esista, Exist
	deve resituire true ed v deve puntare a tale vertice; se invece tale vertice non 
	esiste, Exist deve restituire false e v deve prendere il valore NULL.
	NB: nel caso in cui il vertice non esiste, alla mesh non deve essere 
		aggiunto alcun nuovo vertice.