Porting and debug.
This commit is contained in:
parent
a264ec7c78
commit
a8a6b48bc0
|
@ -24,6 +24,9 @@
|
||||||
History
|
History
|
||||||
|
|
||||||
$Log: not supported by cvs2svn $
|
$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
|
Revision 1.4 2004/09/30 00:27:08 ponchio
|
||||||
Added used counter.
|
Added used counter.
|
||||||
|
|
||||||
|
@ -71,18 +74,18 @@ struct Link {
|
||||||
class Border {
|
class Border {
|
||||||
public:
|
public:
|
||||||
Border(Link *l = NULL, unsigned short _used = 0, unsigned short _size = 0):
|
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; }
|
unsigned int Size() { return used; }
|
||||||
//TODO rename available to capacity.
|
//TODO rename available to capacity.
|
||||||
unsigned int Available() { return size; }
|
unsigned int Available() { return size; }
|
||||||
Link &operator[](unsigned int i) { return start[i]; }
|
Link &operator[](unsigned int i) { return links[i]; }
|
||||||
Link *Start() { return start; }
|
Link *Start() { return links; }
|
||||||
|
|
||||||
//TODO implement an iterator!
|
//TODO implement an iterator!
|
||||||
private:
|
Link *links;
|
||||||
Link *start;
|
unsigned int used;
|
||||||
unsigned short used;
|
unsigned int size;
|
||||||
unsigned short size;
|
unsigned int start;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,19 +6,22 @@ using namespace nxs;
|
||||||
|
|
||||||
bool BorderServer::Create(const string &file) {
|
bool BorderServer::Create(const string &file) {
|
||||||
ram_used = 0;
|
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) {
|
bool BorderServer::Load(const string &file, bool rdonly) {
|
||||||
ram_used = 0;
|
ram_used = 0;
|
||||||
cerr << "Loading...\n";
|
bool success = IndexFile<Border>::Load(file, rdonly);
|
||||||
return IndexFile<BorderEntry>::Load(file, rdonly);
|
if(!success) return false;
|
||||||
|
for(unsigned int i = 0; i < size(); i++)
|
||||||
|
operator[](i).links = NULL;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BorderServer::Close() {
|
void BorderServer::Close() {
|
||||||
if(!Opened()) return;
|
if(!Opened()) return;
|
||||||
Flush();
|
Flush();
|
||||||
IndexFile<BorderEntry>::Close();
|
IndexFile<Border>::Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
void BorderServer::Flush() {
|
void BorderServer::Flush() {
|
||||||
|
@ -31,20 +34,20 @@ void BorderServer::Flush() {
|
||||||
index.clear();
|
index.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void BorderServer::AddBorder(unsigned short nbord, unsigned int used) {
|
void BorderServer::AddBorder(unsigned short _size, unsigned int used) {
|
||||||
BorderEntry entry;
|
Border entry;
|
||||||
assert((Length() % sizeof(Link)) == 0);
|
assert((Length() % sizeof(Link)) == 0);
|
||||||
|
|
||||||
entry.start = Length()/ sizeof(Link);
|
entry.start = Length()/ sizeof(Link);
|
||||||
entry.size = nbord;
|
entry.size = _size;
|
||||||
entry.used = used;
|
entry.used = used;
|
||||||
entry.links = NULL;
|
entry.links = NULL;
|
||||||
push_back(entry);
|
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) {
|
Border &BorderServer::GetBorder(unsigned int border, bool flush) {
|
||||||
BorderEntry &entry = operator[](border);
|
Border &entry = operator[](border);
|
||||||
//assert(entry.size != 0);
|
//assert(entry.size != 0);
|
||||||
if(index.count(border)) {
|
if(index.count(border)) {
|
||||||
//assert(entry.links);
|
//assert(entry.links);
|
||||||
|
@ -59,61 +62,59 @@ Border BorderServer::GetBorder(unsigned int border, bool flush) {
|
||||||
pqueue.pop_back();
|
pqueue.pop_back();
|
||||||
index.erase(to_flush);
|
index.erase(to_flush);
|
||||||
FlushBorder(to_flush);
|
FlushBorder(to_flush);
|
||||||
}
|
}
|
||||||
assert(!entry.links);
|
entry.links = GetRegion(entry.start, entry.size);
|
||||||
if(entry.size != 0)
|
|
||||||
entry.links = GetRegion(entry.start, entry.size);
|
|
||||||
pqueue.push_front(border);
|
pqueue.push_front(border);
|
||||||
index[border] = pqueue.begin();
|
index[border] = pqueue.begin();
|
||||||
ram_used += entry.size;
|
ram_used += entry.size;
|
||||||
}
|
}
|
||||||
return Border(entry.links, entry.used, entry.size);
|
return entry;
|
||||||
}
|
}
|
||||||
//TODO Change when remving borderentry class.
|
//TODO Change when remving borderentry class.
|
||||||
bool BorderServer::ResizeBorder(unsigned int border, unsigned int nbord) {
|
void BorderServer::ResizeBorder(unsigned int border, unsigned int used) {
|
||||||
assert(nbord < 65500);
|
assert(border < size());
|
||||||
assert(border < size());
|
Border &entry = GetBorder(border);
|
||||||
GetBorder(border);
|
if(used <= entry.size) {
|
||||||
BorderEntry &entry = operator[](border);
|
entry.used = used;
|
||||||
if(nbord > entry.size) {
|
return;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
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) {
|
void BorderServer::FlushBorder(unsigned int border) {
|
||||||
BorderEntry &entry = operator[](border);
|
Border &entry = operator[](border);
|
||||||
//assert(entry.links);
|
//assert(entry.links);
|
||||||
if(entry.size && !MFile::IsReadOnly()) { //write back patch
|
if(entry.size && !MFile::IsReadOnly()) { //write back patch
|
||||||
MFile::SetPosition((int64)entry.start * sizeof(Link));
|
MFile::SetPosition((int64)entry.start * sizeof(Link));
|
||||||
MFile::WriteBuffer(entry.links, entry.used * sizeof(Link));
|
MFile::WriteBuffer(entry.links, entry.used * sizeof(Link));
|
||||||
}
|
}
|
||||||
if(entry.size)
|
if(entry.links)
|
||||||
delete [](entry.links);
|
delete [](entry.links);
|
||||||
entry.links = NULL;
|
entry.links = NULL;
|
||||||
ram_used -= entry.size;
|
ram_used -= entry.size;
|
||||||
}
|
}
|
||||||
|
|
||||||
Link *BorderServer::GetRegion(unsigned int start, unsigned int size) {
|
Link *BorderServer::GetRegion(unsigned int start, unsigned int size) {
|
||||||
assert(size > 0);
|
if(size == 0) return NULL;
|
||||||
SetPosition(start * sizeof(Link));
|
SetPosition((int64)start * sizeof(Link));
|
||||||
Link *buf = new Link[size];
|
Link *buf = new Link[size];
|
||||||
assert(buf);
|
assert(buf);
|
||||||
ReadBuffer(buf, size * sizeof(Link));
|
ReadBuffer(buf, size * sizeof(Link));
|
||||||
|
|
|
@ -16,14 +16,14 @@
|
||||||
namespace nxs {
|
namespace nxs {
|
||||||
|
|
||||||
//This should be Border class!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
//This should be Border class!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||||
struct BorderEntry {
|
/*struct BorderEntry {
|
||||||
unsigned int start; //granuralita' Link
|
unsigned int start; //granuralita' Link
|
||||||
unsigned short size; //in Links //TODO what are this? be clear!
|
unsigned short size; //in Links //TODO what are this? be clear!
|
||||||
unsigned short used; //in Links
|
unsigned short used; //in Links
|
||||||
Link *links;
|
Link *links;
|
||||||
};
|
};*/
|
||||||
|
|
||||||
class BorderServer: public IndexFile<BorderEntry> {
|
class BorderServer: public IndexFile<Border> {
|
||||||
public:
|
public:
|
||||||
BorderServer(): ram_max(1000000), ram_used(0) {}
|
BorderServer(): ram_max(1000000), ram_used(0) {}
|
||||||
~BorderServer() { Close(); }
|
~BorderServer() { Close(); }
|
||||||
|
@ -32,17 +32,16 @@ class BorderServer: public IndexFile<BorderEntry> {
|
||||||
void Close();
|
void Close();
|
||||||
void Flush();
|
void Flush();
|
||||||
|
|
||||||
void AddBorder(unsigned short nbord, unsigned int used = 0);
|
void AddBorder(unsigned short size, unsigned int used = 0);
|
||||||
Border GetBorder(unsigned int border, bool flush = true);
|
Border &GetBorder(unsigned int border, bool flush = true);
|
||||||
//return true if you need to reread border as it changed location
|
void ResizeBorder(unsigned int border, unsigned int size);
|
||||||
bool ResizeBorder(unsigned int border, unsigned int nbord);
|
|
||||||
|
|
||||||
unsigned int BorderSize(unsigned int i) {
|
/*unsigned int BorderSize(unsigned int i) {
|
||||||
return operator[](i).used;
|
return operator[](i).used;
|
||||||
}
|
}
|
||||||
unsigned int BorderCapacity(unsigned int i) {
|
unsigned int BorderCapacity(unsigned int i) {
|
||||||
return operator[](i).size;
|
return operator[](i).size;
|
||||||
}
|
} */
|
||||||
protected:
|
protected:
|
||||||
unsigned int ram_max;
|
unsigned int ram_max;
|
||||||
unsigned int ram_used;
|
unsigned int ram_used;
|
||||||
|
|
|
@ -7,8 +7,8 @@
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace nxs;
|
using namespace nxs;
|
||||||
|
|
||||||
Extraction::Extraction(): target_error(4.0f), extr_max(0xffffffff),
|
Extraction::Extraction(): target_error(4.0f), extr_max(10000),
|
||||||
draw_max(640), disk_max(100) {
|
draw_max(10000), disk_max(100) {
|
||||||
metric = new FrustumMetric;
|
metric = new FrustumMetric;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,26 +63,26 @@ void Extraction::Init() {
|
||||||
for(n = node.out_begin(); n != node.out_end(); n++) {
|
for(n = node.out_begin(); n != node.out_end(); n++) {
|
||||||
|
|
||||||
if(!visited[(*n).node - root]) {
|
if(!visited[(*n).node - root]) {
|
||||||
float maxerror = 0;
|
float maxerror = -1;
|
||||||
|
|
||||||
Link &link = *n;
|
Link &link = *n;
|
||||||
for(Link::iterator k = link.begin(); k != link.end(); k++) {
|
for(Link::iterator k = link.begin(); k != link.end(); k++) {
|
||||||
unsigned int patch = (*k).patch;
|
unsigned int patch = (*k).patch;
|
||||||
Entry &entry = (*mt)[patch];
|
Entry &entry = (*mt)[patch];
|
||||||
float error = metric->GetError(entry);
|
float error = metric->GetError(entry);
|
||||||
if(error > maxerror) maxerror = error;
|
if(error > maxerror) maxerror = error;
|
||||||
|
|
||||||
cost.extr += entry.ram_size;
|
cost.extr += entry.ram_size;
|
||||||
vcg::Sphere3f &sphere = entry.sphere;
|
vcg::Sphere3f &sphere = entry.sphere;
|
||||||
if(!frustum.IsOutside(sphere.Center(), sphere.Radius()))
|
if(!frustum.IsOutside(sphere.Center(), sphere.Radius()))
|
||||||
cost.draw += entry.ram_size;
|
cost.draw += entry.ram_size;
|
||||||
if(!entry.patch)
|
if(!entry.patch)
|
||||||
cost.disk += entry.disk_size;
|
cost.disk += entry.disk_size;
|
||||||
}
|
}
|
||||||
if((*n).node != sink && maxerror > target_error)
|
if((*n).node != sink && maxerror > target_error)
|
||||||
front.push_back(HeapNode((*n).node, maxerror));
|
front.push_back(HeapNode((*n).node, maxerror));
|
||||||
} else
|
} else
|
||||||
cancoarse = false;
|
cancoarse = false;
|
||||||
}
|
}
|
||||||
if(cancoarse && &node != root) {
|
if(cancoarse && &node != root) {
|
||||||
float error = GetRefineError(&node);
|
float error = GetRefineError(&node);
|
||||||
|
@ -109,44 +109,80 @@ void Extraction::Update(NexusMt *_mt) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Init();
|
Init();
|
||||||
|
|
||||||
|
bool no_draw = false;
|
||||||
|
bool no_disk = false;
|
||||||
|
|
||||||
//first we coarse
|
//TODO big problem: nodes a (error 10) with parent b (error -1)
|
||||||
while(back.size()) {
|
//i try to refine a, refine b (recursive) but fail to refine a
|
||||||
if(draw_used <= draw_max &&
|
//next step i coarse b whis cause a cycle.
|
||||||
extr_used <= extr_max &&
|
|
||||||
(front.size() && back.front().error > front.front().error))
|
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;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
pop_heap(back.begin(), back.end(), greater<HeapNode>());
|
pop_heap(back.begin(), back.end(), greater<HeapNode>());
|
||||||
HeapNode hnode = back.back();
|
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();
|
back.pop_back();
|
||||||
}
|
if(Visited(hnode.node)) {
|
||||||
|
bool recursive = false;
|
||||||
while(front.size() && (*front.begin()).error > target_error) {
|
Node::iterator i;
|
||||||
pop_heap(front.begin(), front.end());
|
for(i = hnode.node->out_begin(); i != hnode.node->out_end(); i++) {
|
||||||
HeapNode hnode = front.back();
|
Node *child = (*i).node;
|
||||||
|
if(visited[child-root]) recursive = true;
|
||||||
if(!Visited(hnode.node)) {
|
}
|
||||||
if(!Refine(hnode.node)) {
|
if(!recursive && !Coarse(hnode)) { //no more disk so.. push back on heap the heapnode
|
||||||
push_heap(front.begin(), front.end());
|
back.push_back(hnode);
|
||||||
break;
|
push_heap(back.begin(), back.end(), greater<HeapNode>());
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
front.pop_back();
|
|
||||||
}
|
no_draw = false;
|
||||||
|
}
|
||||||
|
|
||||||
Select();
|
Select();
|
||||||
draw_size = selected.size();
|
draw_size = selected.size();
|
||||||
|
|
||||||
|
|
||||||
//Preloading now
|
//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(!front.size() && !back.size()) break;
|
||||||
if((i%2) && front.size()) {
|
if((i%2) && front.size()) {
|
||||||
pop_heap(front.begin(), front.end());
|
pop_heap(front.begin(), front.end());
|
||||||
|
@ -155,10 +191,10 @@ void Extraction::Update(NexusMt *_mt) {
|
||||||
front.pop_back();
|
front.pop_back();
|
||||||
Node::iterator i;
|
Node::iterator i;
|
||||||
for(i = node->out_begin(); i != node->out_end(); i++) {
|
for(i = node->out_begin(); i != node->out_end(); i++) {
|
||||||
Link &link = (*i);
|
Link &link = (*i);
|
||||||
for(Link::iterator k = link.begin(); k != link.end(); k++) {
|
for(Link::iterator k = link.begin(); k != link.end(); k++) {
|
||||||
selected.push_back((*k).patch);
|
selected.push_back((*k).patch);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if(back.size()) {
|
} else if(back.size()) {
|
||||||
pop_heap(back.begin(), back.end(), greater<HeapNode>());
|
pop_heap(back.begin(), back.end(), greater<HeapNode>());
|
||||||
|
@ -167,17 +203,17 @@ void Extraction::Update(NexusMt *_mt) {
|
||||||
back.pop_back();
|
back.pop_back();
|
||||||
Node::iterator i;
|
Node::iterator i;
|
||||||
for(i = node->in_begin(); i != node->in_end(); i++) {
|
for(i = node->in_begin(); i != node->in_end(); i++) {
|
||||||
Link &link = (*i);
|
Link &link = (*i);
|
||||||
for(Link::iterator k = link.begin(); k != link.end(); k++) {
|
for(Link::iterator k = link.begin(); k != link.end(); k++) {
|
||||||
selected.push_back((*k).patch);
|
selected.push_back((*k).patch);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
float Extraction::GetRefineError(Node *node) {
|
float Extraction::GetRefineError(Node *node) {
|
||||||
float maxerror = 0;
|
float maxerror = -1;
|
||||||
Node::iterator i;
|
Node::iterator i;
|
||||||
for(i = node->in_begin(); i != node->in_end(); i++) {
|
for(i = node->in_begin(); i != node->in_end(); i++) {
|
||||||
Link &link = *i;
|
Link &link = *i;
|
||||||
|
@ -190,23 +226,43 @@ float Extraction::GetRefineError(Node *node) {
|
||||||
return maxerror;
|
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.
|
//recursively refine parent if applicable.
|
||||||
Node::iterator i;
|
Node::iterator i;
|
||||||
for(i = node->in_begin(); i != node->in_end(); i++) {
|
for(i = node->in_begin(); i != node->in_end(); i++) {
|
||||||
Node *parent = (*i).node;
|
Node *parent = (*i).node;
|
||||||
if(!Visited(parent))
|
if(!Visited(parent)) {
|
||||||
if(!Refine(parent))
|
//Here i use parent refine error!!!
|
||||||
return false;
|
if(!Refine(HeapNode(parent, hnode.error))) return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Cost cost;
|
Cost cost;
|
||||||
Diff(node, cost);
|
Diff(node, cost);
|
||||||
|
|
||||||
if(disk_used + cost.disk > disk_max) return false;
|
bool failed = false;
|
||||||
if(extr_used + cost.extr > extr_max) return false;
|
if(disk_used + cost.disk > disk_max) {
|
||||||
if(draw_used + cost.draw > draw_max) return false;
|
//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;
|
extr_used += cost.extr;
|
||||||
draw_used += cost.draw;
|
draw_used += cost.draw;
|
||||||
disk_used += cost.disk;
|
disk_used += cost.disk;
|
||||||
|
@ -225,19 +281,25 @@ bool Extraction::Refine(Node *node) {
|
||||||
front.push_back(HeapNode((*i).node, maxerror));
|
front.push_back(HeapNode((*i).node, maxerror));
|
||||||
}
|
}
|
||||||
push_heap(front.begin(), front.end());
|
push_heap(front.begin(), front.end());
|
||||||
|
|
||||||
|
back.push_back(hnode);
|
||||||
|
push_heap(back.begin(), back.end(), greater<HeapNode>());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Extraction::Coarse(HeapNode &hnode) {
|
bool Extraction::Coarse(HeapNode &hnode) {
|
||||||
|
//cerr << "Coarse node: " << (void *)hnode.node << " err: " << hnode.error << endl;
|
||||||
Node *node = hnode.node;
|
Node *node = hnode.node;
|
||||||
|
|
||||||
//recursively coarse children if applicable.
|
//recursively coarse children if applicable.
|
||||||
Node::iterator i;
|
Node::iterator i;
|
||||||
for(i = node->out_begin(); i != node->out_end(); i++) {
|
for(i = node->out_begin(); i != node->out_end(); i++) {
|
||||||
Node *child = (*i).node;
|
Node *child = (*i).node;
|
||||||
float error = GetRefineError(child);
|
float error = GetRefineError(child);
|
||||||
HeapNode hchild(child, error);
|
HeapNode hchild(child, error);
|
||||||
if(Visited(child))
|
if(Visited(child)) {
|
||||||
if(!Coarse(hchild)) return false;
|
if(!Coarse(hchild)) return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -308,7 +370,7 @@ void Extraction::Visit(Node *node) {
|
||||||
disk_used += cost.disk;
|
disk_used += cost.disk;
|
||||||
|
|
||||||
for(i = node->out_begin(); i != node->out_end(); i++) {
|
for(i = node->out_begin(); i != node->out_end(); i++) {
|
||||||
float maxerror = 0;
|
float maxerror = -1;
|
||||||
Link &link = *i;
|
Link &link = *i;
|
||||||
for(Link::iterator k = link.begin(); k != link.end(); k++) {
|
for(Link::iterator k = link.begin(); k != link.end(); k++) {
|
||||||
Entry &entry = (*mt)[(*k).patch];
|
Entry &entry = (*mt)[(*k).patch];
|
||||||
|
|
|
@ -64,7 +64,7 @@ class Extraction {
|
||||||
void Update(NexusMt *mt);
|
void Update(NexusMt *mt);
|
||||||
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
void Select();
|
void Select();
|
||||||
void Visit(Node *node);
|
void Visit(Node *node);
|
||||||
|
@ -72,7 +72,7 @@ class Extraction {
|
||||||
bool Expand(HeapNode &node);
|
bool Expand(HeapNode &node);
|
||||||
void Diff(Node *node, Cost &cost);
|
void Diff(Node *node, Cost &cost);
|
||||||
|
|
||||||
bool Refine(Node *node);
|
bool Refine(HeapNode &node);
|
||||||
bool Coarse(HeapNode &node);
|
bool Coarse(HeapNode &node);
|
||||||
|
|
||||||
void Init();
|
void Init();
|
||||||
|
|
|
@ -232,9 +232,9 @@ bool History::UpdatesToQuick() {
|
||||||
|
|
||||||
vector<unsigned int>::iterator k;
|
vector<unsigned int>::iterator k;
|
||||||
for(k = cells.begin(); k != cells.end(); k++) {
|
for(k = cells.begin(); k != cells.end(); k++) {
|
||||||
Cell cell;
|
Cell cell;
|
||||||
cell.patch = (*k);
|
cell.patch = (*k);
|
||||||
tmp_frags.push_back(cell);
|
tmp_frags.push_back(cell);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Add the new Frag to the node.
|
//Add the new Frag to the node.
|
||||||
|
|
|
@ -30,9 +30,15 @@ namespace nxs {
|
||||||
float dist = (sphere.Center() - frustum.ViewPoint()).Norm() - sphere.Radius();
|
float dist = (sphere.Center() - frustum.ViewPoint()).Norm() - sphere.Radius();
|
||||||
//float dist = Distance(sphere, frustum.ViewPoint());
|
//float dist = Distance(sphere, frustum.ViewPoint());
|
||||||
if(dist < 0)
|
if(dist < 0)
|
||||||
return 1e20f;
|
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);
|
return entry.error/frustum.Resolution(dist);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -161,27 +161,10 @@ Patch &Nexus::GetPatch(unsigned int patch, bool flush) {
|
||||||
return *(entry.patch);
|
return *(entry.patch);
|
||||||
}
|
}
|
||||||
|
|
||||||
Border Nexus::GetBorder(unsigned int patch, bool flush) {
|
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(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 Nexus::AddPatch(unsigned int nvert, unsigned int nface,
|
||||||
unsigned int nbord) {
|
unsigned int nbord) {
|
||||||
|
|
||||||
|
@ -206,121 +189,6 @@ unsigned int Nexus::AddPatch(unsigned int nvert, unsigned int nface,
|
||||||
return size() - 1;
|
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) {
|
Patch *Nexus::LoadPatch(unsigned int idx) {
|
||||||
assert(idx < size());
|
assert(idx < size());
|
||||||
Entry &entry = operator[](idx);
|
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);
|
unsigned int AddPatch(unsigned int nv, unsigned int nf, unsigned int nb);
|
||||||
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);
|
||||||
|
|
||||||
unsigned int &MaxRam() { return ram_max; }
|
unsigned int &MaxRam() { return ram_max; }
|
||||||
// void AddBorder(unsigned int patch, Link &link);
|
// void AddBorder(unsigned int patch, Link &link);
|
||||||
|
|
|
@ -24,6 +24,9 @@
|
||||||
History
|
History
|
||||||
|
|
||||||
$Log: not supported by cvs2svn $
|
$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
|
Revision 1.28 2005/01/14 15:25:29 ponchio
|
||||||
Revolution.
|
Revolution.
|
||||||
|
|
||||||
|
@ -425,7 +428,7 @@ int main(int argc, char *argv[]) {
|
||||||
|
|
||||||
/* if(show_borders) {
|
/* if(show_borders) {
|
||||||
for(unsigned int i = 0; i < cells.size(); i++) {
|
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]);
|
Patch &patch = nexus.GetPatch(cells[i]);
|
||||||
glPointSize(4);
|
glPointSize(4);
|
||||||
glColor3f(1.0f, 1.0f, 1.0f);
|
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.
|
//TODO optimize! it is not necessary to read all the borders.
|
||||||
for(unsigned int p = 0; p < nexus.size(); p++) {
|
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_start.push_back(tmpb_offset);
|
||||||
tmpb_offset += border.Size();
|
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;
|
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;
|
map<unsigned int, map<unsigned short, Point3f> >::iterator k;
|
||||||
for(k = bnorm.begin(); k != bnorm.end(); k++) {
|
for(k = bnorm.begin(); k != bnorm.end(); k++) {
|
||||||
unsigned int patch = (*k).first;
|
unsigned int patch = (*k).first;
|
||||||
Border border = nexus.GetBorder(patch);
|
Border &border = nexus.GetBorder(patch);
|
||||||
unsigned int offset = tmpb_start[patch];
|
unsigned int offset = tmpb_start[patch];
|
||||||
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];
|
||||||
|
@ -151,7 +151,7 @@ void nxs::ComputeNormals(Nexus &nexus) {
|
||||||
|
|
||||||
set<unsigned int>::iterator k;
|
set<unsigned int>::iterator k;
|
||||||
for(k = close.begin(); k != close.end(); 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];
|
unsigned int off = tmpb_start[*k];
|
||||||
|
|
||||||
for(unsigned int i = 0; i < remote.Size(); i++) {
|
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++) {
|
for(unsigned int p = 0; p < nexus.size(); p++) {
|
||||||
report.Step(p);
|
report.Step(p);
|
||||||
Patch &patch = nexus.GetPatch(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++) {
|
for(unsigned int i = 0; i < border.Size(); i++) {
|
||||||
Link &link = border[i];
|
Link &link = border[i];
|
||||||
|
@ -357,7 +357,7 @@ void nxs::Unify(Nexus &nexus, float threshold) {
|
||||||
|
|
||||||
//fix patch borders now
|
//fix patch borders now
|
||||||
set<unsigned int> close; //bordering pathes
|
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++) {
|
for(unsigned int b = 0; b < border.Size(); b++) {
|
||||||
if(border[b].IsNull()) continue;
|
if(border[b].IsNull()) continue;
|
||||||
close.insert(border[b].end_patch);
|
close.insert(border[b].end_patch);
|
||||||
|
@ -366,7 +366,7 @@ void nxs::Unify(Nexus &nexus, float threshold) {
|
||||||
|
|
||||||
set<unsigned int>::iterator c;
|
set<unsigned int>::iterator c;
|
||||||
for(c = close.begin(); c != close.end(); 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++) {
|
for(unsigned int b = 0; b < bord.Size(); b++) {
|
||||||
if(bord[b].IsNull()) continue;
|
if(bord[b].IsNull()) continue;
|
||||||
if(bord[b].end_patch == p) {
|
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.
|
//better to compact directly borders than setting them null.
|
||||||
//finally: there may be duplicated borders
|
//finally: there may be duplicated borders
|
||||||
for(unsigned int p = 0; p < nexus.size(); p++) {
|
for(unsigned int p = 0; p < nexus.size(); p++) {
|
||||||
Border border = nexus.GetBorder(p);
|
Border &border = nexus.GetBorder(p);
|
||||||
set<Link> links;
|
set<Link> links;
|
||||||
for(unsigned int b = 0; b < border.Size(); b++) {
|
for(unsigned int b = 0; b < border.Size(); b++) {
|
||||||
Link &link = border[b];
|
Link &link = border[b];
|
||||||
|
|
|
@ -24,6 +24,9 @@
|
||||||
History
|
History
|
||||||
|
|
||||||
$Log: not supported by cvs2svn $
|
$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
|
Revision 1.12 2005/01/14 15:25:29 ponchio
|
||||||
Revolution.
|
Revolution.
|
||||||
|
|
||||||
|
@ -170,8 +173,8 @@ void FirstStep(const string &crudefile, const string &output,
|
||||||
BlockIndex face_index;
|
BlockIndex face_index;
|
||||||
|
|
||||||
Remap(vchain, baricenters, face_remap, face_index,
|
Remap(vchain, baricenters, face_remap, face_index,
|
||||||
patch_size, patch_threshold, 65000, scaling,
|
patch_size, patch_threshold, 65000, scaling,
|
||||||
optimization_steps);
|
optimization_steps);
|
||||||
|
|
||||||
if(!vchain.Save(output + ".vchain")) {
|
if(!vchain.Save(output + ".vchain")) {
|
||||||
cerr << "Could not save file: " << output << ".vchain\n";
|
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++) {
|
for(unsigned int i = 0; i < face_remap.Size(); i++) {
|
||||||
unsigned int patch = face_remap[i];
|
unsigned int patch = face_remap[i];
|
||||||
assert(patch < face_index.size());
|
assert(patch < face_index.size());
|
||||||
assert(patch >= 0);
|
|
||||||
int64 offset = face_index[patch].offset + done[patch]++;
|
int64 offset = face_index[patch].offset + done[patch]++;
|
||||||
sorted[offset] = crude.GetFace(i);
|
sorted[offset] = crude.GetFace(i);
|
||||||
}
|
}
|
||||||
|
@ -231,16 +233,6 @@ void SecondStep(const string &crudefile, const string &output) {
|
||||||
assert(done[i] == face_index[i].size);
|
assert(done[i] == face_index[i].size);
|
||||||
#endif
|
#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
|
//once sorted
|
||||||
crude.Close();
|
crude.Close();
|
||||||
sorted.Close();
|
sorted.Close();
|
||||||
|
@ -318,16 +310,16 @@ void ThirdStep(const string &crudefile, const string &output,
|
||||||
// Crude::Face face = crude.GetFace(i);
|
// Crude::Face face = crude.GetFace(i);
|
||||||
Crude::Face face = sorted[i];
|
Crude::Face face = sorted[i];
|
||||||
if(face[0] == face[1] || face[1] == face[2] || face[0] == face[2])
|
if(face[0] == face[1] || face[1] == face[2] || face[0] == face[2])
|
||||||
continue; //degenerate
|
continue; //degenerate
|
||||||
for(int j = 0; j < 3; j++) {
|
for(int j = 0; j < 3; j++) {
|
||||||
assert(face[j] < crude.Vertices());
|
assert(face[j] < crude.Vertices());
|
||||||
if(!vremap.count(face[j])) {
|
if(!vremap.count(face[j])) {
|
||||||
Point3f &v = crude.vert[face[j]];
|
Point3f &v = crude.vert[face[j]];
|
||||||
vertices.push_back(v);
|
vertices.push_back(v);
|
||||||
vremap[face[j]] = vcount++;
|
vremap[face[j]] = vcount++;
|
||||||
}
|
}
|
||||||
faces.push_back(vremap[face[j]]);
|
faces.push_back(vremap[face[j]]);
|
||||||
fcount++;
|
fcount++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
assert(vcount == vertices.size());
|
assert(vcount == vertices.size());
|
||||||
|
@ -364,7 +356,7 @@ void ThirdStep(const string &crudefile, const string &output,
|
||||||
//saving vert_remap
|
//saving vert_remap
|
||||||
int64 vroffset = vert_remap.Size();
|
int64 vroffset = vert_remap.Size();
|
||||||
vert_index.push_back(BlockEntry(vroffset, vcount));
|
vert_index.push_back(BlockEntry(vroffset, vcount));
|
||||||
vert_remap.Resize(vroffset + vcount);
|
vert_remap.Resize(vroffset + vcount);
|
||||||
|
|
||||||
map<unsigned int, unsigned short>::iterator r;
|
map<unsigned int, unsigned short>::iterator r;
|
||||||
for(r = vremap.begin(); r != vremap.end(); 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());
|
assert(vroffset + (*r).second < vert_remap.Size());
|
||||||
vert_remap[vroffset + (*r).second] = (*r).first;
|
vert_remap[vroffset + (*r).second] = (*r).first;
|
||||||
}
|
}
|
||||||
}
|
if(vcount < 100) {
|
||||||
|
cerr << "Small patch: " << vcount << "\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//we can now update bounding sphere.
|
//we can now update bounding sphere.
|
||||||
for(unsigned int i = 0; i < nexus.size(); i++)
|
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!
|
//TODO Clear borders in case of failure!
|
||||||
|
|
||||||
VFile<unsigned int> vert_remap;
|
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";
|
cerr << "Could not load: " << crudefile << ".rvm\n";
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
cerr << "Vert_remap.size: " << vert_remap.Size() << endl;
|
||||||
|
|
||||||
BlockIndex vert_index;
|
BlockIndex vert_index;
|
||||||
if(!vert_index.Load(output + ".rvi")) {
|
if(!vert_index.Load(output + ".rvi")) {
|
||||||
|
@ -421,7 +417,7 @@ void FourthStep(const string &crudefile, const string &output,
|
||||||
}
|
}
|
||||||
Report report(nexus.size());
|
Report report(nexus.size());
|
||||||
|
|
||||||
for(int start = 0; start < nexus.size(); start++) {
|
for(int start = 0; start < nexus.size(); start++) {
|
||||||
report.Step(start);
|
report.Step(start);
|
||||||
Entry &s_entry = nexus[start];
|
Entry &s_entry = nexus[start];
|
||||||
|
|
||||||
|
@ -432,6 +428,14 @@ void FourthStep(const string &crudefile, const string &output,
|
||||||
map<unsigned int, unsigned short> vremap;
|
map<unsigned int, unsigned short> vremap;
|
||||||
#endif
|
#endif
|
||||||
for(unsigned int i = 0; i < vert_index[start].size; i++) {
|
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];
|
unsigned int global = vert_remap[vert_index[start].offset + i];
|
||||||
vremap[global] = i;
|
vremap[global] = i;
|
||||||
}
|
}
|
||||||
|
@ -446,21 +450,30 @@ void FourthStep(const string &crudefile, const string &output,
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
for(unsigned int i = 0; i < vert_index[end].size; i++) {
|
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)) {
|
//#ifndef NDEBUG
|
||||||
Link link;
|
if(vert_index[end].offset + i >= vert_remap.Size()) {
|
||||||
link.start_vert = vremap[global];
|
cerr << "aaa Ahi Ahi start: " << end << endl;
|
||||||
link.end_vert = i;
|
cerr << "offset: " << vert_index[end].offset << endl;
|
||||||
link.end_patch = end;
|
cerr << "size: " << vert_index[end].size << endl;
|
||||||
links.push_back(link);
|
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.ResizeBorder(start, 3 * links.size());
|
||||||
nexus.borders[start].used = links.size();
|
border.used = links.size();
|
||||||
Border border = nexus.GetBorder(start);
|
|
||||||
memcpy(&(border[0]), &*links.begin(), links.size() * sizeof(Link));
|
memcpy(&(border[0]), &*links.begin(), links.size() * sizeof(Link));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -699,7 +712,7 @@ void BuildFragment(Nexus &nexus, VPartition &part,
|
||||||
nxs.patch = *f;
|
nxs.patch = *f;
|
||||||
|
|
||||||
Patch &patch = nexus.GetPatch(*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++) {
|
for(unsigned int k = 0; k < patch.nf; k++) {
|
||||||
assert(patch.Face(k)[0] != patch.Face(k)[1]);
|
assert(patch.Face(k)[0] != patch.Face(k)[1]);
|
||||||
|
@ -825,7 +838,7 @@ void SaveFragment(Nexus &nexus, VChain &chain,
|
||||||
newlinks[link.end_patch].insert(up);
|
newlinks[link.end_patch].insert(up);
|
||||||
|
|
||||||
assert(link.end_patch != patch_idx);
|
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++) {
|
for(unsigned int k = 0; k < cborder.Size(); k++) {
|
||||||
//cerr << "Cborder.size: " << cborder.Size() << endl;
|
//cerr << "Cborder.size: " << cborder.Size() << endl;
|
||||||
//cerr << "K: " << k << endl;
|
//cerr << "K: " << k << endl;
|
||||||
|
@ -865,11 +878,9 @@ void SaveFragment(Nexus &nexus, VChain &chain,
|
||||||
set<Link>::iterator l;
|
set<Link>::iterator l;
|
||||||
unsigned int patch = (*n).first;
|
unsigned int patch = (*n).first;
|
||||||
set<Link> &links = (*n).second;
|
set<Link> &links = (*n).second;
|
||||||
Border border = nexus.GetBorder(patch);
|
Border &border = nexus.GetBorder(patch);
|
||||||
unsigned int bstart = border.Size();
|
unsigned int bstart = border.Size();
|
||||||
|
nexus.borders.ResizeBorder(patch, border.Size() + links.size());
|
||||||
if(nexus.borders.ResizeBorder(patch, border.Size() + links.size()))
|
|
||||||
border = nexus.GetBorder(patch);
|
|
||||||
for(l = links.begin(); l != links.end(); l++) {
|
for(l = links.begin(); l != links.end(); l++) {
|
||||||
Link link = *l;
|
Link link = *l;
|
||||||
border[bstart++] = link;
|
border[bstart++] = link;
|
||||||
|
|
|
@ -51,6 +51,7 @@ int main(int argc, char *argv[]) {
|
||||||
string output;
|
string output;
|
||||||
string plysource;
|
string plysource;
|
||||||
bool info = false;
|
bool info = false;
|
||||||
|
bool verbose = false;
|
||||||
unsigned int ram_size = 128000000;
|
unsigned int ram_size = 128000000;
|
||||||
unsigned int chunk_size = 0;
|
unsigned int chunk_size = 0;
|
||||||
|
|
||||||
|
@ -76,9 +77,10 @@ int main(int argc, char *argv[]) {
|
||||||
float qtexture = 0;
|
float qtexture = 0;
|
||||||
|
|
||||||
int option;
|
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) {
|
switch(option) {
|
||||||
case 'i': info = true; break;
|
case 'i': info = true; break;
|
||||||
|
case 'l': verbose = true; break;
|
||||||
case 'o': output = optarg; break;
|
case 'o': output = optarg; break;
|
||||||
case 'a': {
|
case 'a': {
|
||||||
if(strstr(optarg, "strip")) {
|
if(strstr(optarg, "strip")) {
|
||||||
|
@ -195,6 +197,7 @@ int main(int argc, char *argv[]) {
|
||||||
if(optind != argc - 1) {
|
if(optind != argc - 1) {
|
||||||
cerr << "Usage: " << argv[0] << " <nexus file> [options]\n"
|
cerr << "Usage: " << argv[0] << " <nexus file> [options]\n"
|
||||||
<< " -i : display some info about nexus file\n"
|
<< " -i : display some info about nexus file\n"
|
||||||
|
<< " -l : list nodes\n"
|
||||||
<< " -o <file>: output filename (default is adding 00 to nexus)\n"
|
<< " -o <file>: output filename (default is adding 00 to nexus)\n"
|
||||||
<< " -a <what>: Add [colors|normals|strip|textures|data|borders]\n"
|
<< " -a <what>: Add [colors|normals|strip|textures|data|borders]\n"
|
||||||
<< " -r <what>: As add...\n"
|
<< " -r <what>: As add...\n"
|
||||||
|
@ -254,7 +257,7 @@ int main(int argc, char *argv[]) {
|
||||||
|
|
||||||
|
|
||||||
if(info) {
|
if(info) {
|
||||||
cerr << "Nexus file: " << input << "\n\n"
|
cout << "Nexus file: " << input << "\n\n"
|
||||||
<< "\n\tCompressed: " << nexus.IsCompressed()
|
<< "\n\tCompressed: " << nexus.IsCompressed()
|
||||||
<< "\n\tStripped: " << (int)((nexus.signature&NXS_STRIP) !=0)
|
<< "\n\tStripped: " << (int)((nexus.signature&NXS_STRIP) !=0)
|
||||||
<< "\n\tColor : " << (int)((nexus.signature&NXS_COLORS) !=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.Center()[2] << " R: "
|
||||||
<< nexus.sphere.Radius()
|
<< nexus.sphere.Radius()
|
||||||
<< "\n\tChunk size " << nexus.chunk_size << endl;
|
<< "\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:
|
//determine if we must proceed:
|
||||||
|
@ -331,7 +342,7 @@ int main(int argc, char *argv[]) {
|
||||||
report.Step(patch);
|
report.Step(patch);
|
||||||
Entry &src_entry = nexus[patch];
|
Entry &src_entry = nexus[patch];
|
||||||
Patch &src_patch = nexus.GetPatch(patch);
|
Patch &src_patch = nexus.GetPatch(patch);
|
||||||
Border src_border = nexus.GetBorder(patch);
|
Border &src_border = nexus.GetBorder(patch);
|
||||||
|
|
||||||
|
|
||||||
vector<unsigned short> strip;
|
vector<unsigned short> strip;
|
||||||
|
@ -397,7 +408,7 @@ int main(int argc, char *argv[]) {
|
||||||
assert(link.end_patch < nexus.index.size());
|
assert(link.end_patch < nexus.index.size());
|
||||||
}*/
|
}*/
|
||||||
out.borders.ResizeBorder(patch, src_border.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(),
|
memcpy(dst_border.Start(), src_border.Start(),
|
||||||
src_border.Size() * sizeof(Link));
|
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++) {
|
for(unsigned int patchid = 0; patchid < nexus.index.size(); patchid++) {
|
||||||
PatchInfo &info = nexus.index[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++) {
|
for(unsigned int i = 0; i < border.Size(); i++) {
|
||||||
Link &link = border[i];
|
Link &link = border[i];
|
||||||
if(link.start_vert == 0 && link.end_vert == 0 && link.end_patch == 0) {
|
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";
|
cerr << "Reciprocity borders test\n";
|
||||||
for(unsigned int patchid = 0; patchid < nexus.index.size(); patchid++) {
|
for(unsigned int patchid = 0; patchid < nexus.index.size(); patchid++) {
|
||||||
PatchInfo &info = nexus.index[patchid];
|
PatchInfo &info = nexus.index[patchid];
|
||||||
Border border = nexus.GetBorder(patchid);
|
Border &border = nexus.GetBorder(patchid);
|
||||||
vector<Link> links;
|
vector<Link> links;
|
||||||
links.resize(border.Size());
|
links.resize(border.Size());
|
||||||
memcpy(&*links.begin(),&(border[0]),links.size() * sizeof(Link));
|
memcpy(&*links.begin(),&(border[0]),links.size() * sizeof(Link));
|
||||||
for(unsigned int i = 0; i < links.size(); i++) {
|
for(unsigned int i = 0; i < links.size(); i++) {
|
||||||
Link &link = links[i];
|
Link &link = links[i];
|
||||||
Border rborder = nexus.GetBorder(link.end_patch);
|
Border &rborder = nexus.GetBorder(link.end_patch, false);
|
||||||
|
|
||||||
bool found = false;
|
bool found = false;
|
||||||
for(unsigned int k = 0; k < rborder.Size(); k++) {
|
for(unsigned int k = 0; k < rborder.Size(); k++) {
|
||||||
|
|
|
@ -9,9 +9,10 @@ using namespace nxs;
|
||||||
while(!get_signaled()) {
|
while(!get_signaled()) {
|
||||||
lock.enter();
|
lock.enter();
|
||||||
while(!queue.size()) {
|
while(!queue.size()) {
|
||||||
lock.leave();
|
//cerr << "Acc nothing to preload!\n";
|
||||||
pt::psleep(10);
|
lock.leave();
|
||||||
lock.enter();
|
pt::psleep(10);
|
||||||
|
lock.enter();
|
||||||
}
|
}
|
||||||
//TODO check we are not loading too much memory!
|
//TODO check we are not loading too much memory!
|
||||||
assert(queue.size());
|
assert(queue.size());
|
||||||
|
|
|
@ -45,27 +45,22 @@ void nxs::Remap(VChain &chain,
|
||||||
float scaling,
|
float scaling,
|
||||||
int steps) {
|
int steps) {
|
||||||
|
|
||||||
VPartition *finepart = new VPartition;
|
VPartition *finepart = new VPartition;
|
||||||
// finepart.Init();
|
|
||||||
chain.push_back(finepart);
|
chain.push_back(finepart);
|
||||||
BuildPartition(*finepart, points, target_size, min_size, max_size, steps);
|
BuildPartition(*finepart, points, target_size, min_size, max_size, steps);
|
||||||
|
|
||||||
|
VPartition *coarsepart = new VPartition;
|
||||||
VPartition *coarsepart = new VPartition;
|
|
||||||
// coarsepart.Init();
|
|
||||||
chain.push_back(coarsepart);
|
chain.push_back(coarsepart);
|
||||||
BuildPartition(*coarsepart, points,
|
BuildPartition(*coarsepart, points,
|
||||||
(int)(target_size/scaling), min_size, max_size, steps);
|
(int)(target_size/scaling), min_size, max_size, steps);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
cerr << "Fine size: " << finepart->size() << endl;
|
cerr << "Fine size: " << finepart->size() << endl;
|
||||||
cerr << "Coarse size: " << coarsepart->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;
|
FragIndex patches;
|
||||||
|
|
||||||
unsigned int totpatches = 0;
|
unsigned int totpatches = 0;
|
||||||
|
@ -79,12 +74,11 @@ void nxs::Remap(VChain &chain,
|
||||||
unsigned int coarse = coarsepart->Locate(bari);
|
unsigned int coarse = coarsepart->Locate(bari);
|
||||||
|
|
||||||
unsigned int patch;
|
unsigned int patch;
|
||||||
|
if(!patches.count(coarse) || !patches[coarse].count(fine)) {
|
||||||
if(!patches.count(make_pair(coarse, fine))) {
|
|
||||||
patch = totpatches;
|
patch = totpatches;
|
||||||
patches[make_pair(coarse, fine)] = totpatches++;
|
patches[coarse][fine] = totpatches++;
|
||||||
} else
|
} else
|
||||||
patch = patches[make_pair(coarse, fine)];
|
patch = patches[coarse][fine];
|
||||||
|
|
||||||
remap[i] = patch;
|
remap[i] = patch;
|
||||||
|
|
||||||
|
@ -93,40 +87,96 @@ void nxs::Remap(VChain &chain,
|
||||||
count[patch]++;
|
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++) {
|
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) {
|
if(count[i] > 32000) {
|
||||||
//TODO do something to reduce patch size... :P
|
//TODO do something to reduce patch size... :P
|
||||||
cerr << "Found a patch too big... sorry\n";
|
cerr << "Found a patch too big... sorry\n";
|
||||||
exit(0);
|
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
|
//building fragments
|
||||||
FragIndex::iterator f;
|
for(FragIndex::iterator s = patches.begin(); s != patches.end(); s++) {
|
||||||
for(f = patches.begin(); f != patches.end(); f++) {
|
unsigned int coarse = (*s).first;
|
||||||
unsigned int coarse = (*f).first.first;
|
map<unsigned int, unsigned int> &fines = (*s).second;
|
||||||
unsigned int fine = (*f).first.second;
|
map<unsigned int, unsigned int>::iterator t;
|
||||||
unsigned int oldpatch = (*f).second;
|
for(t = fines.begin(); t != fines.end(); t++) {
|
||||||
assert(oldpatch < patch_remap.size());
|
unsigned int fine = (*t).first;
|
||||||
unsigned int patch = patch_remap[oldpatch];
|
unsigned int oldpatch = (*t).second;
|
||||||
if(patch != -1) //not deleted...
|
assert(oldpatch < patch_remap.size());
|
||||||
chain.oldfragments[coarse].insert(patch);
|
unsigned int patch = patch_remap[oldpatch];
|
||||||
}
|
if(patch != -1) //not deleted...
|
||||||
|
chain.oldfragments[coarse].insert(patch);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
cerr << "remapping faces again\n";
|
cerr << "remapping faces again\n";
|
||||||
//remapping faces
|
//remapping faces
|
||||||
|
@ -428,92 +478,4 @@ bool nxs::Optimize(VPartition &part,
|
||||||
}
|
}
|
||||||
part.Init();
|
part.Init();
|
||||||
return true;
|
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
|
History
|
||||||
|
|
||||||
$Log: not supported by cvs2svn $
|
$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
|
Revision 1.1 2004/11/30 22:50:30 ponchio
|
||||||
Level 0.
|
Level 0.
|
||||||
|
|
||||||
|
@ -64,6 +67,7 @@ void VPartition::Closest(const vcg::Point3f &p, unsigned int nsize,
|
||||||
point[0] = p[0];
|
point[0] = p[0];
|
||||||
point[1] = p[1];
|
point[1] = p[1];
|
||||||
point[2] = p[2];
|
point[2] = p[2];
|
||||||
|
if(nsize > size()) nsize = size();
|
||||||
|
|
||||||
nears.resize(nsize);
|
nears.resize(nsize);
|
||||||
dist.resize(nsize);
|
dist.resize(nsize);
|
||||||
|
|
Loading…
Reference in New Issue