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) {
|
||||
|
||||
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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -121,6 +121,12 @@ void nxs::Join(Fragment &in,
|
|||
vector<unsigned short> &face = in.pieces[i].face;
|
||||
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;
|
||||
|
||||
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<BigLink>::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<Link> &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;
|
||||
}*/
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -40,7 +40,7 @@ class MFile {
|
|||
|
||||
protected:
|
||||
std::string filename;
|
||||
std::vector<File> files;
|
||||
std::vector<File *> files;
|
||||
unsigned int curr_pos;
|
||||
unsigned int curr_fp;
|
||||
int64 size;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
#include "nexus.h"
|
||||
#include <vector>
|
||||
#include <queue>
|
||||
|
||||
#include <ptypes/pasync.h>
|
||||
#include <wrap/gui/frustum.h>
|
||||
|
||||
|
||||
|
@ -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<unsigned int> cells;
|
||||
pt::mutex cells_mx;
|
||||
pt::mutex patch_mx;
|
||||
Nexus *nexus;
|
||||
};
|
||||
|
||||
class NexusMt: public Nexus {
|
||||
private:
|
||||
std::vector<Node> 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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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<Point3f> newvert;
|
||||
vector<unsigned int> newface;
|
||||
vector<BigLink> 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();
|
||||
}
|
||||
|
|
|
@ -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<Server *> servers;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
#include "patch.h"
|
||||
#include "mfile.h"
|
||||
#include <ptypes/pasync.h>
|
||||
|
||||
#include <vector>
|
||||
|
||||
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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 <ptypes/pasync.h>
|
||||
|
||||
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<unsigned int> &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<unsigned int> 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<unsigned int, set<Link> > 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<Link> 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<unsigned int, set<Link> >::iterator n;
|
||||
for(n = newlinks.begin(); n != newlinks.end(); n++) {
|
||||
set<Link>::iterator l;
|
||||
unsigned int patch = (*n).first;
|
||||
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]), &(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);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue