Minor changes (visited and Cell)

This commit is contained in:
Federico Ponchio 2005-02-19 16:22:45 +00:00
parent 2bbfa50b0c
commit eed1577b2e
6 changed files with 121 additions and 90 deletions

View File

@ -24,6 +24,9 @@
History
$Log: not supported by cvs2svn $
Revision 1.7 2005/02/10 09:18:20 ponchio
Statistics.
Revision 1.6 2005/02/08 12:43:03 ponchio
Added copyright
@ -58,7 +61,7 @@ void Extraction::Extract(NexusMt *_mt) {
//first we clear the visited flags
visited.clear();
visited.resize(mt->history.n_nodes(), false);
visited.resize(mt->history.n_nodes(), 0);
heap.clear();
@ -70,7 +73,7 @@ void Extraction::Extract(NexusMt *_mt) {
heap.pop_back();
Node *node = hnode.node;
if(visited[node - root]) continue;
if(Visited(node)) continue;
if(Expand(hnode))
Visit(node);
@ -90,27 +93,35 @@ void Extraction::Init() {
Node *nodes = mt->history.nodes;
for(unsigned int i = 0; i < visited.size(); i++) {
if(!visited[i]) continue;
// if(!visited[i]) continue;
Node &node = nodes[i];
bool cancoarse = true;
Node::iterator n;
for(n = node.out_begin(); n != node.out_end(); n++) {
if(!visited[(*n).node - root]) {
if(!Visited((*n).node)) {
// if(!visited[(*n).node - root]) {
float maxerror = -1;
Link &link = *n;
for(Link::iterator k = link.begin(); k != link.end(); k++) {
unsigned int patch = (*k).patch;
unsigned int patch = *k;
Entry &entry = (*mt)[patch];
float error = metric->GetError(entry);
bool visible;
float error = metric->GetError(entry, visible);
if(error > maxerror) maxerror = error;
cost.extr += entry.ram_size;
//TODO if(frustum) else
//if(visible)
// cost.draw += 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;
}
@ -141,7 +152,7 @@ void Extraction::Update(NexusMt *_mt) {
if(!visited.size()) {
visited.resize(mt->history.n_nodes(), false);
visited[0] = true;
SetVisited(root, true);
}
Init();
@ -202,7 +213,7 @@ void Extraction::Update(NexusMt *_mt) {
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(Visited(child)) recursive = true;
}
if(!recursive && !Coarse(hnode)) { //no more disk so.. push back on heap the heapnode
back.push_back(hnode);
@ -229,8 +240,8 @@ void Extraction::Update(NexusMt *_mt) {
for(l = node->out_begin(); l != node->out_end(); l++) {
Link &link = (*l);
for(Link::iterator k = link.begin(); k != link.end(); k++) {
selected.push_back(Item((*k).patch, i));
errors[(*k).patch] = i;
selected.push_back(Item(*k, i));
errors[*k] = i;
}
}
} else if(back.size()) {
@ -242,8 +253,8 @@ void Extraction::Update(NexusMt *_mt) {
for(l = node->in_begin(); l != node->in_end(); l++) {
Link &link = (*l);
for(Link::iterator k = link.begin(); k != link.end(); k++) {
selected.push_back(Item((*k).patch, i));
errors[(*k).patch] = i;
selected.push_back(Item(*k, i));
errors[*k] = i;
}
}
}
@ -256,8 +267,9 @@ float Extraction::GetRefineError(Node *node) {
for(i = node->in_begin(); i != node->in_end(); i++) {
Link &link = *i;
for(Link::iterator k = link.begin(); k != link.end(); k++) {
Entry &entry = (*mt)[(*k).patch];
float error = metric->GetError(entry);
Entry &entry = (*mt)[*k];
bool visible;
float error = metric->GetError(entry, visible);
if(error > maxerror) maxerror = error;
}
}
@ -267,7 +279,6 @@ float Extraction::GetRefineError(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;
@ -305,7 +316,7 @@ bool Extraction::Refine(HeapNode hnode) {
draw_used += cost.draw;
disk_used += cost.disk;
visited[node - root] = true;
SetVisited(node, true);
//now add to the front children (unless sink node)
@ -349,7 +360,7 @@ bool Extraction::Coarse(HeapNode hnode) {
if(disk_used > disk_max) return false;
visited[node - root] = false;
SetVisited(node, false);
//now add to the back parents (unless root node)
for(i = node->in_begin(); i != node->in_end(); i++) {
@ -381,7 +392,7 @@ void Extraction::Select() {
if(!visited[n_out]) {
Link &link = *n;
for(Link::iterator k = link.begin(); k != link.end(); k++) {
unsigned int patch = (*k).patch;
unsigned int patch = *k;
selected.push_back(Item(patch,0));
errors[patch] = 0.0f;
}
@ -391,14 +402,13 @@ void Extraction::Select() {
}
void Extraction::Visit(Node *node) {
if(visited[node - root]) return;
assert(!Visited(node));
visited[node - root] = true;
SetVisited(node, true);
Node::iterator i;
for(i = node->in_begin(); i != node->in_end(); i++) {
unsigned int n_in = (*i).node - root;
if(visited[n_in]) continue;
if(Visited((*i).node)) continue;
Visit((*i).node);
}
@ -412,8 +422,9 @@ void Extraction::Visit(Node *node) {
float maxerror = -1;
Link &link = *i;
for(Link::iterator k = link.begin(); k != link.end(); k++) {
Entry &entry = (*mt)[(*k).patch];
float error = metric->GetError(entry);
Entry &entry = (*mt)[*k];
bool visible;
float error = metric->GetError(entry, visible);
if(error > maxerror) maxerror = error;
}
//TODO this check may be dangerous for non saturating things...
@ -437,7 +448,7 @@ void Extraction::Diff(Node *node, Cost &cost) {
for(i = node->in_begin(); i != node->in_end(); i++) {
Link &link = *i;
for(Link::iterator k = link.begin(); k != link.end(); k++) {
unsigned int patch = (*k).patch;
unsigned int patch = *k;
Entry &entry = (*mt)[patch];
cost.extr -= entry.ram_size;
vcg::Sphere3f &sphere = entry.sphere;
@ -451,7 +462,7 @@ void Extraction::Diff(Node *node, Cost &cost) {
for(i = node->out_begin(); i != node->out_end(); i++) {
Link &link = *i;
for(Link::iterator k = link.begin(); k != link.end(); k++) {
unsigned int patch = (*k).patch;
unsigned int patch = *k;
Entry &entry = (*mt)[patch];
cost.extr += entry.ram_size;
vcg::Sphere3f &sphere = entry.sphere;

View File

@ -24,6 +24,9 @@
History
$Log: not supported by cvs2svn $
Revision 1.7 2005/02/10 09:18:20 ponchio
Statistics.
Revision 1.6 2005/02/08 12:43:03 ponchio
Added copyright
@ -79,6 +82,7 @@ class Extraction {
Metric *metric;
//TODO make a pointer so no need to doubl check visibility...!
vcg::Frustumf frustum;
float target_error;
@ -88,6 +92,7 @@ class Extraction {
unsigned int disk_used, disk_max;
std::vector<bool> visited;
std::vector<bool> visible;
std::map<unsigned int, float> errors;
std::vector<Item> selected;
@ -126,9 +131,10 @@ class Extraction {
Node *root;
Node *sink;
bool Visited(Node *node) {
return visited[node - root];
}
bool Visited(Node *node) { return visited[node - root]; }
void SetVisited(Node *node, bool v) { visited[node - root] = v; }
bool Visible(Node *node) { return visible[node - root]; }
void SetVisible(Node *node, bool v) { visible[node - root] = v; }
float GetRefineError(Node *node);
};

View File

@ -24,6 +24,9 @@
History
$Log: not supported by cvs2svn $
Revision 1.6 2005/02/17 16:40:35 ponchio
Optimized BuildLevels.
Revision 1.5 2005/02/08 12:43:03 ponchio
Added copyright
@ -85,12 +88,12 @@ bool History::LoadQuick(unsigned int _size, char *mem) {
nodes = (Node *)(buffer + 5 * sizeof(int));
in_links = (Link *)(nodes + n_nodes());
out_links = in_links + n_in_links();
frags = (Cell *)(out_links + n_out_links());
frags = (unsigned int *)(out_links + n_out_links());
//check size is ok;
assert(n_nodes() * sizeof(Node) +
(n_in_links() + n_out_links()) * sizeof(Link) +
n_frags() * sizeof(Cell) +
n_frags() * sizeof(unsigned int) +
5 * sizeof(int) == size);
size = _size;
return LoadPointers();
@ -165,13 +168,13 @@ char *History::SaveQuick(unsigned int &_size) {
for(unsigned int i = 0; i < n_in_links(); i++) {
Link &link = in_links[i];
link.node = (Node *)(link.node - nodes);
link.frag_begin = (Cell *)(link.frag_begin - frags);
link.frag_begin = (unsigned int *)(link.frag_begin - frags);
}
for(unsigned int i = 0; i < n_out_links(); i++) {
Link &link = out_links[i];
link.node = (Node *)(link.node - nodes);
link.frag_begin = (Cell *)(link.frag_begin - frags);
link.frag_begin = (unsigned int *)(link.frag_begin - frags);
}
_size = size;
@ -212,7 +215,7 @@ bool History::UpdatesToQuick() {
vector<Link> tmp_in_links;
vector<Link> tmp_out_links;
vector<Cell> tmp_frags;
vector<unsigned int> tmp_frags;
unsigned int current_node = 0;
@ -252,21 +255,19 @@ bool History::UpdatesToQuick() {
Link inlink;
inlink.node = (Node *)floor_node;
inlink.frag_begin = (Cell *)(tmp_frags.size());
inlink.frag_begin = (unsigned int *)(tmp_frags.size());
inlink.frag_size = cells.size();
Link outlink;
outlink.node = (Node *)current_node;
outlink.frag_begin = (Cell *)(tmp_frags.size());
outlink.frag_begin = (unsigned int *)(tmp_frags.size());
outlink.frag_size = cells.size();
//Fill it with erased cells.
vector<unsigned int>::iterator k;
for(k = cells.begin(); k != cells.end(); k++) {
Cell cell;
cell.patch = (*k);
tmp_frags.push_back(cell);
tmp_frags.push_back(*k);
}
//Add the new Frag to the node.
@ -302,7 +303,7 @@ bool History::UpdatesToQuick() {
size = tmp_nodes.size() * sizeof(Node) +
tmp_in_links.size() * sizeof(Link) +
tmp_out_links.size() * sizeof(Link) +
tmp_frags.size() * sizeof(Cell) +
tmp_frags.size() * sizeof(unsigned int) +
5 * sizeof(int);
if(buffer) delete []buffer;
@ -317,13 +318,13 @@ bool History::UpdatesToQuick() {
nodes = (Node *)(buffer + 5 * sizeof(int));
in_links = (Link *)(nodes + n_nodes());
out_links = in_links + n_in_links();
frags = (Cell *)(out_links + n_out_links());
frags = (unsigned int *)(out_links + n_out_links());
memcpy(nodes, &*tmp_nodes.begin(), tmp_nodes.size()*sizeof(Node));
memcpy(in_links, &*tmp_in_links.begin(), tmp_in_links.size()*sizeof(Link));
memcpy(out_links, &*tmp_out_links.begin(),
tmp_out_links.size()*sizeof(Link));
memcpy(frags, &*tmp_frags.begin(), tmp_frags.size() * sizeof(Cell));
memcpy(frags, &*tmp_frags.begin(), tmp_frags.size() * sizeof(unsigned int));
return LoadPointers();
}
@ -338,7 +339,7 @@ void History::BuildLevels(vector<int> &levels) {
unsigned int current = 0;
if(node != nodes) { //not root
Link *inlink = node->in_begin();
unsigned int p = inlink->begin()->patch;
unsigned int p = *(inlink->begin());
assert(p < levels.size());
assert(p >= 0);
current = levels[p]+1;
@ -347,7 +348,7 @@ void History::BuildLevels(vector<int> &levels) {
Link &link = *l;
Link::iterator c;
for(c = link.begin(); c != link.end(); c++) {
unsigned int p = (*c).patch;
unsigned int p = *c;
while(p >= levels.size()) levels.push_back(-1);
levels[p] = current;
}

View File

@ -24,6 +24,9 @@
History
$Log: not supported by cvs2svn $
Revision 1.4 2005/02/17 16:40:35 ponchio
Optimized BuildLevels.
Revision 1.3 2005/02/08 12:43:03 ponchio
Added copyright
@ -50,22 +53,22 @@ namespace nxs {
std::vector<unsigned int> created;
};
struct Cell {
unsigned int patch;
// struct Cell {
// unsigned int patch;
// float error;
};
// };
struct Node;
struct Link {
Node *node;
typedef Cell *iterator;
typedef unsigned int *iterator;
iterator begin() { return frag_begin; }
iterator end() { return frag_begin + frag_size; }
unsigned int size() { return frag_size; }
Cell *frag_begin;
unsigned int *frag_begin;
unsigned int frag_size;
};
@ -89,7 +92,8 @@ namespace nxs {
Node *nodes;
Link *in_links;
Link *out_links;
Cell *frags;
//TODO this list is really not necessary if we order our cells
unsigned int *frags;
std::vector<Update> updates;

View File

@ -24,6 +24,9 @@
History
$Log: not supported by cvs2svn $
Revision 1.4 2005/02/08 12:43:03 ponchio
Added copyright
****************************************************************************/
@ -41,12 +44,14 @@ namespace nxs {
class Metric {
public:
virtual void GetView() {}
virtual float GetError(Entry &entry) = 0;
virtual float GetError(Entry &entry, bool &visible) = 0;
};
class FlatMetric: public Metric {
public:
float GetError(Entry &entry) { return entry.error; }
float GetError(Entry &entry, bool &visible) {
visible = true;
return entry.error; }
};
class FrustumMetric: public Metric {
@ -54,21 +59,20 @@ namespace nxs {
vcg::Frustumf frustum;
virtual void GetView() { frustum.GetView(); }
float GetError(Entry &entry) {
vcg::Sphere3f &sphere = entry.sphere;
float dist = (sphere.Center() - frustum.ViewPoint()).Norm() - sphere.Radius();
//float dist = Distance(sphere, frustum.ViewPoint());
if(dist < 0)
return 1e20f;
float GetError(Entry &entry, bool &visible) {
visible = true;
vcg::Sphere3f &sph = entry.sphere;
float dist = (sph.Center() - frustum.ViewPoint()).Norm() - sph.Radius();
float remote = frustum.Remoteness(sphere.Center(), sphere.Radius());
if(remote > 0)
return (entry.error/remote)/frustum.Resolution(dist);
if(dist < 0) return 1e20f;
//if(frustum.IsOutside(sphere.Center(), sphere.Radius()))
//return -1;
return entry.error/frustum.Resolution(dist);
float remote = frustum.Remoteness(sph.Center(), sph.Radius());
float error = entry.error/frustum.Resolution(dist);
if(remote > 0) {
visible = false;
error /= remote;
}
return error;
}
};
}

View File

@ -24,6 +24,9 @@
History
$Log: not supported by cvs2svn $
Revision 1.21 2005/02/19 10:45:04 ponchio
Patch generalized and small fixes.
Revision 1.20 2005/02/08 12:43:03 ponchio
Added copyright
@ -40,6 +43,7 @@ Added copyright
#include <vcg/space/sphere3.h>
#include "normalscone.h"
#include "patch.h"
#include "index_file.h"
#include "history.h"
@ -72,6 +76,7 @@ struct Entry {
vcg::Sphere3f sphere;
float error;
NCone3s cone;
Patch *patch;
unsigned int vbo_array;