Fixing borders... let's hope.
This commit is contained in:
parent
b5553ec6ca
commit
a8e2df5d3c
|
@ -21,13 +21,15 @@ Border BorderServer::GetBorder(unsigned int border, bool flush) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BorderServer::ResizeBorder(unsigned int border, unsigned int nbord) {
|
bool BorderServer::ResizeBorder(unsigned int border, unsigned int nbord) {
|
||||||
|
assert(nbord < 65500);
|
||||||
assert(border < borders.size());
|
assert(border < borders.size());
|
||||||
BorderEntry &entry = borders[border];
|
BorderEntry &entry = borders[border];
|
||||||
if(nbord > entry.border_size) {
|
if(nbord > entry.border_size) {
|
||||||
int capacity = nbord;
|
int capacity = nbord;
|
||||||
if(capacity < entry.border_size*2)
|
if(capacity < entry.border_size*2)
|
||||||
capacity = entry.border_size * 2;
|
capacity = entry.border_size * 2;
|
||||||
|
if(capacity > 65500)
|
||||||
|
capacity = 65500;
|
||||||
unsigned int newstart = Size();
|
unsigned int newstart = Size();
|
||||||
Resize(newstart + capacity);
|
Resize(newstart + capacity);
|
||||||
|
|
||||||
|
|
|
@ -32,6 +32,7 @@ int main(int argc, char *argv[]) {
|
||||||
cerr << "Could not load nexus: " << input << endl;
|
cerr << "Could not load nexus: " << input << endl;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
Nexus out;
|
Nexus out;
|
||||||
if(!out.Create(output, in.signature, in.chunk_size)) {
|
if(!out.Create(output, in.signature, in.chunk_size)) {
|
||||||
cerr << "Could not create nexus: " << output << endl;
|
cerr << "Could not create nexus: " << output << endl;
|
||||||
|
|
|
@ -121,6 +121,12 @@ void nxs::Join(Fragment &in,
|
||||||
vector<unsigned short> &face = in.pieces[i].face;
|
vector<unsigned short> &face = in.pieces[i].face;
|
||||||
vector<Link> &bord = in.pieces[i].bord;
|
vector<Link> &bord = in.pieces[i].bord;
|
||||||
|
|
||||||
|
for(unsigned int k = 0; k < face.size(); k+=3) {
|
||||||
|
assert(face[k] != face[k+1]);
|
||||||
|
assert(face[k] != face[k+2]);
|
||||||
|
assert(face[k+1] != face[k+2]);
|
||||||
|
}
|
||||||
|
|
||||||
fcount += face.size()/3;
|
fcount += face.size()/3;
|
||||||
|
|
||||||
for(unsigned int k = 0; k < vert.size(); k++) {
|
for(unsigned int k = 0; k < vert.size(); k++) {
|
||||||
|
@ -135,6 +141,7 @@ void nxs::Join(Fragment &in,
|
||||||
|
|
||||||
if(patch_remap.count(link.end_patch)) {//internal
|
if(patch_remap.count(link.end_patch)) {//internal
|
||||||
unsigned int idx = patch_remap[link.end_patch];
|
unsigned int idx = patch_remap[link.end_patch];
|
||||||
|
assert(link.end_patch != in.pieces[i].patch);
|
||||||
unsigned int extoffset = offsets[idx];
|
unsigned int extoffset = offsets[idx];
|
||||||
|
|
||||||
assert(extoffset + link.end_vert < remap.size());
|
assert(extoffset + link.end_vert < remap.size());
|
||||||
|
@ -187,9 +194,23 @@ void nxs::Join(Fragment &in,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
set<BigLink>::iterator b;
|
set<BigLink>::iterator b;
|
||||||
for(b = newborders.begin(); b != newborders.end(); b++)
|
for(b = newborders.begin(); b != newborders.end(); b++) {
|
||||||
newbord.push_back(*b);
|
newbord[bcount++] = *b;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(unsigned int i = 0; i < newface.size(); i+= 3) {
|
||||||
|
if(newface[i] == newface[i+1] ||
|
||||||
|
newface[i] == newface[i+2] ||
|
||||||
|
newface[i+1] == newface[i+2]) {
|
||||||
|
cerr << "i: " << i << endl;
|
||||||
|
for(unsigned int k = 0; k < newface.size(); k+=3) {
|
||||||
|
cerr << k << ": " << newface[k] << " "
|
||||||
|
<< newface[k+1] << " "
|
||||||
|
<< newface[k+2] << endl;
|
||||||
|
}
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
/* old code (more general.. but not parallelizable)
|
/* old code (more general.. but not parallelizable)
|
||||||
|
|
||||||
|
|
||||||
|
@ -371,10 +392,12 @@ void nxs::Split(Fragment &out,
|
||||||
//borders last
|
//borders last
|
||||||
vector<Link> &bords = patch.bord;
|
vector<Link> &bords = patch.bord;
|
||||||
|
|
||||||
//process external borders
|
//process downward borders
|
||||||
//for every esternal link we must update external patches!
|
|
||||||
for(unsigned int i = 0; i < newbord.size(); i++) {
|
for(unsigned int i = 0; i < newbord.size(); i++) {
|
||||||
BigLink link = newbord[i];
|
BigLink link = newbord[i];
|
||||||
|
/* cerr << "Newbord: " << link.start_vert << " "
|
||||||
|
<< link.end_patch << " "
|
||||||
|
<< link.end_vert << endl;*/
|
||||||
if(v_remap[link.start_vert] == -1) continue;
|
if(v_remap[link.start_vert] == -1) continue;
|
||||||
Link llink;
|
Link llink;
|
||||||
llink.start_vert = v_remap[link.start_vert];
|
llink.start_vert = v_remap[link.start_vert];
|
||||||
|
@ -399,6 +422,12 @@ void nxs::Split(Fragment &out,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/* cerr << "patch seed: " << patch.patch << endl;
|
||||||
|
for(unsigned int i = 0; i < bords.size(); i++) {
|
||||||
|
Link &link = bords[i];
|
||||||
|
cerr << "link: " << link.start_vert << " "
|
||||||
|
<< link.end_patch << " " << link.end_vert << endl;
|
||||||
|
}*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,8 +6,8 @@ using namespace std;
|
||||||
using namespace nxs;
|
using namespace nxs;
|
||||||
|
|
||||||
bool MFile::Create(const string &fname, unsigned int mxs) {
|
bool MFile::Create(const string &fname, unsigned int mxs) {
|
||||||
|
Close();
|
||||||
filename = fname;
|
filename = fname;
|
||||||
files.clear();
|
|
||||||
size = 0;
|
size = 0;
|
||||||
readonly = false;
|
readonly = false;
|
||||||
assert(mxs <= MFILE_MAX_SIZE);
|
assert(mxs <= MFILE_MAX_SIZE);
|
||||||
|
@ -16,21 +16,21 @@ bool MFile::Create(const string &fname, unsigned int mxs) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MFile::Load(const string &fname, bool ronly) {
|
bool MFile::Load(const string &fname, bool ronly) {
|
||||||
|
Close();
|
||||||
filename = fname;
|
filename = fname;
|
||||||
files.clear();
|
|
||||||
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());
|
||||||
files.push_back(File());
|
File *file = new File;
|
||||||
File &file = files.back();
|
files.push_back(file);
|
||||||
if(!file.Load(name, ronly)) {
|
if(!file->Load(name, 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) {
|
||||||
|
@ -38,17 +38,19 @@ bool MFile::Load(const string &fname, bool ronly) {
|
||||||
} 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++) {
|
||||||
if(files[i].Length() != files[i++].Length()) {
|
if(files[i]->Length() != files[i++]->Length()) {
|
||||||
//"Inconsistent file size for some file.\n";
|
//"Inconsistent file size for some file.\n";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
max_size = files[0].Length();
|
max_size = files[0]->Length();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MFile::Close() {
|
void MFile::Close() {
|
||||||
|
for(unsigned int i = 0; i < files.size(); i++)
|
||||||
|
delete files[i];
|
||||||
files.clear();
|
files.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -69,13 +71,13 @@ void MFile::Redim(int64 sz) {
|
||||||
}
|
}
|
||||||
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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -85,49 +87,50 @@ void MFile::SetPosition(int64 pos) {
|
||||||
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);
|
||||||
assert(curr_fp < files.size());
|
assert(curr_fp < files.size());
|
||||||
files[curr_fp].SetPosition(curr_pos);
|
files[curr_fp]->SetPosition(curr_pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MFile::ReadBuffer(void *data, unsigned int sz) {
|
void MFile::ReadBuffer(void *data, unsigned int sz) {
|
||||||
while(sz + curr_pos > max_size) {
|
while(sz + curr_pos > max_size) {
|
||||||
unsigned int n = max_size - curr_pos;
|
unsigned int n = max_size - curr_pos;
|
||||||
files[curr_fp].ReadBuffer(data, n);
|
files[curr_fp]->ReadBuffer(data, n);
|
||||||
data = ((char *)data) + n;
|
data = ((char *)data) + n;
|
||||||
sz -= n;
|
sz -= n;
|
||||||
curr_fp++;
|
curr_fp++;
|
||||||
curr_pos = 0;
|
curr_pos = 0;
|
||||||
files[curr_fp].SetPosition(curr_pos);
|
files[curr_fp]->SetPosition(curr_pos);
|
||||||
}
|
}
|
||||||
files[curr_fp].ReadBuffer(data, sz);
|
files[curr_fp]->ReadBuffer(data, sz);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MFile::WriteBuffer(void *data, unsigned int sz) {
|
void MFile::WriteBuffer(void *data, unsigned int sz) {
|
||||||
assert(!readonly);
|
assert(!readonly);
|
||||||
while(sz + curr_pos > max_size) {
|
while(sz + curr_pos > max_size) {
|
||||||
unsigned int n = max_size - curr_pos;
|
unsigned int n = max_size - curr_pos;
|
||||||
files[curr_fp].WriteBuffer(data, n);
|
files[curr_fp]->WriteBuffer(data, n);
|
||||||
data = ((char *)data) + n;
|
data = ((char *)data) + n;
|
||||||
sz -= n;
|
sz -= n;
|
||||||
curr_fp++;
|
curr_fp++;
|
||||||
curr_pos = 0;
|
curr_pos = 0;
|
||||||
files[curr_fp].SetPosition(curr_pos);
|
files[curr_fp]->SetPosition(curr_pos);
|
||||||
}
|
}
|
||||||
files[curr_fp].WriteBuffer(data, sz);
|
files[curr_fp]->WriteBuffer(data, sz);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MFile::AddFile() {
|
bool MFile::AddFile() {
|
||||||
string name = Name(files.size());
|
string name = Name(files.size());
|
||||||
files.push_back(File());
|
File *file = new File;
|
||||||
File &file = files.back();
|
files.push_back(file);
|
||||||
return file.Create(name);
|
return file->Create(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MFile::RemoveFile() {
|
void MFile::RemoveFile() {
|
||||||
assert(files.size());
|
assert(files.size());
|
||||||
|
|
||||||
string name = Name(files.size()-1);
|
string name = Name(files.size()-1);
|
||||||
File &file = files.back();
|
File *file = files.back();
|
||||||
unsigned int last_size = file.Length();
|
unsigned int last_size = file->Length();
|
||||||
|
delete file;
|
||||||
files.pop_back();
|
files.pop_back();
|
||||||
size -= last_size;
|
size -= last_size;
|
||||||
cerr << "Removing file: " << name << endl;
|
cerr << "Removing file: " << name << endl;
|
||||||
|
@ -140,7 +143,7 @@ void MFile::WriteBuffer(void *data, unsigned int sz) {
|
||||||
|
|
||||||
void MFile::RedimLast(unsigned int sz) {
|
void MFile::RedimLast(unsigned int sz) {
|
||||||
assert(sz <= max_size);
|
assert(sz <= max_size);
|
||||||
File &file = files.back();
|
File &file = *files.back();
|
||||||
unsigned int last_size = file.Length();
|
unsigned int last_size = file.Length();
|
||||||
file.Redim(sz);
|
file.Redim(sz);
|
||||||
size += sz - last_size;
|
size += sz - last_size;
|
||||||
|
|
|
@ -40,7 +40,7 @@ class MFile {
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
std::string filename;
|
std::string filename;
|
||||||
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;
|
||||||
|
|
|
@ -151,11 +151,14 @@ 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();
|
||||||
|
if(pos > 65500) {
|
||||||
|
cerr << "Exceding border size!!!\n";
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
if(borders.ResizeBorder(patch, pos+1)) {
|
if(borders.ResizeBorder(patch, pos+1)) {
|
||||||
border = GetBorder(patch);
|
border = GetBorder(patch);
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(border.Size() < border.Available());
|
|
||||||
assert(border.Available() > pos);
|
assert(border.Available() > pos);
|
||||||
|
|
||||||
border[pos] = link;
|
border[pos] = link;
|
||||||
|
|
|
@ -77,10 +77,6 @@ void Policy::NodeVisited(Node *node) {
|
||||||
assert(!(node->out[i]->visited));
|
assert(!(node->out[i]->visited));
|
||||||
Frag &frag = node->frags[i];
|
Frag &frag = node->frags[i];
|
||||||
for(unsigned int k = 0; k < frag.size(); k++) {
|
for(unsigned int k = 0; k < frag.size(); k++) {
|
||||||
unsigned int rr = frag.size();
|
|
||||||
unsigned int tmp = frag[k];
|
|
||||||
unsigned int sz = entries->size();
|
|
||||||
assert(tmp < sz);
|
|
||||||
PatchEntry &entry = (*entries)[frag[k]];
|
PatchEntry &entry = (*entries)[frag[k]];
|
||||||
ram_used += entry.ram_size;
|
ram_used += entry.ram_size;
|
||||||
}
|
}
|
||||||
|
@ -102,12 +98,41 @@ void Policy::NodeVisited(Node *node) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Prefetch::Prefetch(): thread(true), nexus(NULL) {}
|
||||||
|
|
||||||
|
Prefetch::~Prefetch() { signal(); waitfor(); }
|
||||||
|
|
||||||
|
void Prefetch::execute() {
|
||||||
|
assert(nexus != NULL);
|
||||||
|
while(1) {
|
||||||
|
if(get_signaled()) return;
|
||||||
|
if(cells.size() == 0 ||
|
||||||
|
nexus->patches.ram_used > nexus->patches.ram_size) {
|
||||||
|
relax(100);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
cells_mx.lock();
|
||||||
|
|
||||||
|
pop_heap(cells.begin(), cells.end());
|
||||||
|
unsigned int cell = cells.back();
|
||||||
|
cells.pop_back();
|
||||||
|
|
||||||
|
patch_mx.lock();
|
||||||
|
Patch &patch = nexus->GetPatch(cell, false);
|
||||||
|
patch_mx.unlock();
|
||||||
|
|
||||||
|
cells_mx.unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
NexusMt::NexusMt(): vbo_mode(VBO_AUTO),
|
NexusMt::NexusMt(): vbo_mode(VBO_AUTO),
|
||||||
metric(NULL), mode(SMOOTH) {
|
metric(NULL), mode(SMOOTH), prefetching(true) {
|
||||||
metric = new FrustumMetric();
|
metric = new FrustumMetric();
|
||||||
metric->index = &index;
|
metric->index = &index;
|
||||||
policy.error = 4;
|
policy.error = 4;
|
||||||
policy.ram_size = 64000000;
|
policy.ram_size = 64000000;
|
||||||
|
|
||||||
|
prefetch.nexus = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
NexusMt::~NexusMt() {}
|
NexusMt::~NexusMt() {}
|
||||||
|
@ -128,6 +153,7 @@ bool NexusMt::Load(const string &filename, bool readonly) {
|
||||||
SetComponent(TEXTURE, true);
|
SetComponent(TEXTURE, true);
|
||||||
SetComponent(DATA, true);
|
SetComponent(DATA, true);
|
||||||
|
|
||||||
|
SetPrefetching(prefetching);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -272,6 +298,19 @@ void NexusMt::SetVboSize(unsigned int _vbo_size) {
|
||||||
patches.vbo_size = _vbo_size;
|
patches.vbo_size = _vbo_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NexusMt::SetPrefetching(bool on) {
|
||||||
|
if(on && prefetch.Running()) return;
|
||||||
|
if(!on && !prefetch.Running()) return;
|
||||||
|
if(on) {
|
||||||
|
prefetch.cells.clear();
|
||||||
|
prefetch.start();
|
||||||
|
} else {
|
||||||
|
prefetch.signal();
|
||||||
|
prefetch.waitfor();
|
||||||
|
}
|
||||||
|
prefetching = on;
|
||||||
|
}
|
||||||
|
|
||||||
bool NexusMt::SetMode(Mode _mode) {
|
bool NexusMt::SetMode(Mode _mode) {
|
||||||
mode = _mode;
|
mode = _mode;
|
||||||
return true;
|
return true;
|
||||||
|
@ -308,6 +347,9 @@ bool NexusMt::SetComponents(unsigned int mask) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//TODO: nodes and fragment sholuld be kept in another way,
|
||||||
|
// so we can save that structure instead of the history!
|
||||||
|
|
||||||
void NexusMt::LoadHistory() {
|
void NexusMt::LoadHistory() {
|
||||||
//The last update erases everything.
|
//The last update erases everything.
|
||||||
assert(history[0].erased.size() == 0);
|
assert(history[0].erased.size() == 0);
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
#include "nexus.h"
|
#include "nexus.h"
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <queue>
|
#include <queue>
|
||||||
|
#include <ptypes/pasync.h>
|
||||||
#include <wrap/gui/frustum.h>
|
#include <wrap/gui/frustum.h>
|
||||||
|
|
||||||
|
|
||||||
|
@ -73,10 +73,25 @@ namespace nxs {
|
||||||
void NodeVisited(Node *node);
|
void NodeVisited(Node *node);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class Prefetch: public pt::thread {
|
||||||
|
public:
|
||||||
|
Prefetch();
|
||||||
|
~Prefetch();
|
||||||
|
void execute();
|
||||||
|
void cleanup() {}
|
||||||
|
|
||||||
|
bool Running() { return get_running(); }
|
||||||
|
|
||||||
|
std::vector<unsigned int> cells;
|
||||||
|
pt::mutex cells_mx;
|
||||||
|
pt::mutex patch_mx;
|
||||||
|
Nexus *nexus;
|
||||||
|
};
|
||||||
|
|
||||||
class NexusMt: public Nexus {
|
class NexusMt: public Nexus {
|
||||||
private:
|
private:
|
||||||
std::vector<Node> nodes;
|
std::vector<Node> nodes;
|
||||||
|
Prefetch prefetch;
|
||||||
public:
|
public:
|
||||||
//Vertex buffer object mode
|
//Vertex buffer object mode
|
||||||
enum Vbo { VBO_AUTO, //autodetect best size
|
enum Vbo { VBO_AUTO, //autodetect best size
|
||||||
|
@ -106,6 +121,7 @@ class NexusMt: public Nexus {
|
||||||
Policy policy;
|
Policy policy;
|
||||||
|
|
||||||
Mode mode;
|
Mode mode;
|
||||||
|
bool prefetching;
|
||||||
|
|
||||||
unsigned int components;
|
unsigned int components;
|
||||||
bool use_normals;
|
bool use_normals;
|
||||||
|
@ -130,6 +146,8 @@ class NexusMt: public Nexus {
|
||||||
void SetRamExtractionSize(unsigned int ram_size);
|
void SetRamExtractionSize(unsigned int ram_size);
|
||||||
void SetVboSize(unsigned int vbo_size);
|
void SetVboSize(unsigned int vbo_size);
|
||||||
|
|
||||||
|
void SetPrefetching(bool on);
|
||||||
|
|
||||||
bool SetMode(Mode mode);
|
bool SetMode(Mode mode);
|
||||||
bool SetComponent(Component c, bool on);
|
bool SetComponent(Component c, bool on);
|
||||||
bool SetComponents(unsigned int mask);
|
bool SetComponents(unsigned int mask);
|
||||||
|
|
|
@ -24,6 +24,9 @@
|
||||||
History
|
History
|
||||||
|
|
||||||
$Log: not supported by cvs2svn $
|
$Log: not supported by cvs2svn $
|
||||||
|
Revision 1.20 2004/11/18 18:30:14 ponchio
|
||||||
|
Using baricenters... lotsa changes.
|
||||||
|
|
||||||
Revision 1.19 2004/10/30 20:17:03 ponchio
|
Revision 1.19 2004/10/30 20:17:03 ponchio
|
||||||
Fixed big patches problem.
|
Fixed big patches problem.
|
||||||
|
|
||||||
|
@ -214,7 +217,7 @@ int main(int argc, char *argv[]) {
|
||||||
Watch watch;
|
Watch watch;
|
||||||
|
|
||||||
bool rotate = false;
|
bool rotate = false;
|
||||||
bool show_borders = true;
|
bool show_borders = false;
|
||||||
bool show_colors = true;
|
bool show_colors = true;
|
||||||
bool show_normals = true;
|
bool show_normals = true;
|
||||||
bool show_statistics = true;
|
bool show_statistics = true;
|
||||||
|
|
|
@ -23,6 +23,7 @@ void Opener::execute() {
|
||||||
try {
|
try {
|
||||||
server->open();
|
server->open();
|
||||||
server->connected = true;
|
server->connected = true;
|
||||||
|
server->queue = 0;
|
||||||
break;
|
break;
|
||||||
} catch(...) {
|
} catch(...) {
|
||||||
}
|
}
|
||||||
|
@ -33,7 +34,7 @@ void Opener::execute() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void FragIO::execute() {
|
void FragIO::execute() {
|
||||||
|
pincrement(&(server->queue));
|
||||||
server->writing.lock();
|
server->writing.lock();
|
||||||
// cerr << "Writing frag...: " << fragin->id << "\n";
|
// cerr << "Writing frag...: " << fragin->id << "\n";
|
||||||
|
|
||||||
|
@ -45,12 +46,13 @@ void FragIO::execute() {
|
||||||
server->write((const char *)a, length(a));
|
server->write((const char *)a, length(a));
|
||||||
server->flush();
|
server->flush();
|
||||||
} catch (estream *e) {
|
} catch (estream *e) {
|
||||||
perr.putf("Error: %s\n", pconst(e->get_message()));
|
perr.putf("Error reading: %s\n", pconst(e->get_message()));
|
||||||
delete e;
|
delete e;
|
||||||
|
server->close();
|
||||||
|
server->connected = false;
|
||||||
|
server->writing.unlock();
|
||||||
message *msg = new message(MSG_FAIL, (int)fragin);
|
message *msg = new message(MSG_FAIL, (int)fragin);
|
||||||
dispatcher->post(msg);
|
dispatcher->post(msg);
|
||||||
|
|
||||||
//TODO restart Server!
|
//TODO restart Server!
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -59,19 +61,22 @@ void FragIO::execute() {
|
||||||
server->writing.unlock();
|
server->writing.unlock();
|
||||||
|
|
||||||
Fragment *out = new Fragment;
|
Fragment *out = new Fragment;
|
||||||
if(!out->Read(server)) {
|
if(!server->waitfor(10000) || (!out->Read(server))) {
|
||||||
|
perr.putf("Error reading!!\n");
|
||||||
|
server->close();
|
||||||
|
server->connected = false;
|
||||||
|
server->reading.unlock();
|
||||||
message *msg = new message(MSG_FAIL, (int)fragin);
|
message *msg = new message(MSG_FAIL, (int)fragin);
|
||||||
dispatcher->post(msg);
|
dispatcher->post(msg);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
server->reading.unlock();
|
server->reading.unlock();
|
||||||
|
pdecrement(&(server->queue));
|
||||||
// cerr << "Received frag: " << out->id << endl;
|
// cerr << "Received frag: " << out->id << endl;
|
||||||
|
|
||||||
message *msg = new message(MSG_RECEIVE, (int)fragin);
|
message *msg = new message(MSG_RECEIVE, (int)fragin);
|
||||||
msg->result = (int)out;
|
msg->result = (int)out;
|
||||||
dispatcher->post(msg);
|
dispatcher->post(msg);
|
||||||
// dispatcher->ReceiveFragment(fragin, out);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Dispatcher::Init(const std::string &file) {
|
bool Dispatcher::Init(const std::string &file) {
|
||||||
|
@ -113,8 +118,11 @@ Server *Dispatcher::BestServer() {
|
||||||
Server *best = NULL;
|
Server *best = NULL;
|
||||||
for(unsigned int i = 0; i < servers.size(); i++){
|
for(unsigned int i = 0; i < servers.size(); i++){
|
||||||
if(servers[i]->connected) {
|
if(servers[i]->connected) {
|
||||||
if(!best || servers[i]->queue < best->queue) {
|
if((servers[i]->queue <= maxqueue) &&
|
||||||
|
(!best || servers[i]->queue < best->queue)) {
|
||||||
|
|
||||||
best = servers[i];
|
best = servers[i];
|
||||||
|
// cerr << "best: " << i << " queue: " << best->queue << endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -137,14 +145,14 @@ void Dispatcher::ReceiveFragment(Fragment *in, Fragment *out) {
|
||||||
|
|
||||||
void Dispatcher::msghandler(message &msg) {
|
void Dispatcher::msghandler(message &msg) {
|
||||||
switch(msg.id) {
|
switch(msg.id) {
|
||||||
case MSG_FAIL: break;
|
case MSG_FAIL:
|
||||||
case MSG_SEND: {
|
case MSG_SEND: {
|
||||||
//get server!
|
//get server!
|
||||||
Server *best = BestServer();
|
Server *best = BestServer();
|
||||||
Fragment *fragin = (Fragment *)(msg.param);
|
Fragment *fragin = (Fragment *)(msg.param);
|
||||||
|
|
||||||
if(!best) { //no server process locally....
|
if(!best) { //no server process locally....
|
||||||
// cerr << "No best!" << endl;
|
// cerr << "Local: " << fragin->id << endl;
|
||||||
vector<Point3f> newvert;
|
vector<Point3f> newvert;
|
||||||
vector<unsigned int> newface;
|
vector<unsigned int> newface;
|
||||||
vector<BigLink> newbord;
|
vector<BigLink> newbord;
|
||||||
|
@ -163,7 +171,9 @@ void Dispatcher::msghandler(message &msg) {
|
||||||
Split(*fragout, newvert, newface, newbord);
|
Split(*fragout, newvert, newface, newbord);
|
||||||
ReceiveFragment(fragin, fragout);
|
ReceiveFragment(fragin, fragout);
|
||||||
} else {
|
} else {
|
||||||
|
// cerr << "Server: " << fragin->id << endl;
|
||||||
FragIO *frag = new FragIO(best, this, fragin);
|
FragIO *frag = new FragIO(best, this, fragin);
|
||||||
|
if(msg.id == MSG_SEND)
|
||||||
assert(!frags.count(fragin->id));
|
assert(!frags.count(fragin->id));
|
||||||
frags[fragin->id] = frag;
|
frags[fragin->id] = frag;
|
||||||
frag->start();
|
frag->start();
|
||||||
|
|
|
@ -32,7 +32,7 @@ namespace nxs {
|
||||||
|
|
||||||
class Server: public pt::ipstream {
|
class Server: public pt::ipstream {
|
||||||
public:
|
public:
|
||||||
Server(pt::string host, int port): ipstream(host, port),
|
Server(pt::string host, int port): ipstream(host, port), queue(0),
|
||||||
connected(false), opener(this) {}
|
connected(false), opener(this) {}
|
||||||
|
|
||||||
int queue;
|
int queue;
|
||||||
|
@ -46,7 +46,7 @@ namespace nxs {
|
||||||
class Dispatcher: public pt::msgqueue {
|
class Dispatcher: public pt::msgqueue {
|
||||||
public:
|
public:
|
||||||
Dispatcher(Nexus *nx, VoronoiChain *ch):
|
Dispatcher(Nexus *nx, VoronoiChain *ch):
|
||||||
count(0), nexus(nx), chain(ch) {}
|
count(0), maxqueue(3), nexus(nx), chain(ch) {}
|
||||||
~Dispatcher();
|
~Dispatcher();
|
||||||
|
|
||||||
bool Init(const std::string &file);
|
bool Init(const std::string &file);
|
||||||
|
@ -57,6 +57,7 @@ namespace nxs {
|
||||||
void msghandler(pt::message &msg);
|
void msghandler(pt::message &msg);
|
||||||
|
|
||||||
int count;
|
int count;
|
||||||
|
int maxqueue;
|
||||||
Nexus *nexus;
|
Nexus *nexus;
|
||||||
VoronoiChain *chain;
|
VoronoiChain *chain;
|
||||||
std::vector<Server *> servers;
|
std::vector<Server *> servers;
|
||||||
|
|
|
@ -9,7 +9,6 @@ using namespace nxs;
|
||||||
using namespace vcg;
|
using namespace vcg;
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
const int port = 10102;
|
|
||||||
|
|
||||||
class FragOutQueue: public msgqueue {
|
class FragOutQueue: public msgqueue {
|
||||||
public:
|
public:
|
||||||
|
@ -33,6 +32,7 @@ public:
|
||||||
} catch (estream *e) {
|
} catch (estream *e) {
|
||||||
perr.putf("Error: %s\n", pconst(e->get_message()));
|
perr.putf("Error: %s\n", pconst(e->get_message()));
|
||||||
delete e;
|
delete e;
|
||||||
|
posturgent(MSG_QUIT);
|
||||||
}
|
}
|
||||||
delete (Fragment *)(msg.param);
|
delete (Fragment *)(msg.param);
|
||||||
}
|
}
|
||||||
|
@ -44,6 +44,8 @@ public:
|
||||||
FragInQueue(FragOutQueue &o): out(o) {}
|
FragInQueue(FragOutQueue &o): out(o) {}
|
||||||
void msghandler(message &msg) {
|
void msghandler(message &msg) {
|
||||||
if(msg.id != MSG_USER) {
|
if(msg.id != MSG_USER) {
|
||||||
|
if(msg.id == MSG_QUIT)
|
||||||
|
out.posturgent(MSG_QUIT);
|
||||||
defhandler(msg);
|
defhandler(msg);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -90,6 +92,7 @@ public:
|
||||||
Fragment &fragment = *(Fragment *)(msg->param);
|
Fragment &fragment = *(Fragment *)(msg->param);
|
||||||
if(!fragment.Read(&client)) {
|
if(!fragment.Read(&client)) {
|
||||||
pout.putf("Could not read!\n");
|
pout.putf("Could not read!\n");
|
||||||
|
queue.posturgent(MSG_QUIT);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
queue.post(msg);
|
queue.post(msg);
|
||||||
|
@ -128,13 +131,12 @@ public:
|
||||||
|
|
||||||
void servermain(ipstmserver& svr) {
|
void servermain(ipstmserver& svr) {
|
||||||
ipstream client;
|
ipstream client;
|
||||||
pout.putf("Ready to answer queries on port %d\n", port);
|
|
||||||
|
|
||||||
while(true) {
|
while(true) {
|
||||||
// serve() will wait for a connection request and will prepare
|
// serve() will wait for a connection request and will prepare
|
||||||
// the supplied ipstream object for talking to the peer.
|
// the supplied ipstream object for talking to the peer.
|
||||||
svr.serve(client);
|
svr.serve(client);
|
||||||
|
perr.putf("Serving clients!\n");
|
||||||
if (client.get_active()) {
|
if (client.get_active()) {
|
||||||
try {
|
try {
|
||||||
pout.putf("Incoming connection\n");
|
pout.putf("Incoming connection\n");
|
||||||
|
@ -159,16 +161,28 @@ void servermain(ipstmserver& svr) {
|
||||||
delete e;
|
delete e;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
perr.putf("Restarting\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int main() {
|
int main(int argc, char *argv[]) {
|
||||||
ipstmserver svr;
|
ipstmserver svr;
|
||||||
|
|
||||||
|
int port = 10102;
|
||||||
|
if(argc == 2) {
|
||||||
|
port = atoi(argv[1]);
|
||||||
|
if(port < 1024) {
|
||||||
|
perr.putf("Error: invalid port: %s\n", argv[1]);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// bind to all local addresses on port 8085
|
// bind to all local addresses on port 8085
|
||||||
svr.bindall(port);
|
svr.bindall(port);
|
||||||
|
|
||||||
|
pout.putf("Ready to answer queries on port %d\n", port);
|
||||||
|
|
||||||
// enter an infinite loop of serving requests
|
// enter an infinite loop of serving requests
|
||||||
servermain(svr);
|
servermain(svr);
|
||||||
} catch(estream* e) {
|
} catch(estream* e) {
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace nxs;
|
using namespace nxs;
|
||||||
|
using namespace pt;
|
||||||
|
|
||||||
|
|
||||||
bool PatchServer::Create(const std::string &filename,
|
bool PatchServer::Create(const std::string &filename,
|
||||||
|
@ -91,10 +92,15 @@ void PatchServer::AddPatch(unsigned short nvert, unsigned short nface) {
|
||||||
Patch &PatchServer::GetPatch(unsigned int idx,
|
Patch &PatchServer::GetPatch(unsigned int idx,
|
||||||
unsigned short nvert, unsigned short nface,
|
unsigned short nvert, unsigned short nface,
|
||||||
bool flush) {
|
bool flush) {
|
||||||
|
// ramlock.rdlock();
|
||||||
|
|
||||||
assert(idx < patches.size());
|
assert(idx < patches.size());
|
||||||
PatchEntry &entry = patches[idx];
|
PatchEntry &entry = patches[idx];
|
||||||
|
|
||||||
if(entry.lru_pos == 0xffffffff) { //not on buffer
|
if(entry.lru_pos == 0xffffffff) { //not on buffer
|
||||||
|
// scopewrite dlock(disklock);
|
||||||
|
|
||||||
|
if(entry.lru_pos == 0xffffffff) { //still not read!
|
||||||
if(flush) Flush();
|
if(flush) Flush();
|
||||||
PTime nptime(idx);
|
PTime nptime(idx);
|
||||||
|
|
||||||
|
@ -115,7 +121,6 @@ Patch &PatchServer::GetPatch(unsigned int idx,
|
||||||
if((signature & NXS_COMPRESSED) == 0) { //not compressed
|
if((signature & NXS_COMPRESSED) == 0) { //not compressed
|
||||||
ReadBuffer(ram, entry.disk_size * chunk_size);
|
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);
|
ReadBuffer(disk, entry.disk_size * chunk_size);
|
||||||
|
|
||||||
|
@ -124,27 +129,36 @@ Patch &PatchServer::GetPatch(unsigned int idx,
|
||||||
delete []disk;
|
delete []disk;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// ramlock.unlock();
|
||||||
|
// ramlock.wrlock();
|
||||||
entry.lru_pos = lru.size();
|
entry.lru_pos = lru.size();
|
||||||
lru.push_back(nptime);
|
lru.push_back(nptime);
|
||||||
ram_used += entry.ram_size;
|
ram_used += entry.ram_size;
|
||||||
ram_readed += entry.ram_size;
|
ram_readed += entry.ram_size;
|
||||||
|
// ramlock.unlock();
|
||||||
|
// ramlock.rdlock();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PTime &ptime = lru[entry.lru_pos];
|
PTime &ptime = lru[entry.lru_pos];
|
||||||
ptime.frame = frame++;
|
pexchange(&(ptime.frame), frame++);
|
||||||
|
|
||||||
|
// ramlock.unlock();
|
||||||
|
|
||||||
//avoid frame overflow!
|
//avoid frame overflow!
|
||||||
if(frame > (1<<30)) {
|
if(frame > (1<<29)) {
|
||||||
|
// ramlock.wrlock();
|
||||||
cerr << "oVERFLOW! (nothing dangerous... just warning." << endl;;
|
cerr << "oVERFLOW! (nothing dangerous... just warning." << endl;;
|
||||||
for(unsigned int i = 0; i < lru.size(); i++) {
|
for(unsigned int i = 0; i < lru.size(); i++) {
|
||||||
if(lru[i].frame < (1<<29)) lru[i].frame = 0;
|
if(lru[i].frame < (1<<28)) lru[i].frame = 0;
|
||||||
else lru[i].frame -= (1<<29);
|
else lru[i].frame -= (1<<28);
|
||||||
}
|
}
|
||||||
make_heap(lru.begin(), lru.end());
|
make_heap(lru.begin(), lru.end());
|
||||||
for(unsigned int i = 0; i < lru.size(); i++)
|
for(unsigned int i = 0; i < lru.size(); i++)
|
||||||
patches[lru[i].npatch].lru_pos = i;
|
patches[lru[i].npatch].lru_pos = i;
|
||||||
|
// ramlock.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
return *(ptime.patch);
|
return *(ptime.patch);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -191,6 +205,8 @@ void PatchServer::Flush() {
|
||||||
|
|
||||||
if(ram_used < ram_size * 1.1) return;
|
if(ram_used < ram_size * 1.1) return;
|
||||||
|
|
||||||
|
// ramlock.wrlock();
|
||||||
|
|
||||||
make_heap(lru.begin(), lru.end());
|
make_heap(lru.begin(), lru.end());
|
||||||
for(unsigned int i = 0; i < lru.size(); i++)
|
for(unsigned int i = 0; i < lru.size(); i++)
|
||||||
patches[lru[i].npatch].lru_pos = i;
|
patches[lru[i].npatch].lru_pos = i;
|
||||||
|
@ -203,6 +219,8 @@ void PatchServer::Flush() {
|
||||||
}
|
}
|
||||||
for(unsigned int i = 0; i < lru.size(); i++)
|
for(unsigned int i = 0; i < lru.size(); i++)
|
||||||
patches[lru[i].npatch].lru_pos = i;
|
patches[lru[i].npatch].lru_pos = i;
|
||||||
|
|
||||||
|
// ramlock.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
void PatchServer::FlushAll() {
|
void PatchServer::FlushAll() {
|
||||||
|
@ -215,6 +233,8 @@ void PatchServer::FlushAll() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void PatchServer::Flush(PTime &ptime) {
|
void PatchServer::Flush(PTime &ptime) {
|
||||||
|
|
||||||
|
|
||||||
PatchEntry &entry = patches[ptime.npatch];
|
PatchEntry &entry = patches[ptime.npatch];
|
||||||
assert(ptime.patch);
|
assert(ptime.patch);
|
||||||
if(!readonly) { //write back patch
|
if(!readonly) { //write back patch
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
#include "patch.h"
|
#include "patch.h"
|
||||||
#include "mfile.h"
|
#include "mfile.h"
|
||||||
|
#include <ptypes/pasync.h>
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
@ -20,7 +21,7 @@ class PatchServer: public MFile {
|
||||||
|
|
||||||
struct PTime {
|
struct PTime {
|
||||||
unsigned int npatch;
|
unsigned int npatch;
|
||||||
unsigned int frame;
|
int frame;
|
||||||
|
|
||||||
Patch *patch;
|
Patch *patch;
|
||||||
unsigned int vbo_array;
|
unsigned int vbo_array;
|
||||||
|
@ -44,12 +45,16 @@ class PatchServer: public MFile {
|
||||||
unsigned int vbo_used;
|
unsigned int vbo_used;
|
||||||
unsigned int frame;
|
unsigned int frame;
|
||||||
|
|
||||||
|
pt::rwlock ramlock; //read only thread safety...
|
||||||
|
pt::rwlock disklock; //read only thread safety...
|
||||||
|
|
||||||
//statistics:
|
//statistics:
|
||||||
unsigned int ram_readed;
|
unsigned int ram_readed;
|
||||||
unsigned int ram_flushed;
|
unsigned int ram_flushed;
|
||||||
|
|
||||||
|
|
||||||
PatchServer(): chunk_size(1024), ram_size(128000000), vbo_size(32000000) {}
|
PatchServer(): chunk_size(1024), ram_size(128000000),
|
||||||
|
ram_used(0), vbo_size(32000000) {}
|
||||||
bool Create(const std::string &filename, Signature signature,
|
bool Create(const std::string &filename, Signature signature,
|
||||||
unsigned int chunk_size, unsigned int ram_size = 128000000);
|
unsigned int chunk_size, unsigned int ram_size = 128000000);
|
||||||
bool Load(const std::string &filename, Signature sig,
|
bool Load(const std::string &filename, Signature sig,
|
||||||
|
|
|
@ -24,6 +24,9 @@
|
||||||
History
|
History
|
||||||
|
|
||||||
$Log: not supported by cvs2svn $
|
$Log: not supported by cvs2svn $
|
||||||
|
Revision 1.20 2004/11/18 18:30:14 ponchio
|
||||||
|
Using baricenters... lotsa changes.
|
||||||
|
|
||||||
Revision 1.19 2004/11/03 16:31:38 ponchio
|
Revision 1.19 2004/11/03 16:31:38 ponchio
|
||||||
Trying to fix big patches.
|
Trying to fix big patches.
|
||||||
|
|
||||||
|
@ -194,7 +197,6 @@ bool VoronoiChain::Optimize(int mean, VoronoiPartition &part,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cerr << "Join now!" << endl;
|
|
||||||
for(unsigned int i = 0; i < part.size(); i++) {
|
for(unsigned int i = 0; i < part.size(); i++) {
|
||||||
if(mark[i]) continue;
|
if(mark[i]) continue;
|
||||||
if(join && counts[i] < min_size) {
|
if(join && counts[i] < min_size) {
|
||||||
|
@ -232,9 +234,7 @@ bool VoronoiChain::Optimize(int mean, VoronoiPartition &part,
|
||||||
part.push_back(seeds[i]);
|
part.push_back(seeds[i]);
|
||||||
|
|
||||||
if(part.size() == 0) part.push_back(Point3f(0,0,0));
|
if(part.size() == 0) part.push_back(Point3f(0,0,0));
|
||||||
cerr << "Initing!\n";
|
|
||||||
part.Init();
|
part.Init();
|
||||||
cerr << "Inited!\n";
|
|
||||||
return failed == 0;
|
return failed == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,9 @@
|
||||||
History
|
History
|
||||||
|
|
||||||
$Log: not supported by cvs2svn $
|
$Log: not supported by cvs2svn $
|
||||||
|
Revision 1.22 2004/11/18 18:30:15 ponchio
|
||||||
|
Using baricenters... lotsa changes.
|
||||||
|
|
||||||
Revision 1.21 2004/11/03 16:31:38 ponchio
|
Revision 1.21 2004/11/03 16:31:38 ponchio
|
||||||
Trying to fix big patches.
|
Trying to fix big patches.
|
||||||
|
|
||||||
|
@ -111,6 +114,9 @@ using namespace std;
|
||||||
#include "nxsbuild.h"
|
#include "nxsbuild.h"
|
||||||
#include "watch.h"
|
#include "watch.h"
|
||||||
#include "nxsdispatcher.h"
|
#include "nxsdispatcher.h"
|
||||||
|
|
||||||
|
#include <ptypes/pasync.h>
|
||||||
|
|
||||||
using namespace vcg;
|
using namespace vcg;
|
||||||
using namespace nxs;
|
using namespace nxs;
|
||||||
|
|
||||||
|
@ -377,6 +383,7 @@ int main(int argc, char *argv[]) {
|
||||||
}
|
}
|
||||||
//TODO porcata!!!!
|
//TODO porcata!!!!
|
||||||
while(dispatcher.frags.size()) {
|
while(dispatcher.frags.size()) {
|
||||||
|
// cerr << "frags: " << dispatcher.frags.size() << endl;
|
||||||
dispatcher.processmsgs();
|
dispatcher.processmsgs();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -409,6 +416,8 @@ int main(int argc, char *argv[]) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pt::mutex nlock;
|
||||||
|
|
||||||
void BuildFragment(Nexus &nexus, VoronoiPartition &part,
|
void BuildFragment(Nexus &nexus, VoronoiPartition &part,
|
||||||
set<unsigned int> &patches,
|
set<unsigned int> &patches,
|
||||||
Fragment &fragment) {
|
Fragment &fragment) {
|
||||||
|
@ -422,16 +431,26 @@ void BuildFragment(Nexus &nexus, VoronoiPartition &part,
|
||||||
Patch &patch = nexus.GetPatch(*f);
|
Patch &patch = nexus.GetPatch(*f);
|
||||||
Border border = nexus.GetBorder(*f);
|
Border border = nexus.GetBorder(*f);
|
||||||
|
|
||||||
|
for(unsigned int k = 0; k < patch.nf; k++) {
|
||||||
|
assert(patch.Face(k)[0] != patch.Face(k)[1]);
|
||||||
|
assert(patch.Face(k)[0] != patch.Face(k)[2]);
|
||||||
|
assert(patch.Face(k)[1] != patch.Face(k)[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
nxs.vert.resize(patch.nv);
|
nxs.vert.resize(patch.nv);
|
||||||
nxs.face.resize(patch.nf * 3);
|
nxs.face.resize(patch.nf * 3);
|
||||||
memcpy(&*nxs.vert.begin(), patch.VertBegin(), patch.nv * sizeof(Point3f));
|
memcpy(&*nxs.vert.begin(), patch.VertBegin(), patch.nv * sizeof(Point3f));
|
||||||
memcpy(&*nxs.face.begin(), patch.FaceBegin(), patch.nf * 3*sizeof(short));
|
memcpy(&*nxs.face.begin(), patch.FaceBegin(), patch.nf * 3*sizeof(short));
|
||||||
for(unsigned int i = 0; i < border.Size(); i++) {
|
for(unsigned int i = 0; i < border.Size(); i++) {
|
||||||
Link &link = border[i];
|
Link &link = border[i];
|
||||||
if(!link.IsNull() && patch_levels[link.end_patch] == current_level-1)
|
if(!link.IsNull() &&
|
||||||
|
patch_levels[link.end_patch] == current_level-1) {
|
||||||
|
assert(link.end_patch != *f);
|
||||||
nxs.bord.push_back(link);
|
nxs.bord.push_back(link);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
set<unsigned int> seeds;
|
set<unsigned int> seeds;
|
||||||
vector<int> nears;
|
vector<int> nears;
|
||||||
|
@ -452,11 +471,11 @@ void BuildFragment(Nexus &nexus, VoronoiPartition &part,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void SaveFragment(Nexus &nexus, VoronoiChain &chain,
|
void SaveFragment(Nexus &nexus, VoronoiChain &chain,
|
||||||
Fragment &fragin,
|
Fragment &fragin,
|
||||||
Fragment &fragout) {
|
Fragment &fragout) {
|
||||||
|
|
||||||
|
|
||||||
set<unsigned int> orig_patches;
|
set<unsigned int> orig_patches;
|
||||||
|
|
||||||
Nexus::Update update;
|
Nexus::Update update;
|
||||||
|
@ -472,9 +491,11 @@ void SaveFragment(Nexus &nexus, VoronoiChain &chain,
|
||||||
for(unsigned int i = 0; i < fragout.pieces.size(); i++) {
|
for(unsigned int i = 0; i < fragout.pieces.size(); i++) {
|
||||||
NxsPatch &patch = fragout.pieces[i];
|
NxsPatch &patch = fragout.pieces[i];
|
||||||
//TODO detect best parameter below for bordersize...
|
//TODO detect best parameter below for bordersize...
|
||||||
|
unsigned int bordsize = 6 * patch.bord.size();
|
||||||
|
if(bordsize > 65500) bordsize = 65499;
|
||||||
unsigned int patch_idx = nexus.AddPatch(patch.vert.size(),
|
unsigned int patch_idx = nexus.AddPatch(patch.vert.size(),
|
||||||
patch.face.size()/3,
|
patch.face.size()/3,
|
||||||
6 * patch.bord.size());
|
bordsize);
|
||||||
patch_levels.push_back(current_level);
|
patch_levels.push_back(current_level);
|
||||||
Nexus::PatchInfo &entry = nexus.index[patch_idx];
|
Nexus::PatchInfo &entry = nexus.index[patch_idx];
|
||||||
entry.error = fragout.error;
|
entry.error = fragout.error;
|
||||||
|
@ -484,10 +505,20 @@ void SaveFragment(Nexus &nexus, VoronoiChain &chain,
|
||||||
update.created.push_back(patch_idx);
|
update.created.push_back(patch_idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//here i put for every patch all its new links.
|
||||||
|
map<unsigned int, set<Link> > newlinks;
|
||||||
|
|
||||||
for(unsigned int i = 0; i < fragout.pieces.size(); i++) {
|
for(unsigned int i = 0; i < fragout.pieces.size(); i++) {
|
||||||
NxsPatch &outpatch = fragout.pieces[i];
|
NxsPatch &outpatch = fragout.pieces[i];
|
||||||
unsigned int patch_idx = patch_remap[i];
|
unsigned int patch_idx = patch_remap[i];
|
||||||
|
|
||||||
|
for(unsigned int k = 0; k < outpatch.face.size(); k += 3) {
|
||||||
|
assert(k+2 < outpatch.face.size());
|
||||||
|
assert(outpatch.face[k] != outpatch.face[k+1]);
|
||||||
|
assert(outpatch.face[k] != outpatch.face[k+2]);
|
||||||
|
assert(outpatch.face[k+1] != outpatch.face[k+2]);
|
||||||
|
}
|
||||||
|
|
||||||
Patch &patch = nexus.GetPatch(patch_idx);
|
Patch &patch = nexus.GetPatch(patch_idx);
|
||||||
memcpy(patch.FaceBegin(), &outpatch.face[0],
|
memcpy(patch.FaceBegin(), &outpatch.face[0],
|
||||||
outpatch.face.size() * sizeof(unsigned short));
|
outpatch.face.size() * sizeof(unsigned short));
|
||||||
|
@ -500,80 +531,78 @@ void SaveFragment(Nexus &nexus, VoronoiChain &chain,
|
||||||
nexus.sphere.Add(outpatch.vert[v]);
|
nexus.sphere.Add(outpatch.vert[v]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
vector<Link> actual;
|
|
||||||
//remap internal borders
|
//remap internal borders
|
||||||
for(unsigned int i = 0; i < outpatch.bord.size(); i++) {
|
for(unsigned int k = 0; k < outpatch.bord.size(); k++) {
|
||||||
Link &link = outpatch.bord[i];
|
Link &link = outpatch.bord[k];
|
||||||
if(link.end_patch >= (1<<31)) { //internal
|
if(link.end_patch >= (1<<31)) { //internal
|
||||||
link.end_patch = patch_remap[link.end_patch - (1<<31)];
|
link.end_patch = patch_remap[link.end_patch - (1<<31)];
|
||||||
actual.push_back(link);
|
assert(link.end_patch != patch_remap[i]);
|
||||||
|
newlinks[patch_idx].insert(link);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//TODO not efficient!
|
//TODO not efficient!
|
||||||
//processing external borders
|
//processing external borders
|
||||||
for(unsigned int i = 0; i < outpatch.bord.size(); i++) {
|
for(unsigned int l = 0; l < outpatch.bord.size(); l++) {
|
||||||
Link &link = outpatch.bord[i];
|
Link &link = outpatch.bord[l];
|
||||||
if(link.end_patch >= (1<<31)) continue;
|
if(link.end_patch >= (1<<31)) continue;
|
||||||
|
|
||||||
unsigned short &start_vert = link.start_vert;
|
unsigned short &start_vert = link.start_vert;
|
||||||
unsigned int &start_patch = patch_idx;
|
unsigned int &start_patch = patch_idx;
|
||||||
|
|
||||||
|
//Adding vertical connection
|
||||||
|
newlinks[patch_idx].insert(link);
|
||||||
|
|
||||||
|
Link up(link.end_vert, link.start_vert, patch_idx);
|
||||||
|
newlinks[link.end_patch].insert(up);
|
||||||
|
|
||||||
Border cborder = nexus.GetBorder(link.end_patch);
|
Border cborder = nexus.GetBorder(link.end_patch);
|
||||||
for(unsigned int k = 0; k < cborder.Size(); k++) {
|
for(unsigned int k = 0; k < cborder.Size(); k++) {
|
||||||
|
|
||||||
Link &clink = cborder[k];
|
Link &clink = cborder[k];
|
||||||
|
assert(!clink.IsNull());
|
||||||
|
|
||||||
if(clink.start_vert != link.end_vert) continue;
|
if(clink.start_vert != link.end_vert) continue;
|
||||||
if(patch_levels[clink.end_patch] < current_level-1) continue;
|
if(patch_levels[clink.end_patch] < current_level-1) continue;
|
||||||
|
//boy i want only the external links!
|
||||||
|
if(orig_patches.count(clink.end_patch)) continue;
|
||||||
|
|
||||||
unsigned short &end_vert = clink.end_vert;
|
unsigned short &end_vert = clink.end_vert;
|
||||||
unsigned int &end_patch = clink.end_patch;
|
unsigned int &end_patch = clink.end_patch;
|
||||||
|
|
||||||
|
//TODO FIX THIS!!!!
|
||||||
|
assert(clink.end_patch != start_patch);
|
||||||
|
assert(clink.end_patch != link.end_patch);
|
||||||
|
|
||||||
Link newlink;
|
Link newlink;
|
||||||
|
|
||||||
newlink.start_vert = start_vert;
|
newlink.start_vert = start_vert;
|
||||||
newlink.end_vert = end_vert;
|
newlink.end_vert = end_vert;
|
||||||
newlink.end_patch = end_patch;
|
newlink.end_patch = end_patch;
|
||||||
|
|
||||||
actual.push_back(newlink);
|
newlinks[patch_idx].insert(newlink);
|
||||||
// nexus.AddBorder(start_patch, newlink);
|
|
||||||
|
|
||||||
newlink.start_vert = end_vert;
|
newlink.start_vert = end_vert;
|
||||||
newlink.end_vert = start_vert;
|
newlink.end_vert = start_vert;
|
||||||
newlink.end_patch = start_patch;
|
newlink.end_patch = start_patch;
|
||||||
|
|
||||||
nexus.AddBorder(end_patch, newlink);
|
newlinks[end_patch].insert(newlink);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Border rborder = nexus.GetBorder(clink.end_patch);
|
|
||||||
|
|
||||||
unsigned int pos = rborder.Size();
|
|
||||||
if(nexus.borders.ResizeBorder(link.end_patch, pos+1)) {
|
|
||||||
rborder = nexus.GetBorder(link.end_patch);
|
|
||||||
}
|
|
||||||
|
|
||||||
assert(rborder.Size() < rborder.Available());
|
|
||||||
assert(rborder.Available() > pos);
|
|
||||||
|
|
||||||
Link newlink;
|
|
||||||
newlink.start_vert = link.end_vert;
|
|
||||||
newlink.end_vert = link.start_vert;
|
|
||||||
newlink.end_patch = patch_idx;
|
|
||||||
rborder[pos] = newlink;*/
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Border border = nexus.GetBorder(patch_idx);
|
|
||||||
if(nexus.borders.ResizeBorder(patch_idx, actual.size())) {
|
|
||||||
border = nexus.GetBorder(patch_idx);
|
|
||||||
}
|
}
|
||||||
memcpy(&(border[0]), &(actual[0]),
|
map<unsigned int, set<Link> >::iterator n;
|
||||||
actual.size() * sizeof(Link));
|
for(n = newlinks.begin(); n != newlinks.end(); n++) {
|
||||||
/* assert(border.Available() >= outpatch.bord.size());
|
set<Link>::iterator l;
|
||||||
if(nexus.borders.ResizeBorder(patch_idx, outpatch.bord.size())) {
|
unsigned int patch = (*n).first;
|
||||||
border = nexus.GetBorder(patch_idx);
|
set<Link> &links = (*n).second;
|
||||||
|
Border border = nexus.GetBorder(patch);
|
||||||
|
unsigned int bstart = border.Size();
|
||||||
|
|
||||||
|
if(nexus.borders.ResizeBorder(patch, border.Size() + links.size()))
|
||||||
|
border = nexus.GetBorder(patch);
|
||||||
|
for(l = links.begin(); l != links.end(); l++) {
|
||||||
|
Link link = *l;
|
||||||
|
border[bstart++] = link;
|
||||||
}
|
}
|
||||||
memcpy(&(border[0]), &(outpatch.bord[0]),
|
|
||||||
outpatch.bord.size() * sizeof(Link)); */
|
|
||||||
}
|
}
|
||||||
nexus.history.push_back(update);
|
nexus.history.push_back(update);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue