diff --git a/apps/nexus/crude.cpp b/apps/nexus/crude.cpp new file mode 100644 index 00000000..d949da5c --- /dev/null +++ b/apps/nexus/crude.cpp @@ -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; +} + + diff --git a/apps/nexus/crude.h b/apps/nexus/crude.h new file mode 100644 index 00000000..6783c6bd --- /dev/null +++ b/apps/nexus/crude.h @@ -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 +#include +#include +#include + +#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 vert; + VFile face; + + FILE *fp; + unsigned int nvert; + unsigned int nface; + vcg::Box3f box; +}; + +} //namespace + +#endif diff --git a/apps/nexus/mfhash.cpp b/apps/nexus/mfhash.cpp new file mode 100644 index 00000000..f49e8b9e --- /dev/null +++ b/apps/nexus/mfhash.cpp @@ -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; +} diff --git a/apps/nexus/mfhash.h b/apps/nexus/mfhash.h new file mode 100644 index 00000000..96e30ca4 --- /dev/null +++ b/apps/nexus/mfhash.h @@ -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 +#include + +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 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 buffer; + unsigned int space; + }; +}//namespace +#endif diff --git a/apps/nexus/nexus.html b/apps/nexus/nexus.html new file mode 100644 index 00000000..89e89ac4 --- /dev/null +++ b/apps/nexus/nexus.html @@ -0,0 +1,140 @@ + + + + +

+

+

+

Index:

+

+

+ + +

Big picture

+

Structures and interfaces

+ +

VFile

+VFile dovrebbe avere piu' o meno la stessa interfaccia di vector +ma usare un file per storare i dati (un mmapping, ma non limitato a 4Gb).
+ +

Crude

+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)
+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.
+Come interfaccia e' sufficente che dia accesso casuale a facce e vertici... +

PChain

+Sta per 'partition chain' cioe' una catena di partizioni dello +spazio.
+Una PChain 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)
+Oltre a questo va aggiunta una funzione che dato un punto e una patch +ne restituisce la distanza (o un valore 'equivalente').
+Si deve poter salvare su disco e recuperare una pchain
+ +

Remap

+E' composta da 3 files:
+indice delle patches: per ogni patch il numero di vertici, di facce e +di bordi
+ vertici -> lista di patches: per ogni vertice una lista di patch +di cui fa parte (se sono + di 1 e' ovviamente di bordo.
+facce->patches: per ogni faccia un intero che dice in quale patch +sta.
+ + +

Nexus

+E' una struttura con 3 files: 'index', 'patches' e 'borders'.
+'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.
+'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?
+'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)
+ +

Bmt

+Bmt (batched multi triangulation) e' il formato per la +multirisoluzione:
+E' un vettore di 'Cell' scritti su disco + un 'Index' e una 'History'. +Cell contiene i dati da visualizzare: vertici e strip (e altro?).
+Index contiene per ogni cell 'offset' per trovare la cell +corrispondente, error e bounding sphere (e per il face o vertex +count?).
+History e' la storia della multirisoluzione.
+ +

Algorithms

+

Plys to Crude

+Si copiano i vertici un ply dopo l'altro nel crude.
+Per le facce si copiano sommando un offset ai vertici
+Se si montano insieme piu' ply i vertici rimangono duplicati.
+E' piu' semplice fare il join dentro Nexus.
+ +

Crude + PChain to Remap

+Come prima cosa si costruisce il pchain passandogli il Crude.
+Asegnamo per ogni faccia la sua patch al livello 0.
+Per ogni patch sappiamo quante ce ne sono.
+Ridistribuiamo le patch troppo piccole (e rimappiamo i numeri delle +patches per rimuovere i buchi (anche dentro il PChain).
+Per risparmiare nella stessa passata ci segnamo dove vanno i vertici
+Poi facciamo un'altra passate per contare i bordi
+Infine si sortano le facce secondo l'ordine delle patches.
+ +

Crude + Remap to Nexus

+Per ogni patch raccogliamo le facce, e i vertici (ma non li +unifichiamo) e costruiamo una patch nel Nexus.
+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.
+Queste informazioni le tiriamo fuori dal Remap dei vertici
+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.
+ +

Nexus + PChain to Bmt

+Per costruire il file multirisoluzione aggiungeremo semplicemente +nuove patches al file nexus.
+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.
+Poi semplifichiamo e splittiamo (e sempre il PChain ci dice quali +nuove patches creare), ridistribuiamo le patches troppo piccole.
+E aggiungiamo le nuove patches al Nexus, e i nuovi bordi.
+Ci salviamo anche la storia da qualche parte.
+ + diff --git a/apps/nexus/nexus_logo.png b/apps/nexus/nexus_logo.png new file mode 100644 index 00000000..79eab848 Binary files /dev/null and b/apps/nexus/nexus_logo.png differ diff --git a/apps/nexus/nexus_logo_large.png b/apps/nexus/nexus_logo_large.png new file mode 100644 index 00000000..829744cd Binary files /dev/null and b/apps/nexus/nexus_logo_large.png differ diff --git a/apps/nexus/nexus_logo_midi.png b/apps/nexus/nexus_logo_midi.png new file mode 100644 index 00000000..47e791f5 Binary files /dev/null and b/apps/nexus/nexus_logo_midi.png differ diff --git a/apps/nexus/pchain.h b/apps/nexus/pchain.h new file mode 100644 index 00000000..f886978d --- /dev/null +++ b/apps/nexus/pchain.h @@ -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 +#include + +/** Partition must be a class with a Key type, with + Levels, Locate, Priority, Save(FILE *), Load(FILE *) + as in pvoronoi.h */ +namespace { + +template class PChain { + public: + typedef typename Partition::Key Key; + std::vector 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 diff --git a/apps/nexus/pvoronoi.cpp b/apps/nexus/pvoronoi.cpp new file mode 100644 index 00000000..908fb8a3 --- /dev/null +++ b/apps/nexus/pvoronoi.cpp @@ -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 +#include +#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 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(); +} diff --git a/apps/nexus/pvoronoi.h b/apps/nexus/pvoronoi.h new file mode 100644 index 00000000..c932bd1b --- /dev/null +++ b/apps/nexus/pvoronoi.h @@ -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 +#include +#include +#include + +#include +#include +#include + +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 > ug; + std::vector all_seeds; + std::vector ug_seeds; + std::vector seedBuf; + }; + +} +#endif + diff --git a/apps/nexus/vert_remap.cpp b/apps/nexus/vert_remap.cpp new file mode 100644 index 00000000..0cc89113 --- /dev/null +++ b/apps/nexus/vert_remap.cpp @@ -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 +#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]; +} diff --git a/apps/nexus/vert_remap.h b/apps/nexus/vert_remap.h new file mode 100644 index 00000000..9375b61d --- /dev/null +++ b/apps/nexus/vert_remap.h @@ -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 +#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 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 all; + MFHash borders; +}; +} //namespace bmt + +#endif diff --git a/apps/nexus/vfile.h b/apps/nexus/vfile.h new file mode 100644 index 00000000..bb7da8a4 --- /dev/null +++ b/apps/nexus/vfile.h @@ -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 +#include +//#include +#include +#include +#include + +/**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 VFile { + public: + + struct Buffer { + unsigned int key; + T *data; + }; + + private: + + FILE *fp; + std::list buffers; + typedef typename std::list::iterator iterator; + + std::map 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