Moved from wrap/nexus
This commit is contained in:
parent
ef01c54189
commit
2e36dec52b
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
@ -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
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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>
|
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 |
|
@ -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
|
|
@ -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();
|
||||
}
|
|
@ -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
|
||||
|
|
@ -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];
|
||||
}
|
|
@ -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
|
|
@ -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
|
Loading…
Reference in New Issue