Using baricenters... lotsa changes.
This commit is contained in:
parent
b23413ecb2
commit
75c9f2e194
|
@ -0,0 +1,107 @@
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#include "nexus.h"
|
||||||
|
|
||||||
|
using namespace nxs;
|
||||||
|
using namespace vcg;
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
Point3f explode(Point3f &v, Point3f ¢er, Point3f &dir, float mag) {
|
||||||
|
v = ((v - center) * mag + center) + dir;
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char *argv[]) {
|
||||||
|
if(argc < 3) {
|
||||||
|
cerr << "Usage: " << argv[0] << " <input> <output> [factor]\n";
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
string input = argv[1];
|
||||||
|
string output = argv[2];
|
||||||
|
float factor = 2;
|
||||||
|
if(argc == 4) {
|
||||||
|
factor = atoi(argv[3]);
|
||||||
|
if(factor == 0) {
|
||||||
|
cerr << "Invalid factor: " << argv[3] << endl;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Nexus in;
|
||||||
|
if(!in.Load(input, true)) {
|
||||||
|
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;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
out.sphere = in.sphere;
|
||||||
|
out.history = in.history;
|
||||||
|
for(unsigned int i = 0; i < in.index.size(); i++) {
|
||||||
|
unsigned int patch = i;
|
||||||
|
Nexus::PatchInfo &src_entry = in.index[patch];
|
||||||
|
Patch &src_patch = in.GetPatch(patch);
|
||||||
|
Border src_border = in.GetBorder(patch);
|
||||||
|
|
||||||
|
out.AddPatch(src_entry.nvert, src_entry.nface, src_border.Available());
|
||||||
|
|
||||||
|
Nexus::PatchInfo &dst_entry = out.index[patch];
|
||||||
|
|
||||||
|
Patch dst_patch = out.GetPatch(patch);
|
||||||
|
|
||||||
|
Point3f dir = src_entry.sphere.Center() - in.sphere.Center();
|
||||||
|
dir.Normalize();
|
||||||
|
dir *= 10 * src_entry.error;
|
||||||
|
|
||||||
|
memcpy(dst_patch.VertBegin(), src_patch.VertBegin(),
|
||||||
|
src_patch.nv * sizeof(Point3f));
|
||||||
|
|
||||||
|
Point3f *ptr = dst_patch.VertBegin();
|
||||||
|
for(int i = 0; i < dst_patch.nv; i++) {
|
||||||
|
ptr[i] = explode(ptr[i], src_entry.sphere.Center(), dir,
|
||||||
|
0.5 *src_entry.error);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if(in.signature & NXS_STRIP) {
|
||||||
|
memcpy(dst_patch.FaceBegin(), src_patch.FaceBegin(),
|
||||||
|
src_patch.nf * sizeof(unsigned short));
|
||||||
|
} else {
|
||||||
|
memcpy(dst_patch.FaceBegin(), src_patch.FaceBegin(),
|
||||||
|
src_patch.nf * sizeof(unsigned short) * 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
if((in.signature & NXS_COLORS) && (out.signature & NXS_COLORS))
|
||||||
|
memcpy(dst_patch.ColorBegin(), src_patch.ColorBegin(),
|
||||||
|
src_patch.nv * sizeof(unsigned int));
|
||||||
|
|
||||||
|
if((in.signature & NXS_NORMALS_SHORT) &&
|
||||||
|
(out.signature & NXS_NORMALS_SHORT))
|
||||||
|
memcpy(dst_patch.Norm16Begin(), src_patch.Norm16Begin(),
|
||||||
|
src_patch.nv * sizeof(short)*4);
|
||||||
|
|
||||||
|
//reordering
|
||||||
|
//WATCH OUT BORDERS!
|
||||||
|
// Reorder(out.signature, dst_patch);
|
||||||
|
//copying entry information;
|
||||||
|
dst_entry.sphere = src_entry.sphere;
|
||||||
|
dst_entry.error = src_entry.error;
|
||||||
|
|
||||||
|
//adding borders.
|
||||||
|
for(unsigned int i = 0; i < src_border.Size(); i++) {
|
||||||
|
Link &link = src_border[i];
|
||||||
|
if(link.IsNull()) continue;
|
||||||
|
assert(link.end_patch < in.index.size());
|
||||||
|
}
|
||||||
|
Border dst_border = out.GetBorder(patch);
|
||||||
|
out.borders.ResizeBorder(patch, src_border.Size());
|
||||||
|
memcpy(dst_border.Start(), src_border.Start(),
|
||||||
|
src_border.Size() * sizeof(Link));
|
||||||
|
}
|
||||||
|
in.Close();
|
||||||
|
out.Close();
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -120,3 +120,11 @@ void File::WriteBuffer(void *data, unsigned int sz) {
|
||||||
assert(0 && "Could not write");
|
assert(0 && "Could not write");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void File::Delete(const string &filename) {
|
||||||
|
#ifdef WIN32
|
||||||
|
DeleteFile(filename.c_str());
|
||||||
|
#else
|
||||||
|
unlink(filename.c_str());
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
|
@ -39,6 +39,7 @@ class File {
|
||||||
|
|
||||||
bool IsReadOnly() { return readonly; }
|
bool IsReadOnly() { return readonly; }
|
||||||
|
|
||||||
|
static void Delete(const std::string &filename);
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
|
|
|
@ -40,41 +40,54 @@ void NxsPatch::Read(instm *in) {
|
||||||
in->read(&*bord.begin(), bord.size() * sizeof(Link));
|
in->read(&*bord.begin(), bord.size() * sizeof(Link));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Fragment::Write(outstm *out) {
|
bool Fragment::Write(outstm *out) {
|
||||||
out->write(&id, sizeof(unsigned int));
|
try {
|
||||||
out->write(&error, sizeof(float));
|
out->write(&id, sizeof(unsigned int));
|
||||||
|
out->write(&error, sizeof(float));
|
||||||
unsigned int ssize = seeds.size();
|
unsigned int ssize = seeds.size();
|
||||||
out->write(&ssize, sizeof(unsigned int));
|
out->write(&ssize, sizeof(unsigned int));
|
||||||
|
out->write(&*seeds.begin(), ssize * sizeof(Point3f));
|
||||||
out->write(&*seeds.begin(), ssize * sizeof(Point3f));
|
out->write(&*seeds_id.begin(), ssize * sizeof(unsigned int));
|
||||||
out->write(&*seeds_id.begin(), ssize * sizeof(unsigned int));
|
unsigned int psize = pieces.size();
|
||||||
|
out->write(&psize, sizeof(unsigned int));
|
||||||
|
|
||||||
unsigned int psize = pieces.size();
|
for(unsigned int i = 0; i < pieces.size(); i++)
|
||||||
out->write(&psize, sizeof(unsigned int));
|
pieces[i].Write(out);
|
||||||
|
return true;
|
||||||
for(unsigned int i = 0; i < pieces.size(); i++)
|
} catch (estream *e) {
|
||||||
pieces[i].Write(out);
|
perr.putf("Error: %s\n", pconst(e->get_message()));
|
||||||
|
delete e;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Fragment::Read(instm *in) {
|
bool Fragment::Read(instm *in) {
|
||||||
|
try {
|
||||||
in->read(&id, sizeof(unsigned int));
|
in->read(&id, sizeof(unsigned int));
|
||||||
in->read(&error, sizeof(float));
|
in->read(&error, sizeof(float));
|
||||||
|
|
||||||
unsigned int ssize;
|
//TODO move this control to all read!
|
||||||
in->read(&ssize, sizeof(unsigned int));
|
unsigned int ssize;
|
||||||
seeds.resize(ssize);
|
if(sizeof(int) != in->read(&ssize, sizeof(unsigned int)))
|
||||||
seeds_id.resize(ssize);
|
return false;
|
||||||
in->read(&*seeds.begin(), ssize * sizeof(Point3f));
|
seeds.resize(ssize);
|
||||||
in->read(&*seeds_id.begin(), ssize * sizeof(unsigned int));
|
seeds_id.resize(ssize);
|
||||||
|
in->read(&*seeds.begin(), ssize * sizeof(Point3f));
|
||||||
unsigned int psize;
|
in->read(&*seeds_id.begin(), ssize * sizeof(unsigned int));
|
||||||
in->read(&psize, sizeof(unsigned int));
|
|
||||||
pieces.resize(psize);
|
unsigned int psize;
|
||||||
|
in->read(&psize, sizeof(unsigned int));
|
||||||
for(unsigned int i = 0; i < psize; i++)
|
pieces.resize(psize);
|
||||||
pieces[i].Read(in);
|
|
||||||
|
for(unsigned int i = 0; i < psize; i++) {
|
||||||
|
pieces[i].Read(in);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
} catch (estream *e) {
|
||||||
|
perr.putf("Error: %s\n", pconst(e->get_message()));
|
||||||
|
delete e;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void nxs::Join(Fragment &in,
|
void nxs::Join(Fragment &in,
|
||||||
|
@ -132,6 +145,54 @@ void nxs::Join(Fragment &in,
|
||||||
}
|
}
|
||||||
assert(vcount < (1<<16));
|
assert(vcount < (1<<16));
|
||||||
|
|
||||||
|
set<BigLink> newborders;
|
||||||
|
for(unsigned int i = 0; i < in.pieces.size(); i++) {
|
||||||
|
unsigned int offset = offsets[i];
|
||||||
|
vector<Link> &bord = in.pieces[i].bord;
|
||||||
|
for(unsigned int k = 0; k < bord.size(); k++) {
|
||||||
|
Link llink = bord[k];
|
||||||
|
if(llink.IsNull()) continue;
|
||||||
|
if(!patch_remap.count(llink.end_patch)) {//external
|
||||||
|
BigLink link;
|
||||||
|
link.start_vert = remap[offset + llink.start_vert];
|
||||||
|
link.end_patch = in.pieces[i].patch;
|
||||||
|
link.end_vert = llink.start_vert;
|
||||||
|
newborders.insert(link);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
newvert.resize(vcount);
|
||||||
|
newface.resize(fcount*3);
|
||||||
|
newbord.resize(newborders.size());
|
||||||
|
|
||||||
|
fcount = 0;
|
||||||
|
for(unsigned int i = 0; i < in.pieces.size(); i++) {
|
||||||
|
unsigned int offset = offsets[i];
|
||||||
|
vector<Point3f> &vert = in.pieces[i].vert;
|
||||||
|
vector<unsigned short> &face = in.pieces[i].face;
|
||||||
|
vector<Link> &bord = in.pieces[i].bord;
|
||||||
|
|
||||||
|
for(unsigned int i = 0; i < vert.size(); i++) {
|
||||||
|
assert(offset + i < remap.size());
|
||||||
|
assert(remap[offset + i] < vcount);
|
||||||
|
newvert[remap[offset + i]] = vert[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
for(unsigned int i = 0; i < face.size(); i++) {
|
||||||
|
assert(offset + face[i] < remap.size());
|
||||||
|
assert(remap[offset + face[i]] < newvert.size());
|
||||||
|
assert(fcount < newface.size());
|
||||||
|
newface[fcount++] = remap[offset + face[i]];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
set<BigLink>::iterator b;
|
||||||
|
for(b = newborders.begin(); b != newborders.end(); b++)
|
||||||
|
newbord.push_back(*b);
|
||||||
|
|
||||||
|
/* old code (more general.. but not parallelizable)
|
||||||
|
|
||||||
|
|
||||||
//L(a, b): Exist link between a, b
|
//L(a, b): Exist link between a, b
|
||||||
//An external link L(e, v) where v belongs to the patches (and e not)
|
//An external link L(e, v) where v belongs to the patches (and e not)
|
||||||
//is valid only if: for every x in patches L(v, x) => L(e, x)
|
//is valid only if: for every x in patches L(v, x) => L(e, x)
|
||||||
|
@ -148,8 +209,10 @@ void nxs::Join(Fragment &in,
|
||||||
for(unsigned int k = 0; k < bord.size(); k++) {
|
for(unsigned int k = 0; k < bord.size(); k++) {
|
||||||
Link llink = bord[k];
|
Link llink = bord[k];
|
||||||
if(llink.IsNull()) continue;
|
if(llink.IsNull()) continue;
|
||||||
if(!patch_remap.count(llink.end_patch)) {//external...may be erased though
|
if(!patch_remap.count(llink.end_patch)) {//external...may be erased
|
||||||
BigLink link;
|
BigLink link;
|
||||||
|
link.orig_vert = llink.start_vert;
|
||||||
|
link.orig_patch = in.pieces[i].patch;
|
||||||
link.start_vert = remap[offset + llink.start_vert];
|
link.start_vert = remap[offset + llink.start_vert];
|
||||||
link.end_patch = llink.end_patch;
|
link.end_patch = llink.end_patch;
|
||||||
link.end_vert = llink.end_vert;
|
link.end_vert = llink.end_vert;
|
||||||
|
@ -196,14 +259,13 @@ void nxs::Join(Fragment &in,
|
||||||
unsigned int n = (*b).second;
|
unsigned int n = (*b).second;
|
||||||
if(n * (n-1) == internal_links[link.start_vert])
|
if(n * (n-1) == internal_links[link.start_vert])
|
||||||
newbord.push_back(link);
|
newbord.push_back(link);
|
||||||
}
|
}*/
|
||||||
}
|
}
|
||||||
|
|
||||||
void nxs::Split(Fragment &out,
|
void nxs::Split(Fragment &out,
|
||||||
vector<Point3f> &newvert,
|
vector<Point3f> &newvert,
|
||||||
vector<unsigned int> &newface,
|
vector<unsigned int> &newface,
|
||||||
vector<BigLink> &newbord,
|
vector<BigLink> &newbord) {
|
||||||
VoronoiPartition &part) {
|
|
||||||
|
|
||||||
unsigned int nseeds = out.seeds.size();
|
unsigned int nseeds = out.seeds.size();
|
||||||
vector<Point3f> &seeds = out.seeds;
|
vector<Point3f> &seeds = out.seeds;
|
||||||
|
@ -219,12 +281,12 @@ void nxs::Split(Fragment &out,
|
||||||
assert(seed < nseeds);
|
assert(seed < nseeds);
|
||||||
count[seed]++;
|
count[seed]++;
|
||||||
}
|
}
|
||||||
|
|
||||||
//pruning small patches
|
//pruning small patches
|
||||||
float min_size = (newface.size()/3) / 20.0f;
|
float min_size = (newface.size()/3) / 20.0f;
|
||||||
vector<Point3f> newseeds;
|
vector<Point3f> newseeds;
|
||||||
vector<unsigned int> newseeds_id;
|
vector<unsigned int> newseeds_id;
|
||||||
|
|
||||||
for(unsigned int seed = 0; seed < nseeds; seed++) {
|
for(unsigned int seed = 0; seed < nseeds; seed++) {
|
||||||
if(count[seed] > min_size) {
|
if(count[seed] > min_size) {
|
||||||
newseeds.push_back(seeds[seed]);
|
newseeds.push_back(seeds[seed]);
|
||||||
|
@ -313,17 +375,15 @@ void nxs::Split(Fragment &out,
|
||||||
//for every esternal link we must update external patches!
|
//for every esternal link we must update external patches!
|
||||||
for(unsigned int i = 0; i < newbord.size(); i++) {
|
for(unsigned int i = 0; i < newbord.size(); i++) {
|
||||||
BigLink link = newbord[i];
|
BigLink link = newbord[i];
|
||||||
if(v_remap[link.start_vert] == -1) continue;
|
if(v_remap[link.start_vert] == -1) continue;
|
||||||
link.start_vert = v_remap[link.start_vert];
|
|
||||||
assert(link.start_vert < (1<<16));
|
|
||||||
Link llink;
|
Link llink;
|
||||||
llink.start_vert = link.start_vert;
|
llink.start_vert = v_remap[link.start_vert];
|
||||||
llink.end_patch = link.end_patch;
|
llink.end_patch = link.end_patch;
|
||||||
llink.end_vert = link.end_vert;
|
llink.end_vert = link.end_vert;
|
||||||
bords.push_back(llink);
|
bords.push_back(llink);
|
||||||
}
|
}
|
||||||
|
|
||||||
//process internal borders;
|
//process internal borders;
|
||||||
//TODO higly inefficient!!!
|
//TODO higly inefficient!!!
|
||||||
for(unsigned int rseed = 0; rseed < nseeds; rseed++) {
|
for(unsigned int rseed = 0; rseed < nseeds; rseed++) {
|
||||||
if(seed == rseed) continue;
|
if(seed == rseed) continue;
|
||||||
|
|
|
@ -12,6 +12,8 @@ namespace nxs {
|
||||||
class VoronoiPartition;
|
class VoronoiPartition;
|
||||||
|
|
||||||
struct BigLink {
|
struct BigLink {
|
||||||
|
// unsigned int orig_vert;
|
||||||
|
// unsigned int orig_patch;
|
||||||
unsigned int start_vert;
|
unsigned int start_vert;
|
||||||
unsigned int end_patch;
|
unsigned int end_patch;
|
||||||
unsigned int end_vert;
|
unsigned int end_vert;
|
||||||
|
@ -33,8 +35,7 @@ class NxsPatch {
|
||||||
unsigned int patch;
|
unsigned int patch;
|
||||||
std::vector<vcg::Point3f> vert;
|
std::vector<vcg::Point3f> vert;
|
||||||
std::vector<unsigned short> face;
|
std::vector<unsigned short> face;
|
||||||
//when this is an outfragment link.end_patch is (1<<31) + end_patch
|
|
||||||
//when it is an internal border!
|
|
||||||
std::vector<Link> bord;
|
std::vector<Link> bord;
|
||||||
|
|
||||||
void Write(pt::outstm *out);
|
void Write(pt::outstm *out);
|
||||||
|
@ -52,8 +53,8 @@ class Fragment {
|
||||||
|
|
||||||
std::vector<NxsPatch> pieces;
|
std::vector<NxsPatch> pieces;
|
||||||
|
|
||||||
void Write(pt::outstm *out);
|
bool Write(pt::outstm *out);
|
||||||
void Read(pt::instm *in);
|
bool Read(pt::instm *in);
|
||||||
|
|
||||||
//returns the index of the seed
|
//returns the index of the seed
|
||||||
unsigned int Locate(const vcg::Point3f &p);
|
unsigned int Locate(const vcg::Point3f &p);
|
||||||
|
@ -67,8 +68,7 @@ class Fragment {
|
||||||
void Split(Fragment &out,
|
void Split(Fragment &out,
|
||||||
std::vector<vcg::Point3f> &newvert,
|
std::vector<vcg::Point3f> &newvert,
|
||||||
std::vector<unsigned int> &newface,
|
std::vector<unsigned int> &newface,
|
||||||
std::vector<BigLink> &newbord,
|
std::vector<BigLink> &newbord);
|
||||||
VoronoiPartition &part);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -24,6 +24,9 @@
|
||||||
History
|
History
|
||||||
|
|
||||||
$Log: not supported by cvs2svn $
|
$Log: not supported by cvs2svn $
|
||||||
|
Revision 1.5 2004/07/05 15:49:39 ponchio
|
||||||
|
Windows (DevCpp, mingw) port.
|
||||||
|
|
||||||
Revision 1.4 2004/07/04 14:23:14 ponchio
|
Revision 1.4 2004/07/04 14:23:14 ponchio
|
||||||
*** empty log message ***
|
*** empty log message ***
|
||||||
|
|
||||||
|
@ -73,6 +76,11 @@ bool MFHash::Load(const string &file, unsigned int used) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MFHash::Delete() {
|
||||||
|
buffer.Flush();
|
||||||
|
buffer.Delete();
|
||||||
|
}
|
||||||
|
|
||||||
void MFHash::Resize(unsigned int n) {
|
void MFHash::Resize(unsigned int n) {
|
||||||
assert(buffer.Size() - space <= n);
|
assert(buffer.Size() - space <= n);
|
||||||
//lets dump actual content
|
//lets dump actual content
|
||||||
|
|
|
@ -24,6 +24,9 @@
|
||||||
History
|
History
|
||||||
|
|
||||||
$Log: not supported by cvs2svn $
|
$Log: not supported by cvs2svn $
|
||||||
|
Revision 1.4 2004/07/02 17:40:30 ponchio
|
||||||
|
Debug.
|
||||||
|
|
||||||
Revision 1.3 2004/07/02 13:08:43 ponchio
|
Revision 1.3 2004/07/02 13:08:43 ponchio
|
||||||
*** empty log message ***
|
*** empty log message ***
|
||||||
|
|
||||||
|
@ -62,6 +65,7 @@ class MFHash {
|
||||||
MFHash() {}
|
MFHash() {}
|
||||||
bool Create(const std::string &file, unsigned int reserved = 32);
|
bool Create(const std::string &file, unsigned int reserved = 32);
|
||||||
bool Load(const std::string &file, unsigned int used = 0xffffffff);
|
bool Load(const std::string &file, unsigned int used = 0xffffffff);
|
||||||
|
void Delete();
|
||||||
|
|
||||||
void Resize(unsigned int n);
|
void Resize(unsigned int n);
|
||||||
void Insert(unsigned int key, unsigned int value, bool rehash = true);
|
void Insert(unsigned int key, unsigned int value, bool rehash = true);
|
||||||
|
|
|
@ -52,6 +52,11 @@ void MFile::Close() {
|
||||||
files.clear();
|
files.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MFile::Delete() {
|
||||||
|
while(files.size())
|
||||||
|
RemoveFile();
|
||||||
|
}
|
||||||
|
|
||||||
void MFile::Redim(int64 sz) {
|
void MFile::Redim(int64 sz) {
|
||||||
assert(!readonly);
|
assert(!readonly);
|
||||||
if(sz > size) {
|
if(sz > size) {
|
||||||
|
@ -120,11 +125,12 @@ void MFile::WriteBuffer(void *data, unsigned int sz) {
|
||||||
void MFile::RemoveFile() {
|
void MFile::RemoveFile() {
|
||||||
assert(files.size());
|
assert(files.size());
|
||||||
|
|
||||||
string name = Name(files.size());
|
string name = Name(files.size()-1);
|
||||||
File &file = files.back();
|
File &file = files.back();
|
||||||
unsigned int last_size = file.Length();
|
unsigned int last_size = file.Length();
|
||||||
files.pop_back();
|
files.pop_back();
|
||||||
size -= last_size;
|
size -= last_size;
|
||||||
|
cerr << "Removing file: " << name << endl;
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
DeleteFile(name.c_str());
|
DeleteFile(name.c_str());
|
||||||
#else
|
#else
|
||||||
|
|
|
@ -27,6 +27,7 @@ class MFile {
|
||||||
unsigned int max_file_size = MFILE_MAX_SIZE);
|
unsigned int max_file_size = MFILE_MAX_SIZE);
|
||||||
bool Load(const std::string &filename, bool readonly = false);
|
bool Load(const std::string &filename, bool readonly = false);
|
||||||
void Close();
|
void Close();
|
||||||
|
void Delete();
|
||||||
|
|
||||||
int64 Length() { return size; }
|
int64 Length() { return size; }
|
||||||
void Redim(int64 size);
|
void Redim(int64 size);
|
||||||
|
|
|
@ -147,6 +147,19 @@ Border Nexus::GetBorder(unsigned int patch, bool flush) {
|
||||||
return borders.GetBorder(patch);
|
return borders.GetBorder(patch);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Nexus::AddBorder(unsigned int patch, Link &link) {
|
||||||
|
Border border = GetBorder(patch);
|
||||||
|
|
||||||
|
unsigned int pos = border.Size();
|
||||||
|
if(borders.ResizeBorder(patch, pos+1)) {
|
||||||
|
border = GetBorder(patch);
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(border.Size() < border.Available());
|
||||||
|
assert(border.Available() > pos);
|
||||||
|
|
||||||
|
border[pos] = link;
|
||||||
|
}
|
||||||
|
|
||||||
unsigned int Nexus::AddPatch(unsigned int nvert, unsigned int nface,
|
unsigned int Nexus::AddPatch(unsigned int nvert, unsigned int nface,
|
||||||
unsigned int nbord) {
|
unsigned int nbord) {
|
||||||
|
|
|
@ -59,6 +59,8 @@ class Nexus {
|
||||||
Patch &GetPatch(unsigned int patch, bool flush = true);
|
Patch &GetPatch(unsigned int patch, bool flush = true);
|
||||||
Border GetBorder(unsigned int patch, bool flush = true);
|
Border GetBorder(unsigned int patch, bool flush = true);
|
||||||
|
|
||||||
|
void AddBorder(unsigned int patch, Link &link);
|
||||||
|
|
||||||
bool IsCompressed() { return (signature & NXS_COMPRESSED) != 0; }
|
bool IsCompressed() { return (signature & NXS_COMPRESSED) != 0; }
|
||||||
bool HasStrips() { return (signature & NXS_STRIP) != 0; }
|
bool HasStrips() { return (signature & NXS_STRIP) != 0; }
|
||||||
bool HasColors() { return (signature & NXS_COLORS) != 0; }
|
bool HasColors() { return (signature & NXS_COLORS) != 0; }
|
||||||
|
|
|
@ -24,6 +24,9 @@
|
||||||
History
|
History
|
||||||
|
|
||||||
$Log: not supported by cvs2svn $
|
$Log: not supported by cvs2svn $
|
||||||
|
Revision 1.19 2004/10/30 20:17:03 ponchio
|
||||||
|
Fixed big patches problem.
|
||||||
|
|
||||||
Revision 1.18 2004/10/21 13:40:16 ponchio
|
Revision 1.18 2004/10/21 13:40:16 ponchio
|
||||||
Debugging.
|
Debugging.
|
||||||
|
|
||||||
|
@ -386,6 +389,23 @@ int main(int argc, char *argv[]) {
|
||||||
} else
|
} else
|
||||||
nexus.Draw(cells);
|
nexus.Draw(cells);
|
||||||
|
|
||||||
|
if(show_borders) {
|
||||||
|
for(unsigned int i = 0; i < cells.size(); i++) {
|
||||||
|
Border border = nexus.GetBorder(cells[i]);
|
||||||
|
Patch &patch = nexus.GetPatch(cells[i]);
|
||||||
|
glPointSize(4);
|
||||||
|
glColor3f(1.0f, 1.0f, 1.0f);
|
||||||
|
glBegin(GL_POINTS);
|
||||||
|
for(int b = 0; b < border.Size(); b++) {
|
||||||
|
Link &link = border[b];
|
||||||
|
Point3f &p = patch.Vert(link.start_vert);
|
||||||
|
glVertex3f(p[0], p[1], p[2]);
|
||||||
|
}
|
||||||
|
glEnd();
|
||||||
|
glPointSize(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//cerr Do some reporting:
|
//cerr Do some reporting:
|
||||||
if(show_statistics) {
|
if(show_statistics) {
|
||||||
glMatrixMode(GL_MODELVIEW);
|
glMatrixMode(GL_MODELVIEW);
|
||||||
|
|
|
@ -0,0 +1,42 @@
|
||||||
|
#include <ptypes/pinet.h>
|
||||||
|
|
||||||
|
class NxsClientPool {
|
||||||
|
vector<NxsClient> clients;
|
||||||
|
void Push(NxsRequest *request);
|
||||||
|
};
|
||||||
|
|
||||||
|
class NxsClient: public pt::ipstream {
|
||||||
|
public:
|
||||||
|
queue<NxsRequest *> requests;
|
||||||
|
|
||||||
|
void Push(NxsRequest *request);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
ipaddress addr = phostbyname("nb-ponchio.isti.cnr.it");
|
||||||
|
ipstream client;
|
||||||
|
client.set_ip(addr);
|
||||||
|
client.set_port(testport);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
client.open();
|
||||||
|
|
||||||
|
pout.put("Sending a request to the server...\n");
|
||||||
|
client.write("Hello", 6);
|
||||||
|
client.flush();
|
||||||
|
|
||||||
|
// receive the response
|
||||||
|
string rsp = client.line(maxtoken);
|
||||||
|
pout.putf("Received: %s\n", pconst(rsp));
|
||||||
|
|
||||||
|
// need to close the socket explicitly to gracefully shutdown
|
||||||
|
// the peer host too. otherwise, ~ipstream() will call cancel()
|
||||||
|
// and leave the peer in a waiting state (not forever though).
|
||||||
|
client.close();
|
||||||
|
}
|
||||||
|
catch(estream* e)
|
||||||
|
{
|
||||||
|
perr.putf("Error: %s\n", pconst(e->get_message()));
|
||||||
|
delete e;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,178 @@
|
||||||
|
#include "nxsdispatcher.h"
|
||||||
|
#include "fragment.h"
|
||||||
|
#include "decimate.h"
|
||||||
|
#include <iostream>
|
||||||
|
#include <ptypes/ptypes.h>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
using namespace vcg;
|
||||||
|
using namespace nxs;
|
||||||
|
using namespace pt;
|
||||||
|
|
||||||
|
void SaveFragment(Nexus &nexus, VoronoiChain &chain,
|
||||||
|
Fragment &fragin,
|
||||||
|
Fragment &fragout);
|
||||||
|
|
||||||
|
|
||||||
|
void Opener::execute() {
|
||||||
|
server->reading.lock();
|
||||||
|
server->writing.lock();
|
||||||
|
while(1) {
|
||||||
|
if(get_signaled())
|
||||||
|
return;
|
||||||
|
try {
|
||||||
|
server->open();
|
||||||
|
server->connected = true;
|
||||||
|
break;
|
||||||
|
} catch(...) {
|
||||||
|
}
|
||||||
|
sleep(4);
|
||||||
|
}
|
||||||
|
server->reading.unlock();
|
||||||
|
server->writing.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
void FragIO::execute() {
|
||||||
|
|
||||||
|
server->writing.lock();
|
||||||
|
// cerr << "Writing frag...: " << fragin->id << "\n";
|
||||||
|
|
||||||
|
outmemory outm;
|
||||||
|
outm.open();
|
||||||
|
fragin->Write(&outm);
|
||||||
|
pt::string a = outm.get_strdata();
|
||||||
|
try {
|
||||||
|
server->write((const char *)a, length(a));
|
||||||
|
server->flush();
|
||||||
|
} catch (estream *e) {
|
||||||
|
perr.putf("Error: %s\n", pconst(e->get_message()));
|
||||||
|
delete e;
|
||||||
|
|
||||||
|
message *msg = new message(MSG_FAIL, (int)fragin);
|
||||||
|
dispatcher->post(msg);
|
||||||
|
|
||||||
|
//TODO restart Server!
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
server->reading.lock();
|
||||||
|
server->writing.unlock();
|
||||||
|
|
||||||
|
Fragment *out = new Fragment;
|
||||||
|
if(!out->Read(server)) {
|
||||||
|
message *msg = new message(MSG_FAIL, (int)fragin);
|
||||||
|
dispatcher->post(msg);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
server->reading.unlock();
|
||||||
|
|
||||||
|
// 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) {
|
||||||
|
FILE *fp = fopen(file.c_str(), "rb");
|
||||||
|
if(!fp) return false;
|
||||||
|
char host[256];
|
||||||
|
int port;
|
||||||
|
while(fscanf(fp, "%s %d\n", host, &port) == 2) {
|
||||||
|
cerr << "Host: " << host << " port: " << port << endl;
|
||||||
|
Server *server = new Server(host, port);
|
||||||
|
server->opener.start();
|
||||||
|
servers.push_back(server);
|
||||||
|
}
|
||||||
|
fclose(fp);
|
||||||
|
if(servers.size() == 0) {
|
||||||
|
cerr << "Empty server file!\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Dispatcher::~Dispatcher() {
|
||||||
|
for(unsigned int i = 0; i < servers.size(); i++) {
|
||||||
|
Server *server = servers[i];
|
||||||
|
server->opener.signal();
|
||||||
|
server->close();
|
||||||
|
delete server;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Dispatcher::SendFragment(Fragment *frag) {
|
||||||
|
//WARNING this handles no more than 1<<31 fragments!
|
||||||
|
frag->id = count++;
|
||||||
|
message *msg = new message(MSG_SEND, (int)frag);
|
||||||
|
post(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
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) {
|
||||||
|
best = servers[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return best;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Dispatcher::ReceiveFragment(Fragment *in, Fragment *out) {
|
||||||
|
//lock nexus if run in thread.
|
||||||
|
// cerr << "Saving: " << in->id << endl;
|
||||||
|
SaveFragment(*nexus, *chain, *in, *out);
|
||||||
|
|
||||||
|
if(frags.count(in->id)) {
|
||||||
|
FragIO *frag = frags[in->id];
|
||||||
|
delete frag;
|
||||||
|
frags.erase(frags.find(in->id));
|
||||||
|
}
|
||||||
|
delete in;
|
||||||
|
delete out;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Dispatcher::msghandler(message &msg) {
|
||||||
|
switch(msg.id) {
|
||||||
|
case MSG_FAIL: break;
|
||||||
|
case MSG_SEND: {
|
||||||
|
//get server!
|
||||||
|
Server *best = BestServer();
|
||||||
|
Fragment *fragin = (Fragment *)(msg.param);
|
||||||
|
|
||||||
|
if(!best) { //no server process locally....
|
||||||
|
// cerr << "No best!" << endl;
|
||||||
|
vector<Point3f> newvert;
|
||||||
|
vector<unsigned int> newface;
|
||||||
|
vector<BigLink> newbord;
|
||||||
|
Join(*fragin, newvert, newface, newbord);
|
||||||
|
|
||||||
|
float error = Decimate(QUADRIC,
|
||||||
|
(unsigned int)((newface.size()/3) * 0.5),
|
||||||
|
newvert, newface, newbord);
|
||||||
|
|
||||||
|
Fragment *fragout = new Fragment;
|
||||||
|
|
||||||
|
fragout->error = error;
|
||||||
|
fragout->id = fragin->id;
|
||||||
|
fragout->seeds = fragin->seeds;
|
||||||
|
fragout->seeds_id = fragin->seeds_id;
|
||||||
|
Split(*fragout, newvert, newface, newbord);
|
||||||
|
ReceiveFragment(fragin, fragout);
|
||||||
|
} else {
|
||||||
|
FragIO *frag = new FragIO(best, this, fragin);
|
||||||
|
assert(!frags.count(fragin->id));
|
||||||
|
frags[fragin->id] = frag;
|
||||||
|
frag->start();
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
case MSG_RECEIVE:
|
||||||
|
ReceiveFragment((Fragment *)(msg.param), (Fragment *)(msg.result));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
defhandler(msg);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,81 @@
|
||||||
|
#include <ptypes/pinet.h>
|
||||||
|
#include <ptypes/pasync.h>
|
||||||
|
#include <vector>
|
||||||
|
#include <map>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace nxs {
|
||||||
|
|
||||||
|
#define MSG_SEND MSG_USER + 1
|
||||||
|
#define MSG_RECEIVE MSG_USER + 2
|
||||||
|
#define MSG_FAIL MSG_USER + 3
|
||||||
|
|
||||||
|
class Fragment;
|
||||||
|
class Nexus;
|
||||||
|
class VoronoiChain;
|
||||||
|
|
||||||
|
class Server;
|
||||||
|
class FragIO;
|
||||||
|
class Dispatcher;
|
||||||
|
|
||||||
|
|
||||||
|
class Opener: public pt::thread {
|
||||||
|
public:
|
||||||
|
Opener(Server *s): thread(false), server(s) {}
|
||||||
|
~Opener() { waitfor(); }
|
||||||
|
void execute();
|
||||||
|
void cleanup() {}
|
||||||
|
|
||||||
|
Server *server;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class Server: public pt::ipstream {
|
||||||
|
public:
|
||||||
|
Server(pt::string host, int port): ipstream(host, port),
|
||||||
|
connected(false), opener(this) {}
|
||||||
|
|
||||||
|
int queue;
|
||||||
|
pt::mutex reading;
|
||||||
|
pt::mutex writing;
|
||||||
|
bool connected;
|
||||||
|
Opener opener;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class Dispatcher: public pt::msgqueue {
|
||||||
|
public:
|
||||||
|
Dispatcher(Nexus *nx, VoronoiChain *ch):
|
||||||
|
count(0), nexus(nx), chain(ch) {}
|
||||||
|
~Dispatcher();
|
||||||
|
|
||||||
|
bool Init(const std::string &file);
|
||||||
|
void SendFragment(Fragment *frag);
|
||||||
|
void ReceiveFragment(Fragment *in, Fragment *out);
|
||||||
|
Server *BestServer();
|
||||||
|
|
||||||
|
void msghandler(pt::message &msg);
|
||||||
|
|
||||||
|
int count;
|
||||||
|
Nexus *nexus;
|
||||||
|
VoronoiChain *chain;
|
||||||
|
std::vector<Server *> servers;
|
||||||
|
std::map<int, FragIO *> frags;
|
||||||
|
};
|
||||||
|
|
||||||
|
class FragIO: public pt::thread {
|
||||||
|
public:
|
||||||
|
FragIO(Server *se, Dispatcher *di, Fragment *frag):
|
||||||
|
thread(false), server(se), dispatcher(di), fragin(frag) {}
|
||||||
|
~FragIO() { waitfor(); }
|
||||||
|
void execute();
|
||||||
|
void cleanup() {}
|
||||||
|
|
||||||
|
Server *server;
|
||||||
|
Dispatcher *dispatcher;
|
||||||
|
Fragment *fragin;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,47 @@
|
||||||
|
#include <iostream>
|
||||||
|
#include "crude.h"
|
||||||
|
using namespace nxs;
|
||||||
|
using namespace vcg;
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
int main(int argc, char *argv[]) {
|
||||||
|
if(argc != 2) {
|
||||||
|
cerr << "Uso: " << argv[0] << " <side>\n";
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int side = atoi(argv[1]);
|
||||||
|
if(side > 1000 || side == 0) {
|
||||||
|
cerr << "Invalid side: " << argv[1] << endl;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
Crude crude;
|
||||||
|
if(!crude.Create("square")) {
|
||||||
|
cerr << "Could not create square" << endl;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int half = side/2;
|
||||||
|
crude.Resize(side * side, (side-1) * (side-1) * 2);
|
||||||
|
for(unsigned int x = 0; x < side; x++)
|
||||||
|
for(unsigned int y = 0; y < side; y++) {
|
||||||
|
Point3f p(x*x*x/((float)side),
|
||||||
|
y*y*y/((float)side), x*y/((float)side));
|
||||||
|
crude.GetVertex(x + side * y) = p;
|
||||||
|
crude.GetBox().Add(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
for(unsigned int x = 0; x < side-1; x++)
|
||||||
|
for(unsigned int y = 0; y < side-1; y++) {
|
||||||
|
unsigned int pos = x + side*y;
|
||||||
|
Crude::Face face(pos, pos + 1, pos + side);
|
||||||
|
crude.GetFace(0 + 2*x + (side-1)*y*2) = face;
|
||||||
|
|
||||||
|
face = Crude::Face(pos + 1, pos + 1 + side, pos +side);
|
||||||
|
crude.GetFace(1 + 2*x + (side-1)*y*2) = face;
|
||||||
|
}
|
||||||
|
|
||||||
|
crude.Close();
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -0,0 +1,179 @@
|
||||||
|
#include <ptypes/ptime.h>
|
||||||
|
#include <ptypes/pinet.h>
|
||||||
|
#include <ptypes/pasync.h>
|
||||||
|
using namespace pt;
|
||||||
|
|
||||||
|
#include "fragment.h"
|
||||||
|
#include "decimate.h"
|
||||||
|
using namespace nxs;
|
||||||
|
using namespace vcg;
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
const int port = 10102;
|
||||||
|
|
||||||
|
class FragOutQueue: public msgqueue {
|
||||||
|
public:
|
||||||
|
FragOutQueue(ipstream &cli): client(cli) {}
|
||||||
|
void msghandler(message &msg) {
|
||||||
|
if(msg.id != MSG_USER) {
|
||||||
|
defhandler(msg);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Fragment &fragment = *(Fragment *)(msg.param);
|
||||||
|
|
||||||
|
// pout.putf("Sending: %d\n", fragment.id);
|
||||||
|
outmemory outm;
|
||||||
|
outm.open();
|
||||||
|
fragment.Write(&outm);
|
||||||
|
pt::string a = outm.get_strdata();
|
||||||
|
try {
|
||||||
|
client.write((const char *)a, length(a));
|
||||||
|
client.flush();
|
||||||
|
pout.putf("Sent fragment id: %d\n", fragment.id);
|
||||||
|
} catch (estream *e) {
|
||||||
|
perr.putf("Error: %s\n", pconst(e->get_message()));
|
||||||
|
delete e;
|
||||||
|
}
|
||||||
|
delete (Fragment *)(msg.param);
|
||||||
|
}
|
||||||
|
ipstream &client;
|
||||||
|
};
|
||||||
|
|
||||||
|
class FragInQueue: public msgqueue {
|
||||||
|
public:
|
||||||
|
FragInQueue(FragOutQueue &o): out(o) {}
|
||||||
|
void msghandler(message &msg) {
|
||||||
|
if(msg.id != MSG_USER) {
|
||||||
|
defhandler(msg);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Fragment &fragin = *(Fragment *)(msg.param);
|
||||||
|
// pout.putf("Processing: %d\n", fragin.id);
|
||||||
|
vector<Point3f> newvert;
|
||||||
|
vector<unsigned int> newface;
|
||||||
|
vector<BigLink> newbord;
|
||||||
|
Join(fragin, newvert, newface, newbord);
|
||||||
|
|
||||||
|
float error = Decimate(QUADRIC,
|
||||||
|
(unsigned int)((newface.size()/3) * 0.5),
|
||||||
|
newvert, newface, newbord);
|
||||||
|
|
||||||
|
message *outmsg = new message(MSG_USER);
|
||||||
|
outmsg->param = (int)(new Fragment);
|
||||||
|
Fragment &fragout = *(Fragment *)(outmsg->param);
|
||||||
|
|
||||||
|
fragout.error = error;
|
||||||
|
fragout.id = fragin.id;
|
||||||
|
fragout.seeds = fragin.seeds;
|
||||||
|
fragout.seeds_id = fragin.seeds_id;
|
||||||
|
Split(fragout, newvert, newface, newbord);
|
||||||
|
out.post(outmsg);
|
||||||
|
delete (Fragment *)(msg.param);
|
||||||
|
}
|
||||||
|
|
||||||
|
FragOutQueue &out;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class Reader: public thread {
|
||||||
|
public:
|
||||||
|
Reader(ipstream &cli, FragInQueue &que):
|
||||||
|
thread(false), client(cli), queue(que) {}
|
||||||
|
|
||||||
|
~Reader() {waitfor(); }
|
||||||
|
|
||||||
|
void execute() {
|
||||||
|
while(1) {
|
||||||
|
if(get_signaled()) return;
|
||||||
|
message *msg = new message(MSG_USER);
|
||||||
|
msg->param = (int)(new Fragment);
|
||||||
|
Fragment &fragment = *(Fragment *)(msg->param);
|
||||||
|
if(!fragment.Read(&client)) {
|
||||||
|
pout.putf("Could not read!\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
queue.post(msg);
|
||||||
|
// pout.putf("Incoming: %d\n", fragment.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void cleanup() {}
|
||||||
|
|
||||||
|
ipstream &client;
|
||||||
|
FragInQueue &queue;
|
||||||
|
};
|
||||||
|
|
||||||
|
class Worker: public thread {
|
||||||
|
public:
|
||||||
|
Worker(FragInQueue &que): thread(false), queue(que) {}
|
||||||
|
~Worker() { waitfor(); }
|
||||||
|
|
||||||
|
void execute() {
|
||||||
|
queue.run();
|
||||||
|
}
|
||||||
|
void cleanup() {}
|
||||||
|
FragInQueue &queue;
|
||||||
|
};
|
||||||
|
|
||||||
|
class Writer: public thread {
|
||||||
|
public:
|
||||||
|
Writer(FragOutQueue &que): thread(false), queue(que) {}
|
||||||
|
~Writer() {waitfor(); }
|
||||||
|
void execute() {
|
||||||
|
queue.run();
|
||||||
|
}
|
||||||
|
void cleanup() {}
|
||||||
|
FragOutQueue &queue;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
if (client.get_active()) {
|
||||||
|
try {
|
||||||
|
pout.putf("Incoming connection\n");
|
||||||
|
FragOutQueue out(client);
|
||||||
|
FragInQueue in(out);
|
||||||
|
Reader reader(client, in);
|
||||||
|
Worker worker(in);
|
||||||
|
Writer writer(out);
|
||||||
|
|
||||||
|
reader.start();
|
||||||
|
worker.start();
|
||||||
|
writer.start();
|
||||||
|
|
||||||
|
reader.waitfor();
|
||||||
|
worker.waitfor();
|
||||||
|
writer.waitfor();
|
||||||
|
|
||||||
|
client.flush();
|
||||||
|
client.close();
|
||||||
|
} catch(estream* e) {
|
||||||
|
perr.putf("Error: %s\n", pconst(e->get_message()));
|
||||||
|
delete e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
ipstmserver svr;
|
||||||
|
|
||||||
|
try {
|
||||||
|
// bind to all local addresses on port 8085
|
||||||
|
svr.bindall(port);
|
||||||
|
|
||||||
|
// enter an infinite loop of serving requests
|
||||||
|
servermain(svr);
|
||||||
|
} catch(estream* e) {
|
||||||
|
perr.putf("FATAL: %s\n", pconst(e->get_message()));
|
||||||
|
delete e;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -24,6 +24,9 @@
|
||||||
History
|
History
|
||||||
|
|
||||||
$Log: not supported by cvs2svn $
|
$Log: not supported by cvs2svn $
|
||||||
|
Revision 1.5 2004/09/21 00:53:23 ponchio
|
||||||
|
Lotsa changes.
|
||||||
|
|
||||||
Revision 1.4 2004/08/27 00:39:28 ponchio
|
Revision 1.4 2004/08/27 00:39:28 ponchio
|
||||||
Rewrote.
|
Rewrote.
|
||||||
|
|
||||||
|
@ -62,7 +65,8 @@ class PChain {
|
||||||
virtual unsigned int Locate(unsigned int level, const vcg::Point3f &p) = 0;
|
virtual unsigned int Locate(unsigned int level, const vcg::Point3f &p) = 0;
|
||||||
|
|
||||||
|
|
||||||
virtual void RemapFaces(Crude &crude, VFile<unsigned int> &face_remap,
|
virtual void RemapFaces(VFile<vcg::Point3f> &baricenters,
|
||||||
|
VFile<unsigned int> &face_remap,
|
||||||
std::vector<unsigned int> &patch_faces,
|
std::vector<unsigned int> &patch_faces,
|
||||||
float scaling, int steps) = 0;
|
float scaling, int steps) = 0;
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,9 @@
|
||||||
History
|
History
|
||||||
|
|
||||||
$Log: not supported by cvs2svn $
|
$Log: not supported by cvs2svn $
|
||||||
|
Revision 1.5 2004/07/05 15:49:39 ponchio
|
||||||
|
Windows (DevCpp, mingw) port.
|
||||||
|
|
||||||
Revision 1.4 2004/07/02 17:41:37 ponchio
|
Revision 1.4 2004/07/02 17:41:37 ponchio
|
||||||
Debug.
|
Debug.
|
||||||
|
|
||||||
|
@ -66,6 +69,12 @@ void VertRemap::Close() {
|
||||||
borders.Close();
|
borders.Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void VertRemap::Delete() {
|
||||||
|
all.Flush();
|
||||||
|
all.Delete();
|
||||||
|
borders.Delete();
|
||||||
|
}
|
||||||
|
|
||||||
void VertRemap::Resize(unsigned int n_vert) {
|
void VertRemap::Resize(unsigned int n_vert) {
|
||||||
all.Resize(n_vert);
|
all.Resize(n_vert);
|
||||||
for(unsigned int i = 0; i < n_vert; i++)
|
for(unsigned int i = 0; i < n_vert; i++)
|
||||||
|
|
|
@ -24,6 +24,9 @@
|
||||||
History
|
History
|
||||||
|
|
||||||
$Log: not supported by cvs2svn $
|
$Log: not supported by cvs2svn $
|
||||||
|
Revision 1.4 2004/10/01 15:59:52 ponchio
|
||||||
|
Added include <assert.h>
|
||||||
|
|
||||||
Revision 1.3 2004/07/02 17:41:37 ponchio
|
Revision 1.3 2004/07/02 17:41:37 ponchio
|
||||||
Debug.
|
Debug.
|
||||||
|
|
||||||
|
@ -55,6 +58,7 @@ class VertRemap {
|
||||||
bool Create(const std::string &file);
|
bool Create(const std::string &file);
|
||||||
bool Load(const std::string &file);
|
bool Load(const std::string &file);
|
||||||
void Close();
|
void Close();
|
||||||
|
void Delete();
|
||||||
void Resize(unsigned int n_vert);
|
void Resize(unsigned int n_vert);
|
||||||
|
|
||||||
unsigned int Size();
|
unsigned int Size();
|
||||||
|
|
|
@ -24,6 +24,9 @@
|
||||||
History
|
History
|
||||||
|
|
||||||
$Log: not supported by cvs2svn $
|
$Log: not supported by cvs2svn $
|
||||||
|
Revision 1.14 2004/10/19 16:50:27 ponchio
|
||||||
|
Added row file access ....
|
||||||
|
|
||||||
Revision 1.13 2004/10/08 15:12:04 ponchio
|
Revision 1.13 2004/10/08 15:12:04 ponchio
|
||||||
Working version (maybe)
|
Working version (maybe)
|
||||||
|
|
||||||
|
@ -78,7 +81,7 @@ Created
|
||||||
#ifndef VFILE_H
|
#ifndef VFILE_H
|
||||||
#define VFILE_H
|
#define VFILE_H
|
||||||
|
|
||||||
#include "file.h"
|
#include "mfile.h"
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
@ -94,7 +97,7 @@ Created
|
||||||
|
|
||||||
namespace nxs {
|
namespace nxs {
|
||||||
|
|
||||||
template <class T> class VFile: public File {
|
template <class T> class VFile: public MFile {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
struct Buffer {
|
struct Buffer {
|
||||||
|
@ -138,7 +141,7 @@ template <class T> class VFile: public File {
|
||||||
chunk_size = _chunk_size;
|
chunk_size = _chunk_size;
|
||||||
queue_size = _queue_size;
|
queue_size = _queue_size;
|
||||||
|
|
||||||
return File::Create(filename);
|
return MFile::Create(filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Load(const std:: string &filename,
|
bool Load(const std:: string &filename,
|
||||||
|
@ -150,7 +153,7 @@ template <class T> class VFile: public File {
|
||||||
chunk_size = _chunk_size;
|
chunk_size = _chunk_size;
|
||||||
queue_size = _queue_size;
|
queue_size = _queue_size;
|
||||||
|
|
||||||
if(!File::Load(filename)) return false;
|
if(!MFile::Load(filename)) return false;
|
||||||
n_elements = size/sizeof(T);
|
n_elements = size/sizeof(T);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -159,6 +162,11 @@ template <class T> class VFile: public File {
|
||||||
Flush();
|
Flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Delete() {
|
||||||
|
Flush();
|
||||||
|
MFile::Delete();
|
||||||
|
}
|
||||||
|
|
||||||
void Flush() {
|
void Flush() {
|
||||||
list_iterator i;
|
list_iterator i;
|
||||||
for(i = buffers.begin(); i != buffers.end(); i++)
|
for(i = buffers.begin(); i != buffers.end(); i++)
|
||||||
|
@ -176,7 +184,7 @@ template <class T> class VFile: public File {
|
||||||
|
|
||||||
void Resize(unsigned int elem) {
|
void Resize(unsigned int elem) {
|
||||||
Flush();
|
Flush();
|
||||||
File::Redim(elem * sizeof(T));
|
MFile::Redim(elem * sizeof(T));
|
||||||
n_elements = elem;
|
n_elements = elem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,9 @@
|
||||||
History
|
History
|
||||||
|
|
||||||
$Log: not supported by cvs2svn $
|
$Log: not supported by cvs2svn $
|
||||||
|
Revision 1.19 2004/11/03 16:31:38 ponchio
|
||||||
|
Trying to fix big patches.
|
||||||
|
|
||||||
Revision 1.18 2004/10/30 20:17:03 ponchio
|
Revision 1.18 2004/10/30 20:17:03 ponchio
|
||||||
Fixed big patches problem.
|
Fixed big patches problem.
|
||||||
|
|
||||||
|
@ -159,6 +162,8 @@ bool VoronoiChain::Optimize(int mean, VoronoiPartition &part,
|
||||||
vector<unsigned int> &counts,
|
vector<unsigned int> &counts,
|
||||||
bool join) {
|
bool join) {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//remove small or really big patches.
|
//remove small or really big patches.
|
||||||
unsigned int failed = 0;
|
unsigned int failed = 0;
|
||||||
vector<Point3f> seeds;
|
vector<Point3f> seeds;
|
||||||
|
@ -233,8 +238,10 @@ bool VoronoiChain::Optimize(int mean, VoronoiPartition &part,
|
||||||
return failed == 0;
|
return failed == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void VoronoiChain::Init(Crude &crude, float scaling, int steps) {
|
void VoronoiChain::Init(VFile<Point3f> &baricenters,
|
||||||
unsigned int f_cells = crude.Faces() / mean_size;
|
float scaling, int steps) {
|
||||||
|
|
||||||
|
unsigned int f_cells = baricenters.Size() / mean_size;
|
||||||
unsigned int c_cells = (unsigned int)(scaling * f_cells);
|
unsigned int c_cells = (unsigned int)(scaling * f_cells);
|
||||||
|
|
||||||
levels.push_back(VoronoiPartition());
|
levels.push_back(VoronoiPartition());
|
||||||
|
@ -244,23 +251,22 @@ void VoronoiChain::Init(Crude &crude, float scaling, int steps) {
|
||||||
|
|
||||||
srand(0);
|
srand(0);
|
||||||
|
|
||||||
float fine_vmean = mean_size/2.0f;
|
float coarse_vmean = mean_size/scaling;
|
||||||
float coarse_vmean = (mean_size/scaling)/2.0f;
|
|
||||||
|
|
||||||
for(unsigned int i = 0; i < crude.Vertices(); i++) {
|
for(unsigned int i = 0; i < baricenters.Size(); i++) {
|
||||||
int f = (int)(fine_vmean * rand()/(RAND_MAX + 1.0));
|
int f = (int)(mean_size * (float)rand()/(RAND_MAX + 1.0));
|
||||||
int c = (int)(coarse_vmean * rand()/(RAND_MAX + 1.0));
|
int c = (int)(coarse_vmean * (float)rand()/(RAND_MAX + 1.0));
|
||||||
if(f == 2) {
|
if(f == 2) {
|
||||||
Point3f &point = crude.GetVertex(i);
|
Point3f &point = baricenters[i];
|
||||||
fine.push_back(point);
|
fine.push_back(point);
|
||||||
}
|
}
|
||||||
if(c == 2) {
|
if(c == 2) {
|
||||||
Point3f &point = crude.GetVertex(i);
|
Point3f &point = baricenters[i];
|
||||||
coarse.push_back(point);
|
coarse.push_back(point);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//TODO! Check for duplicates (use the closest :P)
|
//TODO! Check for duplicates (use the closest :P)
|
||||||
//cerr << "fine_seeds.size: " << fine.size() << endl;
|
// cerr << "fine_seeds.size: " << fine.size() << endl;
|
||||||
//cerr << "coarse_seeds.size: " << coarse.size() << endl;
|
//cerr << "coarse_seeds.size: " << coarse.size() << endl;
|
||||||
fine.Init();
|
fine.Init();
|
||||||
coarse.Init();
|
coarse.Init();
|
||||||
|
@ -277,18 +283,18 @@ void VoronoiChain::Init(Crude &crude, float scaling, int steps) {
|
||||||
centroids.resize(fine.size(), Point3f(0, 0, 0));
|
centroids.resize(fine.size(), Point3f(0, 0, 0));
|
||||||
counts.resize(fine.size(), 0);
|
counts.resize(fine.size(), 0);
|
||||||
|
|
||||||
report.Init(crude.Vertices());
|
report.Init(baricenters.Size());
|
||||||
for(unsigned int v = 0; v < crude.Vertices(); v++) {
|
for(unsigned int v = 0; v < baricenters.Size(); v++) {
|
||||||
report.Step(v);
|
report.Step(v);
|
||||||
unsigned int target = fine.Locate(crude.vert[v]);
|
unsigned int target = fine.Locate(baricenters[v]);
|
||||||
centroids[target] += crude.vert[v];
|
centroids[target] += baricenters[v];
|
||||||
counts[target]++;
|
counts[target]++;
|
||||||
}
|
}
|
||||||
if(step == steps-1) {
|
if(step == steps-1) {
|
||||||
if(!Optimize(fine_vmean, fine, centroids, counts, false))
|
if(!Optimize(mean_size, fine, centroids, counts, false))
|
||||||
step--;
|
step--;
|
||||||
} else
|
} else
|
||||||
Optimize(fine_vmean, fine, centroids, counts, true);
|
Optimize(mean_size, fine, centroids, counts, true);
|
||||||
}
|
}
|
||||||
cerr << "Optimized (fine)!\n";
|
cerr << "Optimized (fine)!\n";
|
||||||
//here goes some optimization pass.
|
//here goes some optimization pass.
|
||||||
|
@ -302,23 +308,23 @@ void VoronoiChain::Init(Crude &crude, float scaling, int steps) {
|
||||||
counts.resize(coarse.size(), 0);
|
counts.resize(coarse.size(), 0);
|
||||||
//radius.resize(coarse.size(), 0);
|
//radius.resize(coarse.size(), 0);
|
||||||
|
|
||||||
report.Init(crude.Vertices());
|
report.Init(baricenters.Size());
|
||||||
for(unsigned int v = 0; v < crude.Vertices(); v++) {
|
for(unsigned int v = 0; v < baricenters.Size(); v++) {
|
||||||
if(v & 0xffff) report.Step(v);
|
if(v & 0xffff) report.Step(v);
|
||||||
unsigned int ctarget = 0xffffffff;
|
unsigned int ctarget = 0xffffffff;
|
||||||
ctarget = coarse.Locate(crude.vert[v]);
|
ctarget = coarse.Locate(baricenters[v]);
|
||||||
// float dist;
|
// float dist;
|
||||||
// coarse.Closest(crude.vert[v], ctarget, dist);
|
// coarse.Closest(crude.vert[v], ctarget, dist);
|
||||||
assert(ctarget != 0xffffffff);
|
assert(ctarget != 0xffffffff);
|
||||||
centroids[ctarget] += crude.vert[v];
|
centroids[ctarget] += baricenters[v];
|
||||||
counts[ctarget]++;
|
counts[ctarget]++;
|
||||||
//if(dist > radius[ctarget]) radius[ctarget] = dist;
|
//if(dist > radius[ctarget]) radius[ctarget] = dist;
|
||||||
}
|
}
|
||||||
if(step == steps-1) {
|
if(step == steps-1) {
|
||||||
if(!Optimize(coarse_vmean, coarse, centroids, counts, false))
|
if(!Optimize((int)coarse_vmean, coarse, centroids, counts, false))
|
||||||
step --;
|
step --;
|
||||||
} else
|
} else
|
||||||
Optimize(coarse_vmean, coarse, centroids, counts, true);
|
Optimize((int)coarse_vmean, coarse, centroids, counts, true);
|
||||||
}
|
}
|
||||||
cerr << "Optimized coarse!\n";
|
cerr << "Optimized coarse!\n";
|
||||||
}
|
}
|
||||||
|
@ -329,12 +335,12 @@ unsigned int VoronoiChain::Locate(unsigned int level,
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO move this to nxsbuild
|
//TODO move this to nxsbuild
|
||||||
void VoronoiChain::RemapFaces(Crude &crude,
|
void VoronoiChain::RemapFaces(VFile<Point3f> &baricenters,
|
||||||
VFile<unsigned int> &face_remap,
|
VFile<unsigned int> &face_remap,
|
||||||
vector<unsigned int> &patch_faces,
|
vector<unsigned int> &patch_faces,
|
||||||
float scaling, int steps) {
|
float scaling, int steps) {
|
||||||
|
|
||||||
Init(crude, scaling, steps);
|
Init(baricenters, scaling, steps);
|
||||||
|
|
||||||
//TODO: improve quality of patches and implement threshold.
|
//TODO: improve quality of patches and implement threshold.
|
||||||
typedef map<pair<unsigned int, unsigned int>, unsigned int> FragIndex;
|
typedef map<pair<unsigned int, unsigned int>, unsigned int> FragIndex;
|
||||||
|
@ -345,8 +351,8 @@ void VoronoiChain::RemapFaces(Crude &crude,
|
||||||
unsigned int totpatches = 0;
|
unsigned int totpatches = 0;
|
||||||
|
|
||||||
Point3f bari;
|
Point3f bari;
|
||||||
for(unsigned int i = 0; i < crude.Faces(); i++) {
|
for(unsigned int i = 0; i < baricenters.Size(); i++) {
|
||||||
bari = crude.GetBari(i);
|
bari = baricenters[i];
|
||||||
|
|
||||||
unsigned int fine = Locate(0, bari);
|
unsigned int fine = Locate(0, bari);
|
||||||
unsigned int coarse = Locate(1, bari);
|
unsigned int coarse = Locate(1, bari);
|
||||||
|
@ -485,10 +491,10 @@ void VoronoiChain::BuildLevel(Nexus &nexus, unsigned int offset,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(step == steps-1) {
|
if(step == steps-1) {
|
||||||
if(!Optimize(coarse_vmean, coarse, centroids, counts, false))
|
if(!Optimize((int)coarse_vmean, coarse, centroids, counts, false))
|
||||||
step--;
|
step--;
|
||||||
} else
|
} else
|
||||||
Optimize(coarse_vmean, coarse, centroids, counts, true);
|
Optimize((int)coarse_vmean, coarse, centroids, counts, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
newfragments.clear();
|
newfragments.clear();
|
||||||
|
|
|
@ -24,6 +24,9 @@
|
||||||
History
|
History
|
||||||
|
|
||||||
$Log: not supported by cvs2svn $
|
$Log: not supported by cvs2svn $
|
||||||
|
Revision 1.5 2004/10/30 20:17:03 ponchio
|
||||||
|
Fixed big patches problem.
|
||||||
|
|
||||||
Revision 1.4 2004/09/30 00:27:42 ponchio
|
Revision 1.4 2004/09/30 00:27:42 ponchio
|
||||||
Lot of changes. Backup.
|
Lot of changes. Backup.
|
||||||
|
|
||||||
|
@ -49,7 +52,6 @@ First draft.
|
||||||
|
|
||||||
#include "pchain.h"
|
#include "pchain.h"
|
||||||
#include "pvoronoi.h"
|
#include "pvoronoi.h"
|
||||||
#include "crude.h"
|
|
||||||
#include "nexus.h"
|
#include "nexus.h"
|
||||||
#include "vfile.h"
|
#include "vfile.h"
|
||||||
|
|
||||||
|
@ -67,9 +69,10 @@ class VoronoiChain: public PChain {
|
||||||
mean_size(mean_s), min_size(min_s), max_size(max_s) {}
|
mean_size(mean_s), min_size(min_s), max_size(max_s) {}
|
||||||
virtual ~VoronoiChain() {}
|
virtual ~VoronoiChain() {}
|
||||||
|
|
||||||
void Init(Crude &crude, float scaling, int steps);
|
void Init(VFile<vcg::Point3f> &baricenters, float scaling, int steps);
|
||||||
virtual unsigned int Locate(unsigned int level, const vcg::Point3f &p);
|
virtual unsigned int Locate(unsigned int level, const vcg::Point3f &p);
|
||||||
void RemapFaces(Crude &crude, VFile<unsigned int> &face_remap,
|
void RemapFaces(VFile<vcg::Point3f> &baricenters,
|
||||||
|
VFile<unsigned int> &face_remap,
|
||||||
std::vector<unsigned int> &patch_faces, float scaling,
|
std::vector<unsigned int> &patch_faces, float scaling,
|
||||||
int steps);
|
int steps);
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,9 @@
|
||||||
History
|
History
|
||||||
|
|
||||||
$Log: not supported by cvs2svn $
|
$Log: not supported by cvs2svn $
|
||||||
|
Revision 1.21 2004/11/03 16:31:38 ponchio
|
||||||
|
Trying to fix big patches.
|
||||||
|
|
||||||
Revision 1.20 2004/10/30 20:17:03 ponchio
|
Revision 1.20 2004/10/30 20:17:03 ponchio
|
||||||
Fixed big patches problem.
|
Fixed big patches problem.
|
||||||
|
|
||||||
|
@ -107,18 +110,17 @@ using namespace std;
|
||||||
#include "fragment.h"
|
#include "fragment.h"
|
||||||
#include "nxsbuild.h"
|
#include "nxsbuild.h"
|
||||||
#include "watch.h"
|
#include "watch.h"
|
||||||
|
#include "nxsdispatcher.h"
|
||||||
using namespace vcg;
|
using namespace vcg;
|
||||||
using namespace nxs;
|
using namespace nxs;
|
||||||
|
|
||||||
|
|
||||||
void BuildFragment(Nexus &nexus, VoronoiPartition &part,
|
void BuildFragment(Nexus &nexus, VoronoiPartition &part,
|
||||||
set<unsigned int> &patches,
|
set<unsigned int> &patches,
|
||||||
Nexus::Update &update,
|
|
||||||
Fragment &fragment);
|
Fragment &fragment);
|
||||||
|
|
||||||
void SaveFragment(Nexus &nexus, VoronoiChain &chain,
|
void SaveFragment(Nexus &nexus, VoronoiChain &chain,
|
||||||
unsigned int level,
|
Fragment &fragin,
|
||||||
Nexus::Update &update,
|
|
||||||
Fragment &fragout);
|
Fragment &fragout);
|
||||||
|
|
||||||
void ReverseHistory(vector<Nexus::Update> &history);
|
void ReverseHistory(vector<Nexus::Update> &history);
|
||||||
|
@ -126,6 +128,9 @@ void ReverseHistory(vector<Nexus::Update> &history);
|
||||||
void TestBorders(Nexus &nexus);
|
void TestBorders(Nexus &nexus);
|
||||||
void TestPatches(Nexus &nexus);
|
void TestPatches(Nexus &nexus);
|
||||||
|
|
||||||
|
unsigned int current_level;
|
||||||
|
vector<unsigned int> patch_levels;
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
|
|
||||||
Decimation decimation = CLUSTER;
|
Decimation decimation = CLUSTER;
|
||||||
|
@ -258,13 +263,24 @@ int main(int argc, char *argv[]) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VFile<Point3f> baricenters;
|
||||||
|
if(!baricenters.Create(output + string(".bvr"))) {
|
||||||
|
cerr << "Could not create temporary baricenters file\n";
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
baricenters.Resize(crude.Faces());
|
||||||
|
|
||||||
|
//TODO use some smarter rule :P
|
||||||
|
for(unsigned int i = 0; i < crude.Faces(); i++) {
|
||||||
|
baricenters[i] = crude.GetBari(i);
|
||||||
|
}
|
||||||
/* BUILDING FIRST LEVEL */
|
/* BUILDING FIRST LEVEL */
|
||||||
|
|
||||||
//Remapping faces and vertices using level 0 and 1 of the chain
|
//Remapping faces and vertices using level 0 and 1 of the chain
|
||||||
cerr << "Remapping faces.\n";
|
cerr << "Remapping faces.\n";
|
||||||
vector<unsigned int> patch_faces;
|
vector<unsigned int> patch_faces;
|
||||||
|
|
||||||
vchain.RemapFaces(crude, face_remap, patch_faces,
|
vchain.RemapFaces(baricenters, face_remap, patch_faces,
|
||||||
scaling, optimization_steps);
|
scaling, optimization_steps);
|
||||||
|
|
||||||
cerr << "Remapping vertices.\n";
|
cerr << "Remapping vertices.\n";
|
||||||
|
@ -274,6 +290,8 @@ int main(int argc, char *argv[]) {
|
||||||
|
|
||||||
if(stop_after_remap) return 0;
|
if(stop_after_remap) return 0;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
cerr << "Allocating space\n";
|
cerr << "Allocating space\n";
|
||||||
//allocate chunks for patches and copy faces (absoklute indexing) into them.
|
//allocate chunks for patches and copy faces (absoklute indexing) into them.
|
||||||
NexusAllocate(crude, nexus, face_remap, patch_faces, patch_verts);
|
NexusAllocate(crude, nexus, face_remap, patch_faces, patch_verts);
|
||||||
|
@ -282,12 +300,20 @@ int main(int argc, char *argv[]) {
|
||||||
//insert vertices and remap faces, prepare borders
|
//insert vertices and remap faces, prepare borders
|
||||||
NexusFill(crude, nexus, vert_remap, border_remap);
|
NexusFill(crude, nexus, vert_remap, border_remap);
|
||||||
|
|
||||||
// NexusFixBorder(nexus, border_remap);
|
//Now face_remap, vert_remap, border_remap can be deleted!
|
||||||
|
face_remap.Delete();
|
||||||
|
vert_remap.Delete();
|
||||||
|
border_remap.Delete();
|
||||||
|
baricenters.Delete();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//filling history
|
//filling history
|
||||||
Nexus::Update update;
|
Nexus::Update update;
|
||||||
for(unsigned int i = 0; i < nexus.index.size(); i++)
|
for(unsigned int i = 0; i < nexus.index.size(); i++) {
|
||||||
update.created.push_back(i);
|
update.created.push_back(i);
|
||||||
|
patch_levels.push_back(0);
|
||||||
|
}
|
||||||
nexus.history.push_back(update);
|
nexus.history.push_back(update);
|
||||||
|
|
||||||
//unify vertices otherwise you may get cracks.
|
//unify vertices otherwise you may get cracks.
|
||||||
|
@ -297,9 +323,15 @@ int main(int argc, char *argv[]) {
|
||||||
/* BUILDING OTHER LEVELS */
|
/* BUILDING OTHER LEVELS */
|
||||||
|
|
||||||
Report report;
|
Report report;
|
||||||
|
Dispatcher dispatcher(&nexus, &vchain);
|
||||||
|
if(!dispatcher.Init("servers.txt")) {
|
||||||
|
cerr << "Could not parse server file: " << "servers.txt"
|
||||||
|
<< " proceding locally\n";
|
||||||
|
}
|
||||||
|
|
||||||
unsigned int oldoffset = 0;
|
unsigned int oldoffset = 0;
|
||||||
for(unsigned int level = 1; level < max_level; level++) {
|
for(unsigned int level = 1; level < max_level; level++) {
|
||||||
|
current_level = level;
|
||||||
cerr << "Level: " << level << endl;
|
cerr << "Level: " << level << endl;
|
||||||
|
|
||||||
unsigned int newoffset = nexus.index.size();
|
unsigned int newoffset = nexus.index.size();
|
||||||
|
@ -307,20 +339,20 @@ int main(int argc, char *argv[]) {
|
||||||
|
|
||||||
report.Init(vchain.oldfragments.size(), 1);
|
report.Init(vchain.oldfragments.size(), 1);
|
||||||
unsigned int fcount = 0;
|
unsigned int fcount = 0;
|
||||||
vector<Nexus::Update> level_history;
|
|
||||||
map<unsigned int, set<unsigned int> >::iterator fragment;
|
map<unsigned int, set<unsigned int> >::iterator fragment;
|
||||||
for(fragment = vchain.oldfragments.begin();
|
for(fragment = vchain.oldfragments.begin();
|
||||||
fragment != vchain.oldfragments.end(); fragment++) {
|
fragment != vchain.oldfragments.end(); fragment++) {
|
||||||
report.Step(fcount++);
|
report.Step(fcount++);
|
||||||
|
|
||||||
|
Fragment *fragin = new Fragment;
|
||||||
|
BuildFragment(nexus, vchain.levels[level+1],
|
||||||
Fragment fragin;
|
(*fragment).second, *fragin);
|
||||||
BuildFragment(nexus, vchain.levels[level+1], (*fragment).second,
|
|
||||||
update, fragin);
|
|
||||||
|
|
||||||
|
dispatcher.SendFragment(fragin);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
//this can be executed on a remote host
|
||||||
|
|
||||||
//TODO move this part to remote....
|
//TODO move this part to remote....
|
||||||
vector<Point3f> newvert;
|
vector<Point3f> newvert;
|
||||||
|
@ -336,19 +368,19 @@ int main(int argc, char *argv[]) {
|
||||||
fragout.id = fragin.id;
|
fragout.id = fragin.id;
|
||||||
fragout.seeds = fragin.seeds;
|
fragout.seeds = fragin.seeds;
|
||||||
fragout.seeds_id = fragin.seeds_id;
|
fragout.seeds_id = fragin.seeds_id;
|
||||||
Split(fragout, newvert, newface, newbord, vchain.levels[level+1]);
|
Split(fragout, newvert, newface, newbord);//, vchain.levels[level+1]);
|
||||||
|
|
||||||
|
|
||||||
|
SaveFragment(nexus, vchain, fragin, fragout);
|
||||||
|
*/
|
||||||
|
dispatcher.processmsgs();
|
||||||
SaveFragment(nexus, vchain, level, update, fragout);
|
}
|
||||||
level_history.push_back(update);
|
//TODO porcata!!!!
|
||||||
|
while(dispatcher.frags.size()) {
|
||||||
|
dispatcher.processmsgs();
|
||||||
}
|
}
|
||||||
report.Finish();
|
|
||||||
|
|
||||||
for(unsigned int i = 0; i < level_history.size(); i++)
|
report.Finish();
|
||||||
nexus.history.push_back(level_history[i]);
|
|
||||||
|
|
||||||
if(vchain.oldfragments.size() == 1) break;
|
if(vchain.oldfragments.size() == 1) break;
|
||||||
|
|
||||||
|
@ -379,8 +411,8 @@ int main(int argc, char *argv[]) {
|
||||||
|
|
||||||
void BuildFragment(Nexus &nexus, VoronoiPartition &part,
|
void BuildFragment(Nexus &nexus, VoronoiPartition &part,
|
||||||
set<unsigned int> &patches,
|
set<unsigned int> &patches,
|
||||||
Nexus::Update &update,
|
|
||||||
Fragment &fragment) {
|
Fragment &fragment) {
|
||||||
|
|
||||||
set<unsigned int>::iterator f;
|
set<unsigned int>::iterator f;
|
||||||
for(f = patches.begin(); f != patches.end(); f++) {
|
for(f = patches.begin(); f != patches.end(); f++) {
|
||||||
fragment.pieces.push_back(NxsPatch());
|
fragment.pieces.push_back(NxsPatch());
|
||||||
|
@ -396,42 +428,54 @@ void BuildFragment(Nexus &nexus, VoronoiPartition &part,
|
||||||
memcpy(&*nxs.face.begin(), patch.FaceBegin(), patch.nf * 3*sizeof(short));
|
memcpy(&*nxs.face.begin(), patch.FaceBegin(), patch.nf * 3*sizeof(short));
|
||||||
for(unsigned int i = 0; i < border.Size(); i++) {
|
for(unsigned int i = 0; i < border.Size(); i++) {
|
||||||
Link &link = border[i];
|
Link &link = border[i];
|
||||||
if(!link.IsNull())
|
if(!link.IsNull() && patch_levels[link.end_patch] == current_level-1)
|
||||||
nxs.bord.push_back(link);
|
nxs.bord.push_back(link);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
update.created.clear();
|
set<unsigned int> seeds;
|
||||||
update.erased.clear();
|
vector<int> nears;
|
||||||
|
vector<float> dists;
|
||||||
set<unsigned int> &fcells = patches;
|
int nnears = 10;
|
||||||
set<unsigned int>::iterator s;
|
if(part.size() < 10) nnears = part.size();
|
||||||
for(s = fcells.begin(); s != fcells.end(); s++) {
|
for(f = patches.begin(); f != patches.end(); f++) {
|
||||||
update.erased.push_back(*s);
|
Point3f ¢er = nexus.index[*f].sphere.Center();
|
||||||
|
part.Closest(center, nnears, nears, dists);
|
||||||
|
for(int i = 0; i < nnears; i++)
|
||||||
|
seeds.insert(nears[i]);
|
||||||
}
|
}
|
||||||
|
for(f = seeds.begin(); f != seeds.end(); f++) {
|
||||||
//copy all seeds! //TODO copy only closest ones
|
Point3f &p = part[*f];
|
||||||
for(unsigned int i = 0; i < part.size(); i++) {
|
fragment.seeds.push_back(p);
|
||||||
fragment.seeds.push_back(part[i]);
|
fragment.seeds_id.push_back(*f);
|
||||||
fragment.seeds_id.push_back(i);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void SaveFragment(Nexus &nexus, VoronoiChain &chain,
|
void SaveFragment(Nexus &nexus, VoronoiChain &chain,
|
||||||
unsigned int level,
|
Fragment &fragin,
|
||||||
Nexus::Update &update,
|
|
||||||
Fragment &fragout) {
|
Fragment &fragout) {
|
||||||
|
|
||||||
|
|
||||||
|
set<unsigned int> orig_patches;
|
||||||
|
|
||||||
|
Nexus::Update update;
|
||||||
|
for(unsigned int i = 0; i < fragin.pieces.size(); i++) {
|
||||||
|
NxsPatch &patch = fragin.pieces[i];
|
||||||
|
update.erased.push_back(patch.patch);
|
||||||
|
orig_patches.insert(patch.patch);
|
||||||
|
}
|
||||||
|
|
||||||
vector<unsigned int> patch_remap;
|
vector<unsigned int> patch_remap;
|
||||||
patch_remap.resize(fragout.pieces.size());
|
patch_remap.resize(fragout.pieces.size());
|
||||||
|
|
||||||
for(unsigned int i = 0; i < fragout.pieces.size(); i++) {
|
for(unsigned int i = 0; i < fragout.pieces.size(); i++) {
|
||||||
NxsPatch &patch = fragout.pieces[i];
|
NxsPatch &patch = fragout.pieces[i];
|
||||||
//TODO detect best parameter below for bordersize...
|
//TODO detect best parameter below for bordersize...
|
||||||
unsigned int patch_idx = nexus.AddPatch(patch.vert.size(),
|
unsigned int patch_idx = nexus.AddPatch(patch.vert.size(),
|
||||||
patch.face.size()/3,
|
patch.face.size()/3,
|
||||||
6 * patch.bord.size());
|
6 * patch.bord.size());
|
||||||
|
patch_levels.push_back(current_level);
|
||||||
Nexus::PatchInfo &entry = nexus.index[patch_idx];
|
Nexus::PatchInfo &entry = nexus.index[patch_idx];
|
||||||
entry.error = fragout.error;
|
entry.error = fragout.error;
|
||||||
|
|
||||||
|
@ -455,19 +499,59 @@ void SaveFragment(Nexus &nexus, VoronoiChain &chain,
|
||||||
entry.sphere.Add(outpatch.vert[v]);
|
entry.sphere.Add(outpatch.vert[v]);
|
||||||
nexus.sphere.Add(outpatch.vert[v]);
|
nexus.sphere.Add(outpatch.vert[v]);
|
||||||
}
|
}
|
||||||
//remap borders
|
|
||||||
|
|
||||||
|
vector<Link> actual;
|
||||||
|
//remap internal borders
|
||||||
for(unsigned int i = 0; i < outpatch.bord.size(); i++) {
|
for(unsigned int i = 0; i < outpatch.bord.size(); i++) {
|
||||||
Link &link = outpatch.bord[i];
|
Link &link = outpatch.bord[i];
|
||||||
if(link.end_patch >= (1<<31)) //internal
|
if(link.end_patch >= (1<<31)) { //internal
|
||||||
link.end_patch = patch_remap[link.end_patch - (1<<31)];
|
link.end_patch = patch_remap[link.end_patch - (1<<31)];
|
||||||
else { //if external add the reverse border
|
actual.push_back(link);
|
||||||
Border rborder = nexus.GetBorder(link.end_patch);
|
}
|
||||||
|
}
|
||||||
|
//TODO not efficient!
|
||||||
|
//processing external borders
|
||||||
|
for(unsigned int i = 0; i < outpatch.bord.size(); i++) {
|
||||||
|
Link &link = outpatch.bord[i];
|
||||||
|
if(link.end_patch >= (1<<31)) continue;
|
||||||
|
|
||||||
|
unsigned short &start_vert = link.start_vert;
|
||||||
|
unsigned int &start_patch = patch_idx;
|
||||||
|
|
||||||
|
Border cborder = nexus.GetBorder(link.end_patch);
|
||||||
|
for(unsigned int k = 0; k < cborder.Size(); k++) {
|
||||||
|
Link &clink = cborder[k];
|
||||||
|
if(clink.start_vert != link.end_vert) continue;
|
||||||
|
if(patch_levels[clink.end_patch] < current_level-1) continue;
|
||||||
|
|
||||||
|
unsigned short &end_vert = clink.end_vert;
|
||||||
|
unsigned int &end_patch = clink.end_patch;
|
||||||
|
|
||||||
|
Link newlink;
|
||||||
|
|
||||||
|
newlink.start_vert = start_vert;
|
||||||
|
newlink.end_vert = end_vert;
|
||||||
|
newlink.end_patch = end_patch;
|
||||||
|
|
||||||
|
actual.push_back(newlink);
|
||||||
|
// nexus.AddBorder(start_patch, 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();
|
unsigned int pos = rborder.Size();
|
||||||
if(nexus.borders.ResizeBorder(link.end_patch, pos+1)) {
|
if(nexus.borders.ResizeBorder(link.end_patch, pos+1)) {
|
||||||
rborder = nexus.GetBorder(link.end_patch);
|
rborder = nexus.GetBorder(link.end_patch);
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(rborder.Size() < rborder.Available());
|
assert(rborder.Size() < rborder.Available());
|
||||||
assert(rborder.Available() > pos);
|
assert(rborder.Available() > pos);
|
||||||
|
|
||||||
|
@ -475,17 +559,23 @@ void SaveFragment(Nexus &nexus, VoronoiChain &chain,
|
||||||
newlink.start_vert = link.end_vert;
|
newlink.start_vert = link.end_vert;
|
||||||
newlink.end_vert = link.start_vert;
|
newlink.end_vert = link.start_vert;
|
||||||
newlink.end_patch = patch_idx;
|
newlink.end_patch = patch_idx;
|
||||||
rborder[pos] = newlink;
|
rborder[pos] = newlink;*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Border border = nexus.GetBorder(patch_idx);
|
Border border = nexus.GetBorder(patch_idx);
|
||||||
assert(border.Available() >= outpatch.bord.size());
|
if(nexus.borders.ResizeBorder(patch_idx, actual.size())) {
|
||||||
|
border = nexus.GetBorder(patch_idx);
|
||||||
|
}
|
||||||
|
memcpy(&(border[0]), &(actual[0]),
|
||||||
|
actual.size() * sizeof(Link));
|
||||||
|
/* assert(border.Available() >= outpatch.bord.size());
|
||||||
if(nexus.borders.ResizeBorder(patch_idx, outpatch.bord.size())) {
|
if(nexus.borders.ResizeBorder(patch_idx, outpatch.bord.size())) {
|
||||||
border = nexus.GetBorder(patch_idx);
|
border = nexus.GetBorder(patch_idx);
|
||||||
}
|
}
|
||||||
memcpy(&(border[0]), &(outpatch.bord[0]),
|
memcpy(&(border[0]), &(outpatch.bord[0]),
|
||||||
outpatch.bord.size() * sizeof(Link));
|
outpatch.bord.size() * sizeof(Link)); */
|
||||||
}
|
}
|
||||||
|
nexus.history.push_back(update);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ReverseHistory(vector<Nexus::Update> &history) {
|
void ReverseHistory(vector<Nexus::Update> &history) {
|
||||||
|
|
Loading…
Reference in New Issue