Revolution.
This commit is contained in:
parent
0fde2046fc
commit
975ec6ae04
|
@ -4,61 +4,131 @@
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace nxs;
|
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) {
|
void BorderServer::AddBorder(unsigned short nbord, unsigned int used) {
|
||||||
BorderEntry entry;
|
BorderEntry entry;
|
||||||
entry.border_start = Size();
|
assert((Length() % sizeof(Link)) == 0);
|
||||||
entry.border_size = nbord;
|
|
||||||
entry.border_used = used;
|
entry.start = Length()/ sizeof(Link);
|
||||||
borders.push_back(entry);
|
entry.size = nbord;
|
||||||
Resize(entry.border_start + 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) {
|
Border BorderServer::GetBorder(unsigned int border, bool flush) {
|
||||||
assert(border < borders.size());
|
BorderEntry &entry = operator[](border);
|
||||||
BorderEntry &entry = borders[border];
|
if(index.count(border)) {
|
||||||
Link *start = GetRegion(entry.border_start, entry.border_size, flush);
|
assert(entry.links);
|
||||||
return Border(start, entry.border_used, entry.border_size);
|
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) {
|
bool BorderServer::ResizeBorder(unsigned int border, unsigned int nbord) {
|
||||||
assert(nbord < 65500);
|
assert(nbord < 65500);
|
||||||
assert(border < borders.size());
|
assert(border < size());
|
||||||
BorderEntry &entry = borders[border];
|
BorderEntry &entry = operator[](border);
|
||||||
if(nbord > entry.border_size) {
|
if(nbord > entry.size) {
|
||||||
int capacity = nbord;
|
int capacity = nbord;
|
||||||
if(capacity < entry.border_size*2)
|
if(capacity < entry.size*2)
|
||||||
capacity = entry.border_size * 2;
|
capacity = entry.size * 2;
|
||||||
if(capacity > 65500)
|
if(capacity > 65500)
|
||||||
capacity = 65500;
|
capacity = 65500;
|
||||||
unsigned int newstart = Size();
|
unsigned int newstart = Length()/sizeof(Link);
|
||||||
Resize(newstart + capacity);
|
Redim((newstart + capacity) * sizeof(Link));
|
||||||
if(entry.border_used > 0) {
|
if(entry.used > 0) {
|
||||||
Link *src = GetRegion(entry.border_start, entry.border_size);
|
Link *src = GetRegion(entry.start, entry.size);
|
||||||
Link *dst = GetRegion(newstart, capacity, false);
|
Link *dst = GetRegion(newstart, capacity);
|
||||||
memcpy(dst, src, entry.border_used * sizeof(Link));
|
memcpy(dst, src, entry.used * sizeof(Link));
|
||||||
}
|
}
|
||||||
entry.border_start = newstart;
|
entry.start = newstart;
|
||||||
entry.border_size = capacity;
|
entry.size = capacity;
|
||||||
entry.border_used = nbord;
|
entry.used = nbord;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
entry.border_used = nbord;
|
entry.used = nbord;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BorderServer::ReadEntries(FILE *fp) {
|
void BorderServer::FlushBorder(unsigned int border) {
|
||||||
unsigned int n;
|
BorderEntry &entry = operator[](border);
|
||||||
fread(&n, 1, sizeof(int), fp);
|
assert(entry.links);
|
||||||
borders.resize(n);
|
if(!MFile::IsReadOnly()) { //write back patch
|
||||||
fread(&*borders.begin(), n, sizeof(BorderEntry), fp);
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BorderServer::WriteEntries(FILE *fp) {
|
void BorderServer::SaveHeader() {
|
||||||
unsigned int n = borders.size();
|
unsigned int magic = 0x3042584e; // NXB0
|
||||||
fwrite(&n, 1, sizeof(int), fp);
|
WriteBuffer(&magic, sizeof(unsigned int));
|
||||||
fwrite(&*borders.begin(), n, sizeof(BorderEntry), fp);
|
WriteBuffer(&offset, sizeof(int64));
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,40 +1,58 @@
|
||||||
#ifndef NXS_BORDERSERVER_H
|
#ifndef NXS_BORDERSERVER_H
|
||||||
#define NXS_BORDERSERVER_H
|
#define NXS_BORDERSERVER_H
|
||||||
|
|
||||||
#include "vfile.h"
|
#include <list>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
#include "index_file.h"
|
||||||
#include "border.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 {
|
namespace nxs {
|
||||||
|
|
||||||
struct BorderEntry {
|
struct BorderEntry {
|
||||||
unsigned int border_start; //granuralita' Link
|
unsigned int start; //granuralita' Link
|
||||||
unsigned short border_size; //in Links
|
unsigned short size; //in Links
|
||||||
unsigned short border_used; //in Links
|
unsigned short used; //in Links
|
||||||
|
Link *links;
|
||||||
};
|
};
|
||||||
|
|
||||||
class BorderServer: public VFile<Link> {
|
class BorderServer: public IndexFile<BorderEntry> {
|
||||||
public:
|
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);
|
void AddBorder(unsigned short nbord, unsigned int used = 0);
|
||||||
Border GetBorder(unsigned int border, bool flush = true);
|
Border GetBorder(unsigned int border, bool flush = true);
|
||||||
//return true if you need to reread border as it changed location
|
//return true if you need to reread border as it changed location
|
||||||
bool ResizeBorder(unsigned int border, unsigned int nbord);
|
bool ResizeBorder(unsigned int border, unsigned int nbord);
|
||||||
|
|
||||||
bool ReadEntries(FILE *fp);
|
|
||||||
bool WriteEntries(FILE *fp);
|
|
||||||
|
|
||||||
unsigned int BorderSize(unsigned int i) {
|
unsigned int BorderSize(unsigned int i) {
|
||||||
return borders[i].border_used;
|
return operator[](i).used;
|
||||||
}
|
}
|
||||||
unsigned int BorderCapacity(unsigned int i) {
|
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.
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,7 @@ class LruPServer: public PServer {
|
||||||
Flush();
|
Flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
Patch &Lookup(unsigned int patch, unsigned short nv, unsigned short nf) {
|
Patch &Lookup(unsigned int patch) {
|
||||||
if(index.count(patch)) {
|
if(index.count(patch)) {
|
||||||
Items::iterator &i = index[patch];
|
Items::iterator &i = index[patch];
|
||||||
Item item = *i;
|
Item item = *i;
|
||||||
|
@ -32,12 +32,12 @@ class LruPServer: public PServer {
|
||||||
while(ram_used > ram_max) {
|
while(ram_used > ram_max) {
|
||||||
Item item = items.back();
|
Item item = items.back();
|
||||||
index.erase(item.first);
|
index.erase(item.first);
|
||||||
FlushPatch(item.first, item.second);
|
FlushPatch(item.first);
|
||||||
items.pop_back();
|
items.pop_back();
|
||||||
}
|
}
|
||||||
Item item;
|
Item item;
|
||||||
item.first = patch;
|
item.first = patch;
|
||||||
item.second = LoadPatch(patch, nv, nf);
|
item.second = LoadPatch(patch);
|
||||||
items.push_front(item);
|
items.push_front(item);
|
||||||
Items::iterator i = items.begin();
|
Items::iterator i = items.begin();
|
||||||
index[patch] = i;
|
index[patch] = i;
|
||||||
|
@ -52,10 +52,10 @@ class LruPServer: public PServer {
|
||||||
std::map<unsigned int, Items::iterator>::iterator i;
|
std::map<unsigned int, Items::iterator>::iterator i;
|
||||||
for(i = index.begin(); i != index.end(); i++) {
|
for(i = index.begin(); i != index.end(); i++) {
|
||||||
Item &item = *((*i).second);
|
Item &item = *((*i).second);
|
||||||
FlushPatch((*i).first, item.second);
|
FlushPatch((*i).first);
|
||||||
}
|
}
|
||||||
for(int k = 0; k < entries.size(); k++)
|
for(int k = 0; k < size(); k++)
|
||||||
entries[k].patch = NULL;
|
operator[](k).patch = NULL;
|
||||||
|
|
||||||
items.clear();
|
items.clear();
|
||||||
index.clear();
|
index.clear();
|
||||||
|
|
|
@ -8,7 +8,7 @@ using namespace nxs;
|
||||||
bool MFile::Create(const string &fname, unsigned int mxs) {
|
bool MFile::Create(const string &fname, unsigned int mxs) {
|
||||||
Close();
|
Close();
|
||||||
filename = fname;
|
filename = fname;
|
||||||
size = 0;
|
_size = 0;
|
||||||
readonly = false;
|
readonly = false;
|
||||||
assert(mxs <= MFILE_MAX_SIZE);
|
assert(mxs <= MFILE_MAX_SIZE);
|
||||||
max_size = mxs;
|
max_size = mxs;
|
||||||
|
@ -20,7 +20,7 @@ bool MFile::Load(const string &fname, bool ronly) {
|
||||||
filename = fname;
|
filename = fname;
|
||||||
readonly = ronly;
|
readonly = ronly;
|
||||||
max_size = MFILE_MAX_SIZE;
|
max_size = MFILE_MAX_SIZE;
|
||||||
size = 0;
|
_size = 0;
|
||||||
|
|
||||||
while(1) {
|
while(1) {
|
||||||
string name = Name(files.size());
|
string name = Name(files.size());
|
||||||
|
@ -30,11 +30,11 @@ bool MFile::Load(const string &fname, bool ronly) {
|
||||||
files.pop_back();
|
files.pop_back();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
size += file->Length();
|
_size += file->Length();
|
||||||
}
|
}
|
||||||
if(files.size() == 0) return false;
|
if(files.size() == 0) return false;
|
||||||
if(files.size() == 1) {
|
if(files.size() == 1) {
|
||||||
assert(size <= max_size);
|
assert(_size <= max_size);
|
||||||
} else {
|
} else {
|
||||||
//SANITY TEST
|
//SANITY TEST
|
||||||
for(unsigned int i = 0; i < files.size() -2; i++) {
|
for(unsigned int i = 0; i < files.size() -2; i++) {
|
||||||
|
@ -61,28 +61,29 @@ void MFile::Delete() {
|
||||||
|
|
||||||
void MFile::Redim(int64 sz) {
|
void MFile::Redim(int64 sz) {
|
||||||
assert(!readonly);
|
assert(!readonly);
|
||||||
if(sz > size) {
|
if(sz > _size) {
|
||||||
unsigned int totfile = (unsigned int)(sz/max_size);
|
unsigned int totfile = (unsigned int)(sz/max_size);
|
||||||
//TODO test rhis!!!!
|
//TODO test rhis!!!!
|
||||||
while(files.size() <= totfile) {
|
while(files.size() <= totfile) {
|
||||||
RedimLast(max_size);
|
RedimLast(max_size);
|
||||||
assert(size == (int64)max_size * (int64)(files.size()));
|
assert(_size == (int64)max_size * (int64)(files.size()));
|
||||||
AddFile();
|
AddFile();
|
||||||
}
|
}
|
||||||
assert(size <= sz);
|
assert(_size <= sz);
|
||||||
assert(sz - size < max_size);
|
assert(sz - _size < max_size);
|
||||||
assert(files.back()->Length() + (unsigned int)(sz - size) < max_size);
|
assert(files.back()->Length() + (unsigned int)(sz - _size) < max_size);
|
||||||
RedimLast(files.back()->Length() + (unsigned int)(sz - size));
|
RedimLast(files.back()->Length() + (unsigned int)(sz - _size));
|
||||||
} else {
|
} else {
|
||||||
while(size - files.back()->Length() > sz)
|
while(_size - files.back()->Length() > sz)
|
||||||
RemoveFile();
|
RemoveFile();
|
||||||
assert(sz <= size);
|
assert(sz <= _size);
|
||||||
RedimLast(files.back()->Length() - (unsigned int)(size - sz));
|
RedimLast(files.back()->Length() - (unsigned int)(_size - sz));
|
||||||
}
|
}
|
||||||
|
assert(sz == _size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MFile::SetPosition(int64 pos) {
|
void MFile::SetPosition(int64 pos) {
|
||||||
assert(pos < size);
|
assert(pos <= _size);
|
||||||
curr_fp = (unsigned int)(pos/(int64)max_size);
|
curr_fp = (unsigned int)(pos/(int64)max_size);
|
||||||
curr_pos = (unsigned int)(pos - (int64)max_size * (int64)curr_fp);
|
curr_pos = (unsigned int)(pos - (int64)max_size * (int64)curr_fp);
|
||||||
assert(curr_pos < max_size);
|
assert(curr_pos < max_size);
|
||||||
|
@ -134,7 +135,7 @@ void MFile::WriteBuffer(void *data, unsigned int sz) {
|
||||||
unsigned int last_size = file->Length();
|
unsigned int last_size = file->Length();
|
||||||
delete file;
|
delete file;
|
||||||
files.pop_back();
|
files.pop_back();
|
||||||
size -= last_size;
|
_size -= last_size;
|
||||||
cerr << "Removing file: " << name << endl;
|
cerr << "Removing file: " << name << endl;
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
DeleteFile(name.c_str());
|
DeleteFile(name.c_str());
|
||||||
|
@ -148,7 +149,7 @@ void MFile::RedimLast(unsigned int sz) {
|
||||||
File &file = *files.back();
|
File &file = *files.back();
|
||||||
unsigned int last_size = (int64)file.Length();
|
unsigned int last_size = (int64)file.Length();
|
||||||
file.Redim(sz);
|
file.Redim(sz);
|
||||||
size += sz - (int64)last_size;
|
_size += sz - (int64)last_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string MFile::Name(unsigned int n) {
|
std::string MFile::Name(unsigned int n) {
|
||||||
|
|
|
@ -30,13 +30,14 @@ class MFile {
|
||||||
void Close();
|
void Close();
|
||||||
void Delete();
|
void Delete();
|
||||||
|
|
||||||
int64 Length() { return size; }
|
int64 Length() { return _size; }
|
||||||
void Redim(int64 size);
|
void Redim(int64 size);
|
||||||
|
|
||||||
void SetPosition(int64 pos);
|
void SetPosition(int64 pos);
|
||||||
void ReadBuffer(void *data, unsigned int size);
|
void ReadBuffer(void *data, unsigned int size);
|
||||||
void WriteBuffer(void *data, unsigned int size);
|
void WriteBuffer(void *data, unsigned int size);
|
||||||
|
|
||||||
|
bool Opened() { return files.size() > 0; }
|
||||||
bool IsReadOnly() { return readonly; }
|
bool IsReadOnly() { return readonly; }
|
||||||
void SetReadOnly(bool rd) { readonly = rd; } //USE WITH CARE!!!!
|
void SetReadOnly(bool rd) { readonly = rd; } //USE WITH CARE!!!!
|
||||||
protected:
|
protected:
|
||||||
|
@ -44,7 +45,7 @@ class MFile {
|
||||||
std::vector<File *> files;
|
std::vector<File *> files;
|
||||||
unsigned int curr_pos;
|
unsigned int curr_pos;
|
||||||
unsigned int curr_fp;
|
unsigned int curr_fp;
|
||||||
int64 size;
|
int64 _size;
|
||||||
unsigned int max_size;
|
unsigned int max_size;
|
||||||
bool readonly;
|
bool readonly;
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -4,8 +4,6 @@
|
||||||
#include <set>
|
#include <set>
|
||||||
|
|
||||||
#include "nexus.h"
|
#include "nexus.h"
|
||||||
#include "lrupserver.h"
|
|
||||||
#include "queuepserver.h"
|
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace vcg;
|
using namespace vcg;
|
||||||
|
@ -16,155 +14,157 @@ Nexus::~Nexus() {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Nexus::Create(const string &file, Signature sig, unsigned int c_size) {
|
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;
|
signature = sig;
|
||||||
totvert = 0;
|
totvert = 0;
|
||||||
totface = 0;
|
totface = 0;
|
||||||
sphere = Sphere3f();
|
sphere = Sphere3f();
|
||||||
|
|
||||||
index.clear();
|
|
||||||
|
|
||||||
chunk_size = c_size;
|
chunk_size = c_size;
|
||||||
|
unsigned int header_size = 256;
|
||||||
|
if(chunk_size > header_size) header_size = chunk_size;
|
||||||
|
|
||||||
|
history.Clear();
|
||||||
|
ram_used = 0;
|
||||||
|
ram_max = 50 * (1<<20) / chunk_size;
|
||||||
|
|
||||||
history.clear();
|
if(!IndexFile<Entry>::Create(file + ".nxp", header_size)) {
|
||||||
|
|
||||||
if(!patches.Create(file + ".nxp", signature, chunk_size)) {
|
|
||||||
cerr << "Could not create file: " << file << ".nxp" << endl;
|
cerr << "Could not create file: " << file << ".nxp" << endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Important: chunk_size must be 1 so that i can use Region in VFile.
|
//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;
|
cerr << "Could not create file: " << file << ".nxb" << endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
history.clear();
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Nexus::Load(const string &file, bool rdonly) {
|
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+");
|
history.Clear();
|
||||||
if(!index_file) return false;
|
SetPosition(history_offset);
|
||||||
|
unsigned int history_size;
|
||||||
unsigned int readed;
|
ReadBuffer(&history_size, sizeof(unsigned int));
|
||||||
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;
|
|
||||||
|
|
||||||
unsigned int size; //size of index
|
char *buffer = new char[history_size];
|
||||||
readed = fread(&size, sizeof(unsigned int), 1, index_file);
|
ReadBuffer(buffer, history_size);
|
||||||
if(!readed) return false;
|
|
||||||
|
|
||||||
index.resize(size);
|
if(!history.Load(history_size, buffer)) {
|
||||||
readed = fread(&index[0], sizeof(PatchInfo), size, index_file);
|
cerr << "Error loading history\n";
|
||||||
if(readed != size) return false;
|
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(readonly) {
|
|
||||||
fclose(index_file);
|
|
||||||
index_file = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO support readonly
|
borders.Load(file + ".nxb", rdonly);
|
||||||
if(!patches.Load(file + ".nxp", signature, chunk_size, readonly))
|
//TODO on nxsbuilder assure borders are loaded
|
||||||
return false;
|
|
||||||
if(!borders.Load(file + ".nxb", readonly, 1, 500))
|
|
||||||
return false;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Nexus::Close() {
|
void Nexus::Close() {
|
||||||
patches.Close();
|
if(!Opened()) return;
|
||||||
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...
|
Flush();
|
||||||
//BUT it will break compatibility with existing models.
|
|
||||||
patches.WriteEntries(index_file);
|
if(!IsReadOnly()) {
|
||||||
borders.WriteEntries(index_file);
|
//set history_offset
|
||||||
|
if(!size()) history_offset = 0;
|
||||||
vector<unsigned int> buffer;
|
else
|
||||||
buffer.push_back(history.size());
|
history_offset = (back().patch_start + back().disk_size);
|
||||||
for(unsigned int i = 0; i < history.size(); i++) {
|
history_offset *= chunk_size;
|
||||||
Update &update = history[i];
|
|
||||||
buffer.push_back(update.erased.size());
|
unsigned int history_size;
|
||||||
buffer.push_back(update.created.size());
|
char *mem = history.Save(history_size);
|
||||||
for(unsigned int e = 0; e < update.erased.size(); e++)
|
Redim(history_offset + history_size + sizeof(unsigned int));
|
||||||
buffer.push_back(update.erased[e]);
|
SetPosition(history_offset);
|
||||||
for(unsigned int e = 0; e < update.created.size(); e++)
|
WriteBuffer(&history_size, sizeof(unsigned int));
|
||||||
buffer.push_back(update.created[e]);
|
WriteBuffer(mem, history_size);
|
||||||
|
delete []mem;
|
||||||
}
|
}
|
||||||
|
borders.Close();
|
||||||
size = buffer.size();
|
IndexFile<Entry>::Close();
|
||||||
fwrite(&size, sizeof(unsigned int), 1, index_file);
|
|
||||||
fwrite(&(buffer[0]), sizeof(unsigned int), size, index_file);
|
|
||||||
|
|
||||||
fclose(index_file);
|
|
||||||
index_file = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Patch &Nexus::GetPatch(unsigned int patch, bool flush) {
|
void Nexus::SaveHeader() {
|
||||||
assert(patch < index.size());
|
unsigned int magic = 0x3053584e; // nxs0
|
||||||
PatchInfo &info = index[patch];
|
WriteBuffer(&magic, sizeof(unsigned int));
|
||||||
return patches.Lookup(patch, info.nvert, info.nface);
|
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) {
|
||||||
|
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) {
|
Border Nexus::GetBorder(unsigned int patch, bool flush) {
|
||||||
PatchInfo &info = index[patch];
|
|
||||||
return borders.GetBorder(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);
|
Border border = GetBorder(patch);
|
||||||
|
|
||||||
unsigned int pos = border.Size();
|
unsigned int pos = border.Size();
|
||||||
|
@ -179,27 +179,30 @@ void Nexus::AddBorder(unsigned int patch, Link &link) {
|
||||||
assert(border.Available() > pos);
|
assert(border.Available() > pos);
|
||||||
|
|
||||||
border[pos] = link;
|
border[pos] = link;
|
||||||
}
|
}*/
|
||||||
|
|
||||||
unsigned int Nexus::AddPatch(unsigned int nvert, unsigned int nface,
|
unsigned int Nexus::AddPatch(unsigned int nvert, unsigned int nface,
|
||||||
unsigned int nbord) {
|
unsigned int nbord) {
|
||||||
|
|
||||||
PatchInfo info;
|
Entry entry;
|
||||||
info.nvert = nvert;
|
entry.patch_start = 0xffffffff;
|
||||||
info.nface = nface;
|
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);
|
borders.AddBorder(nbord);
|
||||||
|
|
||||||
index.push_back(info);
|
|
||||||
totvert += nvert;
|
totvert += nvert;
|
||||||
totface += nface;
|
totface += nface;
|
||||||
return index.size() -1;
|
return size() - 1;
|
||||||
}
|
|
||||||
|
|
||||||
void Nexus::MaxRamBuffer(unsigned int r_size) {
|
|
||||||
patches.MaxRamBuffer(r_size);
|
|
||||||
//TODO do the same with borders
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Nexus::Unify(float threshold) {
|
void Nexus::Unify(float threshold) {
|
||||||
|
@ -207,9 +210,9 @@ void Nexus::Unify(float threshold) {
|
||||||
unsigned int duplicated = 0;
|
unsigned int duplicated = 0;
|
||||||
unsigned int degenerate = 0;
|
unsigned int degenerate = 0;
|
||||||
|
|
||||||
for(unsigned int p = 0; p < index.size(); p++) {
|
for(unsigned int p = 0; p < size(); p++) {
|
||||||
PatchInfo &entry = index[p];
|
Entry &entry = operator[](p);
|
||||||
Patch patch = GetPatch(p);
|
Patch &patch = GetPatch(p);
|
||||||
|
|
||||||
unsigned int vcount = 0;
|
unsigned int vcount = 0;
|
||||||
map<Point3f, unsigned short> vertices;
|
map<Point3f, unsigned short> vertices;
|
||||||
|
@ -294,7 +297,7 @@ void Nexus::Unify(float threshold) {
|
||||||
}
|
}
|
||||||
//better to compact directly borders than setting them null.
|
//better to compact directly borders than setting them null.
|
||||||
//finally: there may be duplicated borders
|
//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);
|
Border border = GetBorder(p);
|
||||||
set<Link> links;
|
set<Link> links;
|
||||||
for(unsigned int b = 0; b < border.Size(); b++) {
|
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++)
|
for(set<Link>::iterator k = links.begin(); k != links.end(); k++)
|
||||||
border[count++] = *k;
|
border[count++] = *k;
|
||||||
|
|
||||||
borders.borders[p].border_used = links.size();
|
borders[p].used = links.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
totvert -= duplicated;
|
totvert -= duplicated;
|
||||||
|
@ -316,3 +319,77 @@ void Nexus::Unify(float threshold) {
|
||||||
if(degenerate)
|
if(degenerate)
|
||||||
cerr << "Found " << degenerate << " degenerate face while unmifying\n";
|
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;
|
||||||
|
}
|
||||||
|
|
|
@ -3,15 +3,65 @@
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <list>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
#include "nexusbase.h"
|
#include <vcg/space/sphere3.h>
|
||||||
#include "lrupserver.h"
|
|
||||||
|
#include "patch.h"
|
||||||
|
#include "index_file.h"
|
||||||
|
#include "history.h"
|
||||||
#include "borderserver.h"
|
#include "borderserver.h"
|
||||||
|
|
||||||
namespace nxs {
|
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:
|
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() {}
|
||||||
~Nexus();
|
~Nexus();
|
||||||
|
@ -20,12 +70,17 @@ class Nexus: public NexusBase {
|
||||||
unsigned int chunk_size = 1024);
|
unsigned int chunk_size = 1024);
|
||||||
bool Load(const std::string &filename, bool readonly = false);
|
bool Load(const std::string &filename, bool readonly = false);
|
||||||
void Close();
|
void Close();
|
||||||
|
void Flush(bool all = true);
|
||||||
|
|
||||||
unsigned int AddPatch(unsigned int nv, unsigned int nf, unsigned int nb);
|
unsigned int AddPatch(unsigned int nv, unsigned int nf, unsigned int nb);
|
||||||
Patch &GetPatch(unsigned int patch, bool flush = true);
|
Patch &GetPatch(unsigned int patch, bool flush = true);
|
||||||
Border GetBorder(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 IsCompressed() { return (signature & NXS_COMPRESSED) != 0; }
|
||||||
bool HasStrips() { return (signature & NXS_STRIP) != 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 HasNormalsShort() { return (signature & NXS_NORMALS_SHORT) != 0; }
|
||||||
bool HasNormalsFloat() { return (signature & NXS_NORMALS_FLOAT) != 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!
|
std::list<unsigned int> pqueue;
|
||||||
void Unify(float threshold = 0.0f);
|
std::map<unsigned int, std::list<unsigned int>::iterator> index;
|
||||||
|
|
||||||
|
Patch *LoadPatch(unsigned int id);
|
||||||
|
virtual void FlushPatch(unsigned int id);
|
||||||
|
|
||||||
/* Nexus data */
|
bool LoadHeader();
|
||||||
|
void SaveHeader();
|
||||||
//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;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,6 +39,10 @@
|
||||||
|
|
||||||
|
|
||||||
<a name="picture"><h1>Big picture</h1></a>
|
<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="struct"><h1>Structures and interfaces</h1></a>
|
||||||
|
|
||||||
<a name="vfile"><h2>VFile</h2></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>
|
ma usare un file per storare i dati (un mmapping, ma non limitato a 4Gb).<br>
|
||||||
|
|
||||||
<a name="crude"><h2>Crude</h2></a>
|
<a name="crude"><h2>Crude</h2></a>
|
||||||
|
<pre>
|
||||||
Crude e' un formato tipo il ply... solo che usa dei VFile per
|
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>
|
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,
|
Per cui e' composto di 3 files:
|
||||||
vertici e Bounding box), file dei vertici, file delle facce ed
|
Header (<b>.crd</b>)
|
||||||
opzionalmente file degli attributi dei vertici e delle facce.<br>
|
Magic: 'c' 'r' 'd' 0x00 (4 bytes)
|
||||||
Come interfaccia e' sufficente che dia accesso casuale a facce e vertici...
|
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>
|
<a name="pchain"><h2>PChain</h2></a>
|
||||||
Sta per 'partition chain' cioe' una catena di partizioni dello
|
Sta per 'partition chain' cioe' una catena di partizioni dello
|
||||||
spazio.<br>
|
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>
|
ne restituisce la distanza (o un valore 'equivalente').<br>
|
||||||
Si deve poter salvare su disco e recuperare una pchain<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>
|
<a name="nexus"><h2>Nexus</h2></a>
|
||||||
E' una struttura con 3 files: 'index', 'patches' e 'borders'.<br>
|
<pre>
|
||||||
'Index' contiene l'indice delle patches: per ogni patch viene storato
|
E' una struttura con 2 files:
|
||||||
offset, size (ma questa potrebbe essere storata direttamente nei
|
|
||||||
files?) dei dati geometrici nel file delle patches e dei bordi nel
|
File delle patches: (<b>.nxs</b>)
|
||||||
file dei borders, oltre alla bounding sphere.<br>
|
1Kb riservato per dati globali:
|
||||||
'Patches' e' un VFile di chunks da 4k dove i dati geometrici di una
|
Magic: 'n' 'x' 's' 0x00
|
||||||
patch occupano un numero intero di chunks. P.S. Come ce la caviamo con
|
Signature: unsigned int (maschera di bit)
|
||||||
gli attributi dei vertici e delle facce?<br>
|
Chunk size: unsigned int
|
||||||
'Borders' e' un VFile di 'links' dove ogni link fa riferimento ad un
|
Index offset: int64 (offset to the index begin,
|
||||||
vertice di bordo tra la patch A (V_a) e la B (V_b) e contiene
|
must be a multiple of chunk size)
|
||||||
(V_a, V_b, B) (A e' implicito). L'informazione e' replicata nei bordi
|
History offset: int64: multiple of chunk_size
|
||||||
relativi a B con (V_b, V_a, A)<br>
|
|
||||||
|
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>
|
<a name="bmt"><h2>Bmt</h2></a>
|
||||||
Bmt (batched multi triangulation) e' il formato per la
|
Bmt (batched multi triangulation) e' il formato per la
|
||||||
|
|
|
@ -8,13 +8,13 @@
|
||||||
|
|
||||||
namespace nxs {
|
namespace nxs {
|
||||||
|
|
||||||
struct PatchInfo {
|
/*struct PatchInfo {
|
||||||
unsigned short nvert;
|
unsigned short nvert;
|
||||||
unsigned short nface;
|
unsigned short nface;
|
||||||
|
|
||||||
vcg::Sphere3f sphere;
|
vcg::Sphere3f sphere;
|
||||||
float error;
|
float error;
|
||||||
};
|
};*/
|
||||||
|
|
||||||
|
|
||||||
class NexusBase {
|
class NexusBase {
|
||||||
|
@ -49,7 +49,7 @@ class NexusBase {
|
||||||
unsigned int totface;
|
unsigned int totface;
|
||||||
vcg::Sphere3f sphere;
|
vcg::Sphere3f sphere;
|
||||||
|
|
||||||
std::vector<PatchInfo> index;
|
// std::vector<PatchInfo> index;
|
||||||
std::vector<Update> history;
|
std::vector<Update> history;
|
||||||
|
|
||||||
bool readonly;
|
bool readonly;
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,179 +1,109 @@
|
||||||
#ifndef NXS_NEXUS_MT_H
|
#ifndef NXS_MT_H
|
||||||
#define NXS_NEXUS_MT_H
|
#define NXS_MT_H
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <queue>
|
#include <queue>
|
||||||
#include <wrap/gui/frustum.h>
|
#include <wrap/gui/frustum.h>
|
||||||
|
|
||||||
#include "nexusbase.h"
|
#include "nexus.h"
|
||||||
#include "queuepserver.h"
|
#include "history.h"
|
||||||
#include "borderserver.h"
|
#include "extraction.h"
|
||||||
#include "prefetch.h"
|
#include "metric.h"
|
||||||
|
#include "preload.h"
|
||||||
|
#include "watch.h"
|
||||||
|
|
||||||
namespace nxs {
|
namespace nxs {
|
||||||
|
|
||||||
typedef std::vector<unsigned int> Frag;
|
struct DrawContest {
|
||||||
|
|
||||||
struct Node {
|
|
||||||
std::vector<Node *> in;
|
|
||||||
std::vector<Node *> out;
|
|
||||||
std::vector<Frag> frags;
|
|
||||||
float error;
|
|
||||||
bool visited;
|
|
||||||
bool current;
|
|
||||||
// bool pushed;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct TNode {
|
enum Mode { POINTS, SMOOTH, XRAY, HIDDEN_LINE, FLAT_WIRE, FLAT, PATCHES };
|
||||||
float error;
|
enum Attr { COLOR = 0x1, NORMAL = 0x2, TEXTURE = 0x4, DATA = 0x8 };
|
||||||
Node *node;
|
|
||||||
TNode(Node *n, float e): node(n), error(e) {}
|
|
||||||
bool operator<(const TNode &n) { return error < n.error; }
|
|
||||||
};
|
|
||||||
|
|
||||||
class Metric {
|
Mode mode;
|
||||||
public:
|
unsigned int attrs;
|
||||||
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)
|
DrawContest(Mode m = SMOOTH, unsigned int a = 0xf): mode(m), attrs(a) {}
|
||||||
unsigned int extraction_used;
|
void SetAttr(Attr attr, bool value);
|
||||||
unsigned int draw_max; //only visible parts
|
bool HasComponent(Attr attr);
|
||||||
unsigned int draw_used;
|
};
|
||||||
unsigned int disk_max; //max not in ram loadable size
|
|
||||||
unsigned int disk_used;
|
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
Mode mode;
|
//double last_time;
|
||||||
|
unsigned int count;
|
||||||
|
|
||||||
unsigned int components;
|
Watch watch;
|
||||||
bool use_normals;
|
|
||||||
bool use_colors;
|
|
||||||
bool use_textures;
|
|
||||||
bool use_data;
|
|
||||||
|
|
||||||
//statistics:
|
Stats(): count(0) {}
|
||||||
unsigned int tri_rendered;
|
void Init();
|
||||||
unsigned int tri_total;
|
};
|
||||||
|
|
||||||
vector<QueuePServer::Data *> todraw;
|
|
||||||
std::vector<PServer::Item> visited;
|
|
||||||
std::vector<Node *> sequence;
|
|
||||||
|
|
||||||
QueuePServer patches;
|
|
||||||
BorderServer borders;
|
|
||||||
|
|
||||||
Prefetch prefetch;
|
|
||||||
|
|
||||||
NexusMt();
|
|
||||||
~NexusMt();
|
|
||||||
|
|
||||||
bool Load(const std::string &filename);
|
class NexusMt: public Nexus {
|
||||||
void Close();
|
public:
|
||||||
|
bool use_vbo;
|
||||||
|
bool prefetch;
|
||||||
|
|
||||||
bool InitGL(Vbo mode = VBO_AUTO, unsigned int vbo_size = 64000000);
|
unsigned int vbo_used; //TODO remember to zero it!
|
||||||
|
|
||||||
|
Preload preload;
|
||||||
|
|
||||||
|
NexusMt();
|
||||||
|
~NexusMt();
|
||||||
|
|
||||||
|
bool Load(const std::string &filename);
|
||||||
|
// void Close();
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
//Uinits expressed in Kb
|
||||||
|
void SetExtractionSize(unsigned int ksize);
|
||||||
|
void SetDrawSize(unsigned int ksize);
|
||||||
|
void SetDiskDelta(unsigned int kdelta);
|
||||||
|
//void SetPrefetchSize(unsigned int size);
|
||||||
|
};*/
|
||||||
|
|
||||||
void Render();
|
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
|
|
||||||
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);
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -24,6 +24,9 @@
|
||||||
History
|
History
|
||||||
|
|
||||||
$Log: not supported by cvs2svn $
|
$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
|
Revision 1.26 2004/12/15 13:50:32 ponchio
|
||||||
Optimizing realtime vis.
|
Optimizing realtime vis.
|
||||||
|
|
||||||
|
@ -205,7 +208,11 @@ int main(int argc, char *argv[]) {
|
||||||
cerr << "Could not load nexus file: " << argv[1] << endl;
|
cerr << "Could not load nexus file: " << argv[1] << endl;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
Sphere3f sphere = nexus.sphere;
|
Sphere3f sphere = nexus.sphere;
|
||||||
|
Extraction extraction;
|
||||||
|
DrawContest contest;
|
||||||
|
Stats stats;
|
||||||
|
|
||||||
if(!init(argv[1])) {
|
if(!init(argv[1])) {
|
||||||
cerr << "Could not init SDL window\n";
|
cerr << "Could not init SDL window\n";
|
||||||
|
@ -244,11 +251,11 @@ int main(int argc, char *argv[]) {
|
||||||
bool show_statistics = true;
|
bool show_statistics = true;
|
||||||
bool extract = true;
|
bool extract = true;
|
||||||
|
|
||||||
NexusMt::MetricKind metric;
|
// NexusMt::MetricKind metric;
|
||||||
NexusMt::Mode mode = NexusMt::SMOOTH;
|
//DrawContest::Mode mode = DrawContest::SMOOTH;
|
||||||
|
|
||||||
nexus.SetError(error);
|
//nexus.SetError(error);
|
||||||
nexus.SetMetric(NexusMt::FRUSTUM);
|
// nexus.SetMetric(NexusMt::FRUSTUM);
|
||||||
if(!nexus.InitGL()) {
|
if(!nexus.InitGL()) {
|
||||||
cerr << "Could not init glew.\n";
|
cerr << "Could not init glew.\n";
|
||||||
}
|
}
|
||||||
|
@ -274,50 +281,52 @@ int main(int argc, char *argv[]) {
|
||||||
|
|
||||||
watch.Start();
|
watch.Start();
|
||||||
while( !quit ) {
|
while( !quit ) {
|
||||||
unsigned int anything = SDL_PollEvent(&event);
|
unsigned int anything = SDL_PollEvent(&event);
|
||||||
if(!anything && !keepdrawing) {
|
if(!anything && !keepdrawing) {
|
||||||
SDL_WaitEvent(&event);
|
SDL_WaitEvent(&event);
|
||||||
anything = true;
|
anything = true;
|
||||||
}
|
}
|
||||||
if(anything) {
|
if(anything) {
|
||||||
switch( event.type ) {
|
switch( event.type ) {
|
||||||
case SDL_QUIT: quit = 1; break;
|
case SDL_QUIT: quit = 1; break;
|
||||||
case SDL_KEYDOWN:
|
case SDL_KEYDOWN:
|
||||||
switch(event.key.keysym.sym) {
|
switch(event.key.keysym.sym) {
|
||||||
case SDLK_RCTRL:
|
case SDLK_RCTRL:
|
||||||
case SDLK_LCTRL: track.ButtonDown(Trackball::KEY_CTRL); break;
|
case SDLK_LCTRL: track.ButtonDown(Trackball::KEY_CTRL); break;
|
||||||
case SDLK_q: exit(0); break;
|
case SDLK_q: exit(0); break;
|
||||||
case SDLK_k: keepdrawing = !keepdrawing; break;
|
case SDLK_k: keepdrawing = !keepdrawing; break;
|
||||||
case SDLK_e: extract = !extract; break;
|
case SDLK_e: extract = !extract; break;
|
||||||
case SDLK_c: show_colors = !show_colors; break;
|
case SDLK_c: show_colors = !show_colors; break;
|
||||||
case SDLK_n: show_normals = !show_normals; break;
|
case SDLK_n: show_normals = !show_normals; break;
|
||||||
|
|
||||||
case SDLK_LEFT: nexus.patches.ram_max *= 0.8; break;
|
case SDLK_LEFT: nexus.MaxRam() *= 0.8; break;
|
||||||
case SDLK_RIGHT: nexus.patches.ram_max *= 1.3; break;
|
case SDLK_RIGHT: nexus.MaxRam() *= 1.3; break;
|
||||||
case SDLK_UP: nexus.draw_max *= 1.3; break;
|
case SDLK_UP: extraction.draw_max *= 1.3; break;
|
||||||
case SDLK_DOWN: nexus.draw_max *= 0.8; break;
|
case SDLK_DOWN: extraction.draw_max *= 0.8; break;
|
||||||
case SDLK_PAGEUP: nexus.disk_max *= 1.3; break;
|
case SDLK_PAGEUP: extraction.disk_max *= 1.3; break;
|
||||||
case SDLK_PAGEDOWN: nexus.disk_max *= 0.8; 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_s: metric = NexusMt::FRUSTUM; break;
|
||||||
case SDLK_p: mode = NexusMt::POINTS; nexus.SetMode(mode); break;
|
case SDLK_p: contest.mode = DrawContest::POINTS; break;
|
||||||
case SDLK_d: mode = NexusMt::PATCHES; nexus.SetMode(mode); break;
|
case SDLK_d: contest.mode = DrawContest::PATCHES; break;
|
||||||
case SDLK_f: mode = NexusMt::FLAT; nexus.SetMode(mode); break;
|
case SDLK_f: contest.mode = DrawContest::FLAT; break;
|
||||||
case SDLK_m: mode = NexusMt::SMOOTH; nexus.SetMode(mode); break;
|
case SDLK_m: contest.mode = DrawContest::SMOOTH; break;
|
||||||
|
|
||||||
case SDLK_r:
|
case SDLK_r:
|
||||||
case SDLK_SPACE: rotate = !rotate; break;
|
case SDLK_SPACE: rotate = !rotate; break;
|
||||||
|
|
||||||
case SDLK_MINUS:
|
case SDLK_MINUS:
|
||||||
error *= 0.9f;
|
extraction.target_error *= 0.9f;
|
||||||
nexus.SetError(error);
|
cerr << "Error: " << extraction.target_error << endl;
|
||||||
cerr << "Error: " << error << endl; break;
|
break;
|
||||||
|
|
||||||
case SDLK_EQUALS:
|
case SDLK_EQUALS:
|
||||||
case SDLK_PLUS:
|
case SDLK_PLUS:
|
||||||
error *= 1.1f;
|
extraction.target_error *= 1.1f;
|
||||||
nexus.SetError(error);
|
cerr << "Error: " << extraction.target_error << endl;
|
||||||
cerr << "Error: " << error << endl; break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SDL_KEYUP:
|
case SDL_KEYUP:
|
||||||
|
@ -399,23 +408,12 @@ int main(int argc, char *argv[]) {
|
||||||
|
|
||||||
glColor3f(0.8f, 0.8f, 0.8f);
|
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) {
|
if(extract) {
|
||||||
// nexus.patches.Flush();
|
extraction.frustum.GetView();
|
||||||
|
extraction.metric->GetView();
|
||||||
nexus.metric->GetView();
|
extraction.Extract(&nexus);
|
||||||
// nexus.policy.Init();
|
}
|
||||||
nexus.tri_total = 0;
|
nexus.Render(extraction, contest, &stats);
|
||||||
nexus.tri_rendered = 0;
|
|
||||||
nexus.Extract(cells);
|
|
||||||
}
|
|
||||||
nexus.Draw(cells);
|
|
||||||
|
|
||||||
/* if(show_borders) {
|
/* if(show_borders) {
|
||||||
for(unsigned int i = 0; i < cells.size(); i++) {
|
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;
|
double ftime = (tframe[(offset+4)%5] - tframe[(offset)%5])/5.0f;
|
||||||
|
|
||||||
/* sprintf(buffer, "Ram size : %.3fMb (max) %.3fMb (cur)",
|
sprintf(buffer, "Ram size : %.3fMb (max) %.3fMb (cur)",
|
||||||
nexus.patches->ram_size * nexus.chunk_size/(float)(1<<20),
|
nexus.ram_max * nexus.chunk_size/(float)(1<<20),
|
||||||
nexus.patches->ram_used * nexus.chunk_size/(float)(1<<20));
|
nexus.ram_used * nexus.chunk_size/(float)(1<<20));
|
||||||
gl_print(0.03, 0.12, buffer);*/
|
gl_print(0.03, 0.15, buffer);
|
||||||
|
|
||||||
sprintf(buffer, "Ram size: %.3fMb(max) %.3fMb(cur)",
|
sprintf(buffer, "Extr size: %.3fMb(max) %.3fMb(cur)",
|
||||||
nexus.patches.ram_max * nexus.chunk_size/(float)(1<<20),
|
extraction.extr_max * nexus.chunk_size/(float)(1<<20),
|
||||||
nexus.patches.ram_used * 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);
|
gl_print(0.03, 0.09, buffer);
|
||||||
|
|
||||||
sprintf(buffer, "Vbo size : %.3fMb(cur) Load: %.4fK Pref: %.4fK",
|
sprintf(buffer, "Disk size: %.3fMb(max) %.3fMb(cur)",
|
||||||
nexus.patches.vbo_used * nexus.chunk_size/(float)(1<<20),
|
extraction.disk_max * nexus.chunk_size/(float)(1<<20),
|
||||||
nexus.prefetch.loading, nexus.prefetch.prefetching);
|
extraction.disk_used * nexus.chunk_size/(float)(1<<20));
|
||||||
gl_print(0.03, 0.06, buffer);
|
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) "
|
sprintf(buffer, "Triangles: %.2fK (tot) %.2fK (vis) "
|
||||||
"%.3f time %.2f FPS",
|
" %.2f FPS",
|
||||||
nexus.tri_total/(float)(1<<10),
|
stats.ktri/(float)(1<<10),
|
||||||
nexus.tri_rendered/(float)(1<<10),
|
stats.ktri/(float)(1<<10),
|
||||||
ftime, 1/ftime);
|
stats.fps);
|
||||||
gl_print(0.03, 0.03, buffer);
|
gl_print(0.03, 0.03, buffer);
|
||||||
|
|
||||||
glEnable(GL_DEPTH_TEST);
|
glEnable(GL_DEPTH_TEST);
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
//#include <wrap/strip/tristrip.h>
|
//#include <wrap/strip/tristrip.h>
|
||||||
|
|
||||||
#include "nxsalgo.h"
|
#include "nxsalgo.h"
|
||||||
|
#include "vfile.h"
|
||||||
#include "nexus.h"
|
#include "nexus.h"
|
||||||
#include "watch.h"
|
#include "watch.h"
|
||||||
|
|
||||||
|
@ -35,7 +36,7 @@ void nxs::ComputeNormals(Nexus &nexus) {
|
||||||
exit(0);
|
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);
|
Border border = nexus.GetBorder(p);
|
||||||
tmpb_start.push_back(tmpb_offset);
|
tmpb_start.push_back(tmpb_offset);
|
||||||
tmpb_offset += border.Size();
|
tmpb_offset += border.Size();
|
||||||
|
@ -50,10 +51,10 @@ void nxs::ComputeNormals(Nexus &nexus) {
|
||||||
|
|
||||||
//first step normals in the same patch.
|
//first step normals in the same patch.
|
||||||
cerr << "First Step\n";
|
cerr << "First Step\n";
|
||||||
Report report(nexus.index.size(), 5);
|
Report report(nexus.size(), 5);
|
||||||
vector<Point3f> normals;
|
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);
|
report.Step(p);
|
||||||
Patch &patch = nexus.GetPatch(p);
|
Patch &patch = nexus.GetPatch(p);
|
||||||
|
|
||||||
|
@ -166,8 +167,8 @@ void nxs::ComputeNormals(Nexus &nexus) {
|
||||||
|
|
||||||
//Second step unify normals across borders
|
//Second step unify normals across borders
|
||||||
cerr << "Second step\n";
|
cerr << "Second step\n";
|
||||||
report.Init(nexus.index.size());
|
report.Init(nexus.size());
|
||||||
for(unsigned int p = 0; p < nexus.index.size(); p++) {
|
for(unsigned int p = 0; p < nexus.size(); p++) {
|
||||||
report.Step(p);
|
report.Step(p);
|
||||||
Patch &patch = nexus.GetPatch(p);
|
Patch &patch = nexus.GetPatch(p);
|
||||||
Border border = nexus.GetBorder(p);
|
Border border = nexus.GetBorder(p);
|
||||||
|
|
|
@ -24,6 +24,9 @@
|
||||||
History
|
History
|
||||||
|
|
||||||
$Log: not supported by cvs2svn $
|
$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
|
Revision 1.10 2004/12/09 22:33:28 ponchio
|
||||||
Different splitting optimization.
|
Different splitting optimization.
|
||||||
|
|
||||||
|
@ -93,7 +96,7 @@ void SaveFragment(Nexus &nexus, VChain &chain,
|
||||||
Fragment &fragin,
|
Fragment &fragin,
|
||||||
Fragment &fragout);
|
Fragment &fragout);
|
||||||
|
|
||||||
void ReverseHistory(vector<Nexus::Update> &history);
|
void ReverseHistory(vector<History::Update> &history);
|
||||||
|
|
||||||
|
|
||||||
unsigned int current_level;
|
unsigned int current_level;
|
||||||
|
@ -285,7 +288,7 @@ void ThirdStep(const string &crudefile, const string &output,
|
||||||
|
|
||||||
Nexus nexus;
|
Nexus nexus;
|
||||||
//TODO here i really need no ram_buffer.....
|
//TODO here i really need no ram_buffer.....
|
||||||
nexus.MaxRamBuffer(0);
|
nexus.MaxRam() = 0;
|
||||||
if(!nexus.Create(output, NXS_FACES, chunk_size)) {
|
if(!nexus.Create(output, NXS_FACES, chunk_size)) {
|
||||||
cerr << "Could not create nexus output: " << output << endl;
|
cerr << "Could not create nexus output: " << output << endl;
|
||||||
getchar();
|
getchar();
|
||||||
|
@ -341,7 +344,7 @@ void ThirdStep(const string &crudefile, const string &output,
|
||||||
memcpy(patch.FaceBegin(), &*faces.begin(), fcount * sizeof(short));
|
memcpy(patch.FaceBegin(), &*faces.begin(), fcount * sizeof(short));
|
||||||
memcpy(patch.VertBegin(), &*vertices.begin(), vcount * sizeof(Point3f));
|
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++)
|
for(int i = 0; i < vertices.size(); i++)
|
||||||
sphere.Add(vertices[i]);
|
sphere.Add(vertices[i]);
|
||||||
sphere.Radius() *= 1.01;
|
sphere.Radius() *= 1.01;
|
||||||
|
@ -367,21 +370,21 @@ void ThirdStep(const string &crudefile, const string &output,
|
||||||
}
|
}
|
||||||
|
|
||||||
//we can now update bounding sphere.
|
//we can now update bounding sphere.
|
||||||
for(unsigned int i = 0; i < nexus.index.size(); i++)
|
for(unsigned int i = 0; i < nexus.size(); i++)
|
||||||
nexus.sphere.Add(nexus.index[i].sphere);
|
nexus.sphere.Add(nexus[i].sphere);
|
||||||
|
|
||||||
Nexus::Update update;
|
History::Update update;
|
||||||
for(unsigned int i = 1; i < nexus.index.size(); i++) {
|
for(unsigned int i = 1; i < nexus.size(); i++) {
|
||||||
update.created.push_back(i);
|
update.created.push_back(i);
|
||||||
}
|
}
|
||||||
nexus.history.push_back(update);
|
nexus.history.updates.push_back(update);
|
||||||
|
|
||||||
update.created.clear();
|
update.created.clear();
|
||||||
update.created.push_back(0);
|
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);
|
update.erased.push_back(i);
|
||||||
}
|
}
|
||||||
nexus.history.push_back(update);
|
nexus.history.updates.push_back(update);
|
||||||
|
|
||||||
if(!vert_index.Save(output + ".rvi")) {
|
if(!vert_index.Save(output + ".rvi")) {
|
||||||
cerr << "Could not save: " << output << ".rvi\n";
|
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;
|
cerr << "Could not load nexus " << output << endl;
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
nexus.MaxRamBuffer(ram_buffer);
|
nexus.MaxRam() = ram_buffer / nexus.chunk_size;
|
||||||
//TODO Clear borders in case of failure!
|
//TODO Clear borders in case of failure!
|
||||||
|
|
||||||
VFile<unsigned int> vert_remap;
|
VFile<unsigned int> vert_remap;
|
||||||
|
@ -411,11 +414,11 @@ void FourthStep(const string &crudefile, const string &output,
|
||||||
cerr << "Could not load index\n";
|
cerr << "Could not load index\n";
|
||||||
exit(0);
|
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);
|
report.Step(start);
|
||||||
PatchInfo &s_entry = nexus.index[start];
|
Entry &s_entry = nexus[start];
|
||||||
|
|
||||||
vector<Link> links;
|
vector<Link> links;
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
|
@ -428,10 +431,10 @@ void FourthStep(const string &crudefile, const string &output,
|
||||||
vremap[global] = i;
|
vremap[global] = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
for(int end = 0; end < nexus.index.size(); end++) {
|
for(int end = 0; end < nexus.size(); end++) {
|
||||||
if(start == end) continue;
|
if(start == end) continue;
|
||||||
|
|
||||||
PatchInfo &e_entry = nexus.index[end];
|
Entry &e_entry = nexus[end];
|
||||||
float dist = Distance(s_entry.sphere, e_entry.sphere);
|
float dist = Distance(s_entry.sphere, e_entry.sphere);
|
||||||
|
|
||||||
if(dist > s_entry.sphere.Radius() + e_entry.sphere.Radius()) {
|
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!)
|
//TODO Horribili visu (interfaccia di cacca!)
|
||||||
nexus.borders.ResizeBorder(start, 3 * links.size());
|
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);
|
Border border = nexus.GetBorder(start);
|
||||||
memcpy(&(border[0]), &*links.begin(), links.size() * sizeof(Link));
|
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;
|
cerr << "Could not load nexus " << output << endl;
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
nexus.MaxRamBuffer(ram_buffer);
|
nexus.MaxRam() = ram_buffer / nexus.chunk_size;
|
||||||
|
|
||||||
VChain vchain;
|
VChain vchain;
|
||||||
if(!vchain.Load(output + ".vchain")) {
|
if(!vchain.Load(output + ".vchain")) {
|
||||||
cerr << "Could not load : " << output << ".vchain\n";
|
cerr << "Could not load : " << output << ".vchain\n";
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
nexus.history.clear();
|
nexus.history.Clear();
|
||||||
Nexus::Update update;
|
History::Update update;
|
||||||
for(unsigned int i = 0; i < nexus.index.size(); i++) {
|
for(unsigned int i = 0; i < nexus.size(); i++) {
|
||||||
update.created.push_back(i);
|
update.created.push_back(i);
|
||||||
patch_levels.push_back(0);
|
patch_levels.push_back(0);
|
||||||
}
|
}
|
||||||
nexus.history.push_back(update);
|
nexus.history.updates.push_back(update);
|
||||||
nexus.Unify();
|
nexus.Unify();
|
||||||
nexus.patches.Flush();
|
nexus.Flush();
|
||||||
|
|
||||||
|
|
||||||
Dispatcher dispatcher(&nexus, &vchain);
|
Dispatcher dispatcher(&nexus, &vchain);
|
||||||
|
@ -502,7 +505,7 @@ void FifthStep(const string &crudefile, const string &output,
|
||||||
current_level = level;
|
current_level = level;
|
||||||
cerr << "Level: " << level << endl;
|
cerr << "Level: " << level << endl;
|
||||||
|
|
||||||
unsigned int newoffset = nexus.index.size();
|
unsigned int newoffset = nexus.size();
|
||||||
BuildLevel(vchain, nexus, oldoffset, scaling,
|
BuildLevel(vchain, nexus, oldoffset, scaling,
|
||||||
patch_size, patch_threshold, 65000,
|
patch_size, patch_threshold, 65000,
|
||||||
optimization_steps);
|
optimization_steps);
|
||||||
|
@ -571,8 +574,8 @@ void FifthStep(const string &crudefile, const string &output,
|
||||||
for(s = fcells.begin(); s != fcells.end(); s++)
|
for(s = fcells.begin(); s != fcells.end(); s++)
|
||||||
update.erased.push_back(*s);
|
update.erased.push_back(*s);
|
||||||
}
|
}
|
||||||
nexus.history.push_back(update);
|
nexus.history.updates.push_back(update);
|
||||||
ReverseHistory(nexus.history);
|
ReverseHistory(nexus.history.updates);
|
||||||
|
|
||||||
// TestBorders(nexus);
|
// TestBorders(nexus);
|
||||||
nexus.Close();
|
nexus.Close();
|
||||||
|
@ -719,7 +722,7 @@ void BuildFragment(Nexus &nexus, VPartition &part,
|
||||||
int nnears = 10;
|
int nnears = 10;
|
||||||
if(part.size() < 10) nnears = part.size();
|
if(part.size() < 10) nnears = part.size();
|
||||||
for(f = patches.begin(); f != patches.end(); f++) {
|
for(f = patches.begin(); f != patches.end(); f++) {
|
||||||
Point3f ¢er = nexus.index[*f].sphere.Center();
|
Point3f ¢er = nexus[*f].sphere.Center();
|
||||||
part.Closest(center, nnears, nears, dists);
|
part.Closest(center, nnears, nears, dists);
|
||||||
for(int i = 0; i < nnears; i++)
|
for(int i = 0; i < nnears; i++)
|
||||||
seeds.insert(nears[i]);
|
seeds.insert(nears[i]);
|
||||||
|
@ -737,7 +740,7 @@ void SaveFragment(Nexus &nexus, VChain &chain,
|
||||||
|
|
||||||
set<unsigned int> orig_patches;
|
set<unsigned int> orig_patches;
|
||||||
|
|
||||||
Nexus::Update update;
|
History::Update update;
|
||||||
for(unsigned int i = 0; i < fragin.pieces.size(); i++) {
|
for(unsigned int i = 0; i < fragin.pieces.size(); i++) {
|
||||||
NxsPatch &patch = fragin.pieces[i];
|
NxsPatch &patch = fragin.pieces[i];
|
||||||
update.erased.push_back(patch.patch);
|
update.erased.push_back(patch.patch);
|
||||||
|
@ -756,7 +759,7 @@ void SaveFragment(Nexus &nexus, VChain &chain,
|
||||||
patch.face.size()/3,
|
patch.face.size()/3,
|
||||||
bordsize);
|
bordsize);
|
||||||
patch_levels.push_back(current_level);
|
patch_levels.push_back(current_level);
|
||||||
PatchInfo &entry = nexus.index[patch_idx];
|
Entry &entry = nexus[patch_idx];
|
||||||
entry.error = fragout.error;
|
entry.error = fragout.error;
|
||||||
|
|
||||||
patch_remap[i] = patch_idx;
|
patch_remap[i] = patch_idx;
|
||||||
|
@ -784,7 +787,7 @@ void SaveFragment(Nexus &nexus, VChain &chain,
|
||||||
memcpy(patch.VertBegin(), &outpatch.vert[0],
|
memcpy(patch.VertBegin(), &outpatch.vert[0],
|
||||||
outpatch.vert.size() * sizeof(Point3f));
|
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++) {
|
for(unsigned int v = 0; v < outpatch.vert.size(); v++) {
|
||||||
entry.sphere.Add(outpatch.vert[v]);
|
entry.sphere.Add(outpatch.vert[v]);
|
||||||
nexus.sphere.Add(outpatch.vert[v]);
|
nexus.sphere.Add(outpatch.vert[v]);
|
||||||
|
@ -866,16 +869,16 @@ void SaveFragment(Nexus &nexus, VChain &chain,
|
||||||
border[bstart++] = link;
|
border[bstart++] = link;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
nexus.history.push_back(update);
|
nexus.history.updates.push_back(update);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ReverseHistory(vector<Nexus::Update> &history) {
|
void ReverseHistory(vector<History::Update> &history) {
|
||||||
vector<Nexus::Update> revert = history;
|
vector<History::Update> revert = history;
|
||||||
history.clear();
|
history.clear();
|
||||||
for(int i = revert.size()-1; i >= 0; i--)
|
for(int i = revert.size()-1; i >= 0; i--)
|
||||||
history.push_back(revert[i]);
|
history.push_back(revert[i]);
|
||||||
//std::reverse(history.begin(), history.end());
|
//std::reverse(history.begin(), history.end());
|
||||||
vector<Nexus::Update>::iterator i;
|
vector<History::Update>::iterator i;
|
||||||
for(i = history.begin(); i != history.end(); i++)
|
for(i = history.begin(); i != history.end(); i++)
|
||||||
swap((*i).erased, (*i).created);
|
swap((*i).erased, (*i).created);
|
||||||
}
|
}
|
||||||
|
|
|
@ -216,7 +216,7 @@ int main(int argc, char *argv[]) {
|
||||||
cerr << "Could not open nexus file: " << input << "\n";
|
cerr << "Could not open nexus file: " << input << "\n";
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
nexus.MaxRamBuffer(ram_size);
|
nexus.MaxRam() = ram_size / nexus.chunk_size;
|
||||||
|
|
||||||
|
|
||||||
//Sanity tests
|
//Sanity tests
|
||||||
|
@ -263,7 +263,7 @@ int main(int argc, char *argv[]) {
|
||||||
<< "\n\tData : " << (int)((nexus.signature&NXS_DATA32) !=0)
|
<< "\n\tData : " << (int)((nexus.signature&NXS_DATA32) !=0)
|
||||||
<< "\n\n\tVertices: " << nexus.totvert
|
<< "\n\n\tVertices: " << nexus.totvert
|
||||||
<< "\tFaces: " << nexus.totface
|
<< "\tFaces: " << nexus.totface
|
||||||
<< "\tPatches: " << nexus.index.size()
|
<< "\tPatches: " << nexus.size()
|
||||||
<< "\n\tSphere: "
|
<< "\n\tSphere: "
|
||||||
<< nexus.sphere.Center()[0] << " "
|
<< nexus.sphere.Center()[0] << " "
|
||||||
<< nexus.sphere.Center()[1] << " "
|
<< nexus.sphere.Center()[1] << " "
|
||||||
|
@ -315,22 +315,22 @@ int main(int argc, char *argv[]) {
|
||||||
Nexus out;
|
Nexus out;
|
||||||
|
|
||||||
if(!chunk_size)
|
if(!chunk_size)
|
||||||
chunk_size = nexus.patches.chunk_size;
|
chunk_size = nexus.chunk_size;
|
||||||
|
|
||||||
if(!out.Create(output, (Signature)signature, chunk_size)) {
|
if(!out.Create(output, (Signature)signature, chunk_size)) {
|
||||||
cerr << "Could not open output: " << output << endl;
|
cerr << "Could not open output: " << output << endl;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
out.MaxRamBuffer(ram_size);
|
out.MaxRam() = ram_size / out.chunk_size;
|
||||||
|
|
||||||
//TODO set rambuffer low (or even direct access!)
|
//TODO set rambuffer low (or even direct access!)
|
||||||
|
|
||||||
Report report(nexus.index.size());
|
Report report(nexus.size());
|
||||||
cout << "Copying and allocating...\n";
|
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);
|
report.Step(patch);
|
||||||
PatchInfo &src_entry = nexus.index[patch];
|
Entry &src_entry = nexus[patch];
|
||||||
Patch src_patch = nexus.GetPatch(patch);
|
Patch &src_patch = nexus.GetPatch(patch);
|
||||||
Border src_border = nexus.GetBorder(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());
|
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:
|
//copy vertices:
|
||||||
memcpy(dst_patch.VertBegin(), src_patch.VertBegin(),
|
memcpy(dst_patch.VertBegin(), src_patch.VertBegin(),
|
||||||
|
@ -396,8 +396,8 @@ int main(int argc, char *argv[]) {
|
||||||
if(link.IsNull()) continue;
|
if(link.IsNull()) continue;
|
||||||
assert(link.end_patch < nexus.index.size());
|
assert(link.end_patch < nexus.index.size());
|
||||||
}*/
|
}*/
|
||||||
Border dst_border = out.GetBorder(patch);
|
|
||||||
out.borders.ResizeBorder(patch, src_border.Size());
|
out.borders.ResizeBorder(patch, src_border.Size());
|
||||||
|
Border dst_border = out.GetBorder(patch);
|
||||||
memcpy(dst_border.Start(), src_border.Start(),
|
memcpy(dst_border.Start(), src_border.Start(),
|
||||||
src_border.Size() * sizeof(Link));
|
src_border.Size() * sizeof(Link));
|
||||||
}
|
}
|
||||||
|
@ -416,9 +416,9 @@ int main(int argc, char *argv[]) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if(qvertex && add_normals) {
|
if(qvertex && add_normals) {
|
||||||
report.Init(nexus.index.size());
|
report.Init(nexus.size());
|
||||||
cout << "Quantizing vertices\n";
|
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);
|
report.Step(patch);
|
||||||
Patch src_patch = nexus.GetPatch(patch);
|
Patch src_patch = nexus.GetPatch(patch);
|
||||||
|
|
||||||
|
@ -430,7 +430,12 @@ int main(int argc, char *argv[]) {
|
||||||
}
|
}
|
||||||
|
|
||||||
out.sphere = nexus.sphere;
|
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();
|
out.Close();
|
||||||
nexus.Close();
|
nexus.Close();
|
||||||
|
|
|
@ -4,31 +4,26 @@
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace nxs;
|
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;
|
ram_used = 0;
|
||||||
|
|
||||||
return MFile::Create(filename);
|
return MFile::Create(filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PServer::Load(const std::string &filename, Signature sig,
|
bool PServer::Load(const std::string &filename, Signature _signature,
|
||||||
unsigned int csize, bool readonly,
|
bool _readonly, unsigned int _chunk_size) {
|
||||||
unsigned int rsize) {
|
|
||||||
|
|
||||||
signature = sig;
|
signature = _signature;
|
||||||
chunk_size = csize;
|
chunk_size = _chunk_size;
|
||||||
|
|
||||||
ram_max = rsize/chunk_size + 1;
|
|
||||||
ram_used = 0;
|
ram_used = 0;
|
||||||
|
|
||||||
return MFile::Load(filename, readonly);
|
return MFile::Load(filename, _readonly);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PServer::Close() {
|
void PServer::Close() {
|
||||||
|
@ -40,23 +35,21 @@ void PServer::Close() {
|
||||||
bool PServer::ReadEntries(FILE *fp) {
|
bool PServer::ReadEntries(FILE *fp) {
|
||||||
unsigned int n;
|
unsigned int n;
|
||||||
fread(&n, 1, sizeof(int), fp);
|
fread(&n, 1, sizeof(int), fp);
|
||||||
entries.resize(n);
|
resize(n);
|
||||||
for(unsigned int i = 0; i < n; i++) {
|
for(unsigned int i = 0; i < n; i++) {
|
||||||
fread(&(entries[i].patch_start), 1, sizeof(unsigned int), fp);
|
Entry &entry = operator[](i);
|
||||||
fread(&(entries[i].ram_size), 1, sizeof(unsigned short), fp);
|
fread(&entry, sizeof(Entry), 1, fp);
|
||||||
fread(&(entries[i].disk_size), 1, sizeof(unsigned short), fp);
|
entry.patch = NULL;
|
||||||
entries[i].patch = NULL;
|
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PServer::WriteEntries(FILE *fp) {
|
bool PServer::WriteEntries(FILE *fp) {
|
||||||
unsigned int n = entries.size();
|
unsigned int n = size();
|
||||||
fwrite(&n, 1, sizeof(int), fp);
|
fwrite(&n, 1, sizeof(int), fp);
|
||||||
for(unsigned int i = 0; i < entries.size(); i++) {
|
for(unsigned int i = 0; i < size(); i++) {
|
||||||
fwrite(&(entries[i].patch_start), 1, sizeof(unsigned int), fp);
|
Entry &entry = operator[](i);
|
||||||
fwrite(&(entries[i].ram_size), 1, sizeof(unsigned short), fp);
|
fwrite(&entry, sizeof(Entry), 1, fp);
|
||||||
fwrite(&(entries[i].disk_size), 1, sizeof(unsigned short), fp);
|
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -66,17 +59,19 @@ void PServer::AddPatch(unsigned short nvert, unsigned short nface) {
|
||||||
entry.patch_start = 0xffffffff;
|
entry.patch_start = 0xffffffff;
|
||||||
entry.ram_size = Patch::ChunkSize(signature, nvert, nface, chunk_size);
|
entry.ram_size = Patch::ChunkSize(signature, nvert, nface, chunk_size);
|
||||||
entry.disk_size = 0xffff;
|
entry.disk_size = 0xffff;
|
||||||
|
entry.nvert = nvert;
|
||||||
|
entry.nface = nface;
|
||||||
|
//sphere and error undefined.
|
||||||
entry.patch = NULL;
|
entry.patch = NULL;
|
||||||
entries.push_back(entry);
|
entry.vbo_array = 0;
|
||||||
|
entry.vbo_element = 0;
|
||||||
|
|
||||||
|
push_back(entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
Patch *PServer::LoadPatch(unsigned int idx,
|
Patch *PServer::LoadPatch(unsigned int idx) {
|
||||||
unsigned short nvert, unsigned short nface) {
|
assert(idx < size());
|
||||||
|
Entry &entry = operator[](idx);
|
||||||
// ramlock.rdlock();
|
|
||||||
|
|
||||||
assert(idx < entries.size());
|
|
||||||
Entry &entry = entries[idx];
|
|
||||||
if(entry.patch) return entry.patch;
|
if(entry.patch) return entry.patch;
|
||||||
|
|
||||||
char *ram = new char[entry.ram_size * chunk_size];
|
char *ram = new char[entry.ram_size * chunk_size];
|
||||||
|
@ -87,18 +82,18 @@ Patch *PServer::LoadPatch(unsigned int idx,
|
||||||
}
|
}
|
||||||
#endif
|
#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.
|
if(entry.patch_start != 0xffffffff) { //was allocated.
|
||||||
assert(entry.disk_size != 0xffff);
|
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
|
if((signature & NXS_COMPRESSED) == 0) { //not compressed
|
||||||
ReadBuffer(ram, entry.disk_size * chunk_size);
|
MFile::ReadBuffer(ram, entry.disk_size * chunk_size);
|
||||||
} else {
|
} else {
|
||||||
unsigned char *disk = new unsigned char[entry.disk_size * chunk_size];
|
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,
|
patch->Decompress(entry.ram_size * chunk_size,
|
||||||
disk, entry.disk_size * chunk_size);
|
disk, entry.disk_size * chunk_size);
|
||||||
|
@ -110,46 +105,127 @@ Patch *PServer::LoadPatch(unsigned int idx,
|
||||||
return patch;
|
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!!!!
|
//TODO move this into an assert!!!!
|
||||||
if(!patch) return;
|
if(!entry.patch) return;
|
||||||
Entry &entry = entries[id];
|
|
||||||
// cerr << "entry: " << (void *)(entry.patch) << " patch: " << (void *)patch << endl;
|
|
||||||
entry.patch = NULL;
|
|
||||||
|
|
||||||
if(!readonly) { //write back patch
|
|
||||||
|
if(!MFile::IsReadOnly()) { //write back patch
|
||||||
if((signature & NXS_COMPRESSED)) {
|
if((signature & NXS_COMPRESSED)) {
|
||||||
unsigned int compressed_size;
|
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);
|
compressed_size);
|
||||||
if(entry.disk_size == 0xffff) {//allocate space
|
if(entry.disk_size == 0xffff) {//allocate space
|
||||||
assert(entry.patch_start == 0xffffffff);
|
assert(entry.patch_start == 0xffffffff);
|
||||||
entry.disk_size = (unsigned int)((compressed_size-1)/chunk_size) + 1;
|
entry.disk_size = (unsigned int)((compressed_size-1)/chunk_size) + 1;
|
||||||
entry.patch_start = (unsigned int)(Length()/chunk_size);
|
entry.patch_start = (unsigned int)( MFile::Length()/chunk_size);
|
||||||
Redim(Length() + entry.disk_size * chunk_size);
|
MFile::Redim(MFile::Length() + entry.disk_size * chunk_size);
|
||||||
} else {
|
} else {
|
||||||
//cerr << "OOOOPSPPPS not supported!" << endl;
|
//cerr << "OOOOPSPPPS not supported!" << endl;
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
SetPosition((int64)entry.patch_start * (int64)chunk_size);
|
MFile::SetPosition((int64)entry.patch_start * (int64)chunk_size);
|
||||||
WriteBuffer(compressed, entry.disk_size * chunk_size);
|
MFile::WriteBuffer(compressed, entry.disk_size * chunk_size);
|
||||||
delete []compressed;
|
delete []compressed;
|
||||||
} else {
|
} else {
|
||||||
if(entry.disk_size == 0xffff) {
|
if(entry.disk_size == 0xffff) {
|
||||||
entry.disk_size = entry.ram_size;
|
entry.disk_size = entry.ram_size;
|
||||||
entry.patch_start = (unsigned int)(Length()/chunk_size);
|
entry.patch_start = (unsigned int)(MFile::Length()/chunk_size);
|
||||||
Redim(Length() + entry.disk_size * chunk_size);
|
MFile::Redim(MFile::Length() + entry.disk_size * chunk_size);
|
||||||
}
|
}
|
||||||
SetPosition((int64)entry.patch_start * (int64)chunk_size);
|
MFile::SetPosition((int64)entry.patch_start * (int64)chunk_size);
|
||||||
WriteBuffer(patch->start, entry.disk_size * chunk_size);
|
MFile::WriteBuffer(entry.patch->start, entry.disk_size * chunk_size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
delete [](patch->start);
|
delete [](entry.patch->start);
|
||||||
delete patch;
|
delete entry.patch;
|
||||||
|
entry.patch = NULL;
|
||||||
ram_used -= entry.ram_size;
|
ram_used -= entry.ram_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PServer::MaxRamBuffer(unsigned int r_buffer) {
|
bool PServer::IsLoaded(unsigned int patch) {
|
||||||
ram_max = (unsigned int)(r_buffer/chunk_size) + 1;
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -2,81 +2,95 @@
|
||||||
#define NXS_PSERVER_H
|
#define NXS_PSERVER_H
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <list>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
#include "patch.h"
|
#include "patch.h"
|
||||||
#include "mfile.h"
|
#include "mfile.h"
|
||||||
|
|
||||||
namespace nxs {
|
namespace nxs {
|
||||||
|
|
||||||
class PServer: public MFile {
|
/* HEader fo pserver
|
||||||
public:
|
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)
|
||||||
|
|
||||||
|
unsigned short nvert;
|
||||||
|
unsigned short nface;
|
||||||
|
|
||||||
struct Entry {
|
vcg::Sphere3f sphere;
|
||||||
unsigned int patch_start; //granularita' Chunk
|
float error;
|
||||||
unsigned short ram_size; //in chunks
|
|
||||||
unsigned short disk_size; // in chunks (used when compressed)
|
|
||||||
Patch *patch;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* struct Data {
|
Patch *patch;
|
||||||
// unsigned int npatch;
|
unsigned int vbo_array;
|
||||||
Patch *patch;
|
unsigned int vbo_element;
|
||||||
unsigned int vbo_array;
|
};
|
||||||
unsigned int vbo_element;
|
|
||||||
Data(): patch(NULL), vbo_array(0), vbo_element(0) {}
|
class PServer: public IndexFile<Entry,
|
||||||
};*/
|
public:
|
||||||
|
|
||||||
struct Item { //used by lru and pqueue.
|
std::list<unsigned int> pqueue;
|
||||||
unsigned int patch;
|
std::map<unsigned int, std::list<unsigned int>::iterator> index;
|
||||||
float priority;
|
|
||||||
Item(unsigned int p, float f): patch(p), priority(f) {}
|
|
||||||
bool operator<(const Item &i) const {
|
|
||||||
return priority < i.priority;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Signature signature;
|
Signature signature;
|
||||||
unsigned int chunk_size;
|
unsigned int chunk_size;
|
||||||
|
|
||||||
unsigned int ram_max;
|
unsigned int ram_max;
|
||||||
unsigned int ram_used;
|
unsigned int ram_used;
|
||||||
|
|
||||||
std::vector<Entry> entries;
|
|
||||||
|
|
||||||
PServer(): chunk_size(1024),
|
PServer(): chunk_size(1024),
|
||||||
ram_max(128000000),
|
ram_max(128000000),
|
||||||
ram_used(0) {}
|
ram_used(0) {}
|
||||||
virtual ~PServer() {
|
|
||||||
MFile::Close();
|
~PServer() { PServer::Close(); }
|
||||||
}
|
|
||||||
|
|
||||||
bool Create(const std::string &filename, Signature signature,
|
bool Create(const std::string &filename, Signature signature,
|
||||||
unsigned int chunk_size, unsigned int ram_max = 128000000);
|
unsigned int chunk_size = 1024);
|
||||||
bool Load(const std::string &filename, Signature sig,
|
bool Load(const std::string &filename, Signature signature,
|
||||||
unsigned int chunk_size, bool readonly,
|
bool readonly = true, unsigned int chunk_size = 1024);
|
||||||
unsigned int ram_max = 128000000);
|
void Close();
|
||||||
|
|
||||||
bool ReadEntries(FILE *fp);
|
bool ReadEntries(FILE *fp);
|
||||||
bool WriteEntries(FILE *fp);
|
bool WriteEntries(FILE *fp);
|
||||||
virtual void Close();
|
|
||||||
|
|
||||||
void AddPatch(unsigned short nvert, unsigned short nface);
|
void AddPatch(unsigned short nvert, unsigned short nface);
|
||||||
Patch *LoadPatch(unsigned int id, unsigned short nv, unsigned short nf);
|
Patch *LoadPatch(unsigned int id);
|
||||||
void FlushPatch(unsigned int id, Patch *patch);
|
void FlushPatch(unsigned int id);
|
||||||
|
void Flush();
|
||||||
virtual bool IsLoaded(unsigned int patch) = 0;
|
|
||||||
// virtual Patch &Lookup(unsigned int patch,
|
bool IsLoaded(unsigned int patch);
|
||||||
// unsigned short nv, unsigned short nf) = 0;
|
Entry &Lookup(unsigned int patch, std::vector<unsigned int> &flushed);
|
||||||
virtual void Flush() = 0;
|
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 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);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -245,9 +245,9 @@ void nxs::BuildLevel(VChain &chain,
|
||||||
|
|
||||||
unsigned int totface = 0;
|
unsigned int totface = 0;
|
||||||
unsigned int totvert = 0;
|
unsigned int totvert = 0;
|
||||||
for(unsigned int idx = offset; idx < nexus.index.size(); idx++) {
|
for(unsigned int idx = offset; idx < nexus.size(); idx++) {
|
||||||
totface += nexus.index[idx].nface;
|
totface += nexus[idx].nface;
|
||||||
totvert += nexus.index[idx].nvert;
|
totvert += nexus[idx].nvert;
|
||||||
}
|
}
|
||||||
|
|
||||||
VPartition *fine = chain[chain.size()-1];
|
VPartition *fine = chain[chain.size()-1];
|
||||||
|
@ -260,9 +260,9 @@ void nxs::BuildLevel(VChain &chain,
|
||||||
unsigned int ncells = (unsigned int)(scaling * totface/target_size);
|
unsigned int ncells = (unsigned int)(scaling * totface/target_size);
|
||||||
|
|
||||||
//TODO this method for selecting the seeds is ugly!
|
//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;
|
float cratio = 0;
|
||||||
for(unsigned int idx = offset; idx < nexus.index.size(); idx++) {
|
for(unsigned int idx = offset; idx < nexus.size(); idx++) {
|
||||||
cratio += ratio;
|
cratio += ratio;
|
||||||
if(cratio > 1) {
|
if(cratio > 1) {
|
||||||
Patch patch = nexus.GetPatch(idx);
|
Patch patch = nexus.GetPatch(idx);
|
||||||
|
@ -296,8 +296,8 @@ void nxs::BuildLevel(VChain &chain,
|
||||||
centroids.resize(coarse->size(), Point3f(0, 0, 0));
|
centroids.resize(coarse->size(), Point3f(0, 0, 0));
|
||||||
counts.resize(coarse->size(), 0);
|
counts.resize(coarse->size(), 0);
|
||||||
|
|
||||||
Report report(nexus.index.size());
|
Report report(nexus.size());
|
||||||
for(unsigned int idx = offset; idx < nexus.index.size(); idx++) {
|
for(unsigned int idx = offset; idx < nexus.size(); idx++) {
|
||||||
report.Step(idx);
|
report.Step(idx);
|
||||||
Patch patch = nexus.GetPatch(idx);
|
Patch patch = nexus.GetPatch(idx);
|
||||||
for(unsigned int i = 0; i < patch.nf; i++) {
|
for(unsigned int i = 0; i < patch.nf; i++) {
|
||||||
|
|
|
@ -24,6 +24,9 @@
|
||||||
History
|
History
|
||||||
|
|
||||||
$Log: not supported by cvs2svn $
|
$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
|
Revision 1.18 2004/12/01 03:24:32 ponchio
|
||||||
Level 2.
|
Level 2.
|
||||||
|
|
||||||
|
@ -168,7 +171,7 @@ template <class T> class VFile: public MFile {
|
||||||
queue_size = _queue_size;
|
queue_size = _queue_size;
|
||||||
|
|
||||||
if(!MFile::Load(filename, rdonly)) return false;
|
if(!MFile::Load(filename, rdonly)) return false;
|
||||||
n_elements = size/sizeof(T);
|
n_elements = _size/sizeof(T);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,9 @@
|
||||||
History
|
History
|
||||||
|
|
||||||
$Log: not supported by cvs2svn $
|
$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
|
Revision 1.5 2004/12/01 16:00:35 ponchio
|
||||||
Level 3
|
Level 3
|
||||||
|
|
||||||
|
@ -54,6 +57,9 @@ First draft created.
|
||||||
|
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef VCG_WATCH_H
|
||||||
|
#define VCG_WATCH_H
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
#ifndef _WINDOWS_
|
#ifndef _WINDOWS_
|
||||||
#define _WINSOCKAPI_
|
#define _WINSOCKAPI_
|
||||||
|
@ -98,3 +104,5 @@ class Report {
|
||||||
double last;
|
double last;
|
||||||
double interval;
|
double interval;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue