From a8e2df5d3cfb53870d3ca5ec6e3509857c9ff242 Mon Sep 17 00:00:00 2001 From: ponchio Date: Sun, 28 Nov 2004 01:23:26 +0000 Subject: [PATCH] Fixing borders... let's hope. --- apps/nexus/borderserver.cpp | 4 +- apps/nexus/exploder.cpp | 1 + apps/nexus/fragment.cpp | 37 ++++++++++-- apps/nexus/mfile.cpp | 53 ++++++++-------- apps/nexus/mfile.h | 2 +- apps/nexus/nexus.cpp | 5 +- apps/nexus/nexusmt.cpp | 54 +++++++++++++++-- apps/nexus/nexusmt.h | 24 +++++++- apps/nexus/nexusview.cpp | 5 +- apps/nexus/nxsdispatcher.cpp | 32 ++++++---- apps/nexus/nxsdispatcher.h | 5 +- apps/nexus/nxsserver.cpp | 24 ++++++-- apps/nexus/patchserver.cpp | 90 +++++++++++++++++----------- apps/nexus/patchserver.h | 9 ++- apps/nexus/voronoichain.cpp | 6 +- apps/nexus/voronoinxs.cpp | 113 ++++++++++++++++++++++------------- 16 files changed, 322 insertions(+), 142 deletions(-) diff --git a/apps/nexus/borderserver.cpp b/apps/nexus/borderserver.cpp index 7a9203f3..a81b5826 100644 --- a/apps/nexus/borderserver.cpp +++ b/apps/nexus/borderserver.cpp @@ -21,13 +21,15 @@ Border BorderServer::GetBorder(unsigned int border, bool flush) { } bool BorderServer::ResizeBorder(unsigned int border, unsigned int nbord) { - + assert(nbord < 65500); assert(border < borders.size()); BorderEntry &entry = borders[border]; if(nbord > entry.border_size) { int capacity = nbord; if(capacity < entry.border_size*2) capacity = entry.border_size * 2; + if(capacity > 65500) + capacity = 65500; unsigned int newstart = Size(); Resize(newstart + capacity); diff --git a/apps/nexus/exploder.cpp b/apps/nexus/exploder.cpp index e15b3a77..b5126591 100644 --- a/apps/nexus/exploder.cpp +++ b/apps/nexus/exploder.cpp @@ -32,6 +32,7 @@ int main(int argc, char *argv[]) { cerr << "Could not load nexus: " << input << endl; return -1; } + Nexus out; if(!out.Create(output, in.signature, in.chunk_size)) { cerr << "Could not create nexus: " << output << endl; diff --git a/apps/nexus/fragment.cpp b/apps/nexus/fragment.cpp index a80ab0ba..1efdd29e 100644 --- a/apps/nexus/fragment.cpp +++ b/apps/nexus/fragment.cpp @@ -121,6 +121,12 @@ void nxs::Join(Fragment &in, vector &face = in.pieces[i].face; vector &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; 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 unsigned int idx = patch_remap[link.end_patch]; + assert(link.end_patch != in.pieces[i].patch); unsigned int extoffset = offsets[idx]; assert(extoffset + link.end_vert < remap.size()); @@ -187,9 +194,23 @@ void nxs::Join(Fragment &in, } } set::iterator b; - for(b = newborders.begin(); b != newborders.end(); b++) - newbord.push_back(*b); + for(b = newborders.begin(); b != newborders.end(); 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) @@ -371,10 +392,12 @@ void nxs::Split(Fragment &out, //borders last vector &bords = patch.bord; - //process external borders - //for every esternal link we must update external patches! + //process downward borders for(unsigned int i = 0; i < newbord.size(); 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; Link llink; 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; + }*/ } } diff --git a/apps/nexus/mfile.cpp b/apps/nexus/mfile.cpp index 50c55bf3..c68921f2 100644 --- a/apps/nexus/mfile.cpp +++ b/apps/nexus/mfile.cpp @@ -6,8 +6,8 @@ using namespace std; using namespace nxs; bool MFile::Create(const string &fname, unsigned int mxs) { + Close(); filename = fname; - files.clear(); size = 0; readonly = false; 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) { + Close(); filename = fname; - files.clear(); readonly = ronly; max_size = MFILE_MAX_SIZE; size = 0; while(1) { string name = Name(files.size()); - files.push_back(File()); - File &file = files.back(); - if(!file.Load(name, ronly)) { + File *file = new File; + files.push_back(file); + if(!file->Load(name, ronly)) { files.pop_back(); break; } - size += file.Length(); + size += file->Length(); } if(files.size() == 0) return false; if(files.size() == 1) { @@ -38,17 +38,19 @@ bool MFile::Load(const string &fname, bool ronly) { } else { //SANITY TEST 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"; return false; } - max_size = files[0].Length(); + max_size = files[0]->Length(); } } return true; } void MFile::Close() { + for(unsigned int i = 0; i < files.size(); i++) + delete files[i]; files.clear(); } @@ -69,13 +71,13 @@ void MFile::Redim(int64 sz) { } assert(size <= sz); assert(sz - size < max_size); - assert(files.back().Length() + (unsigned int)(sz - size) < max_size); - RedimLast(files.back().Length() + (unsigned int)(sz - size)); + assert(files.back()->Length() + (unsigned int)(sz - size) < max_size); + RedimLast(files.back()->Length() + (unsigned int)(sz - size)); } else { - while(size - files.back().Length() > sz) + while(size - files.back()->Length() > sz) RemoveFile(); assert(sz <= size); - RedimLast(files.back().Length() - (unsigned int)(size - sz)); + 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); assert(curr_pos < max_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) { while(sz + curr_pos > max_size) { unsigned int n = max_size - curr_pos; - files[curr_fp].ReadBuffer(data, n); + files[curr_fp]->ReadBuffer(data, n); data = ((char *)data) + n; sz -= n; curr_fp++; 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) { assert(!readonly); while(sz + curr_pos > max_size) { unsigned int n = max_size - curr_pos; - files[curr_fp].WriteBuffer(data, n); + files[curr_fp]->WriteBuffer(data, n); data = ((char *)data) + n; sz -= n; curr_fp++; 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() { string name = Name(files.size()); - files.push_back(File()); - File &file = files.back(); - return file.Create(name); + File *file = new File; + files.push_back(file); + return file->Create(name); } void MFile::RemoveFile() { assert(files.size()); string name = Name(files.size()-1); - File &file = files.back(); - unsigned int last_size = file.Length(); + File *file = files.back(); + unsigned int last_size = file->Length(); + delete file; files.pop_back(); size -= last_size; cerr << "Removing file: " << name << endl; @@ -140,7 +143,7 @@ void MFile::WriteBuffer(void *data, unsigned int sz) { void MFile::RedimLast(unsigned int sz) { assert(sz <= max_size); - File &file = files.back(); + File &file = *files.back(); unsigned int last_size = file.Length(); file.Redim(sz); size += sz - last_size; diff --git a/apps/nexus/mfile.h b/apps/nexus/mfile.h index 12d2408d..d84f2034 100644 --- a/apps/nexus/mfile.h +++ b/apps/nexus/mfile.h @@ -40,7 +40,7 @@ class MFile { protected: std::string filename; - std::vector files; + std::vector files; unsigned int curr_pos; unsigned int curr_fp; int64 size; diff --git a/apps/nexus/nexus.cpp b/apps/nexus/nexus.cpp index a187c1c1..f991c76a 100644 --- a/apps/nexus/nexus.cpp +++ b/apps/nexus/nexus.cpp @@ -151,11 +151,14 @@ void Nexus::AddBorder(unsigned int patch, Link &link) { Border border = GetBorder(patch); unsigned int pos = border.Size(); + if(pos > 65500) { + cerr << "Exceding border size!!!\n"; + exit(0); + } if(borders.ResizeBorder(patch, pos+1)) { border = GetBorder(patch); } - assert(border.Size() < border.Available()); assert(border.Available() > pos); border[pos] = link; diff --git a/apps/nexus/nexusmt.cpp b/apps/nexus/nexusmt.cpp index 6ed3760a..c0517717 100644 --- a/apps/nexus/nexusmt.cpp +++ b/apps/nexus/nexusmt.cpp @@ -77,10 +77,6 @@ void Policy::NodeVisited(Node *node) { assert(!(node->out[i]->visited)); Frag &frag = node->frags[i]; 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]]; 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), - metric(NULL), mode(SMOOTH) { + metric(NULL), mode(SMOOTH), prefetching(true) { metric = new FrustumMetric(); metric->index = &index; policy.error = 4; policy.ram_size = 64000000; + + prefetch.nexus = this; } NexusMt::~NexusMt() {} @@ -127,7 +152,8 @@ bool NexusMt::Load(const string &filename, bool readonly) { SetComponent(NORMAL, true); SetComponent(TEXTURE, true); SetComponent(DATA, true); - + + SetPrefetching(prefetching); return true; } @@ -272,6 +298,19 @@ void NexusMt::SetVboSize(unsigned int _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) { mode = _mode; return true; @@ -308,6 +347,9 @@ bool NexusMt::SetComponents(unsigned int mask) { 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() { //The last update erases everything. assert(history[0].erased.size() == 0); diff --git a/apps/nexus/nexusmt.h b/apps/nexus/nexusmt.h index 9e782a52..c7cb6e0f 100644 --- a/apps/nexus/nexusmt.h +++ b/apps/nexus/nexusmt.h @@ -5,7 +5,7 @@ #include "nexus.h" #include #include - +#include #include @@ -73,10 +73,25 @@ namespace nxs { void NodeVisited(Node *node); }; +class Prefetch: public pt::thread { + public: + Prefetch(); + ~Prefetch(); + void execute(); + void cleanup() {} + + bool Running() { return get_running(); } + + std::vector cells; + pt::mutex cells_mx; + pt::mutex patch_mx; + Nexus *nexus; +}; + class NexusMt: public Nexus { private: std::vector nodes; - + Prefetch prefetch; public: //Vertex buffer object mode enum Vbo { VBO_AUTO, //autodetect best size @@ -84,7 +99,7 @@ class NexusMt: public Nexus { VBO_FIXED }; //user supplied size enum MetricKind { FRUSTUM, //screen error extraction - GEOMETRY, //geometry error extraction + GEOMETRY, //geometry error extraction DELTA }; //delta error enum Mode { POINTS, @@ -106,6 +121,7 @@ class NexusMt: public Nexus { Policy policy; Mode mode; + bool prefetching; unsigned int components; bool use_normals; @@ -130,6 +146,8 @@ class NexusMt: public Nexus { void SetRamExtractionSize(unsigned int ram_size); void SetVboSize(unsigned int vbo_size); + void SetPrefetching(bool on); + bool SetMode(Mode mode); bool SetComponent(Component c, bool on); bool SetComponents(unsigned int mask); diff --git a/apps/nexus/nexusview.cpp b/apps/nexus/nexusview.cpp index 8d5a4b48..fbb25957 100644 --- a/apps/nexus/nexusview.cpp +++ b/apps/nexus/nexusview.cpp @@ -24,6 +24,9 @@ History $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 Fixed big patches problem. @@ -214,7 +217,7 @@ int main(int argc, char *argv[]) { Watch watch; bool rotate = false; - bool show_borders = true; + bool show_borders = false; bool show_colors = true; bool show_normals = true; bool show_statistics = true; diff --git a/apps/nexus/nxsdispatcher.cpp b/apps/nexus/nxsdispatcher.cpp index 0cd4d145..07a8bfe0 100644 --- a/apps/nexus/nxsdispatcher.cpp +++ b/apps/nexus/nxsdispatcher.cpp @@ -23,6 +23,7 @@ void Opener::execute() { try { server->open(); server->connected = true; + server->queue = 0; break; } catch(...) { } @@ -33,7 +34,7 @@ void Opener::execute() { } void FragIO::execute() { - + pincrement(&(server->queue)); server->writing.lock(); // cerr << "Writing frag...: " << fragin->id << "\n"; @@ -45,12 +46,13 @@ void FragIO::execute() { server->write((const char *)a, length(a)); server->flush(); } catch (estream *e) { - perr.putf("Error: %s\n", pconst(e->get_message())); + perr.putf("Error reading: %s\n", pconst(e->get_message())); delete e; - + server->close(); + server->connected = false; + server->writing.unlock(); message *msg = new message(MSG_FAIL, (int)fragin); dispatcher->post(msg); - //TODO restart Server! return; } @@ -59,19 +61,22 @@ void FragIO::execute() { server->writing.unlock(); 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); dispatcher->post(msg); return; } server->reading.unlock(); - + pdecrement(&(server->queue)); // cerr << "Received frag: " << out->id << endl; message *msg = new message(MSG_RECEIVE, (int)fragin); msg->result = (int)out; dispatcher->post(msg); - // dispatcher->ReceiveFragment(fragin, out); } bool Dispatcher::Init(const std::string &file) { @@ -113,8 +118,11 @@ Server *Dispatcher::BestServer() { Server *best = NULL; for(unsigned int i = 0; i < servers.size(); i++){ 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]; + // cerr << "best: " << i << " queue: " << best->queue << endl; } } } @@ -137,14 +145,14 @@ void Dispatcher::ReceiveFragment(Fragment *in, Fragment *out) { void Dispatcher::msghandler(message &msg) { switch(msg.id) { - case MSG_FAIL: break; + case MSG_FAIL: case MSG_SEND: { //get server! Server *best = BestServer(); Fragment *fragin = (Fragment *)(msg.param); if(!best) { //no server process locally.... - // cerr << "No best!" << endl; + // cerr << "Local: " << fragin->id << endl; vector newvert; vector newface; vector newbord; @@ -163,8 +171,10 @@ void Dispatcher::msghandler(message &msg) { Split(*fragout, newvert, newface, newbord); ReceiveFragment(fragin, fragout); } else { + // cerr << "Server: " << fragin->id << endl; FragIO *frag = new FragIO(best, this, fragin); - assert(!frags.count(fragin->id)); + if(msg.id == MSG_SEND) + assert(!frags.count(fragin->id)); frags[fragin->id] = frag; frag->start(); } diff --git a/apps/nexus/nxsdispatcher.h b/apps/nexus/nxsdispatcher.h index 11e90995..e09763bb 100644 --- a/apps/nexus/nxsdispatcher.h +++ b/apps/nexus/nxsdispatcher.h @@ -32,7 +32,7 @@ namespace nxs { class Server: public pt::ipstream { 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) {} int queue; @@ -46,7 +46,7 @@ namespace nxs { class Dispatcher: public pt::msgqueue { public: Dispatcher(Nexus *nx, VoronoiChain *ch): - count(0), nexus(nx), chain(ch) {} + count(0), maxqueue(3), nexus(nx), chain(ch) {} ~Dispatcher(); bool Init(const std::string &file); @@ -57,6 +57,7 @@ namespace nxs { void msghandler(pt::message &msg); int count; + int maxqueue; Nexus *nexus; VoronoiChain *chain; std::vector servers; diff --git a/apps/nexus/nxsserver.cpp b/apps/nexus/nxsserver.cpp index f34400c8..330a1188 100644 --- a/apps/nexus/nxsserver.cpp +++ b/apps/nexus/nxsserver.cpp @@ -9,7 +9,6 @@ using namespace nxs; using namespace vcg; using namespace std; -const int port = 10102; class FragOutQueue: public msgqueue { public: @@ -33,6 +32,7 @@ public: } catch (estream *e) { perr.putf("Error: %s\n", pconst(e->get_message())); delete e; + posturgent(MSG_QUIT); } delete (Fragment *)(msg.param); } @@ -44,6 +44,8 @@ public: FragInQueue(FragOutQueue &o): out(o) {} void msghandler(message &msg) { if(msg.id != MSG_USER) { + if(msg.id == MSG_QUIT) + out.posturgent(MSG_QUIT); defhandler(msg); return; } @@ -90,6 +92,7 @@ public: Fragment &fragment = *(Fragment *)(msg->param); if(!fragment.Read(&client)) { pout.putf("Could not read!\n"); + queue.posturgent(MSG_QUIT); return; } queue.post(msg); @@ -128,13 +131,12 @@ public: void servermain(ipstmserver& svr) { ipstream client; - pout.putf("Ready to answer queries on port %d\n", port); while(true) { // serve() will wait for a connection request and will prepare // the supplied ipstream object for talking to the peer. svr.serve(client); - + perr.putf("Serving clients!\n"); if (client.get_active()) { try { pout.putf("Incoming connection\n"); @@ -159,15 +161,27 @@ void servermain(ipstmserver& svr) { delete e; } } + perr.putf("Restarting\n"); } } -int main() { +int main(int argc, char *argv[]) { 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 { // bind to all local addresses on port 8085 svr.bindall(port); + + pout.putf("Ready to answer queries on port %d\n", port); // enter an infinite loop of serving requests servermain(svr); diff --git a/apps/nexus/patchserver.cpp b/apps/nexus/patchserver.cpp index 0d7f4032..892c29e7 100644 --- a/apps/nexus/patchserver.cpp +++ b/apps/nexus/patchserver.cpp @@ -6,6 +6,7 @@ using namespace std; using namespace nxs; +using namespace pt; bool PatchServer::Create(const std::string &filename, @@ -91,60 +92,73 @@ void PatchServer::AddPatch(unsigned short nvert, unsigned short nface) { Patch &PatchServer::GetPatch(unsigned int idx, unsigned short nvert, unsigned short nface, bool flush) { + // ramlock.rdlock(); + assert(idx < patches.size()); PatchEntry &entry = patches[idx]; if(entry.lru_pos == 0xffffffff) { //not on buffer - if(flush) Flush(); - PTime nptime(idx); + // scopewrite dlock(disklock); - char *ram = new char[entry.ram_size * chunk_size]; + if(entry.lru_pos == 0xffffffff) { //still not read! + if(flush) Flush(); + PTime nptime(idx); + + char *ram = new char[entry.ram_size * chunk_size]; #ifdef CONTROLS - if(!ram) { - cerr << "COuld not allocate ram!\n"; - exit(0); - } + if(!ram) { + cerr << "COuld not allocate ram!\n"; + exit(0); + } #endif - nptime.patch = new Patch(signature, ram, nvert, nface); - - if(entry.patch_start != 0xffffffff) { //was allocated. - assert(entry.disk_size != 0xffff); - - SetPosition(entry.patch_start * chunk_size); - - if((signature & NXS_COMPRESSED) == 0) { //not compressed - ReadBuffer(ram, entry.disk_size * chunk_size); - } else { - - unsigned char *disk = new unsigned char[entry.disk_size * chunk_size]; - ReadBuffer(disk, entry.disk_size * chunk_size); - - nptime.patch->Decompress(entry.ram_size * chunk_size, - disk, entry.disk_size * chunk_size); - delete []disk; - } + nptime.patch = new Patch(signature, ram, nvert, nface); + + if(entry.patch_start != 0xffffffff) { //was allocated. + assert(entry.disk_size != 0xffff); + + SetPosition(entry.patch_start * chunk_size); + + if((signature & NXS_COMPRESSED) == 0) { //not compressed + ReadBuffer(ram, entry.disk_size * chunk_size); + } else { + unsigned char *disk = new unsigned char[entry.disk_size * chunk_size]; + ReadBuffer(disk, entry.disk_size * chunk_size); + + nptime.patch->Decompress(entry.ram_size * chunk_size, + disk, entry.disk_size * chunk_size); + delete []disk; + } + } + // ramlock.unlock(); + // ramlock.wrlock(); + entry.lru_pos = lru.size(); + lru.push_back(nptime); + ram_used += entry.ram_size; + ram_readed += entry.ram_size; + // ramlock.unlock(); + // ramlock.rdlock(); } - - entry.lru_pos = lru.size(); - lru.push_back(nptime); - ram_used += entry.ram_size; - ram_readed += entry.ram_size; } PTime &ptime = lru[entry.lru_pos]; - ptime.frame = frame++; - + pexchange(&(ptime.frame), frame++); + + // ramlock.unlock(); + //avoid frame overflow! - if(frame > (1<<30)) { + if(frame > (1<<29)) { + // ramlock.wrlock(); cerr << "oVERFLOW! (nothing dangerous... just warning." << endl;; for(unsigned int i = 0; i < lru.size(); i++) { - if(lru[i].frame < (1<<29)) lru[i].frame = 0; - else lru[i].frame -= (1<<29); + if(lru[i].frame < (1<<28)) lru[i].frame = 0; + else lru[i].frame -= (1<<28); } make_heap(lru.begin(), lru.end()); for(unsigned int i = 0; i < lru.size(); i++) patches[lru[i].npatch].lru_pos = i; + // ramlock.unlock(); } + return *(ptime.patch); } @@ -191,6 +205,8 @@ void PatchServer::Flush() { if(ram_used < ram_size * 1.1) return; + // ramlock.wrlock(); + make_heap(lru.begin(), lru.end()); for(unsigned int i = 0; i < lru.size(); i++) patches[lru[i].npatch].lru_pos = i; @@ -203,6 +219,8 @@ void PatchServer::Flush() { } for(unsigned int i = 0; i < lru.size(); i++) patches[lru[i].npatch].lru_pos = i; + + // ramlock.unlock(); } void PatchServer::FlushAll() { @@ -215,6 +233,8 @@ void PatchServer::FlushAll() { } void PatchServer::Flush(PTime &ptime) { + + PatchEntry &entry = patches[ptime.npatch]; assert(ptime.patch); if(!readonly) { //write back patch diff --git a/apps/nexus/patchserver.h b/apps/nexus/patchserver.h index a039d6f6..9f3f4c3a 100644 --- a/apps/nexus/patchserver.h +++ b/apps/nexus/patchserver.h @@ -3,6 +3,7 @@ #include "patch.h" #include "mfile.h" +#include #include @@ -20,7 +21,7 @@ class PatchServer: public MFile { struct PTime { unsigned int npatch; - unsigned int frame; + int frame; Patch *patch; unsigned int vbo_array; @@ -44,12 +45,16 @@ class PatchServer: public MFile { unsigned int vbo_used; unsigned int frame; + pt::rwlock ramlock; //read only thread safety... + pt::rwlock disklock; //read only thread safety... + //statistics: unsigned int ram_readed; 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, unsigned int chunk_size, unsigned int ram_size = 128000000); bool Load(const std::string &filename, Signature sig, diff --git a/apps/nexus/voronoichain.cpp b/apps/nexus/voronoichain.cpp index b3e02a08..10bb30d8 100644 --- a/apps/nexus/voronoichain.cpp +++ b/apps/nexus/voronoichain.cpp @@ -24,6 +24,9 @@ History $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 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++) { if(mark[i]) continue; if(join && counts[i] < min_size) { @@ -232,9 +234,7 @@ bool VoronoiChain::Optimize(int mean, VoronoiPartition &part, part.push_back(seeds[i]); if(part.size() == 0) part.push_back(Point3f(0,0,0)); - cerr << "Initing!\n"; part.Init(); - cerr << "Inited!\n"; return failed == 0; } diff --git a/apps/nexus/voronoinxs.cpp b/apps/nexus/voronoinxs.cpp index 98b8192d..e3957747 100644 --- a/apps/nexus/voronoinxs.cpp +++ b/apps/nexus/voronoinxs.cpp @@ -24,6 +24,9 @@ History $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 Trying to fix big patches. @@ -111,6 +114,9 @@ using namespace std; #include "nxsbuild.h" #include "watch.h" #include "nxsdispatcher.h" + +#include + using namespace vcg; using namespace nxs; @@ -377,6 +383,7 @@ int main(int argc, char *argv[]) { } //TODO porcata!!!! while(dispatcher.frags.size()) { + // cerr << "frags: " << dispatcher.frags.size() << endl; dispatcher.processmsgs(); } @@ -409,6 +416,8 @@ int main(int argc, char *argv[]) { return 0; } +pt::mutex nlock; + void BuildFragment(Nexus &nexus, VoronoiPartition &part, set &patches, Fragment &fragment) { @@ -422,14 +431,24 @@ void BuildFragment(Nexus &nexus, VoronoiPartition &part, Patch &patch = nexus.GetPatch(*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.face.resize(patch.nf * 3); memcpy(&*nxs.vert.begin(), patch.VertBegin(), patch.nv * sizeof(Point3f)); memcpy(&*nxs.face.begin(), patch.FaceBegin(), patch.nf * 3*sizeof(short)); for(unsigned int i = 0; i < border.Size(); 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); + } } } @@ -452,11 +471,11 @@ void BuildFragment(Nexus &nexus, VoronoiPartition &part, } + void SaveFragment(Nexus &nexus, VoronoiChain &chain, Fragment &fragin, Fragment &fragout) { - set orig_patches; Nexus::Update update; @@ -472,9 +491,11 @@ void SaveFragment(Nexus &nexus, VoronoiChain &chain, for(unsigned int i = 0; i < fragout.pieces.size(); i++) { NxsPatch &patch = fragout.pieces[i]; //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(), patch.face.size()/3, - 6 * patch.bord.size()); + bordsize); patch_levels.push_back(current_level); Nexus::PatchInfo &entry = nexus.index[patch_idx]; entry.error = fragout.error; @@ -483,11 +504,21 @@ void SaveFragment(Nexus &nexus, VoronoiChain &chain, chain.newfragments[patch.patch].insert(patch_idx); update.created.push_back(patch_idx); } + + //here i put for every patch all its new links. + map > newlinks; for(unsigned int i = 0; i < fragout.pieces.size(); i++) { NxsPatch &outpatch = fragout.pieces[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); memcpy(patch.FaceBegin(), &outpatch.face[0], outpatch.face.size() * sizeof(unsigned short)); @@ -500,33 +531,47 @@ void SaveFragment(Nexus &nexus, VoronoiChain &chain, nexus.sphere.Add(outpatch.vert[v]); } - - vector actual; //remap internal borders - for(unsigned int i = 0; i < outpatch.bord.size(); i++) { - Link &link = outpatch.bord[i]; + for(unsigned int k = 0; k < outpatch.bord.size(); k++) { + Link &link = outpatch.bord[k]; if(link.end_patch >= (1<<31)) { //internal 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! //processing external borders - for(unsigned int i = 0; i < outpatch.bord.size(); i++) { - Link &link = outpatch.bord[i]; + for(unsigned int l = 0; l < outpatch.bord.size(); l++) { + Link &link = outpatch.bord[l]; if(link.end_patch >= (1<<31)) continue; unsigned short &start_vert = link.start_vert; 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); for(unsigned int k = 0; k < cborder.Size(); k++) { + Link &clink = cborder[k]; + assert(!clink.IsNull()); + if(clink.start_vert != link.end_vert) 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 int &end_patch = clink.end_patch; + + //TODO FIX THIS!!!! + assert(clink.end_patch != start_patch); + assert(clink.end_patch != link.end_patch); Link newlink; @@ -534,46 +579,30 @@ void SaveFragment(Nexus &nexus, VoronoiChain &chain, newlink.end_vert = end_vert; newlink.end_patch = end_patch; - actual.push_back(newlink); - // nexus.AddBorder(start_patch, newlink); + newlinks[patch_idx].insert(newlink); newlink.start_vert = end_vert; newlink.end_vert = start_vert; newlink.end_patch = start_patch; - nexus.AddBorder(end_patch, 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;*/ + newlinks[end_patch].insert(newlink); } } - Border border = nexus.GetBorder(patch_idx); - if(nexus.borders.ResizeBorder(patch_idx, actual.size())) { - border = nexus.GetBorder(patch_idx); + } + map >::iterator n; + for(n = newlinks.begin(); n != newlinks.end(); n++) { + set::iterator l; + unsigned int patch = (*n).first; + set &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]), &(actual[0]), - actual.size() * sizeof(Link)); - /* assert(border.Available() >= outpatch.bord.size()); - if(nexus.borders.ResizeBorder(patch_idx, outpatch.bord.size())) { - border = nexus.GetBorder(patch_idx); - } - memcpy(&(border[0]), &(outpatch.bord[0]), - outpatch.bord.size() * sizeof(Link)); */ } nexus.history.push_back(update); }