Fixing borders... let's hope.

This commit is contained in:
Federico Ponchio 2004-11-28 01:23:26 +00:00
parent b5553ec6ca
commit a8e2df5d3c
16 changed files with 322 additions and 142 deletions

View File

@ -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);

View File

@ -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;

View File

@ -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;
}*/
}
}

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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);

View File

@ -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);

View File

@ -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;

View File

@ -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();
}

View File

@ -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;

View File

@ -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);

View File

@ -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

View File

@ -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,

View File

@ -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;
}

View File

@ -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);
}