Moved from wrap/nexus

This commit is contained in:
Federico Ponchio 2004-06-24 14:32:45 +00:00
parent ef01c54189
commit 2e36dec52b
14 changed files with 1321 additions and 0 deletions

123
apps/nexus/crude.cpp Normal file
View File

@ -0,0 +1,123 @@
/****************************************************************************
* VCGLib o o *
* Visual and Computer Graphics Library o o *
* _ O _ *
* Copyright(C) 2004 \/)\/ *
* Visual Computing Lab /\/| *
* ISTI - Italian National Research Council | *
* \ *
* All rights reserved. *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License (http://www.gnu.org/licenses/gpl.txt) *
* for more details. *
* *
****************************************************************************/
/****************************************************************************
History
$Log: not supported by cvs2svn $
Revision 1.1 2004/06/22 15:31:54 ponchio
Created
****************************************************************************/
#include "crude.h"
using namespace std;
using namespace vcg;
using namespace nxs;
Crude::~Crude() {
if(fp)
Close();
}
bool Crude::Create(const std::string &file, unsigned int nv, unsigned int nf) {
if(!vert.Create(file + ".vrt")) return false;
if(!face.Create(file + ".frt")) return false;
fp = fopen(file.c_str(), "wb+");
if(!fp) return false;
Resize(nv, nf);
return true;
}
bool Crude::Load(const std::string &file) {
if(!vert.Load(file + ".vrt")) return false;
if(!face.Load(file + ".frt")) return false;
fp = fopen(file.c_str(), "rb+");
if(!fp) return false;
fread(&nvert, sizeof(unsigned int), 1, fp);
fread(&nface, sizeof(unsigned int), 1, fp);
fread(&box, sizeof(Box3f), 1, fp);
return true;
}
void Crude::Close() {
vert.Close();
face.Close();
rewind(fp);
fwrite(&nvert, sizeof(unsigned int), 1, fp);
fwrite(&nface, sizeof(unsigned int), 1, fp);
fwrite(&box, sizeof(Box3f), 1, fp);
fclose(fp);
fp = NULL;
}
void Crude::Resize(unsigned int nv, unsigned int nf) {
nvert = nv;
nface = nf;
vert.Resize(nv);
face.Resize(nf);
}
unsigned int Crude::Vertices() {
return nvert;
}
unsigned int Crude::Faces() {
return nface;
}
void Crude::SetVertex(unsigned int i, float *f) {
Point3f &p = vert[i];
p[0] = f[0];
p[1] = f[1];
p[2] = f[2];
}
Point3f &Crude::GetVertex(unsigned int i) {
return vert[i];
}
Crude::Face &Crude::GetFace(unsigned int i) {
return face[i];
}
void Crude::SetFace(unsigned int i, unsigned int *f) {
Face &ff = face[i];
ff[0] = f[0];
ff[1] = f[1];
ff[2] = f[2];
}
vcg::Point3f Crude::GetBari(unsigned int i) {
Point3f bari(0, 0, 0);
Face &f = face[i];
for(int k = 0; k < 3; k++)
bari += vert[f[k]];
bari /= 3;
return bari;
}
vcg::Box3f &Crude::GetBox() {
return box;
}

92
apps/nexus/crude.h Normal file
View File

@ -0,0 +1,92 @@
/****************************************************************************
* VCGLib o o *
* Visual and Computer Graphics Library o o *
* _ O _ *
* Copyright(C) 2004 \/)\/ *
* Visual Computing Lab /\/| *
* ISTI - Italian National Research Council | *
* \ *
* All rights reserved. *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License (http://www.gnu.org/licenses/gpl.txt) *
* for more details. *
* *
****************************************************************************/
/****************************************************************************
History
$Log: not supported by cvs2svn $
Revision 1.1 2004/06/22 15:31:40 ponchio
Created
****************************************************************************/
#ifndef NXS_CRUDE_H
#define NXS_CRUDE_H
#include <stdio.h>
#include <string>
#include <vcg/space/point3.h>
#include <vcg/space/box3.h>
#include "vfile.h"
namespace nxs {
class Crude {
public:
struct Face {
Face() {}
Face(unsigned int a, unsigned int b, unsigned int c) {
v[0] = a; v[1] = b; v[2] = c;
}
unsigned int v[3];
unsigned int &operator[](int k) { return v[k]; }
unsigned int *ptr() { return v; }
};
Crude(): fp(NULL), nvert(0), nface(0) {}
~Crude();
bool Create(const std::string &file, unsigned int nvert = 0,
unsigned int nface = 0);
bool Load(const std::string &file);
void Close();
void Resize(unsigned int nvert, unsigned int nface);
unsigned int Vertices();
unsigned int Faces();
vcg::Point3f &GetVertex(unsigned int i);
void SetVertex(unsigned int i, float *p);
Face &GetFace(unsigned int i);
void SetFace(unsigned int i, unsigned int *f);
vcg::Point3f GetBari(unsigned int i);
vcg::Box3f &GetBox();
protected:
VFile<vcg::Point3f> vert;
VFile<Face> face;
FILE *fp;
unsigned int nvert;
unsigned int nface;
vcg::Box3f box;
};
} //namespace
#endif

133
apps/nexus/mfhash.cpp Normal file
View File

@ -0,0 +1,133 @@
/****************************************************************************
* VCGLib o o *
* Visual and Computer Graphics Library o o *
* _ O _ *
* Copyright(C) 2004 \/)\/ *
* Visual Computing Lab /\/| *
* ISTI - Italian National Research Council | *
* \ *
* All rights reserved. *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License (http://www.gnu.org/licenses/gpl.txt) *
* for more details. *
* *
****************************************************************************/
/****************************************************************************
History
$Log: not supported by cvs2svn $
Revision 1.1 2004/06/24 14:18:58 ponchio
Created
****************************************************************************/
#include "mfhash.h"
using namespace std;
using namespace nxs;
bool MFHash::Create(const string &file, unsigned int reserved) {
if(!buffer.Create(file)) return false;
buffer.Resize(reserved);
Bucket empty;
for(unsigned int i = 0; i < buffer.Size(); i++)
buffer[i] = empty;
space = reserved;
return true;
}
bool MFHash::Load(const string &file, unsigned int used) {
if(!buffer.Load(file)) return false;
if(used != 0xffffffff) {
space = buffer.Size() - used;
} else {
space = 0;
for(unsigned int i = 0; i < buffer.Size(); i++)
if(buffer[i].Empty()) space++;
}
return true;
}
void MFHash::Resize(unsigned int n) {
assert(buffer.Size() - space <= n);
//lets dump actual content
FILE *fp = tmpfile();
unsigned int count = 0;
for(unsigned int i = 0; i < buffer.Size(); i++) {
if(!buffer[i].Empty()) {
fwrite(&buffer[i], sizeof(Bucket), 1, fp);
++count;
}
}
buffer.Resize(n);
Clear();
rewind(fp);
Bucket bucket;
for(unsigned int i = 0; i < count; i++) {
fread(&bucket, sizeof(Bucket), 1, fp);
Insert(bucket.key, bucket.value, false);
}
fclose(fp);
}
void MFHash::Insert(unsigned int key, unsigned int value, bool rehash) {
if(buffer.Size() < 5)
Resize(5);
assert(space > 0);
unsigned int hash_size = buffer.Size();
unsigned int j = key % hash_size;
while(!buffer[j].Empty()) {
if(buffer[j].key == key && buffer[j].value == value) //already here
return;
j++;
if(j >= hash_size) j = 0;
}
buffer[j] = Bucket(key, value);
space--;
if(rehash) {
float ratio = space / (float)buffer.Size();
if(ratio < 0.4) //need to resize
Resize(buffer.Size() * 2 - 1);
}
}
unsigned int MFHash::Count(unsigned int key) {
unsigned int count = 0;
unsigned int hash_size = buffer.Size();
unsigned int j = key % hash_size;
while(!buffer[j].Empty()) {
if(buffer[j].key == key)
count++;
j++;
if(j >= hash_size) j = 0;
}
return count;
}
void MFHash::Clear() {
Bucket empty;
for(unsigned int i = 0; i < buffer.Size(); i++)
buffer[i] = empty;
space = buffer.Size();
}
void MFHash::Close() {
buffer.Close();
}
unsigned int MFHash::Size() {
return buffer.Size() - space;
}

81
apps/nexus/mfhash.h Normal file
View File

@ -0,0 +1,81 @@
/****************************************************************************
* VCGLib o o *
* Visual and Computer Graphics Library o o *
* _ O _ *
* Copyright(C) 2004 \/)\/ *
* Visual Computing Lab /\/| *
* ISTI - Italian National Research Council | *
* \ *
* All rights reserved. *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License (http://www.gnu.org/licenses/gpl.txt) *
* for more details. *
* *
****************************************************************************/
/****************************************************************************
History
$Log: not supported by cvs2svn $
Revision 1.1 2004/06/24 14:18:58 ponchio
Created
****************************************************************************/
#ifndef NXS_MFHASH_H
#define NXS_MFHASH_H
#include "vfile.h"
#include <stdio.h>
#include <iostream>
namespace nxs {
class MFHash {
public:
struct Bucket {
unsigned int key;
unsigned int value;
Bucket(): key(0xffffffff) {}
Bucket(unsigned int k, unsigned int v): key(k), value(v) {}
bool Empty() { return key == 0xffffffff; }
};
MFHash() {}
bool Create(const std::string &file, unsigned int reserved = 32);
bool Load(const std::string &file, unsigned int used = 0xffffffff);
void Resize(unsigned int n);
void Insert(unsigned int key, unsigned int value, bool rehash = true);
template <class C> void GetValues(unsigned int key, C &container) {
container.clear();
unsigned int hash_size = buffer.Size();
unsigned int j = key % hash_size;
while(!buffer[j].Empty()) {
if(buffer[j].key == key) {
container.push_back(buffer[j].value);
}
j++;
if(j >= hash_size) j = 0;
}
}
unsigned int Count(unsigned int key);
void Clear();
unsigned int Size();
void Close();
private:
VFile<Bucket> buffer;
unsigned int space;
};
}//namespace
#endif

140
apps/nexus/nexus.html Normal file
View File

@ -0,0 +1,140 @@
<html>
<style type="text/css"><!--
body { margin-left: 10%; margin-right: 10%; }
h1 { font-size: 150%; margin-left: 3%; page-break-before: always;}
h2 { font-size: 120%; margin-left: 1%; }
h3 { font-size: 110%; margin-left: 0%; }
ul { list-style: none; }
ul { padding: 0 0 0 1.5em; }
li { padding: 0 0 0.5em 0; }
em {font-size: 133%; font-family:monospace}
--></style>
<body>
<p>
<center><img src="nexus_logo_midi.png"></center>
<p>
<h2>Index:</h2>
<p>
<ul>
<li><a href="#picture">Big picture</a></li>
<li><a href="#struct">Structures and interfaces</a></li>
<ul>
<li><a href="#vfile">VFile</a></li>
<li><a href="#crude">Crude</a></li>
<li><a href="#pchain">PChain</a></li>
<li><a href="#nexus">Nexus</a></li>
<li><a href="#bmt">Bmt</a></li>
</ul>
<li><a href="#algo">Algorithms</a></li>
<ul>
<li><a href="#plyto">Plys to Crude</a></li>
<li><a href="#crudeto">Crude to PChain</a></li>
<li><a href="#crudepchainto">Crude + Pchain to Nexus</a></li>
<li><a href="#nexusto">Nexus to Bmt</a></li>
</ul>
</ul>
<a name="picture"><h1>Big picture</h1></a>
<a name="struct"><h1>Structures and interfaces</h1></a>
<a name="vfile"><h2>VFile</h2></a>
VFile dovrebbe avere piu' o meno la stessa interfaccia di <em>vector</em>
ma usare un file per storare i dati (un mmapping, ma non limitato a 4Gb).<br>
<a name="crude"><h2>Crude</h2></a>
Crude e' un formato tipo il ply... solo che usa dei VFile per
storare i dati.(3 unsigned int per una faccia e 3 float per un vertice)<br>
Per cui e' composto di 3 files almeno: header (numero di facce,
vertici e Bounding box), file dei vertici, file delle facce ed
opzionalmente file degli attributi dei vertici e delle facce.<br>
Come interfaccia e' sufficente che dia accesso casuale a facce e vertici...
<a name="pchain"><h2>PChain</h2></a>
Sta per 'partition chain' cioe' una catena di partizioni dello
spazio.<br>
Una <em>PChain</em> detto in matematichese e' una funzione da
[0..L] X R^3 -> N (cioe' dato un livello e un punto nello spazio
restituisce un numero naturale. (una patch)<br>
Oltre a questo va aggiunta una funzione che dato un punto e una patch
ne restituisce la distanza (o un valore 'equivalente').<br>
Si deve poter salvare su disco e recuperare una pchain<br>
<a name="remap"><h2>Remap</h2></a>
E' composta da 3 files:<br>
indice delle patches: per ogni patch il numero di vertici, di facce e
di bordi<br>
vertici -> lista di patches: per ogni vertice una lista di patch
di cui fa parte (se sono + di 1 e' ovviamente di bordo.<br>
facce->patches: per ogni faccia un intero che dice in quale patch
sta.<br>
<a name="nexus"><h2>Nexus</h2></a>
E' una struttura con 3 files: 'index', 'patches' e 'borders'.<br>
'Index' contiene l'indice delle patches: per ogni patch viene storato
offset, size (ma questa potrebbe essere storata direttamente nei
files?) dei dati geometrici nel file delle patches e dei bordi nel
file dei borders, oltre alla bounding sphere.<br>
'Patches' e' un VFile di chunks da 4k dove i dati geometrici di una
patch occupano un numero intero di chunks. P.S. Come ce la caviamo con
gli attributi dei vertici e delle facce?<br>
'Borders' e' un VFile di 'links' dove ogni link fa riferimento ad un
vertice di bordo tra la patch A (V_a) e la B (V_b) e contiene
(V_a, V_b, B) (A e' implicito). L'informazione e' replicata nei bordi
relativi a B con (V_b, V_a, A)<br>
<a name="bmt"><h2>Bmt</h2></a>
Bmt (batched multi triangulation) e' il formato per la
multirisoluzione:<br>
E' un vettore di 'Cell' scritti su disco + un 'Index' e una 'History'.
Cell contiene i dati da visualizzare: vertici e strip (e altro?).<br>
Index contiene per ogni cell 'offset' per trovare la cell
corrispondente, error e bounding sphere (e per il face o vertex
count?).<br>
History e' la storia della multirisoluzione.<br>
<a name="algo"><h1>Algorithms</h1></a>
<a name="plyto"><h2>Plys to Crude</h2></a>
Si copiano i vertici un ply dopo l'altro nel crude.<br>
Per le facce si copiano sommando un offset ai vertici<br>
Se si montano insieme piu' ply i vertici rimangono duplicati.<br>
E' piu' semplice fare il join dentro Nexus.<br>
<a name="crudeto"><h2>Crude + PChain to Remap</h2></a>
Come prima cosa si costruisce il pchain passandogli il Crude.<br>
Asegnamo per ogni faccia la sua patch al livello 0.<br>
Per ogni patch sappiamo quante ce ne sono.<br>
Ridistribuiamo le patch troppo piccole (e rimappiamo i numeri delle
patches per rimuovere i buchi (anche dentro il PChain).<br>
Per risparmiare nella stessa passata ci segnamo dove vanno i vertici<br>
Poi facciamo un'altra passate per contare i bordi<br>
Infine si sortano le facce secondo l'ordine delle patches.<br>
<a name="crudepchainto"><h2>Crude + Remap to Nexus</h2></a>
Per ogni patch raccogliamo le facce, e i vertici (ma non li
unifichiamo) e costruiamo una patch nel Nexus.<br>
Ci dobbiamo segnare i bordi mano a mano che lo facciamo:
per ogni patch ci salviamo una lista di triplette: il numero assoluto
del vertice di bordo, il numero relativo nella patch che stiamo
salvando, e il numero della patch (o delle patch) con la quale
confina.<br>
Queste informazioni le tiriamo fuori dal Remap dei vertici<br>
Una volta salvate tutte le patches ci smazziamo i bordi:
per ogni patch prendiamo quella lista e la incrociamo con quella
delle patches confinanti per costruire i bordi da passare a nexus.<br>
<a name="nexusto"><h2>Nexus + PChain to Bmt</h2></a>
Per costruire il file multirisoluzione aggiungeremo semplicemente
nuove patches al file nexus.<br>
Ad ogni passo selezioniamo un gruppo di patches (il PChain ci dice i
gruppi), li joiniamo insieme usando i bordi per riunificare i vertici
e per marcare i bordi esterni.<br>
Poi semplifichiamo e splittiamo (e sempre il PChain ci dice quali
nuove patches creare), ridistribuiamo le patches troppo piccole.<br>
E aggiungiamo le nuove patches al Nexus, e i nuovi bordi.<br>
Ci salviamo anche la storia da qualche parte.<br>
</body>
</html>

BIN
apps/nexus/nexus_logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 151 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

92
apps/nexus/pchain.h Normal file
View File

@ -0,0 +1,92 @@
/****************************************************************************
* VCGLib o o *
* Visual and Computer Graphics Library o o *
* _ O _ *
* Copyright(C) 2004 \/)\/ *
* Visual Computing Lab /\/| *
* ISTI - Italian National Research Council | *
* \ *
* All rights reserved. *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License (http://www.gnu.org/licenses/gpl.txt) *
* for more details. *
* *
****************************************************************************/
/****************************************************************************
History
$Log: not supported by cvs2svn $
Revision 1.2 2004/06/24 14:19:20 ponchio
Debugged
Revision 1.1 2004/06/23 17:17:46 ponchio
Created
****************************************************************************/
#ifndef NXS_PCHAIN_H
#define NXS_PCHAIN_H
#include <stdio.h>
#include <vcg/space/point3.h>
/** Partition must be a class with a Key type, with
Levels, Locate, Priority, Save(FILE *), Load(FILE *)
as in pvoronoi.h */
namespace {
template <class Partition> class PChain {
public:
typedef typename Partition::Key Key;
std::vector<Partition> levels;
unsigned int Levels() {
return levels.size();
}
Key Locate(unsigned int level, const vcg::Point3f &p) {
assert(level < levels.size());
return levels[level].Locate(p);
}
float Priority(unsigned int level, const vcg::Point3f &p, Key key) {
assert(level < levels.size());
return levels[level].Priority(level, p, key);
}
bool Save(const std::string &file) {
FILE *fp = fopen(file.c_str(), "wb+");
if(!fp) return false;
int n = Levels();
fwrite(&n, sizeof(int), 1, fp);
for(int i = 0; i < n; i++)
levels[i].Save(fp);
fclose(fp);
return true;
}
bool Load(const std::string &file) {
levels.clear();
FILE *fp = fopen(file.c_str(), "rb");
if(!fp) return false;
int n;
fread(&n, sizeof(int), 1, fp);
levels.resize(n);
for(int i = 0; i < n; i++)
levels[i].Load(fp);
fclose(fp);
return true;
}
};
}//namespace
#endif

185
apps/nexus/pvoronoi.cpp Normal file
View File

@ -0,0 +1,185 @@
/****************************************************************************
* VCGLib o o *
* Visual and Computer Graphics Library o o *
* _ O _ *
* Copyright(C) 2004 \/)\/ *
* Visual Computing Lab /\/| *
* ISTI - Italian National Research Council | *
* \ *
* All rights reserved. *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License (http://www.gnu.org/licenses/gpl.txt) *
* for more details. *
* *
****************************************************************************/
/****************************************************************************
History
$Log: not supported by cvs2svn $
Revision 1.2 2004/06/24 14:19:20 ponchio
Debugged
Revision 1.1 2004/06/23 17:17:46 ponchio
Created
****************************************************************************/
#pragma warning(disable:4786 4804 4244 4018 4267 4311)
#include <stdio.h>
#include <iostream>
#include "pvoronoi.h"
using namespace std;
using namespace vcg;
using namespace nxs;
bool Seed::Dist(const Point3f &point, float &mindist,
Point3f &res) {
float newdist = Distance(p, point);
if(newdist < mindist) {
mindist = newdist;
res = p;
return true;
} else
return false;
}
int VoronoiPartition::Add(vcg::Point3f p, float weight) {
Seed ns(p,weight);
all_seeds.push_back(ns);
seedBuf.push_back(p);
if(seedBuf.size() >= MAX_BUF) {
for(unsigned int i = 0; i < seedBuf.size(); ++i)
ug_seeds.push_back(seedBuf[i]);
seedBuf.clear();
ug.Set(ug_seeds);
}
return size();
}
float VoronoiPartition::Closest(const vcg::Point3f &p, int &target, float radius) {
Point3f res;
float mindist = 1e20;
target = -1;
if(ug_seeds.size()) {
Seed *nsp = ug.GetClosest(p, mindist, res);
if(nsp) {
target = nsp-&*ug_seeds.begin();
}
}
for(unsigned int i=0;i<seedBuf.size();++i) {
float dist = seedBuf[i].Dist(p);
if(mindist > dist) {
target=ug_seeds.size()+i;
mindist=dist;
}
}
//assert(target >=0 );
//assert (target < size()+seedBuf.size());
return mindist;
}
void VoronoiPartition::iterator::operator++() {
++seed;
}
const VoronoiPartition::Key VoronoiPartition::iterator::operator*() {
return seed;
}
bool VoronoiPartition::iterator::operator==(const VoronoiPartition::iterator &key) {
return key.seed == seed;
}
bool VoronoiPartition::iterator::operator!=(const VoronoiPartition::iterator &key) {
return key.seed != seed;
}
VoronoiPartition::iterator VoronoiPartition::begin() {
iterator i;
i.seed = 0;
return i;
}
VoronoiPartition::iterator VoronoiPartition::end() {
iterator i;
i.seed = size();
return i;
}
int VoronoiPartition::size() {
return all_seeds.size();
}
void VoronoiPartition::clear() {
all_seeds.clear();
ug_seeds.clear();
seedBuf.clear();
}
unsigned int VoronoiPartition::count(Key key) {
return key > 0 && key < size();
}
Seed &VoronoiPartition::operator[](Key key) {
assert(key < all_seeds.size());
return all_seeds[key];
}
VoronoiPartition::Key VoronoiPartition::Locate(const vcg::Point3f &p) {
int target;
Closest(p, target);
assert(target != -1);
return target;
}
float VoronoiPartition::Priority(const vcg::Point3f &p, Key key) {
Seed &seed = all_seeds[key];
return seed.Dist(p);
}
bool VoronoiPartition::Save(const std::string &file) {
FILE *fp = fopen(file.c_str(), "wb+");
if(!fp) return false;
Save(fp);
fclose(fp);
return true;
}
bool VoronoiPartition::Load(const std::string &file) {
FILE *fp = fopen(file.c_str(), "rb");
if(!fp) return false;
Load(fp);
fclose(fp);
return true;
}
unsigned int VoronoiPartition::Save(FILE *fp) {
fwrite(&bbox, sizeof(Box3f), 1, fp);
int n = all_seeds.size();
fwrite(&n, sizeof(int), 1, fp);
fwrite(&all_seeds[0], sizeof(Seed), all_seeds.size(), fp);
return sizeof(Box3f) + sizeof(int) + sizeof(Seed) * all_seeds.size();
}
unsigned int VoronoiPartition::Load(FILE *fp) {
clear();
fread(&bbox, sizeof(Box3f), 1, fp);
int n;
fread(&n, sizeof(int), 1, fp);
all_seeds.resize(n);
fread(&all_seeds[0], sizeof(Seed), all_seeds.size(), fp);
ug_seeds.resize(n);
for(int i = 0; i < n; i++)
ug_seeds[i] = all_seeds[i];
ug.SetBBox(bbox);
ug.Set(ug_seeds);
return sizeof(Box3f) + sizeof(int) + sizeof(Seed) * all_seeds.size();
}

117
apps/nexus/pvoronoi.h Normal file
View File

@ -0,0 +1,117 @@
/****************************************************************************
* VCGLib o o *
* Visual and Computer Graphics Library o o *
* _ O _ *
* Copyright(C) 2004 \/)\/ *
* Visual Computing Lab /\/| *
* ISTI - Italian National Research Council | *
* \ *
* All rights reserved. *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License (http://www.gnu.org/licenses/gpl.txt) *
* for more details. *
* *
****************************************************************************/
/****************************************************************************
History
$Log: not supported by cvs2svn $
Revision 1.2 2004/06/24 14:19:20 ponchio
Debugged
Revision 1.1 2004/06/23 17:17:46 ponchio
Created
****************************************************************************/
#ifndef NXS_NET_GRID_H
#define NXS_NET_GRID_H
#include <vector>
#include <set>
#include <string>
#include <stdio.h>
#include <vcg/space/point3.h>
#include <vcg/space/box3.h>
#include <vcg/space/index/grid_static_ptr.h>
namespace nxs {
class Seed {
public:
vcg::Point3f p;
float weight;
typedef float ScalarType;
bool Dist(const vcg::Point3f & point, float &mindist, vcg::Point3f &res);
void GetBBox(vcg::Box3f &b) {b.Set(p);}
bool IsD() { return false; }
Seed(): weight(1) {}
Seed(const vcg::Point3f &point): p(point), weight(1) {}
Seed(const vcg::Point3f &point, const float w):
p(point), weight(w) {}
inline float Dist(const vcg::Point3f &q) const {
return weight * vcg::Distance(p,q);
}
inline float SquaredDist(const vcg::Point3f &q) const {
return weight * weight *vcg::SquaredDistance(p,q);
}
};
class VoronoiPartition {
public:
enum { MAX_BUF=25 };
typedef int Key;
VoronoiPartition() {}
void Init(vcg::Box3f &bb) { bbox=bb; ug.SetBBox(bb); }
int Add(vcg::Point3f p, float weight = 1);
float Closest(const vcg::Point3f &p, Key &target, float radius = 0);
class iterator {
public:
void operator++();
const Key operator*();
bool operator==(const iterator &key);
bool operator!=(const iterator &key);
private:
int seed;
friend class VoronoiPartition;
};
iterator begin();
iterator end();
int size();
unsigned int count(Key key);
Seed &operator[](Key key);
void clear();
Key Locate(const vcg::Point3f &p);
float Priority(const vcg::Point3f &p, Key key);
bool Save(const std::string &file);
bool Load(const std::string &file);
unsigned int Save(FILE *fp);
unsigned int Load(FILE *fp);
private:
vcg::Box3f bbox;
vcg::GridStaticPtr< std::vector<Seed> > ug;
std::vector<Seed> all_seeds;
std::vector<Seed> ug_seeds;
std::vector<Seed> seedBuf;
};
}
#endif

79
apps/nexus/vert_remap.cpp Normal file
View File

@ -0,0 +1,79 @@
/****************************************************************************
* VCGLib o o *
* Visual and Computer Graphics Library o o *
* _ O _ *
* Copyright(C) 2004 \/)\/ *
* Visual Computing Lab /\/| *
* ISTI - Italian National Research Council | *
* \ *
* All rights reserved. *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License (http://www.gnu.org/licenses/gpl.txt) *
* for more details. *
* *
****************************************************************************/
/****************************************************************************
History
$Log: not supported by cvs2svn $
Revision 1.1 2004/06/24 14:18:58 ponchio
Created
****************************************************************************/
#include <iostream>
#include "vert_remap.h"
using namespace std;
using namespace nxs;
bool VertRemap::Create(const std::string &file) {
if(all.Create(file)) return false;
if(!borders.Create(file)) return false;
return true;
}
bool VertRemap::Load(const std::string &file) {
if(!all.Load(file)) return false;
if(!borders.Create(file)) return false;
return true;
}
void VertRemap::Resize(unsigned int n_vert) {
all.Resize(n_vert);
for(unsigned int i = 0; i < n_vert; i++)
all[i] = 0xffffffff;
borders.Clear();
borders.Resize(n_vert/10);
}
unsigned int VertRemap::Size() {
return all.Size();
}
unsigned int VertRemap::Count(unsigned int key) {
assert(key < Size());
if(all[key] == 0xffffffff) return 0;
return 1 + borders.Count(key);
}
void VertRemap::Insert(unsigned int key, unsigned int value) {
if(all[key] == 0xffffffff)
all[key] = value;
else
borders.Insert(key, value);
}
unsigned int VertRemap::GetValue(unsigned int key) { //return first value
assert(key < Size());
return all[key];
}

66
apps/nexus/vert_remap.h Normal file
View File

@ -0,0 +1,66 @@
/****************************************************************************
* VCGLib o o *
* Visual and Computer Graphics Library o o *
* _ O _ *
* Copyright(C) 2004 \/)\/ *
* Visual Computing Lab /\/| *
* ISTI - Italian National Research Council | *
* \ *
* All rights reserved. *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License (http://www.gnu.org/licenses/gpl.txt) *
* for more details. *
* *
****************************************************************************/
/****************************************************************************
History
$Log: not supported by cvs2svn $
Revision 1.1 2004/06/24 14:18:58 ponchio
Created
****************************************************************************/
#ifndef NXS_VERTEX_REMAP_H
#define NXS_VERTEX_REMAP_H
#include <string>
#include "vfile.h"
#include "mfhash.h"
namespace nxs {
class VertRemap {
public:
bool Create(const std::string &file);
bool Load(const std::string &file);
void Resize(unsigned int n_vert);
unsigned int Size();
unsigned int Count(unsigned int key);
void Insert(unsigned int key, unsigned int value);
unsigned int GetValue(unsigned int key); //return first value
template <class C> void GetValues(unsigned int key,
C &container) {
assert(key < Size());
container.clear();
if(all[key] == 0xffffffff) return;
container.push_back(all[key]);
borders.GetValue(key, container);
}
private:
VFile<unsigned int> all;
MFHash borders;
};
} //namespace bmt
#endif

213
apps/nexus/vfile.h Normal file
View File

@ -0,0 +1,213 @@
/****************************************************************************
* VCGLib o o *
* Visual and Computer Graphics Library o o *
* _ O _ *
* Copyright(C) 2004 \/)\/ *
* Visual Computing Lab /\/| *
* ISTI - Italian National Research Council | *
* \ *
* All rights reserved. *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License (http://www.gnu.org/licenses/gpl.txt) *
* for more details. *
* *
****************************************************************************/
/****************************************************************************
History
$Log: not supported by cvs2svn $
Revision 1.3 2004/06/22 15:32:09 ponchio
Tested
Revision 1.2 2004/06/22 10:27:16 ponchio
*** empty log message ***
Revision 1.1 2004/06/22 00:39:56 ponchio
Created
****************************************************************************/
#ifndef VFILE_H
#define VFILE_H
#include <unistd.h>
#include <errno.h>
//#include <hash_map>
#include <map>
#include <list>
#include <string>
/**Vector structure on file with simulated mmapping.
* a priority queue of buffers is used
* TODO: port to over 4Gb usable space
* some mechanism to report errors?
* use an Iterator?
*/
namespace nxs {
template <class T> class VFile {
public:
struct Buffer {
unsigned int key;
T *data;
};
private:
FILE *fp;
std::list<Buffer> buffers;
typedef typename std::list<Buffer>::iterator iterator;
std::map<unsigned int, iterator> index; //TODO move to hash_map
unsigned int chunk_size; //default buffer size (expressed in number of T)
unsigned int queue_size;
unsigned int n_elements; //size of the vector
public:
VFile(): fp(NULL) {}
~VFile() { if(fp) Close(); }
bool Create(const std::string &filename,
unsigned int _chunk_size = 4096/sizeof(T),
unsigned int _queue_size = 1000) {
assert(_chunk_size > 0);
chunk_size = _chunk_size;
queue_size = _queue_size;
n_elements = 0;
fp = fopen(filename.c_str(), "wb+");
if(!fp) return false;
return true;
}
bool Load(const std:: string &filename,
unsigned int _chunk_size = 4096/sizeof(T),
unsigned int _queue_size = 1000) {
assert(_chunk_size > 0);
chunk_size = _chunk_size;
queue_size = _queue_size;
fp = fopen(filename.c_str(), "rb+");
if(!fp) return false;
fseek(fp, 0, SEEK_END);
n_elements = ftell(fp)/ sizeof(T);
return true;
}
void Close() {
Flush();
fclose(fp);
fp = 0;
}
void Flush() {
iterator i;
for(i = buffers.begin(); i != buffers.end(); i++)
FlushBuffer(*i);
buffers.clear();
index.clear();
}
void FlushBuffer(Buffer buffer) {
fseek(fp, buffer.key * chunk_size * sizeof(T), SEEK_SET);
if(chunk_size != fwrite(buffer.data, sizeof(T), chunk_size, fp)) {
assert(0 && "Could not write");
}
delete []buffer.data;
}
void Resize(unsigned int elem) {
if(elem > n_elements) {
if(-1 == fseek(fp, elem*sizeof(T) -1, SEEK_SET)) {
assert(0 && "Could not resize");
}
unsigned char a;
fwrite(&a, sizeof(unsigned char), 1, fp);
} else {
//TODO optimize: we do not need flush for buffers over elem.
Flush();
int fd = fileno(fp);
ftruncate(fd, elem*sizeof(T));
}
n_elements = elem;
}
/** Remember that T is a valid pointer only until next call of
* getElement or setElement
*/
T &operator[](unsigned int n) {
assert(n <= n_elements);
unsigned int chunk = n/chunk_size;
unsigned int offset = n - chunk*chunk_size;
assert(offset < chunk_size*sizeof(T));
if(index.count(chunk))
return *((*(index[chunk])).data + offset);
if(buffers.size() > queue_size) {
Buffer &buffer= buffers.back();
FlushBuffer(buffer);
index.erase(buffer.key);
buffers.pop_back();
}
Buffer buffer;
buffer.key = chunk;
buffer.data = new T[chunk_size * sizeof(T)];
if(fseek(fp, chunk * chunk_size * sizeof(T), SEEK_SET)) {
assert(0 && "failed to fseek");
return *(buffer.data);
}
unsigned int data_size = chunk_size;
if(data_size + chunk * chunk_size > n_elements)
data_size = -chunk * chunk_size + n_elements;
if(data_size != fread(buffer.data, sizeof(T), data_size, fp)) {
if(feof(fp)) {
assert(0 && "end of file");
} else {
assert(0 && "failed reading!");
}
return (*buffer.data);
}
buffers.push_front(buffer);
index[chunk] = buffers.begin();
return *(buffer.data + offset);
}
/**use this for directly writing on the file...
* be careful to flush (unless you never readed or flushed)
*/
unsigned int Size() { return n_elements; }
unsigned int ChunkSize() { return chunk_size; }
unsigned int QueueSize() { return queue_size; }
protected:
void SetPosition(unsigned int chunk) {
fseek(fp, chunk * chunk_size * sizeof(T), SEEK_SET);
}
};
}//namespace
#endif