Porting and debug.
This commit is contained in:
parent
a264ec7c78
commit
a8a6b48bc0
|
@ -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;
|
||||
//TODO implement an iterator!
|
||||
Link *links;
|
||||
unsigned int used;
|
||||
unsigned int size;
|
||||
unsigned int start;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
ram_used = 0;
|
||||
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);
|
||||
|
@ -59,61 +62,59 @@ Border BorderServer::GetBorder(unsigned int border, bool flush) {
|
|||
pqueue.pop_back();
|
||||
index.erase(to_flush);
|
||||
FlushBorder(to_flush);
|
||||
}
|
||||
assert(!entry.links);
|
||||
if(entry.size != 0)
|
||||
entry.links = GetRegion(entry.start, entry.size);
|
||||
}
|
||||
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);
|
||||
assert(border < size());
|
||||
GetBorder(border);
|
||||
BorderEntry &entry = operator[](border);
|
||||
if(nbord > entry.size) {
|
||||
int capacity = nbord;
|
||||
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);
|
||||
if(entry.used > 0) {
|
||||
Link *src = GetRegion(entry.start, entry.size);
|
||||
memcpy(dst, src, entry.used * sizeof(Link));
|
||||
}
|
||||
entry.links = dst;
|
||||
entry.start = newstart;
|
||||
entry.size = capacity;
|
||||
entry.used = nbord;
|
||||
return true;
|
||||
void BorderServer::ResizeBorder(unsigned int border, unsigned int used) {
|
||||
assert(border < size());
|
||||
Border &entry = GetBorder(border);
|
||||
if(used <= entry.size) {
|
||||
entry.used = used;
|
||||
return;
|
||||
}
|
||||
entry.used = nbord;
|
||||
return false;
|
||||
|
||||
int capacity = used;
|
||||
if(capacity < entry.size * 2)
|
||||
capacity = entry.size * 2;
|
||||
|
||||
unsigned int newstart = Length()/sizeof(Link);
|
||||
Redim((newstart + capacity) * sizeof(Link));
|
||||
Link *newlinks = new Link[capacity];
|
||||
if(entry.used > 0) {
|
||||
assert(entry.links);
|
||||
memcpy(newlinks, entry.links, entry.used * sizeof(Link));
|
||||
delete []entry.links;
|
||||
entry.links = NULL;
|
||||
}
|
||||
assert(entry.links == NULL);
|
||||
entry.links = newlinks;
|
||||
entry.start = newstart;
|
||||
entry.size = capacity;
|
||||
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));
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,26 +63,26 @@ 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++) {
|
||||
unsigned int patch = (*k).patch;
|
||||
Entry &entry = (*mt)[patch];
|
||||
float error = metric->GetError(entry);
|
||||
if(error > maxerror) maxerror = error;
|
||||
Link &link = *n;
|
||||
for(Link::iterator k = link.begin(); k != link.end(); k++) {
|
||||
unsigned int patch = (*k).patch;
|
||||
Entry &entry = (*mt)[patch];
|
||||
float error = metric->GetError(entry);
|
||||
if(error > maxerror) maxerror = error;
|
||||
|
||||
cost.extr += entry.ram_size;
|
||||
vcg::Sphere3f &sphere = entry.sphere;
|
||||
if(!frustum.IsOutside(sphere.Center(), sphere.Radius()))
|
||||
cost.draw += entry.ram_size;
|
||||
if(!entry.patch)
|
||||
cost.disk += entry.disk_size;
|
||||
}
|
||||
if((*n).node != sink && maxerror > target_error)
|
||||
front.push_back(HeapNode((*n).node, maxerror));
|
||||
cost.extr += entry.ram_size;
|
||||
vcg::Sphere3f &sphere = entry.sphere;
|
||||
if(!frustum.IsOutside(sphere.Center(), sphere.Radius()))
|
||||
cost.draw += entry.ram_size;
|
||||
if(!entry.patch)
|
||||
cost.disk += entry.disk_size;
|
||||
}
|
||||
if((*n).node != sink && maxerror > target_error)
|
||||
front.push_back(HeapNode((*n).node, maxerror));
|
||||
} else
|
||||
cancoarse = false;
|
||||
cancoarse = false;
|
||||
}
|
||||
if(cancoarse && &node != root) {
|
||||
float error = GetRefineError(&node);
|
||||
|
@ -109,44 +109,80 @@ void Extraction::Update(NexusMt *_mt) {
|
|||
}
|
||||
|
||||
Init();
|
||||
|
||||
bool no_draw = false;
|
||||
bool no_disk = false;
|
||||
|
||||
//first we coarse
|
||||
while(back.size()) {
|
||||
if(draw_used <= draw_max &&
|
||||
extr_used <= extr_max &&
|
||||
(front.size() && back.front().error > front.front().error))
|
||||
//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();
|
||||
|
||||
if(Visited(hnode.node)) {
|
||||
if(!Coarse(hnode)) { //push back on heap the heapnode
|
||||
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;
|
||||
if(Visited(hnode.node)) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
front.pop_back();
|
||||
}
|
||||
|
||||
no_draw = false;
|
||||
}
|
||||
|
||||
Select();
|
||||
draw_size = selected.size();
|
||||
|
||||
|
||||
//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());
|
||||
|
@ -155,10 +191,10 @@ void Extraction::Update(NexusMt *_mt) {
|
|||
front.pop_back();
|
||||
Node::iterator i;
|
||||
for(i = node->out_begin(); i != node->out_end(); i++) {
|
||||
Link &link = (*i);
|
||||
for(Link::iterator k = link.begin(); k != link.end(); k++) {
|
||||
selected.push_back((*k).patch);
|
||||
}
|
||||
Link &link = (*i);
|
||||
for(Link::iterator k = link.begin(); k != link.end(); k++) {
|
||||
selected.push_back((*k).patch);
|
||||
}
|
||||
}
|
||||
} else if(back.size()) {
|
||||
pop_heap(back.begin(), back.end(), greater<HeapNode>());
|
||||
|
@ -167,17 +203,17 @@ void Extraction::Update(NexusMt *_mt) {
|
|||
back.pop_back();
|
||||
Node::iterator i;
|
||||
for(i = node->in_begin(); i != node->in_end(); i++) {
|
||||
Link &link = (*i);
|
||||
for(Link::iterator k = link.begin(); k != link.end(); k++) {
|
||||
selected.push_back((*k).patch);
|
||||
}
|
||||
Link &link = (*i);
|
||||
for(Link::iterator k = link.begin(); k != link.end(); k++) {
|
||||
selected.push_back((*k).patch);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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,19 +281,25 @@ 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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -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];
|
||||
|
|
|
@ -64,7 +64,7 @@ class Extraction {
|
|||
void Update(NexusMt *mt);
|
||||
|
||||
|
||||
protected:
|
||||
protected:
|
||||
|
||||
void Select();
|
||||
void Visit(Node *node);
|
||||
|
@ -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();
|
||||
|
|
|
@ -232,9 +232,9 @@ bool History::UpdatesToQuick() {
|
|||
|
||||
vector<unsigned int>::iterator k;
|
||||
for(k = cells.begin(); k != cells.end(); k++) {
|
||||
Cell cell;
|
||||
cell.patch = (*k);
|
||||
tmp_frags.push_back(cell);
|
||||
Cell cell;
|
||||
cell.patch = (*k);
|
||||
tmp_frags.push_back(cell);
|
||||
}
|
||||
|
||||
//Add the new Frag to the node.
|
||||
|
|
|
@ -30,9 +30,15 @@ namespace nxs {
|
|||
float dist = (sphere.Center() - frustum.ViewPoint()).Norm() - sphere.Radius();
|
||||
//float dist = Distance(sphere, frustum.ViewPoint());
|
||||
if(dist < 0)
|
||||
return 1e20f;
|
||||
if(frustum.IsOutside(sphere.Center(), sphere.Radius()))
|
||||
return -1;
|
||||
return 1e20f;
|
||||
|
||||
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);
|
||||
}
|
||||
};
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
@ -170,8 +173,8 @@ void FirstStep(const string &crudefile, const string &output,
|
|||
BlockIndex face_index;
|
||||
|
||||
Remap(vchain, baricenters, face_remap, face_index,
|
||||
patch_size, patch_threshold, 65000, scaling,
|
||||
optimization_steps);
|
||||
patch_size, patch_threshold, 65000, scaling,
|
||||
optimization_steps);
|
||||
|
||||
if(!vchain.Save(output + ".vchain")) {
|
||||
cerr << "Could not save file: " << output << ".vchain\n";
|
||||
|
@ -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();
|
||||
|
@ -318,16 +310,16 @@ void ThirdStep(const string &crudefile, const string &output,
|
|||
// Crude::Face face = crude.GetFace(i);
|
||||
Crude::Face face = sorted[i];
|
||||
if(face[0] == face[1] || face[1] == face[2] || face[0] == face[2])
|
||||
continue; //degenerate
|
||||
continue; //degenerate
|
||||
for(int j = 0; j < 3; j++) {
|
||||
assert(face[j] < crude.Vertices());
|
||||
if(!vremap.count(face[j])) {
|
||||
Point3f &v = crude.vert[face[j]];
|
||||
vertices.push_back(v);
|
||||
vremap[face[j]] = vcount++;
|
||||
}
|
||||
faces.push_back(vremap[face[j]]);
|
||||
fcount++;
|
||||
assert(face[j] < crude.Vertices());
|
||||
if(!vremap.count(face[j])) {
|
||||
Point3f &v = crude.vert[face[j]];
|
||||
vertices.push_back(v);
|
||||
vremap[face[j]] = vcount++;
|
||||
}
|
||||
faces.push_back(vremap[face[j]]);
|
||||
fcount++;
|
||||
}
|
||||
}
|
||||
assert(vcount == vertices.size());
|
||||
|
@ -364,7 +356,7 @@ void ThirdStep(const string &crudefile, const string &output,
|
|||
//saving vert_remap
|
||||
int64 vroffset = vert_remap.Size();
|
||||
vert_index.push_back(BlockEntry(vroffset, vcount));
|
||||
vert_remap.Resize(vroffset + vcount);
|
||||
vert_remap.Resize(vroffset + vcount);
|
||||
|
||||
map<unsigned int, unsigned short>::iterator r;
|
||||
for(r = vremap.begin(); r != vremap.end(); r++) {
|
||||
|
@ -372,7 +364,10 @@ 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.
|
||||
for(unsigned int i = 0; i < nexus.size(); i++)
|
||||
|
@ -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")) {
|
||||
|
@ -421,7 +417,7 @@ void FourthStep(const string &crudefile, const string &output,
|
|||
}
|
||||
Report report(nexus.size());
|
||||
|
||||
for(int start = 0; start < nexus.size(); start++) {
|
||||
for(int start = 0; start < nexus.size(); start++) {
|
||||
report.Step(start);
|
||||
Entry &s_entry = nexus[start];
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -446,21 +450,30 @@ void FourthStep(const string &crudefile, const string &output,
|
|||
continue;
|
||||
}
|
||||
|
||||
for(unsigned int i = 0; i < vert_index[end].size; i++) {
|
||||
unsigned int global = vert_remap[vert_index[end].offset + i];
|
||||
if(vremap.count(global)) {
|
||||
Link link;
|
||||
link.start_vert = vremap[global];
|
||||
link.end_vert = i;
|
||||
link.end_patch = end;
|
||||
links.push_back(link);
|
||||
}
|
||||
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;
|
||||
link.start_vert = vremap[global];
|
||||
link.end_vert = i;
|
||||
link.end_patch = end;
|
||||
links.push_back(link);
|
||||
}
|
||||
}
|
||||
}
|
||||
//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;
|
||||
|
|
|
@ -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)
|
||||
|
@ -270,7 +273,15 @@ int main(int argc, char *argv[]) {
|
|||
<< nexus.sphere.Center()[2] << " R: "
|
||||
<< 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));
|
||||
}
|
||||
|
|
|
@ -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++) {
|
||||
|
|
|
@ -9,9 +9,10 @@ using namespace nxs;
|
|||
while(!get_signaled()) {
|
||||
lock.enter();
|
||||
while(!queue.size()) {
|
||||
lock.leave();
|
||||
pt::psleep(10);
|
||||
lock.enter();
|
||||
//cerr << "Acc nothing to preload!\n";
|
||||
lock.leave();
|
||||
pt::psleep(10);
|
||||
lock.enter();
|
||||
}
|
||||
//TODO check we are not loading too much memory!
|
||||
assert(queue.size());
|
||||
|
|
|
@ -45,27 +45,22 @@ void nxs::Remap(VChain &chain,
|
|||
float scaling,
|
||||
int steps) {
|
||||
|
||||
VPartition *finepart = new VPartition;
|
||||
// finepart.Init();
|
||||
VPartition *finepart = new VPartition;
|
||||
chain.push_back(finepart);
|
||||
BuildPartition(*finepart, points, target_size, min_size, max_size, steps);
|
||||
|
||||
|
||||
VPartition *coarsepart = new VPartition;
|
||||
// coarsepart.Init();
|
||||
VPartition *coarsepart = new VPartition;
|
||||
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,40 +87,96 @@ 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";
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
cerr << "BUilding fragmenbts\n";
|
||||
unsigned int mean = 0;
|
||||
for(unsigned int i = 0; i < count.size(); i++)
|
||||
mean += count[i];
|
||||
mean /= count.size();
|
||||
|
||||
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;
|
||||
assert(oldpatch < patch_remap.size());
|
||||
unsigned int patch = patch_remap[oldpatch];
|
||||
if(patch != -1) //not deleted...
|
||||
chain.oldfragments[coarse].insert(patch);
|
||||
}
|
||||
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;*/
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue