Porting and debug.

This commit is contained in:
Federico Ponchio 2005-01-21 17:09:13 +00:00
parent a264ec7c78
commit a8a6b48bc0
17 changed files with 386 additions and 455 deletions

View File

@ -24,6 +24,9 @@
History
$Log: not supported by cvs2svn $
Revision 1.5 2004/10/08 14:46:26 ponchio
Working version.
Revision 1.4 2004/09/30 00:27:08 ponchio
Added used counter.
@ -71,18 +74,18 @@ struct Link {
class Border {
public:
Border(Link *l = NULL, unsigned short _used = 0, unsigned short _size = 0):
start(l), used(_used), size(_size) {}
links(l), used(_used), size(_size), start(0) {}
unsigned int Size() { return used; }
//TODO rename available to capacity.
unsigned int Available() { return size; }
Link &operator[](unsigned int i) { return start[i]; }
Link *Start() { return start; }
Link &operator[](unsigned int i) { return links[i]; }
Link *Start() { return links; }
//TODO implement an iterator!
private:
Link *start;
unsigned short used;
unsigned short size;
Link *links;
unsigned int used;
unsigned int size;
unsigned int start;
};
}

View File

@ -6,19 +6,22 @@ using namespace nxs;
bool BorderServer::Create(const string &file) {
ram_used = 0;
return IndexFile<BorderEntry>::Create(file, 2 * sizeof(Link));
return IndexFile<Border>::Create(file, 2 * sizeof(Link));
}
bool BorderServer::Load(const string &file, bool rdonly) {
ram_used = 0;
cerr << "Loading...\n";
return IndexFile<BorderEntry>::Load(file, rdonly);
bool success = IndexFile<Border>::Load(file, rdonly);
if(!success) return false;
for(unsigned int i = 0; i < size(); i++)
operator[](i).links = NULL;
return true;
}
void BorderServer::Close() {
if(!Opened()) return;
Flush();
IndexFile<BorderEntry>::Close();
IndexFile<Border>::Close();
}
void BorderServer::Flush() {
@ -31,20 +34,20 @@ void BorderServer::Flush() {
index.clear();
}
void BorderServer::AddBorder(unsigned short nbord, unsigned int used) {
BorderEntry entry;
void BorderServer::AddBorder(unsigned short _size, unsigned int used) {
Border entry;
assert((Length() % sizeof(Link)) == 0);
entry.start = Length()/ sizeof(Link);
entry.size = nbord;
entry.size = _size;
entry.used = used;
entry.links = NULL;
push_back(entry);
Redim(entry.start * sizeof(Link) + nbord * sizeof(Link));
Redim(entry.start * sizeof(Link) + _size * sizeof(Link));
}
Border BorderServer::GetBorder(unsigned int border, bool flush) {
BorderEntry &entry = operator[](border);
Border &BorderServer::GetBorder(unsigned int border, bool flush) {
Border &entry = operator[](border);
//assert(entry.size != 0);
if(index.count(border)) {
//assert(entry.links);
@ -60,60 +63,58 @@ Border BorderServer::GetBorder(unsigned int border, bool flush) {
index.erase(to_flush);
FlushBorder(to_flush);
}
assert(!entry.links);
if(entry.size != 0)
entry.links = GetRegion(entry.start, entry.size);
pqueue.push_front(border);
index[border] = pqueue.begin();
ram_used += entry.size;
}
return Border(entry.links, entry.used, entry.size);
return entry;
}
//TODO Change when remving borderentry class.
bool BorderServer::ResizeBorder(unsigned int border, unsigned int nbord) {
assert(nbord < 65500);
void BorderServer::ResizeBorder(unsigned int border, unsigned int used) {
assert(border < size());
GetBorder(border);
BorderEntry &entry = operator[](border);
if(nbord > entry.size) {
int capacity = nbord;
if(capacity < entry.size*2)
Border &entry = GetBorder(border);
if(used <= entry.size) {
entry.used = used;
return;
}
int capacity = used;
if(capacity < entry.size * 2)
capacity = entry.size * 2;
if(capacity > 65500)
capacity = 65500;
unsigned int newstart = Length()/sizeof(Link);
Redim((newstart + capacity) * sizeof(Link));
Link *dst = GetRegion(newstart, capacity);
Link *newlinks = new Link[capacity];
if(entry.used > 0) {
Link *src = GetRegion(entry.start, entry.size);
memcpy(dst, src, entry.used * sizeof(Link));
assert(entry.links);
memcpy(newlinks, entry.links, entry.used * sizeof(Link));
delete []entry.links;
entry.links = NULL;
}
entry.links = dst;
assert(entry.links == NULL);
entry.links = newlinks;
entry.start = newstart;
entry.size = capacity;
entry.used = nbord;
return true;
}
entry.used = nbord;
return false;
entry.used = used;
}
void BorderServer::FlushBorder(unsigned int border) {
BorderEntry &entry = operator[](border);
Border &entry = operator[](border);
//assert(entry.links);
if(entry.size && !MFile::IsReadOnly()) { //write back patch
MFile::SetPosition((int64)entry.start * sizeof(Link));
MFile::WriteBuffer(entry.links, entry.used * sizeof(Link));
}
if(entry.size)
if(entry.links)
delete [](entry.links);
entry.links = NULL;
ram_used -= entry.size;
}
Link *BorderServer::GetRegion(unsigned int start, unsigned int size) {
assert(size > 0);
SetPosition(start * sizeof(Link));
if(size == 0) return NULL;
SetPosition((int64)start * sizeof(Link));
Link *buf = new Link[size];
assert(buf);
ReadBuffer(buf, size * sizeof(Link));

View File

@ -16,14 +16,14 @@
namespace nxs {
//This should be Border class!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
struct BorderEntry {
/*struct BorderEntry {
unsigned int start; //granuralita' Link
unsigned short size; //in Links //TODO what are this? be clear!
unsigned short used; //in Links
Link *links;
};
};*/
class BorderServer: public IndexFile<BorderEntry> {
class BorderServer: public IndexFile<Border> {
public:
BorderServer(): ram_max(1000000), ram_used(0) {}
~BorderServer() { Close(); }
@ -32,17 +32,16 @@ class BorderServer: public IndexFile<BorderEntry> {
void Close();
void Flush();
void AddBorder(unsigned short nbord, unsigned int used = 0);
Border GetBorder(unsigned int border, bool flush = true);
//return true if you need to reread border as it changed location
bool ResizeBorder(unsigned int border, unsigned int nbord);
void AddBorder(unsigned short size, unsigned int used = 0);
Border &GetBorder(unsigned int border, bool flush = true);
void ResizeBorder(unsigned int border, unsigned int size);
unsigned int BorderSize(unsigned int i) {
/*unsigned int BorderSize(unsigned int i) {
return operator[](i).used;
}
unsigned int BorderCapacity(unsigned int i) {
return operator[](i).size;
}
} */
protected:
unsigned int ram_max;
unsigned int ram_used;

View File

@ -7,8 +7,8 @@
using namespace std;
using namespace nxs;
Extraction::Extraction(): target_error(4.0f), extr_max(0xffffffff),
draw_max(640), disk_max(100) {
Extraction::Extraction(): target_error(4.0f), extr_max(10000),
draw_max(10000), disk_max(100) {
metric = new FrustumMetric;
}
@ -63,7 +63,7 @@ void Extraction::Init() {
for(n = node.out_begin(); n != node.out_end(); n++) {
if(!visited[(*n).node - root]) {
float maxerror = 0;
float maxerror = -1;
Link &link = *n;
for(Link::iterator k = link.begin(); k != link.end(); k++) {
@ -110,35 +110,71 @@ void Extraction::Update(NexusMt *_mt) {
Init();
//first we coarse
while(back.size()) {
if(draw_used <= draw_max &&
extr_used <= extr_max &&
(front.size() && back.front().error > front.front().error))
bool no_draw = false;
bool no_disk = false;
//TODO big problem: nodes a (error 10) with parent b (error -1)
//i try to refine a, refine b (recursive) but fail to refine a
//next step i coarse b whis cause a cycle.
while(1) {
if(!no_draw && //we have buffer
front.size() && //we are not at max level
front[0].error > target_error) { //we are not already target_error
pop_heap(front.begin(), front.end());
HeapNode hnode = front.back();
front.pop_back();
if(!Visited(hnode.node)) {
if(!Refine(hnode)) {
no_draw = true;
}
}
continue;
}
if(!back.size()) {
//cerr << "nothing to coarse!\n";
break; //nothing to coarse (happen only on extr_max < root.extr
}
if(no_draw) { //suppose i have no more buffer
//if i do error damages coarsening better get out
if(front.size() && ((back.front().error + 0.001) >= front.front().error)) {
//cerr << "Balanced cut\n";
break;
}
if(!front.size() && back.front().error >= target_error) {
//cerr << "Maxed out\n";
break;
}
}
//nothing to refine, coarse only if error <= target_error
if(!no_draw && back.front().error >= target_error) {
//cerr << "error dominating\n";
break;
}
pop_heap(back.begin(), back.end(), greater<HeapNode>());
HeapNode hnode = back.back();
back.pop_back();
if(Visited(hnode.node)) {
if(!Coarse(hnode)) { //push back on heap the heapnode
bool recursive = false;
Node::iterator i;
for(i = hnode.node->out_begin(); i != hnode.node->out_end(); i++) {
Node *child = (*i).node;
if(visited[child-root]) recursive = true;
}
if(!recursive && !Coarse(hnode)) { //no more disk so.. push back on heap the heapnode
back.push_back(hnode);
push_heap(back.begin(), back.end(), greater<HeapNode>());
break;
}
}
back.pop_back();
}
while(front.size() && (*front.begin()).error > target_error) {
pop_heap(front.begin(), front.end());
HeapNode hnode = front.back();
if(!Visited(hnode.node)) {
if(!Refine(hnode.node)) {
push_heap(front.begin(), front.end());
break;
}
}
front.pop_back();
no_draw = false;
}
Select();
@ -146,7 +182,7 @@ void Extraction::Update(NexusMt *_mt) {
//Preloading now
for(unsigned int i = 0; i < 100; i++) {
for(unsigned int i = 0; i < 1000; i++) {
if(!front.size() && !back.size()) break;
if((i%2) && front.size()) {
pop_heap(front.begin(), front.end());
@ -177,7 +213,7 @@ void Extraction::Update(NexusMt *_mt) {
}
float Extraction::GetRefineError(Node *node) {
float maxerror = 0;
float maxerror = -1;
Node::iterator i;
for(i = node->in_begin(); i != node->in_end(); i++) {
Link &link = *i;
@ -190,23 +226,43 @@ float Extraction::GetRefineError(Node *node) {
return maxerror;
}
bool Extraction::Refine(Node *node) {
bool Extraction::Refine(HeapNode &hnode) {
Node *node = hnode.node;
//cerr << "Refine node: " << (void *)hnode.node << " err: " << hnode.error << endl;
//recursively refine parent if applicable.
Node::iterator i;
for(i = node->in_begin(); i != node->in_end(); i++) {
Node *parent = (*i).node;
if(!Visited(parent))
if(!Refine(parent))
return false;
if(!Visited(parent)) {
//Here i use parent refine error!!!
if(!Refine(HeapNode(parent, hnode.error))) return false;
}
}
Cost cost;
Diff(node, cost);
if(disk_used + cost.disk > disk_max) return false;
if(extr_used + cost.extr > extr_max) return false;
if(draw_used + cost.draw > draw_max) return false;
bool failed = false;
if(disk_used + cost.disk > disk_max) {
//cerr << "Disk failed\n";
failed = true;
}
if(extr_used + cost.extr > extr_max) {
//cerr << "Extr failed\n";
failed = true;
}
if(draw_used + cost.draw > draw_max) {
//cerr << "Draw failed\n";
failed = true;
}
if(failed) {
front.push_back(hnode);
push_heap(front.begin(), front.end());
return false;
}
extr_used += cost.extr;
draw_used += cost.draw;
disk_used += cost.disk;
@ -225,20 +281,26 @@ bool Extraction::Refine(Node *node) {
front.push_back(HeapNode((*i).node, maxerror));
}
push_heap(front.begin(), front.end());
back.push_back(hnode);
push_heap(back.begin(), back.end(), greater<HeapNode>());
return true;
}
bool Extraction::Coarse(HeapNode &hnode) {
//cerr << "Coarse node: " << (void *)hnode.node << " err: " << hnode.error << endl;
Node *node = hnode.node;
//recursively coarse children if applicable.
Node::iterator i;
for(i = node->out_begin(); i != node->out_end(); i++) {
Node *child = (*i).node;
float error = GetRefineError(child);
HeapNode hchild(child, error);
if(Visited(child))
if(Visited(child)) {
if(!Coarse(hchild)) return false;
}
}
Cost cost;
@ -308,7 +370,7 @@ void Extraction::Visit(Node *node) {
disk_used += cost.disk;
for(i = node->out_begin(); i != node->out_end(); i++) {
float maxerror = 0;
float maxerror = -1;
Link &link = *i;
for(Link::iterator k = link.begin(); k != link.end(); k++) {
Entry &entry = (*mt)[(*k).patch];

View File

@ -72,7 +72,7 @@ class Extraction {
bool Expand(HeapNode &node);
void Diff(Node *node, Cost &cost);
bool Refine(Node *node);
bool Refine(HeapNode &node);
bool Coarse(HeapNode &node);
void Init();

View File

@ -31,8 +31,14 @@ namespace nxs {
//float dist = Distance(sphere, frustum.ViewPoint());
if(dist < 0)
return 1e20f;
if(frustum.IsOutside(sphere.Center(), sphere.Radius()))
return -1;
float remote = frustum.Remoteness(sphere.Center(), sphere.Radius());
if(remote > 0)
return (entry.error/remote)/frustum.Resolution(dist);
//if(frustum.IsOutside(sphere.Center(), sphere.Radius()))
//return -1;
return entry.error/frustum.Resolution(dist);
}
};

View File

@ -161,27 +161,10 @@ Patch &Nexus::GetPatch(unsigned int patch, bool flush) {
return *(entry.patch);
}
Border Nexus::GetBorder(unsigned int patch, bool flush) {
Border &Nexus::GetBorder(unsigned int patch, bool flush) {
return borders.GetBorder(patch);
}
/*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.Available() > pos);
border[pos] = link;
}*/
unsigned int Nexus::AddPatch(unsigned int nvert, unsigned int nface,
unsigned int nbord) {
@ -206,121 +189,6 @@ unsigned int Nexus::AddPatch(unsigned int nvert, unsigned int nface,
return size() - 1;
}
/*void Nexus::Unify(float threshold) {
//TODO what if colors or normals or strips?
unsigned int duplicated = 0;
unsigned int degenerate = 0;
for(unsigned int p = 0; p < size(); p++) {
Entry &entry = operator[](p);
Patch &patch = GetPatch(p);
unsigned int vcount = 0;
map<Point3f, unsigned short> vertices;
vector<unsigned short> remap;
remap.resize(patch.nv);
for(unsigned int i = 0; i < patch.nv; i++) {
Point3f &point = patch.Vert(i);
if(!vertices.count(point))
vertices[point] = vcount++;
else
duplicated++;
remap[i] = vertices[point];
}
assert(vertices.size() <= patch.nv);
if(vertices.size() == patch.nv) //no need to unify
continue;
vector<Point3f> newvert;
newvert.resize(vertices.size());
map<Point3f, unsigned short>::iterator k;
for(k = vertices.begin(); k != vertices.end(); k++) {
newvert[(*k).second] = (*k).first;
}
vector<unsigned short> newface;
//check no degenerate faces get created.
for(unsigned int f = 0; f < entry.nface; f++) {
unsigned short *face = patch.Face(f);
if(face[0] != face[1] && face[1] != face[2] && face[0] != face[2] &&
newvert[remap[face[0]]] != newvert[remap[face[1]]] &&
newvert[remap[face[0]]] != newvert[remap[face[2]]] &&
newvert[remap[face[1]]] != newvert[remap[face[2]]]) {
newface.push_back(remap[face[0]]);
newface.push_back(remap[face[1]]);
newface.push_back(remap[face[2]]);
} else {
degenerate++;
}
}
//rewrite patch now.
entry.nvert = newvert.size();
entry.nface = newface.size()/3;
patch.Init(signature, entry.nvert, entry.nface);
memcpy(patch.VertBegin(), &(newvert[0]), entry.nvert*sizeof(Point3f));
memcpy(patch.FaceBegin(), &(newface[0]), entry.nface*3*sizeof(short));
//testiamo il tutto... TODO remove this of course
for(unsigned int i =0; i < patch.nf; i++) {
for(int k =0 ; k < 3; k++)
if(patch.Face(i)[k] >= patch.nv) {
cerr <<" Unify has problems\n";
exit(0);
}
}
//fix patch borders now
set<unsigned int> close; //bordering pathes
Border border = GetBorder(p);
for(unsigned int b = 0; b < border.Size(); b++) {
if(border[b].IsNull()) continue;
close.insert(border[b].end_patch);
border[b].start_vert = remap[border[b].start_vert];
}
set<unsigned int>::iterator c;
for(c = close.begin(); c != close.end(); c++) {
Border bord = GetBorder(*c);
for(unsigned int b = 0; b < bord.Size(); b++) {
if(bord[b].IsNull()) continue;
if(bord[b].end_patch == p) {
bord[b].end_vert = remap[bord[b].end_vert];
}
}
}
}
//better to compact directly borders than setting them null.
//finally: there may be duplicated borders
for(unsigned int p = 0; p < size(); p++) {
Border border = GetBorder(p);
set<Link> links;
for(unsigned int b = 0; b < border.Size(); b++) {
Link &link = border[b];
assert(!link.IsNull());
//if(border[b].IsNull()) continue;
links.insert(link);
}
int count = 0;
for(set<Link>::iterator k = links.begin(); k != links.end(); k++)
border[count++] = *k;
borders[p].used = links.size();
}
totvert -= duplicated;
if(duplicated)
cerr << "Found " << duplicated << " duplicated vertices" << endl;
if(degenerate)
cerr << "Found " << degenerate << " degenerate face while unmifying\n";
}*/
Patch *Nexus::LoadPatch(unsigned int idx) {
assert(idx < size());
Entry &entry = operator[](idx);

View File

@ -74,7 +74,7 @@ class Nexus: public IndexFile<Entry> {
unsigned int AddPatch(unsigned int nv, unsigned int nf, unsigned int nb);
Patch &GetPatch(unsigned int patch, bool flush = true);
Border GetBorder(unsigned int patch, bool flush = true);
Border &GetBorder(unsigned int patch, bool flush = true);
unsigned int &MaxRam() { return ram_max; }
// void AddBorder(unsigned int patch, Link &link);

View File

@ -24,6 +24,9 @@
History
$Log: not supported by cvs2svn $
Revision 1.29 2005/01/17 17:35:47 ponchio
Small changes and adding realtime extr.
Revision 1.28 2005/01/14 15:25:29 ponchio
Revolution.
@ -425,7 +428,7 @@ int main(int argc, char *argv[]) {
/* if(show_borders) {
for(unsigned int i = 0; i < cells.size(); i++) {
Border border = nexus.GetBorder(cells[i]);
Border &border = nexus.GetBorder(cells[i]);
Patch &patch = nexus.GetPatch(cells[i]);
glPointSize(4);
glColor3f(1.0f, 1.0f, 1.0f);

View File

@ -39,7 +39,7 @@ void nxs::ComputeNormals(Nexus &nexus) {
//TODO optimize! it is not necessary to read all the borders.
for(unsigned int p = 0; p < nexus.size(); p++) {
Border border = nexus.GetBorder(p);
Border &border = nexus.GetBorder(p);
tmpb_start.push_back(tmpb_offset);
tmpb_offset += border.Size();
}
@ -106,7 +106,7 @@ void nxs::ComputeNormals(Nexus &nexus) {
}
Border border = nexus.GetBorder(p);
Border &border = nexus.GetBorder(p);
map<unsigned int, map<unsigned short, Point3f> > bnorm;
@ -125,7 +125,7 @@ void nxs::ComputeNormals(Nexus &nexus) {
map<unsigned int, map<unsigned short, Point3f> >::iterator k;
for(k = bnorm.begin(); k != bnorm.end(); k++) {
unsigned int patch = (*k).first;
Border border = nexus.GetBorder(patch);
Border &border = nexus.GetBorder(patch);
unsigned int offset = tmpb_start[patch];
for(unsigned int i = 0; i < border.Size(); i++) {
Link &link = border[i];
@ -151,7 +151,7 @@ void nxs::ComputeNormals(Nexus &nexus) {
set<unsigned int>::iterator k;
for(k = close.begin(); k != close.end(); k++) {
Border remote = nexus.GetBorder(*k);
Border &remote = nexus.GetBorder(*k);
unsigned int off = tmpb_start[*k];
for(unsigned int i = 0; i < remote.Size(); i++) {
@ -172,7 +172,7 @@ void nxs::ComputeNormals(Nexus &nexus) {
for(unsigned int p = 0; p < nexus.size(); p++) {
report.Step(p);
Patch &patch = nexus.GetPatch(p);
Border border = nexus.GetBorder(p);
Border &border = nexus.GetBorder(p);
for(unsigned int i = 0; i < border.Size(); i++) {
Link &link = border[i];
@ -357,7 +357,7 @@ void nxs::Unify(Nexus &nexus, float threshold) {
//fix patch borders now
set<unsigned int> close; //bordering pathes
Border border = nexus.GetBorder(p);
Border &border = nexus.GetBorder(p);
for(unsigned int b = 0; b < border.Size(); b++) {
if(border[b].IsNull()) continue;
close.insert(border[b].end_patch);
@ -366,7 +366,7 @@ void nxs::Unify(Nexus &nexus, float threshold) {
set<unsigned int>::iterator c;
for(c = close.begin(); c != close.end(); c++) {
Border bord = nexus.GetBorder(*c);
Border &bord = nexus.GetBorder(*c);
for(unsigned int b = 0; b < bord.Size(); b++) {
if(bord[b].IsNull()) continue;
if(bord[b].end_patch == p) {
@ -378,7 +378,7 @@ void nxs::Unify(Nexus &nexus, float threshold) {
//better to compact directly borders than setting them null.
//finally: there may be duplicated borders
for(unsigned int p = 0; p < nexus.size(); p++) {
Border border = nexus.GetBorder(p);
Border &border = nexus.GetBorder(p);
set<Link> links;
for(unsigned int b = 0; b < border.Size(); b++) {
Link &link = border[b];

View File

@ -24,6 +24,9 @@
History
$Log: not supported by cvs2svn $
Revision 1.13 2005/01/17 17:35:48 ponchio
Small changes and adding realtime extr.
Revision 1.12 2005/01/14 15:25:29 ponchio
Revolution.
@ -221,7 +224,6 @@ void SecondStep(const string &crudefile, const string &output) {
for(unsigned int i = 0; i < face_remap.Size(); i++) {
unsigned int patch = face_remap[i];
assert(patch < face_index.size());
assert(patch >= 0);
int64 offset = face_index[patch].offset + done[patch]++;
sorted[offset] = crude.GetFace(i);
}
@ -231,16 +233,6 @@ void SecondStep(const string &crudefile, const string &output) {
assert(done[i] == face_index[i].size);
#endif
/*#ifndef NDEBUG
//test:
for(unsigned int i = 0; i < sorted.Size(); i++) {
Crude::Face face = sorted[i];
assert(face[0] < crude.Vertices());
assert(face[1] < crude.Vertices());
assert(face[2] < crude.Vertices());
}
#endif*/
//once sorted
crude.Close();
sorted.Close();
@ -372,6 +364,9 @@ void ThirdStep(const string &crudefile, const string &output,
assert(vroffset + (*r).second < vert_remap.Size());
vert_remap[vroffset + (*r).second] = (*r).first;
}
if(vcount < 100) {
cerr << "Small patch: " << vcount << "\n";
}
}
//we can now update bounding sphere.
@ -409,10 +404,11 @@ void FourthStep(const string &crudefile, const string &output,
//TODO Clear borders in case of failure!
VFile<unsigned int> vert_remap;
if(!vert_remap.Load(crudefile + ".rvm", true)) {
if(!vert_remap.Load(output + ".rvm", true)) {
cerr << "Could not load: " << crudefile << ".rvm\n";
exit(0);
}
cerr << "Vert_remap.size: " << vert_remap.Size() << endl;
BlockIndex vert_index;
if(!vert_index.Load(output + ".rvi")) {
@ -432,6 +428,14 @@ void FourthStep(const string &crudefile, const string &output,
map<unsigned int, unsigned short> vremap;
#endif
for(unsigned int i = 0; i < vert_index[start].size; i++) {
//#ifndef NDEBUG
if(vert_index[start].offset + i >= vert_remap.Size()) {
cerr << "Ahi Ahi start: " << start << endl;
cerr << "offset: " << vert_index[start].offset << endl;
cerr << "size: " << vert_index[start].size << endl;
exit(0);
}
//#endif
unsigned int global = vert_remap[vert_index[start].offset + i];
vremap[global] = i;
}
@ -447,6 +451,15 @@ void FourthStep(const string &crudefile, const string &output,
}
for(unsigned int i = 0; i < vert_index[end].size; i++) {
//#ifndef NDEBUG
if(vert_index[end].offset + i >= vert_remap.Size()) {
cerr << "aaa Ahi Ahi start: " << end << endl;
cerr << "offset: " << vert_index[end].offset << endl;
cerr << "size: " << vert_index[end].size << endl;
exit(0);
}
//#endif
unsigned int global = vert_remap[vert_index[end].offset + i];
if(vremap.count(global)) {
Link link;
@ -457,10 +470,10 @@ void FourthStep(const string &crudefile, const string &output,
}
}
}
//TODO Horribili visu (interfaccia di cacca!)
Border &border = nexus.GetBorder(start);
nexus.borders.ResizeBorder(start, 3 * links.size());
nexus.borders[start].used = links.size();
Border border = nexus.GetBorder(start);
border.used = links.size();
memcpy(&(border[0]), &*links.begin(), links.size() * sizeof(Link));
}
}
@ -699,7 +712,7 @@ void BuildFragment(Nexus &nexus, VPartition &part,
nxs.patch = *f;
Patch &patch = nexus.GetPatch(*f);
Border border = nexus.GetBorder(*f);
Border &border = nexus.GetBorder(*f);
for(unsigned int k = 0; k < patch.nf; k++) {
assert(patch.Face(k)[0] != patch.Face(k)[1]);
@ -825,7 +838,7 @@ void SaveFragment(Nexus &nexus, VChain &chain,
newlinks[link.end_patch].insert(up);
assert(link.end_patch != patch_idx);
Border cborder = nexus.GetBorder(link.end_patch);
Border &cborder = nexus.GetBorder(link.end_patch);
for(unsigned int k = 0; k < cborder.Size(); k++) {
//cerr << "Cborder.size: " << cborder.Size() << endl;
//cerr << "K: " << k << endl;
@ -865,11 +878,9 @@ void SaveFragment(Nexus &nexus, VChain &chain,
set<Link>::iterator l;
unsigned int patch = (*n).first;
set<Link> &links = (*n).second;
Border border = nexus.GetBorder(patch);
Border &border = nexus.GetBorder(patch);
unsigned int bstart = border.Size();
if(nexus.borders.ResizeBorder(patch, border.Size() + links.size()))
border = nexus.GetBorder(patch);
nexus.borders.ResizeBorder(patch, border.Size() + links.size());
for(l = links.begin(); l != links.end(); l++) {
Link link = *l;
border[bstart++] = link;

View File

@ -51,6 +51,7 @@ int main(int argc, char *argv[]) {
string output;
string plysource;
bool info = false;
bool verbose = false;
unsigned int ram_size = 128000000;
unsigned int chunk_size = 0;
@ -76,9 +77,10 @@ int main(int argc, char *argv[]) {
float qtexture = 0;
int option;
while((option = getopt(argc, argv, "io:a:r:zxv:n:k:t:b:c:")) != EOF) {
while((option = getopt(argc, argv, "ilo:a:r:zxv:n:k:t:b:c:")) != EOF) {
switch(option) {
case 'i': info = true; break;
case 'l': verbose = true; break;
case 'o': output = optarg; break;
case 'a': {
if(strstr(optarg, "strip")) {
@ -195,6 +197,7 @@ int main(int argc, char *argv[]) {
if(optind != argc - 1) {
cerr << "Usage: " << argv[0] << " <nexus file> [options]\n"
<< " -i : display some info about nexus file\n"
<< " -l : list nodes\n"
<< " -o <file>: output filename (default is adding 00 to nexus)\n"
<< " -a <what>: Add [colors|normals|strip|textures|data|borders]\n"
<< " -r <what>: As add...\n"
@ -254,7 +257,7 @@ int main(int argc, char *argv[]) {
if(info) {
cerr << "Nexus file: " << input << "\n\n"
cout << "Nexus file: " << input << "\n\n"
<< "\n\tCompressed: " << nexus.IsCompressed()
<< "\n\tStripped: " << (int)((nexus.signature&NXS_STRIP) !=0)
<< "\n\tColor : " << (int)((nexus.signature&NXS_COLORS) !=0)
@ -271,6 +274,14 @@ int main(int argc, char *argv[]) {
<< nexus.sphere.Radius()
<< "\n\tChunk size " << nexus.chunk_size << endl;
if(verbose) {
for(unsigned int i = 0; i < nexus.size(); i++) {
Entry &entry = nexus[i];
cout << i << " -> nv: " << entry.nvert << " nf: " << entry.nface
<< " error: " << entry.error << " disk_size: " << entry.disk_size << endl;
}
cout << endl;
}
}
//determine if we must proceed:
@ -331,7 +342,7 @@ int main(int argc, char *argv[]) {
report.Step(patch);
Entry &src_entry = nexus[patch];
Patch &src_patch = nexus.GetPatch(patch);
Border src_border = nexus.GetBorder(patch);
Border &src_border = nexus.GetBorder(patch);
vector<unsigned short> strip;
@ -397,7 +408,7 @@ int main(int argc, char *argv[]) {
assert(link.end_patch < nexus.index.size());
}*/
out.borders.ResizeBorder(patch, src_border.Size());
Border dst_border = out.GetBorder(patch);
Border &dst_border = out.GetBorder(patch);
memcpy(dst_border.Start(), src_border.Start(),
src_border.Size() * sizeof(Link));
}

View File

@ -53,7 +53,7 @@ int main(int argc, char *argv[]) {
for(unsigned int patchid = 0; patchid < nexus.index.size(); patchid++) {
PatchInfo &info = nexus.index[patchid];
Border border = nexus.GetBorder(patchid);
Border &border = nexus.GetBorder(patchid);
for(unsigned int i = 0; i < border.Size(); i++) {
Link &link = border[i];
if(link.start_vert == 0 && link.end_vert == 0 && link.end_patch == 0) {
@ -81,13 +81,13 @@ int main(int argc, char *argv[]) {
cerr << "Reciprocity borders test\n";
for(unsigned int patchid = 0; patchid < nexus.index.size(); patchid++) {
PatchInfo &info = nexus.index[patchid];
Border border = nexus.GetBorder(patchid);
Border &border = nexus.GetBorder(patchid);
vector<Link> links;
links.resize(border.Size());
memcpy(&*links.begin(),&(border[0]),links.size() * sizeof(Link));
for(unsigned int i = 0; i < links.size(); i++) {
Link &link = links[i];
Border rborder = nexus.GetBorder(link.end_patch);
Border &rborder = nexus.GetBorder(link.end_patch, false);
bool found = false;
for(unsigned int k = 0; k < rborder.Size(); k++) {

View File

@ -9,6 +9,7 @@ using namespace nxs;
while(!get_signaled()) {
lock.enter();
while(!queue.size()) {
//cerr << "Acc nothing to preload!\n";
lock.leave();
pt::psleep(10);
lock.enter();

View File

@ -46,26 +46,21 @@ void nxs::Remap(VChain &chain,
int steps) {
VPartition *finepart = new VPartition;
// finepart.Init();
chain.push_back(finepart);
BuildPartition(*finepart, points, target_size, min_size, max_size, steps);
VPartition *coarsepart = new VPartition;
// coarsepart.Init();
chain.push_back(coarsepart);
BuildPartition(*coarsepart, points,
(int)(target_size/scaling), min_size, max_size, steps);
cerr << "Fine size: " << finepart->size() << endl;
cerr << "Coarse size: " << coarsepart->size() << endl;
typedef map<pair<unsigned int, unsigned int>, unsigned int> FragIndex;
// typedef map<pair<unsigned int, unsigned int>, unsigned int> FragIndex;
typedef map<unsigned int, map<unsigned int, unsigned int> > FragIndex;
FragIndex patches;
unsigned int totpatches = 0;
@ -79,12 +74,11 @@ void nxs::Remap(VChain &chain,
unsigned int coarse = coarsepart->Locate(bari);
unsigned int patch;
if(!patches.count(make_pair(coarse, fine))) {
if(!patches.count(coarse) || !patches[coarse].count(fine)) {
patch = totpatches;
patches[make_pair(coarse, fine)] = totpatches++;
patches[coarse][fine] = totpatches++;
} else
patch = patches[make_pair(coarse, fine)];
patch = patches[coarse][fine];
remap[i] = patch;
@ -93,19 +87,7 @@ void nxs::Remap(VChain &chain,
count[patch]++;
}
cerr << "Prune faces...\n";
//prune faces (now only 0 faces);
unsigned int new_totpatches = 0;
vector<int> patch_remap;
for(unsigned int i = 0; i < totpatches; i++) {
//if below threshold (and can join faces)
// if(count[i] < min_size)
if(count[i] == 0)
patch_remap.push_back(-1);
else
patch_remap.push_back(new_totpatches++);
if(count[i] > 32000) {
//TODO do something to reduce patch size... :P
cerr << "Found a patch too big... sorry\n";
@ -113,20 +95,88 @@ void nxs::Remap(VChain &chain,
}
}
unsigned int mean = 0;
for(unsigned int i = 0; i < count.size(); i++)
mean += count[i];
mean /= count.size();
cerr << "BUilding fragmenbts\n";
min_size /= 4;
cerr << "Pruning small patches... < " << min_size << " mean: " << mean << endl;
//prune small patches
vector<int> patch_map;
patch_map.resize(totpatches);
for(unsigned int i = 0; i < totpatches; i++)
patch_map[i] = i;
for(FragIndex::iterator s = patches.begin(); s != patches.end(); s++) {
map<unsigned int, unsigned int> &fines = (*s).second;
while(1) {
if(fines.size() <= 1) break;
unsigned int inf_fine = 0xffffffff;
unsigned int inf_count, min_count;
unsigned int min_fine = 0xffffffff;
unsigned int min_patch, inf_patch;
map<unsigned int, unsigned int>::iterator t;
for(t = fines.begin(); t != fines.end(); t++) {
unsigned int c = count[(*t).second];
if(inf_fine == 0xffffffff || c < inf_count) {
if(inf_fine != 0xffffffff) {
min_fine = inf_fine;
min_count = inf_count;
min_patch = inf_patch;
}
inf_fine = (*t).first;
inf_count = c;
inf_patch = (*t).second;
} else if(min_fine == 0xffffffff || c < min_count) {
min_fine = (*t).first;
min_count = c;
min_patch = (*t).second;
}
}
if(inf_count >= min_size ||
inf_count + min_count > max_size) break;
count[min_patch] += count[inf_patch];
patch_map[inf_patch] = min_patch;
fines.erase(inf_fine);
}
}
for(unsigned int i = 0; i < totpatches; i++)
while(patch_map[patch_map[i]] != patch_map[i])
patch_map[i] = patch_map[patch_map[i]];
//now we remap remaining patches into 0 - n.
unsigned int new_totpatches = 0;
vector<int> patch_remap;
patch_remap.resize(totpatches, -1);
for(unsigned int i = 0; i < totpatches; i++) {
unsigned int p = patch_map[i];
if(patch_remap[p] == -1)
patch_remap[p] = new_totpatches++;
patch_remap[i] = patch_remap[p];
}
cerr << "Building fragments\n";
//building fragments
FragIndex::iterator f;
for(f = patches.begin(); f != patches.end(); f++) {
unsigned int coarse = (*f).first.first;
unsigned int fine = (*f).first.second;
unsigned int oldpatch = (*f).second;
for(FragIndex::iterator s = patches.begin(); s != patches.end(); s++) {
unsigned int coarse = (*s).first;
map<unsigned int, unsigned int> &fines = (*s).second;
map<unsigned int, unsigned int>::iterator t;
for(t = fines.begin(); t != fines.end(); t++) {
unsigned int fine = (*t).first;
unsigned int oldpatch = (*t).second;
assert(oldpatch < patch_remap.size());
unsigned int patch = patch_remap[oldpatch];
if(patch != -1) //not deleted...
chain.oldfragments[coarse].insert(patch);
}
}
cerr << "remapping faces again\n";
//remapping faces
@ -428,92 +478,4 @@ bool nxs::Optimize(VPartition &part,
}
part.Init();
return true;
// for(unsigned int i = 0; i < part.size(); i++) {
// if(counts[i] > max_size || counts[i] > max_size) {
// failed++;
// } else {
// }
// }
//PREPHASE:
/* if(join) {
// float bigthresh = 1.2f;
// float smallthresh = 0.5f;
float bigthresh = 10.0f;
float smallthresh = 0.1f;
unsigned int failed = 0;
vector<Point3f> seeds;
vector<bool> mark;
mark.resize(part.size(), false);
//first pass we check only big ones
for(unsigned int i = 0; i < part.size(); i++) {
if(counts[i] > max_size || counts[i] > bigthresh * target_size) {
failed++;
float radius;
if(part.size() == 1)
radius = 0.00001;
else
radius = part.Radius(i);
if(radius == 0) {
cerr << "Radius zero???\n";
exit(0);
}
radius /= 4;
seeds.push_back(centroids[i] + Point3f(1, -1, 1) * radius);
seeds.push_back(centroids[i] + Point3f(-1, 1, 1) * radius);
seeds.push_back(centroids[i] + Point3f(-1, -1, -1) * radius);
seeds.push_back(centroids[i] + Point3f(1, 1, -1) * radius);
mark[i] = true;
}
}
if(failed > 0)
cerr << "Found " << failed << " patches too big.\n";
if(join) {
for(unsigned int i = 0; i < part.size(); i++) {
if(mark[i]) continue;
if(counts[i] >= min_size && counts[i] >= smallthresh * target_size) continue;
failed++;
int best = GetBest(part, i, mark, counts);
if(best < 0) {
cerr << "Best not found! while looking for: " << i << "\n";
continue;
}
assert(mark[best] == false);
mark[best] = true;
mark[i] = true;
seeds.push_back((part[i] + part[best])/2);
}
}
for(unsigned int i = 0; i < part.size(); i++) {
if(mark[i]) continue;
if(counts[i] == 0) continue;
if(join) {
// if(counts[i] < min_size) {
// cerr << "Could not fix: " << i << endl;
// } else {
part[i] = centroids[i];
// }
}
seeds.push_back(part[i]);
}
part.clear();
for(unsigned int i = 0; i < seeds.size(); i++)
part.push_back(seeds[i]);
if(part.size() == 0) {
cerr << "OOOPS i accidentally deleted all seeds... backup :P\n";
part.push_back(Point3f(0,0,0));
}
part.Init();
return failed == 0;*/
}

View File

@ -24,6 +24,9 @@
History
$Log: not supported by cvs2svn $
Revision 1.2 2004/12/04 13:24:27 ponchio
Fixed a couple of memory leak...
Revision 1.1 2004/11/30 22:50:30 ponchio
Level 0.
@ -64,6 +67,7 @@ void VPartition::Closest(const vcg::Point3f &p, unsigned int nsize,
point[0] = p[0];
point[1] = p[1];
point[2] = p[2];
if(nsize > size()) nsize = size();
nears.resize(nsize);
dist.resize(nsize);