Revolution.

This commit is contained in:
Federico Ponchio 2005-01-14 15:25:29 +00:00
parent 0fde2046fc
commit 975ec6ae04
20 changed files with 1588 additions and 995 deletions

View File

@ -4,61 +4,131 @@
using namespace std;
using namespace nxs;
bool BorderServer::Create(const string &file) {
ram_used = 0;
return IndexFile<BorderEntry>::Create(file, 2 * sizeof(Link));
}
bool BorderServer::Load(const string &file, bool rdonly) {
ram_used = 0;
cerr << "Loading...\n";
return IndexFile<BorderEntry>::Load(file, rdonly);
}
void BorderServer::Close() {
if(!Opened()) return;
Flush();
IndexFile<BorderEntry>::Close();
}
void BorderServer::Flush() {
std::map<unsigned int, list<unsigned int>::iterator>::iterator i;
for(i = index.begin(); i != index.end(); i++) {
unsigned int patch = (*i).first;
FlushBorder(patch);
}
pqueue.clear();
index.clear();
}
void BorderServer::AddBorder(unsigned short nbord, unsigned int used) {
BorderEntry entry;
entry.border_start = Size();
entry.border_size = nbord;
entry.border_used = used;
borders.push_back(entry);
Resize(entry.border_start + nbord);
assert((Length() % sizeof(Link)) == 0);
entry.start = Length()/ sizeof(Link);
entry.size = nbord;
entry.used = used;
entry.links = NULL;
push_back(entry);
Redim(entry.start * sizeof(Link) + nbord * sizeof(Link));
}
Border BorderServer::GetBorder(unsigned int border, bool flush) {
assert(border < borders.size());
BorderEntry &entry = borders[border];
Link *start = GetRegion(entry.border_start, entry.border_size, flush);
return Border(start, entry.border_used, entry.border_size);
BorderEntry &entry = operator[](border);
if(index.count(border)) {
assert(entry.links);
list<unsigned int>::iterator &i = index[border];
pqueue.erase(i);
pqueue.push_front(border);
} else {
while(flush && ram_used > ram_max) {
unsigned int to_flush = pqueue.back();
pqueue.pop_back();
index.erase(to_flush);
FlushBorder(to_flush);
}
assert(!entry.links);
entry.links = GetRegion(entry.start, entry.size);
pqueue.push_front(border);
list<unsigned int>::iterator i = pqueue.begin();
index[border] = i;
ram_used += entry.size;
}
return Border(entry.links, entry.used, entry.size);
}
bool BorderServer::ResizeBorder(unsigned int border, unsigned int nbord) {
assert(nbord < 65500);
assert(border < borders.size());
BorderEntry &entry = borders[border];
if(nbord > entry.border_size) {
assert(border < size());
BorderEntry &entry = operator[](border);
if(nbord > entry.size) {
int capacity = nbord;
if(capacity < entry.border_size*2)
capacity = entry.border_size * 2;
if(capacity < entry.size*2)
capacity = entry.size * 2;
if(capacity > 65500)
capacity = 65500;
unsigned int newstart = Size();
Resize(newstart + capacity);
if(entry.border_used > 0) {
Link *src = GetRegion(entry.border_start, entry.border_size);
Link *dst = GetRegion(newstart, capacity, false);
memcpy(dst, src, entry.border_used * sizeof(Link));
unsigned int newstart = Length()/sizeof(Link);
Redim((newstart + capacity) * sizeof(Link));
if(entry.used > 0) {
Link *src = GetRegion(entry.start, entry.size);
Link *dst = GetRegion(newstart, capacity);
memcpy(dst, src, entry.used * sizeof(Link));
}
entry.border_start = newstart;
entry.border_size = capacity;
entry.border_used = nbord;
entry.start = newstart;
entry.size = capacity;
entry.used = nbord;
return true;
}
entry.border_used = nbord;
entry.used = nbord;
return false;
}
bool BorderServer::ReadEntries(FILE *fp) {
unsigned int n;
fread(&n, 1, sizeof(int), fp);
borders.resize(n);
fread(&*borders.begin(), n, sizeof(BorderEntry), fp);
void BorderServer::FlushBorder(unsigned int border) {
BorderEntry &entry = operator[](border);
assert(entry.links);
if(!MFile::IsReadOnly()) { //write back patch
MFile::SetPosition((int64)entry.start * sizeof(Link));
MFile::WriteBuffer(entry.links, entry.used * sizeof(Link));
}
delete [](entry.links);
entry.links = NULL;
ram_used -= entry.size;
}
Link *BorderServer::GetRegion(unsigned int start, unsigned int size) {
SetPosition(start * sizeof(Link));
Link *buf = new Link[size];
assert(buf);
ReadBuffer(buf, size * sizeof(Link));
return buf;
}
bool BorderServer::LoadHeader() {
unsigned int magic;
ReadBuffer(&magic, sizeof(unsigned int));
if(magic != 0x3042584e) { //NXB0
cerr << "Invalid magic. Not a nxs file\n";
return false;
}
ReadBuffer(&offset, sizeof(int64));
cerr << "Offset: " << offset << endl;
return true;
}
bool BorderServer::WriteEntries(FILE *fp) {
unsigned int n = borders.size();
fwrite(&n, 1, sizeof(int), fp);
fwrite(&*borders.begin(), n, sizeof(BorderEntry), fp);
return true;
void BorderServer::SaveHeader() {
unsigned int magic = 0x3042584e; // NXB0
WriteBuffer(&magic, sizeof(unsigned int));
WriteBuffer(&offset, sizeof(int64));
}

View File

@ -1,40 +1,58 @@
#ifndef NXS_BORDERSERVER_H
#define NXS_BORDERSERVER_H
#include "vfile.h"
#include <list>
#include <map>
#include "index_file.h"
#include "border.h"
#include <vector>
/*nell'header ci sta scritto solo:
spazio riservato: 2 * sizeof(Link);
magic: nxb0 (4 bytes)
offset: (int64) */
namespace nxs {
struct BorderEntry {
unsigned int border_start; //granuralita' Link
unsigned short border_size; //in Links
unsigned short border_used; //in Links
unsigned int start; //granuralita' Link
unsigned short size; //in Links
unsigned short used; //in Links
Link *links;
};
class BorderServer: public VFile<Link> {
class BorderServer: public IndexFile<BorderEntry> {
public:
BorderServer(): ram_max(1000000), ram_used(0) {}
~BorderServer() { Close(); }
bool Create(const std::string &file);
bool Load(const std::string &file, bool readonly = true);
void Close();
void Flush();
void AddBorder(unsigned short nbord, unsigned int used = 0);
Border GetBorder(unsigned int border, bool flush = true);
//return true if you need to reread border as it changed location
bool ResizeBorder(unsigned int border, unsigned int nbord);
bool ReadEntries(FILE *fp);
bool WriteEntries(FILE *fp);
unsigned int BorderSize(unsigned int i) {
return borders[i].border_used;
return operator[](i).used;
}
unsigned int BorderCapacity(unsigned int i) {
return borders[i].border_size;
return operator[](i).size;
}
protected:
unsigned int ram_max;
unsigned int ram_used;
std::list<unsigned int> pqueue;
std::map<unsigned int, std::list<unsigned int>::iterator> index;
bool LoadHeader();
void SaveHeader();
std::vector<BorderEntry> borders;
void FlushBorder(unsigned int border);
Link *GetRegion(unsigned int start, unsigned int size); //size in links.
};
}

View File

@ -20,7 +20,7 @@ class LruPServer: public PServer {
Flush();
}
Patch &Lookup(unsigned int patch, unsigned short nv, unsigned short nf) {
Patch &Lookup(unsigned int patch) {
if(index.count(patch)) {
Items::iterator &i = index[patch];
Item item = *i;
@ -32,12 +32,12 @@ class LruPServer: public PServer {
while(ram_used > ram_max) {
Item item = items.back();
index.erase(item.first);
FlushPatch(item.first, item.second);
FlushPatch(item.first);
items.pop_back();
}
Item item;
item.first = patch;
item.second = LoadPatch(patch, nv, nf);
item.second = LoadPatch(patch);
items.push_front(item);
Items::iterator i = items.begin();
index[patch] = i;
@ -52,10 +52,10 @@ class LruPServer: public PServer {
std::map<unsigned int, Items::iterator>::iterator i;
for(i = index.begin(); i != index.end(); i++) {
Item &item = *((*i).second);
FlushPatch((*i).first, item.second);
FlushPatch((*i).first);
}
for(int k = 0; k < entries.size(); k++)
entries[k].patch = NULL;
for(int k = 0; k < size(); k++)
operator[](k).patch = NULL;
items.clear();
index.clear();

View File

@ -8,7 +8,7 @@ using namespace nxs;
bool MFile::Create(const string &fname, unsigned int mxs) {
Close();
filename = fname;
size = 0;
_size = 0;
readonly = false;
assert(mxs <= MFILE_MAX_SIZE);
max_size = mxs;
@ -20,7 +20,7 @@ bool MFile::Load(const string &fname, bool ronly) {
filename = fname;
readonly = ronly;
max_size = MFILE_MAX_SIZE;
size = 0;
_size = 0;
while(1) {
string name = Name(files.size());
@ -30,11 +30,11 @@ bool MFile::Load(const string &fname, bool ronly) {
files.pop_back();
break;
}
size += file->Length();
_size += file->Length();
}
if(files.size() == 0) return false;
if(files.size() == 1) {
assert(size <= max_size);
assert(_size <= max_size);
} else {
//SANITY TEST
for(unsigned int i = 0; i < files.size() -2; i++) {
@ -61,28 +61,29 @@ void MFile::Delete() {
void MFile::Redim(int64 sz) {
assert(!readonly);
if(sz > size) {
if(sz > _size) {
unsigned int totfile = (unsigned int)(sz/max_size);
//TODO test rhis!!!!
while(files.size() <= totfile) {
RedimLast(max_size);
assert(size == (int64)max_size * (int64)(files.size()));
assert(_size == (int64)max_size * (int64)(files.size()));
AddFile();
}
assert(size <= sz);
assert(sz - size < max_size);
assert(files.back()->Length() + (unsigned int)(sz - size) < max_size);
RedimLast(files.back()->Length() + (unsigned int)(sz - size));
assert(_size <= sz);
assert(sz - _size < max_size);
assert(files.back()->Length() + (unsigned int)(sz - _size) < max_size);
RedimLast(files.back()->Length() + (unsigned int)(sz - _size));
} else {
while(size - files.back()->Length() > sz)
while(_size - files.back()->Length() > sz)
RemoveFile();
assert(sz <= size);
RedimLast(files.back()->Length() - (unsigned int)(size - sz));
assert(sz <= _size);
RedimLast(files.back()->Length() - (unsigned int)(_size - sz));
}
assert(sz == _size);
}
void MFile::SetPosition(int64 pos) {
assert(pos < size);
assert(pos <= _size);
curr_fp = (unsigned int)(pos/(int64)max_size);
curr_pos = (unsigned int)(pos - (int64)max_size * (int64)curr_fp);
assert(curr_pos < max_size);
@ -134,7 +135,7 @@ void MFile::WriteBuffer(void *data, unsigned int sz) {
unsigned int last_size = file->Length();
delete file;
files.pop_back();
size -= last_size;
_size -= last_size;
cerr << "Removing file: " << name << endl;
#ifdef WIN32
DeleteFile(name.c_str());
@ -148,7 +149,7 @@ void MFile::RedimLast(unsigned int sz) {
File &file = *files.back();
unsigned int last_size = (int64)file.Length();
file.Redim(sz);
size += sz - (int64)last_size;
_size += sz - (int64)last_size;
}
std::string MFile::Name(unsigned int n) {

View File

@ -30,13 +30,14 @@ class MFile {
void Close();
void Delete();
int64 Length() { return size; }
int64 Length() { return _size; }
void Redim(int64 size);
void SetPosition(int64 pos);
void ReadBuffer(void *data, unsigned int size);
void WriteBuffer(void *data, unsigned int size);
bool Opened() { return files.size() > 0; }
bool IsReadOnly() { return readonly; }
void SetReadOnly(bool rd) { readonly = rd; } //USE WITH CARE!!!!
protected:
@ -44,7 +45,7 @@ class MFile {
std::vector<File *> files;
unsigned int curr_pos;
unsigned int curr_fp;
int64 size;
int64 _size;
unsigned int max_size;
bool readonly;
private:

View File

@ -4,8 +4,6 @@
#include <set>
#include "nexus.h"
#include "lrupserver.h"
#include "queuepserver.h"
using namespace std;
using namespace vcg;
@ -16,155 +14,157 @@ Nexus::~Nexus() {
}
bool Nexus::Create(const string &file, Signature sig, unsigned int c_size) {
index_file = fopen((file + ".nxs").c_str(), "wb+");
if(!index_file) {
cerr << "Could not create file: " << file << ".nxs\n";
return false;
}
signature = sig;
totvert = 0;
totface = 0;
sphere = Sphere3f();
index.clear();
chunk_size = c_size;
unsigned int header_size = 256;
if(chunk_size > header_size) header_size = chunk_size;
history.clear();
history.Clear();
ram_used = 0;
ram_max = 50 * (1<<20) / chunk_size;
if(!patches.Create(file + ".nxp", signature, chunk_size)) {
if(!IndexFile<Entry>::Create(file + ".nxp", header_size)) {
cerr << "Could not create file: " << file << ".nxp" << endl;
return false;
}
//Important: chunk_size must be 1 so that i can use Region in VFile.
if(!borders.Create(file + ".nxb", 1, 100)) {
if(!borders.Create(file + ".nxb")) {
cerr << "Could not create file: " << file << ".nxb" << endl;
return false;
}
history.clear();
return true;
}
bool Nexus::Load(const string &file, bool rdonly) {
readonly = rdonly;
if(!IndexFile<Entry>::Load(file + ".nxp", rdonly)) return false;
ram_used = 0;
ram_max = 50 * (1<<20) / chunk_size;
index_file = fopen((file + ".nxs").c_str(), "rb+");
if(!index_file) return false;
history.Clear();
SetPosition(history_offset);
unsigned int history_size;
ReadBuffer(&history_size, sizeof(unsigned int));
unsigned int readed;
readed = fread(&signature, sizeof(unsigned int), 1, index_file);
if(!readed) return false;
readed = fread(&totvert, sizeof(unsigned int), 1, index_file);
if(!readed) return false;
readed = fread(&totface, sizeof(unsigned int), 1, index_file);
if(!readed) return false;
readed = fread(&sphere, sizeof(Sphere3f), 1, index_file);
if(!readed) return false;
readed = fread(&chunk_size, sizeof(unsigned int), 1, index_file);
if(!readed) return false;
char *buffer = new char[history_size];
ReadBuffer(buffer, history_size);
unsigned int size; //size of index
readed = fread(&size, sizeof(unsigned int), 1, index_file);
if(!readed) return false;
index.resize(size);
readed = fread(&index[0], sizeof(PatchInfo), size, index_file);
if(readed != size) return false;
patches.ReadEntries(index_file);
borders.ReadEntries(index_file);
//history size;
fread(&size, sizeof(unsigned int), 1, index_file);
vector<unsigned int> buffer;
buffer.resize(size);
fread(&(buffer[0]), sizeof(unsigned int), size, index_file);
//number of history updates
size = buffer[0];
history.resize(size);
unsigned int pos = 1;
for(unsigned int i = 0; i < size; i++) {
unsigned int erased = buffer[pos++];
unsigned int created = buffer[pos++];
history[i].erased.resize(erased);
history[i].created.resize(created);
for(unsigned int e = 0; e < erased; e++)
history[i].erased[e] = buffer[pos++];
for(unsigned int e = 0; e < created; e++)
history[i].created[e] = buffer[pos++];
if(!history.Load(history_size, buffer)) {
cerr << "Error loading history\n";
return false;
}
if(readonly) {
fclose(index_file);
index_file = NULL;
}
//TODO support readonly
if(!patches.Load(file + ".nxp", signature, chunk_size, readonly))
return false;
if(!borders.Load(file + ".nxb", readonly, 1, 500))
return false;
borders.Load(file + ".nxb", rdonly);
//TODO on nxsbuilder assure borders are loaded
return true;
}
void Nexus::Close() {
patches.Close();
if(!Opened()) return;
Flush();
if(!IsReadOnly()) {
//set history_offset
if(!size()) history_offset = 0;
else
history_offset = (back().patch_start + back().disk_size);
history_offset *= chunk_size;
unsigned int history_size;
char *mem = history.Save(history_size);
Redim(history_offset + history_size + sizeof(unsigned int));
SetPosition(history_offset);
WriteBuffer(&history_size, sizeof(unsigned int));
WriteBuffer(mem, history_size);
delete []mem;
}
borders.Close();
if(!index_file) return;
rewind(index_file);
fwrite(&signature, sizeof(unsigned int), 1, index_file);
fwrite(&totvert, sizeof(unsigned int), 1, index_file);
fwrite(&totface, sizeof(unsigned int), 1, index_file);
fwrite(&sphere, sizeof(Sphere3f), 1, index_file);
fwrite(&chunk_size, sizeof(unsigned int), 1, index_file);
unsigned int size = index.size(); //size of index
fwrite(&size, sizeof(unsigned int), 1, index_file);
fwrite(&(index[0]), sizeof(PatchInfo), size, index_file);
//TODO this should be moved to the end...
//BUT it will break compatibility with existing models.
patches.WriteEntries(index_file);
borders.WriteEntries(index_file);
vector<unsigned int> buffer;
buffer.push_back(history.size());
for(unsigned int i = 0; i < history.size(); i++) {
Update &update = history[i];
buffer.push_back(update.erased.size());
buffer.push_back(update.created.size());
for(unsigned int e = 0; e < update.erased.size(); e++)
buffer.push_back(update.erased[e]);
for(unsigned int e = 0; e < update.created.size(); e++)
buffer.push_back(update.created[e]);
IndexFile<Entry>::Close();
}
size = buffer.size();
fwrite(&size, sizeof(unsigned int), 1, index_file);
fwrite(&(buffer[0]), sizeof(unsigned int), size, index_file);
fclose(index_file);
index_file = NULL;
void Nexus::SaveHeader() {
unsigned int magic = 0x3053584e; // nxs0
WriteBuffer(&magic, sizeof(unsigned int));
WriteBuffer(&signature, sizeof(unsigned int));
WriteBuffer(&chunk_size, sizeof(unsigned int));
WriteBuffer(&offset, sizeof(int64));
WriteBuffer(&history_offset, sizeof(int64));
WriteBuffer(&totvert, sizeof(unsigned int));
WriteBuffer(&totface, sizeof(unsigned int));
WriteBuffer(&sphere, sizeof(Sphere3f));
}
bool Nexus::LoadHeader() {
unsigned int magic;
ReadBuffer(&magic, sizeof(unsigned int));
if(magic != 0x3053584e) {
cerr << "Invalid magic. Not a nxs file\n";
return false;
}
ReadBuffer(&signature, sizeof(unsigned int));
ReadBuffer(&chunk_size, sizeof(unsigned int));
ReadBuffer(&offset, sizeof(int64));
ReadBuffer(&history_offset, sizeof(int64));
ReadBuffer(&totvert, sizeof(unsigned int));
ReadBuffer(&totface, sizeof(unsigned int));
ReadBuffer(&sphere, sizeof(Sphere3f));
}
void Nexus::Flush(bool all) {
if(all) {
std::map<unsigned int, list<unsigned int>::iterator>::iterator i;
for(i = index.begin(); i != index.end(); i++) {
unsigned int patch = (*i).first;
FlushPatch(patch);
}
pqueue.clear();
index.clear();
} else {
while(ram_used > ram_max) {
unsigned int to_flush = pqueue.back();
pqueue.pop_back();
index.erase(to_flush);
FlushPatch(to_flush);
}
}
}
Patch &Nexus::GetPatch(unsigned int patch, bool flush) {
assert(patch < index.size());
PatchInfo &info = index[patch];
return patches.Lookup(patch, info.nvert, info.nface);
Entry &entry = operator[](patch);
if(index.count(patch)) {
assert(entry.patch);
list<unsigned int>::iterator &i = index[patch];
pqueue.erase(i);
pqueue.push_front(patch);
} else {
while(flush && ram_used > ram_max) {
unsigned int to_flush = pqueue.back();
pqueue.pop_back();
index.erase(to_flush);
FlushPatch(to_flush);
}
assert(!entry.patch);
entry.patch = LoadPatch(patch);
pqueue.push_front(patch);
list<unsigned int>::iterator i = pqueue.begin();
index[patch] = i;
}
return *(entry.patch);
}
Border Nexus::GetBorder(unsigned int patch, bool flush) {
PatchInfo &info = index[patch];
return borders.GetBorder(patch);
}
void Nexus::AddBorder(unsigned int patch, Link &link) {
/*void Nexus::AddBorder(unsigned int patch, Link &link) {
Border border = GetBorder(patch);
unsigned int pos = border.Size();
@ -179,27 +179,30 @@ void Nexus::AddBorder(unsigned int patch, Link &link) {
assert(border.Available() > pos);
border[pos] = link;
}
}*/
unsigned int Nexus::AddPatch(unsigned int nvert, unsigned int nface,
unsigned int nbord) {
PatchInfo info;
info.nvert = nvert;
info.nface = nface;
Entry entry;
entry.patch_start = 0xffffffff;
entry.ram_size = Patch::ChunkSize(signature, nvert, nface, chunk_size);
entry.disk_size = 0xffff;
entry.nvert = nvert;
entry.nface = nface;
entry.error = 0;
//sphere undefined.
entry.patch = NULL;
entry.vbo_array = 0;
entry.vbo_element = 0;
push_back(entry);
patches.AddPatch(nvert, nface);
borders.AddBorder(nbord);
index.push_back(info);
totvert += nvert;
totface += nface;
return index.size() -1;
}
void Nexus::MaxRamBuffer(unsigned int r_size) {
patches.MaxRamBuffer(r_size);
//TODO do the same with borders
return size() - 1;
}
void Nexus::Unify(float threshold) {
@ -207,9 +210,9 @@ void Nexus::Unify(float threshold) {
unsigned int duplicated = 0;
unsigned int degenerate = 0;
for(unsigned int p = 0; p < index.size(); p++) {
PatchInfo &entry = index[p];
Patch patch = GetPatch(p);
for(unsigned int p = 0; p < size(); p++) {
Entry &entry = operator[](p);
Patch &patch = GetPatch(p);
unsigned int vcount = 0;
map<Point3f, unsigned short> vertices;
@ -294,7 +297,7 @@ void Nexus::Unify(float threshold) {
}
//better to compact directly borders than setting them null.
//finally: there may be duplicated borders
for(unsigned int p = 0; p < index.size(); p++) {
for(unsigned int p = 0; p < size(); p++) {
Border border = GetBorder(p);
set<Link> links;
for(unsigned int b = 0; b < border.Size(); b++) {
@ -307,7 +310,7 @@ void Nexus::Unify(float threshold) {
for(set<Link>::iterator k = links.begin(); k != links.end(); k++)
border[count++] = *k;
borders.borders[p].border_used = links.size();
borders[p].used = links.size();
}
totvert -= duplicated;
@ -316,3 +319,77 @@ void Nexus::Unify(float threshold) {
if(degenerate)
cerr << "Found " << degenerate << " degenerate face while unmifying\n";
}
Patch *Nexus::LoadPatch(unsigned int idx) {
assert(idx < size());
Entry &entry = operator[](idx);
if(entry.patch) return entry.patch;
char *ram = new char[entry.ram_size * chunk_size];
#ifndef NDEBUG
if(!ram) {
cerr << "COuld not allocate ram!\n";
exit(0);
}
#endif
Patch *patch = new Patch(signature, ram, entry.nvert, entry.nface);
if(entry.patch_start != 0xffffffff) { //was allocated.
assert(entry.disk_size != 0xffff);
MFile::SetPosition((int64)entry.patch_start * (int64)chunk_size);
if((signature & NXS_COMPRESSED) == 0) { //not compressed
MFile::ReadBuffer(ram, entry.disk_size * chunk_size);
} else {
unsigned char *disk = new unsigned char[entry.disk_size * chunk_size];
MFile::ReadBuffer(disk, entry.disk_size * chunk_size);
patch->Decompress(entry.ram_size * chunk_size,
disk, entry.disk_size * chunk_size);
delete []disk;
}
}
ram_used += entry.ram_size;
entry.patch = patch;
return patch;
}
void Nexus::FlushPatch(unsigned int id) {
Entry &entry = operator[](id);
assert(entry.patch);
if(!MFile::IsReadOnly()) { //write back patch
if((signature & NXS_COMPRESSED)) {
unsigned int compressed_size;
char *compressed = entry.patch->Compress(entry.ram_size * chunk_size,
compressed_size);
if(entry.disk_size == 0xffff) {//allocate space
assert(entry.patch_start == 0xffffffff);
entry.disk_size = (unsigned int)((compressed_size-1)/chunk_size) + 1;
entry.patch_start = (unsigned int)(Length()/chunk_size);
Redim(Length() + entry.disk_size * chunk_size);
} else {
//cerr << "OOOOPSPPPS not supported!" << endl;
exit(-1);
}
MFile::SetPosition((int64)entry.patch_start * (int64)chunk_size);
MFile::WriteBuffer(compressed, entry.disk_size * chunk_size);
delete []compressed;
} else {
if(entry.disk_size == 0xffff) {
entry.disk_size = entry.ram_size;
entry.patch_start = (unsigned int)(Length()/chunk_size);
Redim(Length() + entry.disk_size * chunk_size);
}
MFile::SetPosition((int64)entry.patch_start * (int64)chunk_size);
MFile::WriteBuffer(entry.patch->start, entry.disk_size * chunk_size);
}
}
delete [](entry.patch->start);
delete entry.patch;
entry.patch = NULL;
ram_used -= entry.ram_size;
}

View File

@ -3,15 +3,65 @@
#include <string>
#include <vector>
#include <list>
#include <map>
#include "nexusbase.h"
#include "lrupserver.h"
#include <vcg/space/sphere3.h>
#include "patch.h"
#include "index_file.h"
#include "history.h"
#include "borderserver.h"
namespace nxs {
class Nexus: public NexusBase {
/* Header fo nexus:
1Kb riservato per dati globali:
Magic: 'n' 'x' 's' 0x00
Signature: unsigned int (maschera di bit)
Chunk size: unsigned int
Index offset: unsigned int (offset to the index begin,
must be a multiple of chunk size)
History offset: unsigned int: multiple of chunk_size
Tot vert: unsigned int
Tot face: unsigned int
Bound sphere: Sphere3f (4 float: Point3f center (x, y, z), (radius))
11 * 4 = 44 bytes -> 4k per alignment purpoouses and reserving space. */
struct Entry {
unsigned int patch_start; //granularita' Chunk
unsigned short ram_size; //in chunks
unsigned short disk_size; // in chunks (used when compressed)
unsigned short nvert;
unsigned short nface;
vcg::Sphere3f sphere;
float error;
Patch *patch;
unsigned int vbo_array;
unsigned int vbo_element;
};
class Nexus: public IndexFile<Entry> {
public:
//HEader data:
Signature signature;
unsigned int chunk_size;
//unsigned int .IndexFile::offset;
int64 history_offset;
unsigned int totvert;
unsigned int totface;
vcg::Sphere3f sphere;
History history;
BorderServer borders;
Nexus() {}
~Nexus();
@ -20,12 +70,17 @@ class Nexus: public NexusBase {
unsigned int chunk_size = 1024);
bool Load(const std::string &filename, bool readonly = false);
void Close();
void Flush(bool all = true);
unsigned int AddPatch(unsigned int nv, unsigned int nf, unsigned int nb);
Patch &GetPatch(unsigned int patch, bool flush = true);
Border GetBorder(unsigned int patch, bool flush = true);
void AddBorder(unsigned int patch, Link &link);
unsigned int &MaxRam() { return ram_max; }
// void AddBorder(unsigned int patch, Link &link);
//move to nxsalgo!
void Unify(float threshold = 0.0f);
bool IsCompressed() { return (signature & NXS_COMPRESSED) != 0; }
bool HasStrips() { return (signature & NXS_STRIP) != 0; }
@ -33,34 +88,18 @@ class Nexus: public NexusBase {
bool HasNormalsShort() { return (signature & NXS_NORMALS_SHORT) != 0; }
bool HasNormalsFloat() { return (signature & NXS_NORMALS_FLOAT) != 0; }
void MaxRamBuffer(unsigned int ram_size);
unsigned int ram_max;
unsigned int ram_used;
protected:
//move to nxsalgo!
void Unify(float threshold = 0.0f);
std::list<unsigned int> pqueue;
std::map<unsigned int, std::list<unsigned int>::iterator> index;
Patch *LoadPatch(unsigned int id);
virtual void FlushPatch(unsigned int id);
/* Nexus data */
//BE CAREFUL: this 2 members get replicated into patchserver
//TODO fix this nasty thing it is dangerous as it is.
// Signature signature;
// unsigned int chunk_size;
// unsigned int totvert;
// unsigned int totface;
// vcg::Sphere3f sphere;
// std::vector<PatchInfo> index;
LruPServer patches;
BorderServer borders;
// std::vector<Update> history;
// bool readonly;
// private:
// FILE *index_file;
bool LoadHeader();
void SaveHeader();
};
}

View File

@ -39,6 +39,10 @@
<a name="picture"><h1>Big picture</h1></a>
La truttura nexus divide la mesh in tante piccole parti.<br>
Ciascuna parte ha le facce indicizzate localmente, e sono codificate
esplicitamente le corrispondenze tra vertici di patches diverse.<br>
<a name="struct"><h1>Structures and interfaces</h1></a>
<a name="vfile"><h2>VFile</h2></a>
@ -46,12 +50,24 @@ 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>
<pre>
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>
storare i dati.(3 unsigned int per una faccia e 3 float per un vertice).
Per cui e' composto di 3 files:
Header (<b>.crd</b>)
Magic: 'c' 'r' 'd' 0x00 (4 bytes)
N vertici: unsigned int (4 bytes)
N facce: unsigned int (4 bytes)
Box: Box3f (6 float min(x, y, z) e max(x, y, z))
File dei vertici: Point3f in sequenza (3 float, x, y, z)
File delle facce: 3 unsigned int
opzionalmente file degli attributi dei vertici e delle facce.
Come interfaccia e' sufficente che dia accesso casuale a facce e vertici...
</pre>
<a name="pchain"><h2>PChain</h2></a>
Sta per 'partition chain' cioe' una catena di partizioni dello
spazio.<br>
@ -62,29 +78,47 @@ 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>
<pre>
E' una struttura con 2 files:
File delle patches: (<b>.nxs</b>)
1Kb riservato per dati globali:
Magic: 'n' 'x' 's' 0x00
Signature: unsigned int (maschera di bit)
Chunk size: unsigned int
Index offset: int64 (offset to the index begin,
must be a multiple of chunk size)
History offset: int64: multiple of chunk_size
Tot vert: unsigned int
Tot face: unsigned int
Bound sphere: Sphere3f (4 float: Point3f center (x, y, z), (radius))
Dati (la sequenza di patches)
Index
History
'Index' contiene l'indice delle patches, per ogni patch viene storato:
offset, size dei dati geometrici nel file delle patches etc.
'History' vedi history.h
Index e History sono tenuti in memoria se il file e' aperto per creare
o per modificare, e sono salvati quando si chiude il file.
File dei bordi:
Links.
Index (offset, size tot size used)
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)
</pre>
<br>
<a name="bmt"><h2>Bmt</h2></a>
Bmt (batched multi triangulation) e' il formato per la

View File

@ -8,13 +8,13 @@
namespace nxs {
struct PatchInfo {
/*struct PatchInfo {
unsigned short nvert;
unsigned short nface;
vcg::Sphere3f sphere;
float error;
};
};*/
class NexusBase {
@ -49,7 +49,7 @@ class NexusBase {
unsigned int totface;
vcg::Sphere3f sphere;
std::vector<PatchInfo> index;
// std::vector<PatchInfo> index;
std::vector<Update> history;
bool readonly;

File diff suppressed because it is too large Load Diff

View File

@ -1,178 +1,108 @@
#ifndef NXS_NEXUS_MT_H
#define NXS_NEXUS_MT_H
#ifndef NXS_MT_H
#define NXS_MT_H
#include <vector>
#include <queue>
#include <wrap/gui/frustum.h>
#include "nexusbase.h"
#include "queuepserver.h"
#include "borderserver.h"
#include "prefetch.h"
#include "nexus.h"
#include "history.h"
#include "extraction.h"
#include "metric.h"
#include "preload.h"
#include "watch.h"
namespace nxs {
typedef std::vector<unsigned int> Frag;
struct Node {
std::vector<Node *> in;
std::vector<Node *> out;
std::vector<Frag> frags;
float error;
bool visited;
bool current;
// bool pushed;
};
struct TNode {
float error;
Node *node;
TNode(Node *n, float e): node(n), error(e) {}
bool operator<(const TNode &n) { return error < n.error; }
};
class Metric {
public:
std::vector<PatchInfo> *index;
float GetError(Node *node);
float GetError(Frag &frag);
virtual float GetError(unsigned int cell) = 0;
virtual void GetView() {}
};
class FlatMetric: public Metric {
public:
void GetView() {}
float GetError(unsigned int cell);
};
class DeltaMetric: public Metric {
public:
vcg::Point3f delta;
void GetView() {}
float GetError(unsigned int cell);
};
class FrustumMetric: public Metric {
public:
vcg::Frustumf frustum;
void GetView() { frustum.GetView(); }
float GetError(unsigned int cell);
};
/* class Policy {
public:
float error;
int ram_used;
int ram_size;
vector<PatchEntry> *entries;
void Init();
bool Expand(TNode &node);
void NodeVisited(Node *node);
};*/
class NexusMt: public NexusBase {
public:
//Vertex buffer object mode
enum Vbo { VBO_AUTO, //autodetect best size
VBO_OFF, //no vertex buffer object
VBO_FIXED }; //user supplied size
enum MetricKind { FRUSTUM, //screen error extraction
GEOMETRY, //geometry error extraction
DELTA }; //delta error
enum Mode { POINTS,
SMOOTH,
XRAY,
HIDDEN_LINE,
FLAT_WIRE,
FLAT,
PATCHES };
enum Component { COLOR = 0x1,
NORMAL = 0x2,
TEXTURE = 0x4,
DATA = 0x8};
Vbo vbo_mode;
Metric *metric;
float target_error;
vcg::Frustumf frustum;
unsigned int extraction_max; //total extraxtion (even culled parts)
unsigned int extraction_used;
unsigned int draw_max; //only visible parts
unsigned int draw_used;
unsigned int disk_max; //max not in ram loadable size
unsigned int disk_used;
struct DrawContest {
enum Mode { POINTS, SMOOTH, XRAY, HIDDEN_LINE, FLAT_WIRE, FLAT, PATCHES };
enum Attr { COLOR = 0x1, NORMAL = 0x2, TEXTURE = 0x4, DATA = 0x8 };
Mode mode;
unsigned int attrs;
unsigned int components;
bool use_normals;
bool use_colors;
bool use_textures;
bool use_data;
DrawContest(Mode m = SMOOTH, unsigned int a = 0xf): mode(m), attrs(a) {}
void SetAttr(Attr attr, bool value);
bool HasComponent(Attr attr);
};
//statistics:
unsigned int tri_rendered;
unsigned int tri_total;
struct Stats {
float ktri; //k triangles rendered.
float kdisk; //k readed per frame (mean)
float kdisk_peak; //k readed peak.
float fps;
float fps_peak; //low fps peaks
vector<QueuePServer::Data *> todraw;
std::vector<PServer::Item> visited;
std::vector<Node *> sequence;
//double last_time;
unsigned int count;
QueuePServer patches;
BorderServer borders;
Watch watch;
Prefetch prefetch;
Stats(): count(0) {}
void Init();
};
class NexusMt: public Nexus {
public:
bool use_vbo;
bool prefetch;
unsigned int vbo_used; //TODO remember to zero it!
Preload preload;
NexusMt();
~NexusMt();
bool Load(const std::string &filename);
void Close();
// void Close();
bool InitGL(Vbo mode = VBO_AUTO, unsigned int vbo_size = 64000000);
bool InitGL(bool use_vbo = true);
void Render(DrawContest contest = DrawContest());
void Render(Extraction &extraction,
DrawContest &contest,
Stats *stats = NULL);
// void Draw(std::vector<unsigned int> &selected);
// void Extract(std::vector<unsigned int> &selected);
protected:
void FlushPatch(unsigned int id);
void LoadVbo(Entry &entry);
void FlushVbo(Entry &entry);
void Draw(unsigned int cell, DrawContest &contest);
};
/* class NexusViewer {
public:
NexusMt &mt;
DrawContest contest;
Extraction extraction;
Statistics stats;
NexusViewer(NexyusMt &_mt): mt(&mt) {}
void Render();
bool SetMode(DrawContest::Mode mode);
bool SetComponent(DrawContest::Component c, bool on);
bool SetComponents(unsigned int mask);
void SetMetric(MetricKind kind);
void SetError(float error);
void SetExtractionSize(unsigned int ram_size);
void SetPrefetchSize(unsigned int size);
void SetVboSize(unsigned int vbo_size);
//Uinits expressed in Kb
void SetExtractionSize(unsigned int ksize);
void SetDrawSize(unsigned int ksize);
void SetDiskDelta(unsigned int kdelta);
//void SetPrefetchSize(unsigned int size);
};*/
bool SetMode(Mode mode);
bool SetComponent(Component c, bool on);
bool SetComponents(unsigned int mask);
void Draw(std::vector<unsigned int> &selected);
void Draw(unsigned int cell, QueuePServer::Data &data);
void Extract(std::vector<unsigned int> &selected);
protected:
std::vector<Node> nodes;
bool Expand(TNode &node);
void NodeVisited(Node *node);
void LoadHistory();
void ClearHistory();
void VisitNode(Node *node, std::vector<TNode> &heap);
void UnvisitNode(Node *node, std::vector<TNode> &heap);
void Select(std::vector<unsigned int> &selected);
Patch &LoadPatch(unsigned int p);
};
}

View File

@ -24,6 +24,9 @@
History
$Log: not supported by cvs2svn $
Revision 1.27 2004/12/15 16:37:55 ponchio
Optimizing realtime vis.
Revision 1.26 2004/12/15 13:50:32 ponchio
Optimizing realtime vis.
@ -205,7 +208,11 @@ int main(int argc, char *argv[]) {
cerr << "Could not load nexus file: " << argv[1] << endl;
return -1;
}
Sphere3f sphere = nexus.sphere;
Extraction extraction;
DrawContest contest;
Stats stats;
if(!init(argv[1])) {
cerr << "Could not init SDL window\n";
@ -244,11 +251,11 @@ int main(int argc, char *argv[]) {
bool show_statistics = true;
bool extract = true;
NexusMt::MetricKind metric;
NexusMt::Mode mode = NexusMt::SMOOTH;
// NexusMt::MetricKind metric;
//DrawContest::Mode mode = DrawContest::SMOOTH;
nexus.SetError(error);
nexus.SetMetric(NexusMt::FRUSTUM);
//nexus.SetError(error);
// nexus.SetMetric(NexusMt::FRUSTUM);
if(!nexus.InitGL()) {
cerr << "Could not init glew.\n";
}
@ -292,32 +299,34 @@ int main(int argc, char *argv[]) {
case SDLK_c: show_colors = !show_colors; break;
case SDLK_n: show_normals = !show_normals; break;
case SDLK_LEFT: nexus.patches.ram_max *= 0.8; break;
case SDLK_RIGHT: nexus.patches.ram_max *= 1.3; break;
case SDLK_UP: nexus.draw_max *= 1.3; break;
case SDLK_DOWN: nexus.draw_max *= 0.8; break;
case SDLK_PAGEUP: nexus.disk_max *= 1.3; break;
case SDLK_PAGEDOWN: nexus.disk_max *= 0.8; break;
case SDLK_LEFT: nexus.MaxRam() *= 0.8; break;
case SDLK_RIGHT: nexus.MaxRam() *= 1.3; break;
case SDLK_UP: extraction.draw_max *= 1.3; break;
case SDLK_DOWN: extraction.draw_max *= 0.8; break;
case SDLK_PAGEUP: extraction.disk_max *= 1.3; break;
case SDLK_PAGEDOWN: extraction.disk_max *= 0.8; break;
case SDLK_0: extraction.extr_max *= 1.3; break;
case SDLK_9: extraction.extr_max *= 0.8; break;
case SDLK_s: metric = NexusMt::FRUSTUM; break;
case SDLK_p: mode = NexusMt::POINTS; nexus.SetMode(mode); break;
case SDLK_d: mode = NexusMt::PATCHES; nexus.SetMode(mode); break;
case SDLK_f: mode = NexusMt::FLAT; nexus.SetMode(mode); break;
case SDLK_m: mode = NexusMt::SMOOTH; nexus.SetMode(mode); break;
// case SDLK_s: metric = NexusMt::FRUSTUM; break;
case SDLK_p: contest.mode = DrawContest::POINTS; break;
case SDLK_d: contest.mode = DrawContest::PATCHES; break;
case SDLK_f: contest.mode = DrawContest::FLAT; break;
case SDLK_m: contest.mode = DrawContest::SMOOTH; break;
case SDLK_r:
case SDLK_SPACE: rotate = !rotate; break;
case SDLK_MINUS:
error *= 0.9f;
nexus.SetError(error);
cerr << "Error: " << error << endl; break;
extraction.target_error *= 0.9f;
cerr << "Error: " << extraction.target_error << endl;
break;
case SDLK_EQUALS:
case SDLK_PLUS:
error *= 1.1f;
nexus.SetError(error);
cerr << "Error: " << error << endl; break;
extraction.target_error *= 1.1f;
cerr << "Error: " << extraction.target_error << endl;
break;
}
break;
case SDL_KEYUP:
@ -399,23 +408,12 @@ int main(int argc, char *argv[]) {
glColor3f(0.8f, 0.8f, 0.8f);
//nexus.SetPolicy(policy, error);
nexus.SetComponent(NexusMt::COLOR, show_colors);
nexus.SetComponent(NexusMt::NORMAL, show_normals);
static vector<unsigned int> cells;
//watch.Start();
if(extract) {
// nexus.patches.Flush();
nexus.metric->GetView();
// nexus.policy.Init();
nexus.tri_total = 0;
nexus.tri_rendered = 0;
nexus.Extract(cells);
extraction.frustum.GetView();
extraction.metric->GetView();
extraction.Extract(&nexus);
}
nexus.Draw(cells);
nexus.Render(extraction, contest, &stats);
/* if(show_borders) {
for(unsigned int i = 0; i < cells.size(); i++) {
@ -452,26 +450,36 @@ int main(int argc, char *argv[]) {
double ftime = (tframe[(offset+4)%5] - tframe[(offset)%5])/5.0f;
/* sprintf(buffer, "Ram size : %.3fMb (max) %.3fMb (cur)",
nexus.patches->ram_size * nexus.chunk_size/(float)(1<<20),
nexus.patches->ram_used * nexus.chunk_size/(float)(1<<20));
gl_print(0.03, 0.12, buffer);*/
sprintf(buffer, "Ram size : %.3fMb (max) %.3fMb (cur)",
nexus.patches.ram_max * nexus.chunk_size/(float)(1<<20),
nexus.patches.ram_used * nexus.chunk_size/(float)(1<<20));
nexus.ram_max * nexus.chunk_size/(float)(1<<20),
nexus.ram_used * nexus.chunk_size/(float)(1<<20));
gl_print(0.03, 0.15, buffer);
sprintf(buffer, "Extr size: %.3fMb(max) %.3fMb(cur)",
extraction.extr_max * nexus.chunk_size/(float)(1<<20),
extraction.extr_used * nexus.chunk_size/(float)(1<<20));
gl_print(0.03, 0.12, buffer);
sprintf(buffer, "Draw size: %.3fMb(max) %.3fMb(cur)",
extraction.draw_max * nexus.chunk_size/(float)(1<<20),
extraction.draw_used * nexus.chunk_size/(float)(1<<20));
gl_print(0.03, 0.09, buffer);
sprintf(buffer, "Vbo size : %.3fMb(cur) Load: %.4fK Pref: %.4fK",
nexus.patches.vbo_used * nexus.chunk_size/(float)(1<<20),
nexus.prefetch.loading, nexus.prefetch.prefetching);
sprintf(buffer, "Disk size: %.3fMb(max) %.3fMb(cur)",
extraction.disk_max * nexus.chunk_size/(float)(1<<20),
extraction.disk_used * nexus.chunk_size/(float)(1<<20));
gl_print(0.03, 0.06, buffer);
// sprintf(buffer, "Vbo size : %.3fMb(cur) Load: %.4fK Pref: %.4fK",
// nexus.patches.vbo_used * nexus.chunk_size/(float)(1<<20),
// nexus.prefetch.loading, nexus.prefetch.prefetching);
// gl_print(0.03, 0.06, buffer);
sprintf(buffer, "Triangles: %.2fK (tot) %.2fK (vis) "
"%.3f time %.2f FPS",
nexus.tri_total/(float)(1<<10),
nexus.tri_rendered/(float)(1<<10),
ftime, 1/ftime);
" %.2f FPS",
stats.ktri/(float)(1<<10),
stats.ktri/(float)(1<<10),
stats.fps);
gl_print(0.03, 0.03, buffer);
glEnable(GL_DEPTH_TEST);

View File

@ -5,6 +5,7 @@
//#include <wrap/strip/tristrip.h>
#include "nxsalgo.h"
#include "vfile.h"
#include "nexus.h"
#include "watch.h"
@ -35,7 +36,7 @@ void nxs::ComputeNormals(Nexus &nexus) {
exit(0);
}
for(unsigned int p = 0; p < nexus.index.size(); p++) {
for(unsigned int p = 0; p < nexus.size(); p++) {
Border border = nexus.GetBorder(p);
tmpb_start.push_back(tmpb_offset);
tmpb_offset += border.Size();
@ -50,10 +51,10 @@ void nxs::ComputeNormals(Nexus &nexus) {
//first step normals in the same patch.
cerr << "First Step\n";
Report report(nexus.index.size(), 5);
Report report(nexus.size(), 5);
vector<Point3f> normals;
for(unsigned int p = 0; p < nexus.index.size(); p++) {
for(unsigned int p = 0; p < nexus.size(); p++) {
report.Step(p);
Patch &patch = nexus.GetPatch(p);
@ -166,8 +167,8 @@ void nxs::ComputeNormals(Nexus &nexus) {
//Second step unify normals across borders
cerr << "Second step\n";
report.Init(nexus.index.size());
for(unsigned int p = 0; p < nexus.index.size(); p++) {
report.Init(nexus.size());
for(unsigned int p = 0; p < nexus.size(); p++) {
report.Step(p);
Patch &patch = nexus.GetPatch(p);
Border border = nexus.GetBorder(p);

View File

@ -24,6 +24,9 @@
History
$Log: not supported by cvs2svn $
Revision 1.11 2004/12/13 00:44:48 ponchio
Lotsa changes...
Revision 1.10 2004/12/09 22:33:28 ponchio
Different splitting optimization.
@ -93,7 +96,7 @@ void SaveFragment(Nexus &nexus, VChain &chain,
Fragment &fragin,
Fragment &fragout);
void ReverseHistory(vector<Nexus::Update> &history);
void ReverseHistory(vector<History::Update> &history);
unsigned int current_level;
@ -285,7 +288,7 @@ void ThirdStep(const string &crudefile, const string &output,
Nexus nexus;
//TODO here i really need no ram_buffer.....
nexus.MaxRamBuffer(0);
nexus.MaxRam() = 0;
if(!nexus.Create(output, NXS_FACES, chunk_size)) {
cerr << "Could not create nexus output: " << output << endl;
getchar();
@ -341,7 +344,7 @@ void ThirdStep(const string &crudefile, const string &output,
memcpy(patch.FaceBegin(), &*faces.begin(), fcount * sizeof(short));
memcpy(patch.VertBegin(), &*vertices.begin(), vcount * sizeof(Point3f));
Sphere3f &sphere = nexus.index[patch_idx].sphere;
Sphere3f &sphere = nexus[patch_idx].sphere;
for(int i = 0; i < vertices.size(); i++)
sphere.Add(vertices[i]);
sphere.Radius() *= 1.01;
@ -367,21 +370,21 @@ void ThirdStep(const string &crudefile, const string &output,
}
//we can now update bounding sphere.
for(unsigned int i = 0; i < nexus.index.size(); i++)
nexus.sphere.Add(nexus.index[i].sphere);
for(unsigned int i = 0; i < nexus.size(); i++)
nexus.sphere.Add(nexus[i].sphere);
Nexus::Update update;
for(unsigned int i = 1; i < nexus.index.size(); i++) {
History::Update update;
for(unsigned int i = 1; i < nexus.size(); i++) {
update.created.push_back(i);
}
nexus.history.push_back(update);
nexus.history.updates.push_back(update);
update.created.clear();
update.created.push_back(0);
for(unsigned int i = 1; i < nexus.index.size(); i++) {
for(unsigned int i = 1; i < nexus.size(); i++) {
update.erased.push_back(i);
}
nexus.history.push_back(update);
nexus.history.updates.push_back(update);
if(!vert_index.Save(output + ".rvi")) {
cerr << "Could not save: " << output << ".rvi\n";
@ -397,7 +400,7 @@ void FourthStep(const string &crudefile, const string &output,
cerr << "Could not load nexus " << output << endl;
exit(0);
}
nexus.MaxRamBuffer(ram_buffer);
nexus.MaxRam() = ram_buffer / nexus.chunk_size;
//TODO Clear borders in case of failure!
VFile<unsigned int> vert_remap;
@ -411,11 +414,11 @@ void FourthStep(const string &crudefile, const string &output,
cerr << "Could not load index\n";
exit(0);
}
Report report(nexus.index.size());
Report report(nexus.size());
for(int start = 0; start < nexus.index.size(); start++) {
for(int start = 0; start < nexus.size(); start++) {
report.Step(start);
PatchInfo &s_entry = nexus.index[start];
Entry &s_entry = nexus[start];
vector<Link> links;
#ifdef WIN32
@ -428,10 +431,10 @@ void FourthStep(const string &crudefile, const string &output,
vremap[global] = i;
}
for(int end = 0; end < nexus.index.size(); end++) {
for(int end = 0; end < nexus.size(); end++) {
if(start == end) continue;
PatchInfo &e_entry = nexus.index[end];
Entry &e_entry = nexus[end];
float dist = Distance(s_entry.sphere, e_entry.sphere);
if(dist > s_entry.sphere.Radius() + e_entry.sphere.Radius()) {
@ -451,7 +454,7 @@ void FourthStep(const string &crudefile, const string &output,
}
//TODO Horribili visu (interfaccia di cacca!)
nexus.borders.ResizeBorder(start, 3 * links.size());
nexus.borders.borders[start].border_used = links.size();
nexus.borders[start].used = links.size();
Border border = nexus.GetBorder(start);
memcpy(&(border[0]), &*links.begin(), links.size() * sizeof(Link));
}
@ -471,22 +474,22 @@ void FifthStep(const string &crudefile, const string &output,
cerr << "Could not load nexus " << output << endl;
exit(0);
}
nexus.MaxRamBuffer(ram_buffer);
nexus.MaxRam() = ram_buffer / nexus.chunk_size;
VChain vchain;
if(!vchain.Load(output + ".vchain")) {
cerr << "Could not load : " << output << ".vchain\n";
exit(0);
}
nexus.history.clear();
Nexus::Update update;
for(unsigned int i = 0; i < nexus.index.size(); i++) {
nexus.history.Clear();
History::Update update;
for(unsigned int i = 0; i < nexus.size(); i++) {
update.created.push_back(i);
patch_levels.push_back(0);
}
nexus.history.push_back(update);
nexus.history.updates.push_back(update);
nexus.Unify();
nexus.patches.Flush();
nexus.Flush();
Dispatcher dispatcher(&nexus, &vchain);
@ -502,7 +505,7 @@ void FifthStep(const string &crudefile, const string &output,
current_level = level;
cerr << "Level: " << level << endl;
unsigned int newoffset = nexus.index.size();
unsigned int newoffset = nexus.size();
BuildLevel(vchain, nexus, oldoffset, scaling,
patch_size, patch_threshold, 65000,
optimization_steps);
@ -571,8 +574,8 @@ void FifthStep(const string &crudefile, const string &output,
for(s = fcells.begin(); s != fcells.end(); s++)
update.erased.push_back(*s);
}
nexus.history.push_back(update);
ReverseHistory(nexus.history);
nexus.history.updates.push_back(update);
ReverseHistory(nexus.history.updates);
// TestBorders(nexus);
nexus.Close();
@ -719,7 +722,7 @@ void BuildFragment(Nexus &nexus, VPartition &part,
int nnears = 10;
if(part.size() < 10) nnears = part.size();
for(f = patches.begin(); f != patches.end(); f++) {
Point3f &center = nexus.index[*f].sphere.Center();
Point3f &center = nexus[*f].sphere.Center();
part.Closest(center, nnears, nears, dists);
for(int i = 0; i < nnears; i++)
seeds.insert(nears[i]);
@ -737,7 +740,7 @@ void SaveFragment(Nexus &nexus, VChain &chain,
set<unsigned int> orig_patches;
Nexus::Update update;
History::Update update;
for(unsigned int i = 0; i < fragin.pieces.size(); i++) {
NxsPatch &patch = fragin.pieces[i];
update.erased.push_back(patch.patch);
@ -756,7 +759,7 @@ void SaveFragment(Nexus &nexus, VChain &chain,
patch.face.size()/3,
bordsize);
patch_levels.push_back(current_level);
PatchInfo &entry = nexus.index[patch_idx];
Entry &entry = nexus[patch_idx];
entry.error = fragout.error;
patch_remap[i] = patch_idx;
@ -784,7 +787,7 @@ void SaveFragment(Nexus &nexus, VChain &chain,
memcpy(patch.VertBegin(), &outpatch.vert[0],
outpatch.vert.size() * sizeof(Point3f));
PatchInfo &entry = nexus.index[patch_idx];
Entry &entry = nexus[patch_idx];
for(unsigned int v = 0; v < outpatch.vert.size(); v++) {
entry.sphere.Add(outpatch.vert[v]);
nexus.sphere.Add(outpatch.vert[v]);
@ -866,16 +869,16 @@ void SaveFragment(Nexus &nexus, VChain &chain,
border[bstart++] = link;
}
}
nexus.history.push_back(update);
nexus.history.updates.push_back(update);
}
void ReverseHistory(vector<Nexus::Update> &history) {
vector<Nexus::Update> revert = history;
void ReverseHistory(vector<History::Update> &history) {
vector<History::Update> revert = history;
history.clear();
for(int i = revert.size()-1; i >= 0; i--)
history.push_back(revert[i]);
//std::reverse(history.begin(), history.end());
vector<Nexus::Update>::iterator i;
vector<History::Update>::iterator i;
for(i = history.begin(); i != history.end(); i++)
swap((*i).erased, (*i).created);
}

View File

@ -216,7 +216,7 @@ int main(int argc, char *argv[]) {
cerr << "Could not open nexus file: " << input << "\n";
return -1;
}
nexus.MaxRamBuffer(ram_size);
nexus.MaxRam() = ram_size / nexus.chunk_size;
//Sanity tests
@ -263,7 +263,7 @@ int main(int argc, char *argv[]) {
<< "\n\tData : " << (int)((nexus.signature&NXS_DATA32) !=0)
<< "\n\n\tVertices: " << nexus.totvert
<< "\tFaces: " << nexus.totface
<< "\tPatches: " << nexus.index.size()
<< "\tPatches: " << nexus.size()
<< "\n\tSphere: "
<< nexus.sphere.Center()[0] << " "
<< nexus.sphere.Center()[1] << " "
@ -315,22 +315,22 @@ int main(int argc, char *argv[]) {
Nexus out;
if(!chunk_size)
chunk_size = nexus.patches.chunk_size;
chunk_size = nexus.chunk_size;
if(!out.Create(output, (Signature)signature, chunk_size)) {
cerr << "Could not open output: " << output << endl;
return -1;
}
out.MaxRamBuffer(ram_size);
out.MaxRam() = ram_size / out.chunk_size;
//TODO set rambuffer low (or even direct access!)
Report report(nexus.index.size());
Report report(nexus.size());
cout << "Copying and allocating...\n";
for(unsigned int patch = 0; patch < nexus.index.size(); patch++) {
for(unsigned int patch = 0; patch < nexus.size(); patch++) {
report.Step(patch);
PatchInfo &src_entry = nexus.index[patch];
Patch src_patch = nexus.GetPatch(patch);
Entry &src_entry = nexus[patch];
Patch &src_patch = nexus.GetPatch(patch);
Border src_border = nexus.GetBorder(patch);
@ -343,9 +343,9 @@ int main(int argc, char *argv[]) {
out.AddPatch(src_entry.nvert, src_entry.nface, src_border.Available());
PatchInfo &dst_entry = out.index[patch];
Entry &dst_entry = out[patch];
Patch dst_patch = out.GetPatch(patch);
Patch &dst_patch = out.GetPatch(patch);
//copy vertices:
memcpy(dst_patch.VertBegin(), src_patch.VertBegin(),
@ -396,8 +396,8 @@ int main(int argc, char *argv[]) {
if(link.IsNull()) continue;
assert(link.end_patch < nexus.index.size());
}*/
Border dst_border = out.GetBorder(patch);
out.borders.ResizeBorder(patch, src_border.Size());
Border dst_border = out.GetBorder(patch);
memcpy(dst_border.Start(), src_border.Start(),
src_border.Size() * sizeof(Link));
}
@ -416,9 +416,9 @@ int main(int argc, char *argv[]) {
}
if(qvertex && add_normals) {
report.Init(nexus.index.size());
report.Init(nexus.size());
cout << "Quantizing vertices\n";
for(unsigned int patch = 0; patch < nexus.index.size(); patch++) {
for(unsigned int patch = 0; patch < nexus.size(); patch++) {
report.Step(patch);
Patch src_patch = nexus.GetPatch(patch);
@ -430,7 +430,12 @@ int main(int argc, char *argv[]) {
}
out.sphere = nexus.sphere;
out.history = nexus.history;
//Fixing history
unsigned int h_size;
char *buffer = nexus.history.Save(h_size);
out.history.Load(h_size, buffer);
// out.history = nexus.history;
out.Close();
nexus.Close();

View File

@ -4,31 +4,26 @@
using namespace std;
using namespace nxs;
bool PServer::Create(const std::string &_filename,
Signature _signature,
unsigned int _chunk_size) {
signature = _signature;
chunk_size = _chunk_size;
bool PServer::Create(const std::string &filename,
Signature sig,
unsigned int csize,
unsigned int rsize) {
signature = sig;
chunk_size = csize;
ram_max = rsize/chunk_size + 1;
ram_used = 0;
return MFile::Create(filename);
}
bool PServer::Load(const std::string &filename, Signature sig,
unsigned int csize, bool readonly,
unsigned int rsize) {
bool PServer::Load(const std::string &filename, Signature _signature,
bool _readonly, unsigned int _chunk_size) {
signature = sig;
chunk_size = csize;
signature = _signature;
chunk_size = _chunk_size;
ram_max = rsize/chunk_size + 1;
ram_used = 0;
return MFile::Load(filename, readonly);
return MFile::Load(filename, _readonly);
}
void PServer::Close() {
@ -40,23 +35,21 @@ void PServer::Close() {
bool PServer::ReadEntries(FILE *fp) {
unsigned int n;
fread(&n, 1, sizeof(int), fp);
entries.resize(n);
resize(n);
for(unsigned int i = 0; i < n; i++) {
fread(&(entries[i].patch_start), 1, sizeof(unsigned int), fp);
fread(&(entries[i].ram_size), 1, sizeof(unsigned short), fp);
fread(&(entries[i].disk_size), 1, sizeof(unsigned short), fp);
entries[i].patch = NULL;
Entry &entry = operator[](i);
fread(&entry, sizeof(Entry), 1, fp);
entry.patch = NULL;
}
return true;
}
bool PServer::WriteEntries(FILE *fp) {
unsigned int n = entries.size();
unsigned int n = size();
fwrite(&n, 1, sizeof(int), fp);
for(unsigned int i = 0; i < entries.size(); i++) {
fwrite(&(entries[i].patch_start), 1, sizeof(unsigned int), fp);
fwrite(&(entries[i].ram_size), 1, sizeof(unsigned short), fp);
fwrite(&(entries[i].disk_size), 1, sizeof(unsigned short), fp);
for(unsigned int i = 0; i < size(); i++) {
Entry &entry = operator[](i);
fwrite(&entry, sizeof(Entry), 1, fp);
}
return true;
}
@ -66,17 +59,19 @@ void PServer::AddPatch(unsigned short nvert, unsigned short nface) {
entry.patch_start = 0xffffffff;
entry.ram_size = Patch::ChunkSize(signature, nvert, nface, chunk_size);
entry.disk_size = 0xffff;
entry.nvert = nvert;
entry.nface = nface;
//sphere and error undefined.
entry.patch = NULL;
entries.push_back(entry);
entry.vbo_array = 0;
entry.vbo_element = 0;
push_back(entry);
}
Patch *PServer::LoadPatch(unsigned int idx,
unsigned short nvert, unsigned short nface) {
// ramlock.rdlock();
assert(idx < entries.size());
Entry &entry = entries[idx];
Patch *PServer::LoadPatch(unsigned int idx) {
assert(idx < size());
Entry &entry = operator[](idx);
if(entry.patch) return entry.patch;
char *ram = new char[entry.ram_size * chunk_size];
@ -87,18 +82,18 @@ Patch *PServer::LoadPatch(unsigned int idx,
}
#endif
Patch *patch = new Patch(signature, ram, nvert, nface);
Patch *patch = new Patch(signature, ram, entry.nvert, entry.nface);
if(entry.patch_start != 0xffffffff) { //was allocated.
assert(entry.disk_size != 0xffff);
SetPosition((int64)entry.patch_start * (int64)chunk_size);
MFile::SetPosition((int64)entry.patch_start * (int64)chunk_size);
if((signature & NXS_COMPRESSED) == 0) { //not compressed
ReadBuffer(ram, entry.disk_size * chunk_size);
MFile::ReadBuffer(ram, entry.disk_size * chunk_size);
} else {
unsigned char *disk = new unsigned char[entry.disk_size * chunk_size];
ReadBuffer(disk, entry.disk_size * chunk_size);
MFile::ReadBuffer(disk, entry.disk_size * chunk_size);
patch->Decompress(entry.ram_size * chunk_size,
disk, entry.disk_size * chunk_size);
@ -110,46 +105,127 @@ Patch *PServer::LoadPatch(unsigned int idx,
return patch;
}
void PServer::FlushPatch(unsigned int id, Patch *patch) {
void PServer::FlushPatch(unsigned int id) {
Entry &entry = operator[](id);
//TODO move this into an assert!!!!
if(!patch) return;
Entry &entry = entries[id];
// cerr << "entry: " << (void *)(entry.patch) << " patch: " << (void *)patch << endl;
entry.patch = NULL;
if(!entry.patch) return;
if(!readonly) { //write back patch
if(!MFile::IsReadOnly()) { //write back patch
if((signature & NXS_COMPRESSED)) {
unsigned int compressed_size;
char *compressed = patch->Compress(entry.ram_size * chunk_size,
char *compressed = entry.patch->Compress(entry.ram_size * chunk_size,
compressed_size);
if(entry.disk_size == 0xffff) {//allocate space
assert(entry.patch_start == 0xffffffff);
entry.disk_size = (unsigned int)((compressed_size-1)/chunk_size) + 1;
entry.patch_start = (unsigned int)(Length()/chunk_size);
Redim(Length() + entry.disk_size * chunk_size);
entry.patch_start = (unsigned int)( MFile::Length()/chunk_size);
MFile::Redim(MFile::Length() + entry.disk_size * chunk_size);
} else {
//cerr << "OOOOPSPPPS not supported!" << endl;
exit(-1);
}
SetPosition((int64)entry.patch_start * (int64)chunk_size);
WriteBuffer(compressed, entry.disk_size * chunk_size);
MFile::SetPosition((int64)entry.patch_start * (int64)chunk_size);
MFile::WriteBuffer(compressed, entry.disk_size * chunk_size);
delete []compressed;
} else {
if(entry.disk_size == 0xffff) {
entry.disk_size = entry.ram_size;
entry.patch_start = (unsigned int)(Length()/chunk_size);
Redim(Length() + entry.disk_size * chunk_size);
entry.patch_start = (unsigned int)(MFile::Length()/chunk_size);
MFile::Redim(MFile::Length() + entry.disk_size * chunk_size);
}
SetPosition((int64)entry.patch_start * (int64)chunk_size);
WriteBuffer(patch->start, entry.disk_size * chunk_size);
MFile::SetPosition((int64)entry.patch_start * (int64)chunk_size);
MFile::WriteBuffer(entry.patch->start, entry.disk_size * chunk_size);
}
}
delete [](patch->start);
delete patch;
delete [](entry.patch->start);
delete entry.patch;
entry.patch = NULL;
ram_used -= entry.ram_size;
}
void PServer::MaxRamBuffer(unsigned int r_buffer) {
ram_max = (unsigned int)(r_buffer/chunk_size) + 1;
bool PServer::IsLoaded(unsigned int patch) {
return operator[](patch).patch != NULL;
}
Entry &PServer::Lookup(unsigned int patch, std::vector<unsigned int> &flush) {
Entry &entry = operator[](patch);
if(index.count(patch)) {
list<unsigned int>::iterator &i = index[patch];
pqueue.erase(i);
pqueue.push_front(patch);
assert(entry.patch);
} else {
while(ram_used > ram_max) {
unsigned int to_flush = pqueue.back();
pqueue.pop_back();
//TODO i should not flush current extraction!
//CRITICAL actually works just if ram_max is big enough.
index.erase(to_flush);
FlushPatch(to_flush);
flush.push_back(to_flush);
}
assert(!entry.patch);
entry.patch = LoadPatch(patch);
pqueue.push_front(patch);
list<unsigned int>::iterator i = pqueue.begin();
index[patch] = i;
}
return entry;
}
void PServer::Flush() {
std::map<unsigned int, list<unsigned int>::iterator>::iterator i;
for(i = index.begin(); i != index.end(); i++) {
unsigned int patch = *((*i).second);
Item &item = *((*i).second);
FlushVbo(patch);
FlushPatch(patch);
}
pqueue.clear();
index.clear();
}
void PServer::LoadVbo(unsigned int npatch) {
//WORKING if(!vbo_max) return;
Entryg &entry = operator[](npatch);
Patch &patch = *entry.patch;
glGenBuffersARB(1, &entry.vbo_element);
assert(entry.vbo_element);
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, entry.vbo_element);
unsigned int size = patch.nf * sizeof(unsigned short);
if((signature & NXS_FACES) != 0) size *= 3;
glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, size, patch.FaceBegin(),
GL_STATIC_DRAW_ARB);
vbo_used += size;
//TODO fix this when we allow data :p
size = sizeof(float) * patch.dstart;
glGenBuffersARB(1, &entry.vbo_array);
assert(entry.vbo_array);
glBindBufferARB(GL_ARRAY_BUFFER_ARB, entry.vbo_array);
glBufferDataARB(GL_ARRAY_BUFFER_ARB, size, patch.VertBegin(),
GL_STATIC_DRAW_ARB);
vbo_used += size;
}
void PServer::FlushVbo(unsigned int npatch) {
Entryg &entry = operator[](npatch);
if(!entry.vbo_element) return;
glDeleteBuffersARB(1, &entry.vbo_element);
glDeleteBuffersARB(1, &entry.vbo_array);
entry.vbo_element = 0;
entry.vbo_array = 0;
Patch &patch = *entry.patch;
vbo_used -= patch.nf * sizeof(unsigned short);
vbo_used -= sizeof(float) * patch.dstart;
}

View File

@ -2,41 +2,55 @@
#define NXS_PSERVER_H
#include <vector>
#include <list>
#include <map>
#include <iostream>
#include "patch.h"
#include "mfile.h"
namespace nxs {
class PServer: public MFile {
public:
/* HEader fo pserver
1Kb riservato per dati globali:
Magic: 'n' 'x' 's' 0x00
Signature: unsigned int (maschera di bit)
Chunk size: unsigned int
Index offset: unsigned int (offset to the index begin,
must be a multiple of chunk size)
Index size: unsigned int (in number of entryies)
History mode: unsigned int 0 means erased and created
1 means ready for drawing
History offset: unsigned int: multiple of chunk_size
History size: unsigned int (in chars)
Tot vert: unsigned int
Tot face: unsigned int
Bound sphere: Sphere3f (4 float: Point3f center (x, y, z), (radius))*/
struct Entry {
unsigned int patch_start; //granularita' Chunk
unsigned short ram_size; //in chunks
unsigned short disk_size; // in chunks (used when compressed)
Patch *patch;
};
/* struct Data {
// unsigned int npatch;
unsigned short nvert;
unsigned short nface;
vcg::Sphere3f sphere;
float error;
Patch *patch;
unsigned int vbo_array;
unsigned int vbo_element;
Data(): patch(NULL), vbo_array(0), vbo_element(0) {}
};*/
struct Item { //used by lru and pqueue.
unsigned int patch;
float priority;
Item(unsigned int p, float f): patch(p), priority(f) {}
bool operator<(const Item &i) const {
return priority < i.priority;
}
};
class PServer: public IndexFile<Entry,
public:
std::list<unsigned int> pqueue;
std::map<unsigned int, std::list<unsigned int>::iterator> index;
Signature signature;
unsigned int chunk_size;
@ -44,39 +58,39 @@ class PServer: public MFile {
unsigned int ram_max;
unsigned int ram_used;
std::vector<Entry> entries;
PServer(): chunk_size(1024),
ram_max(128000000),
ram_used(0) {}
virtual ~PServer() {
MFile::Close();
}
~PServer() { PServer::Close(); }
bool Create(const std::string &filename, Signature signature,
unsigned int chunk_size, unsigned int ram_max = 128000000);
bool Load(const std::string &filename, Signature sig,
unsigned int chunk_size, bool readonly,
unsigned int ram_max = 128000000);
unsigned int chunk_size = 1024);
bool Load(const std::string &filename, Signature signature,
bool readonly = true, unsigned int chunk_size = 1024);
void Close();
bool ReadEntries(FILE *fp);
bool WriteEntries(FILE *fp);
virtual void Close();
void AddPatch(unsigned short nvert, unsigned short nface);
Patch *LoadPatch(unsigned int id, unsigned short nv, unsigned short nf);
void FlushPatch(unsigned int id, Patch *patch);
Patch *LoadPatch(unsigned int id);
void FlushPatch(unsigned int id);
void Flush();
virtual bool IsLoaded(unsigned int patch) = 0;
// virtual Patch &Lookup(unsigned int patch,
// unsigned short nv, unsigned short nf) = 0;
virtual void Flush() = 0;
bool IsLoaded(unsigned int patch);
Entry &Lookup(unsigned int patch, std::vector<unsigned int> &flushed);
void LoadVbo(unsigned int patch);
void FlushVbo(unsigned int patch);
bool IsCompressed() { return (signature & NXS_COMPRESSED) != 0; }
bool HasStrips() { return (signature & NXS_STRIP) != 0; }
bool HasColors() { return (signature & NXS_COLORS) != 0; }
bool HasNormalsShort() { return (signature & NXS_NORMALS_SHORT) != 0; }
bool HasNormalsFloat() { return (signature & NXS_NORMALS_FLOAT) != 0; }
void MaxRamBuffer(unsigned int ram_buffer);
//void GetVbo(unsigned int patch, unsigned int &elem, unsigned int &array);
//bool FlushVbo(unsigned int patch, Data &data);
//void MaxVboBuffer(unsigned int ram_buffer);
};

View File

@ -245,9 +245,9 @@ void nxs::BuildLevel(VChain &chain,
unsigned int totface = 0;
unsigned int totvert = 0;
for(unsigned int idx = offset; idx < nexus.index.size(); idx++) {
totface += nexus.index[idx].nface;
totvert += nexus.index[idx].nvert;
for(unsigned int idx = offset; idx < nexus.size(); idx++) {
totface += nexus[idx].nface;
totvert += nexus[idx].nvert;
}
VPartition *fine = chain[chain.size()-1];
@ -260,9 +260,9 @@ void nxs::BuildLevel(VChain &chain,
unsigned int ncells = (unsigned int)(scaling * totface/target_size);
//TODO this method for selecting the seeds is ugly!
float ratio = ncells/(float)(nexus.index.size() - offset);
float ratio = ncells/(float)(nexus.size() - offset);
float cratio = 0;
for(unsigned int idx = offset; idx < nexus.index.size(); idx++) {
for(unsigned int idx = offset; idx < nexus.size(); idx++) {
cratio += ratio;
if(cratio > 1) {
Patch patch = nexus.GetPatch(idx);
@ -296,8 +296,8 @@ void nxs::BuildLevel(VChain &chain,
centroids.resize(coarse->size(), Point3f(0, 0, 0));
counts.resize(coarse->size(), 0);
Report report(nexus.index.size());
for(unsigned int idx = offset; idx < nexus.index.size(); idx++) {
Report report(nexus.size());
for(unsigned int idx = offset; idx < nexus.size(); idx++) {
report.Step(idx);
Patch patch = nexus.GetPatch(idx);
for(unsigned int i = 0; i < patch.nf; i++) {

View File

@ -24,6 +24,9 @@
History
$Log: not supported by cvs2svn $
Revision 1.19 2004/12/03 01:20:56 ponchio
Debug
Revision 1.18 2004/12/01 03:24:32 ponchio
Level 2.
@ -168,7 +171,7 @@ template <class T> class VFile: public MFile {
queue_size = _queue_size;
if(!MFile::Load(filename, rdonly)) return false;
n_elements = size/sizeof(T);
n_elements = _size/sizeof(T);
return true;
}

View File

@ -24,6 +24,9 @@
History
$Log: not supported by cvs2svn $
Revision 1.6 2004/12/15 13:50:32 ponchio
Optimizing realtime vis.
Revision 1.5 2004/12/01 16:00:35 ponchio
Level 3
@ -54,6 +57,9 @@ First draft created.
****************************************************************************/
#ifndef VCG_WATCH_H
#define VCG_WATCH_H
#ifdef WIN32
#ifndef _WINDOWS_
#define _WINSOCKAPI_
@ -98,3 +104,5 @@ class Report {
double last;
double interval;
};
#endif