cleaning.

This commit is contained in:
Federico Ponchio 2005-02-20 18:07:01 +00:00
parent a99a702c9c
commit 80ddbed065
9 changed files with 356 additions and 222 deletions

View File

@ -24,6 +24,9 @@
History History
$Log: not supported by cvs2svn $ $Log: not supported by cvs2svn $
Revision 1.9 2005/02/20 00:43:23 ponchio
Less memory x extraction. (removed frags)
Revision 1.8 2005/02/19 16:22:45 ponchio Revision 1.8 2005/02/19 16:22:45 ponchio
Minor changes (visited and Cell) Minor changes (visited and Cell)
@ -64,7 +67,9 @@ void Extraction::Extract(NexusMt *_mt) {
//first we clear the visited flags //first we clear the visited flags
visited.clear(); visited.clear();
visited.resize(mt->history.n_nodes(), 0); visited.resize(mt->history.n_nodes(), false);
visible.clear();
visible.resize(mt->size(), true);
heap.clear(); heap.clear();
@ -96,34 +101,28 @@ void Extraction::Init() {
Node *nodes = mt->history.nodes; Node *nodes = mt->history.nodes;
for(unsigned int i = 0; i < visited.size(); i++) { for(unsigned int i = 0; i < visited.size(); i++) {
if(!visited[i]) continue; if(!visited[i]) continue;
// if(!visited[i]) continue;
Node &node = nodes[i]; Node &node = nodes[i];
bool cancoarse = true; bool cancoarse = true;
Node::iterator n; Node::iterator n;
for(n = node.out_begin(); n != node.out_end(); n++) { for(n = node.out_begin(); n != node.out_end(); n++) {
if(!Visited((*n).node)) { if(!Visited((*n).node)) {
// if(!visited[(*n).node - root]) {
float maxerror = -1; 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;
unsigned int patch = k; unsigned int patch = k;
Entry &entry = (*mt)[patch]; Entry &entry = (*mt)[patch];
bool visible; bool visible;
float error = metric->GetError(entry, visible); float error = metric->GetError(entry, visible);
if(error > maxerror) maxerror = error; if(error > maxerror) maxerror = error;
cost.extr += entry.ram_size; cost.extr += entry.ram_size;
//TODO if(frustum) else
//if(visible)
// cost.draw += entry.ram_size;
vcg::Sphere3f &sphere = entry.sphere; SetVisible(patch, visible);
if(!frustum.IsOutside(sphere.Center(), sphere.Radius())) if(visible)
cost.draw += entry.ram_size; cost.draw += entry.ram_size;
if(!entry.patch) if(!entry.patch)
@ -135,7 +134,7 @@ void Extraction::Init() {
} else } else
cancoarse = false; cancoarse = false;
} }
if(cancoarse && &node != root) { if(cancoarse && (&node != root)) {
float error = GetRefineError(&node); float error = GetRefineError(&node);
back.push_back(HeapNode(&node, error)); back.push_back(HeapNode(&node, error));
} }
@ -157,31 +156,48 @@ void Extraction::Update(NexusMt *_mt) {
if(!visited.size()) { if(!visited.size()) {
visited.resize(mt->history.n_nodes(), false); visited.resize(mt->history.n_nodes(), false);
SetVisited(root, true); SetVisited(root, true);
} }
visible.clear();
visible.resize(mt->size(), true);
Init(); Init();
bool no_draw = false; bool no_draw = false;
bool no_disk = false;
//TODO big problem: nodes a (error 10) with parent b (error -1) //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 //i try to refine a, refine b (recursive) but fail to refine a
//next step i coarse b whis cause a cycle. //next step i coarse b whis cause a cycle.
/* Updateing strategy:
if i can refine (not at leaves, have draw and extr buffer, not past target_error)
i try to refine BUT
i can fail because i finish some buffer (exp. while recursively refine)
(then i put the operation back on the stack)
if i have finished disk i should just quit
if i cannot refine i consider coarsening:
i need 1) not be at root (eheh)
2) have finished draw and extr buffer
3) do not make global error worse (unless it is < target_error...)
4) check it is not a recursive coarsening (drop it otherwise)
i try to coarse BUT
i can fail because i need disk
(then i put the operation back on the stack)
if i cannot coarse i just quit
*/
while(1) { while(1) {
if(!no_draw && //we have buffer if(!no_draw && //we have buffer
front.size() && //we are not at max level front.size() && //we are not at max level
front[0].error > target_error) { //we are not already target_error front[0].error > target_error) { //we are not already at target_error
max_error = front[0].error; max_error = front[0].error;
pop_heap(front.begin(), front.end()); pop_heap(front.begin(), front.end());
HeapNode hnode = front.back(); HeapNode hnode = front.back();
front.pop_back(); front.pop_back();
if(!Visited(hnode.node)) {
if(!Refine(hnode)) { if(!Visited(hnode.node) && !Refine(hnode))
no_draw = true; no_draw = true;
}
}
continue; continue;
} }
@ -191,6 +207,7 @@ void Extraction::Update(NexusMt *_mt) {
} }
if(no_draw) { //suppose i have no more buffer if(no_draw) { //suppose i have no more buffer
//TODO see point 3
//if i do error damages coarsening better get out //if i do error damages coarsening better get out
if(front.size() && ((back.front().error + 0.001) >= front.front().error)) { if(front.size() && ((back.front().error + 0.001) >= front.front().error)) {
//cerr << "Balanced cut\n"; //cerr << "Balanced cut\n";
@ -219,10 +236,10 @@ void Extraction::Update(NexusMt *_mt) {
Node *child = (*i).node; Node *child = (*i).node;
if(Visited(child)) recursive = true; if(Visited(child)) recursive = true;
} }
if(!recursive && !Coarse(hnode)) { //no more disk so.. push back on heap the heapnode if(!recursive && !Coarse(hnode)) { //no more disk so. push back on heap the heapnode
back.push_back(hnode); back.push_back(hnode);
push_heap(back.begin(), back.end(), greater<HeapNode>()); push_heap(back.begin(), back.end(), greater<HeapNode>());
break; break;
} }
} }
@ -244,8 +261,6 @@ void Extraction::Update(NexusMt *_mt) {
for(l = node->out_begin(); l != node->out_end(); l++) { for(l = node->out_begin(); l != node->out_end(); l++) {
Link &link = (*l); Link &link = (*l);
for(Link::iterator k = link.begin(); k != link.end(); k++) { for(Link::iterator k = link.begin(); k != link.end(); k++) {
// selected.push_back(Item(*k, i));
// errors[*k] = i;
selected.push_back(Item(k, i)); selected.push_back(Item(k, i));
errors[k] = i; errors[k] = i;
} }
@ -259,8 +274,6 @@ void Extraction::Update(NexusMt *_mt) {
for(l = node->in_begin(); l != node->in_end(); l++) { for(l = node->in_begin(); l != node->in_end(); l++) {
Link &link = (*l); Link &link = (*l);
for(Link::iterator k = link.begin(); k != link.end(); k++) { for(Link::iterator k = link.begin(); k != link.end(); k++) {
// selected.push_back(Item(*k, i));
// errors[*k] = i;
selected.push_back(Item(k, i)); selected.push_back(Item(k, i));
errors[k] = i; errors[k] = i;
} }
@ -279,6 +292,7 @@ float Extraction::GetRefineError(Node *node) {
bool visible; bool visible;
float error = metric->GetError(entry, visible); float error = metric->GetError(entry, visible);
if(error > maxerror) maxerror = error; if(error > maxerror) maxerror = error;
SetVisible(p, visible);
} }
} }
return maxerror; return maxerror;
@ -399,11 +413,6 @@ void Extraction::Select() {
unsigned int n_out = (*n).node - root; unsigned int n_out = (*n).node - root;
if(!visited[n_out]) { if(!visited[n_out]) {
Link &link = *n; Link &link = *n;
/* for(Link::iterator k = link.begin(); k != link.end(); k++) {
unsigned int patch = *k;
selected.push_back(Item(patch,0));
errors[patch] = 0.0f;
}*/
for(Link::iterator p= link.begin(); p != link.end(); p++) { for(Link::iterator p= link.begin(); p != link.end(); p++) {
selected.push_back(Item(p, 0)); selected.push_back(Item(p, 0));
errors[p] = 0.0f; errors[p] = 0.0f;
@ -438,6 +447,7 @@ void Extraction::Visit(Node *node) {
bool visible; bool visible;
float error = metric->GetError(entry, visible); float error = metric->GetError(entry, visible);
if(error > maxerror) maxerror = error; if(error > maxerror) maxerror = error;
SetVisible(p, visible);
} }
//TODO this check may be dangerous for non saturating things... //TODO this check may be dangerous for non saturating things...
if(maxerror > target_error) { if(maxerror > target_error) {
@ -462,9 +472,8 @@ void Extraction::Diff(Node *node, Cost &cost) {
for(Link::iterator p = link.begin(); p != link.end(); p++) { for(Link::iterator p = link.begin(); p != link.end(); p++) {
Entry &entry = (*mt)[p]; Entry &entry = (*mt)[p];
cost.extr -= entry.ram_size; cost.extr -= entry.ram_size;
vcg::Sphere3f &sphere = entry.sphere; if(Visible(p)) cost.draw -= entry.ram_size;
if(!frustum.IsOutside(sphere.Center(), sphere.Radius()))
cost.draw -= entry.ram_size;
if(!entry.patch) if(!entry.patch)
cost.disk -= entry.disk_size; cost.disk -= entry.disk_size;
} }
@ -475,9 +484,8 @@ void Extraction::Diff(Node *node, Cost &cost) {
for(Link::iterator p = link.begin(); p != link.end(); p++) { for(Link::iterator p = link.begin(); p != link.end(); p++) {
Entry &entry = (*mt)[p]; Entry &entry = (*mt)[p];
cost.extr += entry.ram_size; cost.extr += entry.ram_size;
vcg::Sphere3f &sphere = entry.sphere; if(Visible(p)) cost.draw += entry.ram_size;
if(!frustum.IsOutside(sphere.Center(), sphere.Radius()))
cost.draw += entry.ram_size;
if(!entry.patch) if(!entry.patch)
cost.disk += entry.disk_size; cost.disk += entry.disk_size;
} }

View File

@ -24,6 +24,9 @@
History History
$Log: not supported by cvs2svn $ $Log: not supported by cvs2svn $
Revision 1.8 2005/02/19 16:22:45 ponchio
Minor changes (visited and Cell)
Revision 1.7 2005/02/10 09:18:20 ponchio Revision 1.7 2005/02/10 09:18:20 ponchio
Statistics. Statistics.
@ -81,12 +84,9 @@ class Extraction {
}; };
Metric *metric; Metric *metric;
//TODO make a pointer so no need to doubl check visibility...!
vcg::Frustumf frustum;
float target_error; float target_error;
float max_error;
float max_error; //actual error at end of extraction
unsigned int extr_used, extr_max; unsigned int extr_used, extr_max;
unsigned int draw_used, draw_max; unsigned int draw_used, draw_max;
unsigned int disk_used, disk_max; unsigned int disk_used, disk_max;
@ -98,7 +98,7 @@ class Extraction {
std::vector<Item> selected; std::vector<Item> selected;
unsigned int draw_size; //first in selected should be drawn unsigned int draw_size; //first in selected should be drawn
std::vector<HeapNode> heap; //no realtime extraxtion std::vector<HeapNode> heap; //no realtime extraxtion TODO (use front)
//nodes that i can expand to //nodes that i can expand to
std::vector<HeapNode> front; std::vector<HeapNode> front;
@ -114,6 +114,8 @@ class Extraction {
void Update(NexusMt *mt); void Update(NexusMt *mt);
bool Visible(unsigned int p) { return visible[p]; }
void SetVisible(unsigned int p, bool v) { visible[p] = v; }
protected: protected:
void Select(); void Select();
@ -126,16 +128,15 @@ class Extraction {
bool Coarse(HeapNode node); bool Coarse(HeapNode node);
void Init(); void Init();
bool Visited(Node *node) { return visited[node - root]; }
void SetVisited(Node *node, bool v) { visited[node - root] = v; }
private: private:
NexusMt *mt; NexusMt *mt;
Node *root; Node *root;
Node *sink; Node *sink;
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); float GetRefineError(Node *node);
}; };

View File

@ -24,6 +24,9 @@
History History
$Log: not supported by cvs2svn $ $Log: not supported by cvs2svn $
Revision 1.5 2005/02/19 16:22:45 ponchio
Minor changes (visited and Cell)
Revision 1.4 2005/02/08 12:43:03 ponchio Revision 1.4 2005/02/08 12:43:03 ponchio
Added copyright Added copyright
@ -43,22 +46,25 @@ namespace nxs {
class Metric { class Metric {
public: public:
virtual void GetView() {} vcg::Frustumf frustum;
bool culling;
Metric(): culling(true) {}
virtual void GetView() { frustum.GetView(); }
virtual float GetError(Entry &entry, bool &visible) = 0; virtual float GetError(Entry &entry, bool &visible) = 0;
}; };
class FlatMetric: public Metric { class FlatMetric: public Metric {
public: public:
float GetError(Entry &entry, bool &visible) { float GetError(Entry &entry, bool &visible) {
visible = true; visible = true;
return entry.error; } return entry.error;
}
}; };
class FrustumMetric: public Metric { class FrustumMetric: public Metric {
public: public:
vcg::Frustumf frustum;
virtual void GetView() { frustum.GetView(); }
float GetError(Entry &entry, bool &visible) { float GetError(Entry &entry, bool &visible) {
visible = true; visible = true;
vcg::Sphere3f &sph = entry.sphere; vcg::Sphere3f &sph = entry.sphere;
@ -66,12 +72,16 @@ namespace nxs {
if(dist < 0) return 1e20f; if(dist < 0) return 1e20f;
float remote = frustum.Remoteness(sph.Center(), sph.Radius());
float error = entry.error/frustum.Resolution(dist); float error = entry.error/frustum.Resolution(dist);
if(remote > 0) { if(culling) {
visible = false; float remote = frustum.Remoteness(sph.Center(), sph.Radius());
error /= remote; if(remote > 0) {
} visible = false;
error /= remote;
} else if(entry.cone.Backface(sph, frustum.ViewPoint())) {
visible = false;
}
}
return error; return error;
} }
}; };

View File

@ -24,6 +24,9 @@
History History
$Log: not supported by cvs2svn $ $Log: not supported by cvs2svn $
Revision 1.33 2005/02/20 00:43:23 ponchio
Less memory x extraction. (removed frags)
Revision 1.32 2005/02/19 12:06:53 ponchio Revision 1.32 2005/02/19 12:06:53 ponchio
Debug... Debug...
@ -129,7 +132,6 @@ bool NexusMt::InitGL(bool vbo) {
void NexusMt::Render(DrawContest contest) { void NexusMt::Render(DrawContest contest) {
Extraction extraction; Extraction extraction;
extraction.frustum.GetView();
extraction.metric->GetView(); extraction.metric->GetView();
extraction.Extract(this); extraction.Extract(this);
Render(extraction, contest); Render(extraction, contest);
@ -162,11 +164,9 @@ void NexusMt::Render(Extraction &extraction, DrawContest &contest,
for(unsigned int i = 0; i < extraction.draw_size; i++) { for(unsigned int i = 0; i < extraction.draw_size; i++) {
unsigned int patch = extraction.selected[i].id; unsigned int patch = extraction.selected[i].id;
Entry &entry = operator[](patch); Entry &entry = operator[](patch);
vcg::Sphere3f &sphere = entry.sphere;
if(stats) stats->extr += 2*entry.nvert; if(stats) stats->extr += 2*entry.nvert;
if(extraction.frustum.IsOutside(sphere.Center(), sphere.Radius())) if(!extraction.Visible(patch))
continue; continue;
if(stats) stats->tri += 2*entry.nvert; if(stats) stats->tri += 2*entry.nvert;

View File

@ -24,6 +24,9 @@
History History
$Log: not supported by cvs2svn $ $Log: not supported by cvs2svn $
Revision 1.42 2005/02/20 00:43:24 ponchio
Less memory x extraction. (removed frags)
Revision 1.41 2005/02/19 12:06:55 ponchio Revision 1.41 2005/02/19 12:06:55 ponchio
Debug... Debug...
@ -314,9 +317,6 @@ int main(int argc, char *argv[]) {
return -1; return -1;
} }
// FrustumPolicy frustum_policy;
cerr << "Commands: \n" cerr << "Commands: \n"
" q : quit\n" " q : quit\n"
" t : toggle statistics\n" " t : toggle statistics\n"
@ -408,7 +408,6 @@ int main(int argc, char *argv[]) {
case SDLK_0: extraction.extr_max *= 1.3; break; case SDLK_0: extraction.extr_max *= 1.3; break;
case SDLK_9: extraction.extr_max *= 0.8; break; case SDLK_9: extraction.extr_max *= 0.8; break;
// case SDLK_s: metric = NexusMt::FRUSTUM; break;
case SDLK_p: contest.mode = DrawContest::POINTS; break; case SDLK_p: contest.mode = DrawContest::POINTS; break;
case SDLK_d: contest.mode = DrawContest::PATCHES; break; case SDLK_d: contest.mode = DrawContest::PATCHES; break;
case SDLK_f: contest.mode = DrawContest::FLAT; break; case SDLK_f: contest.mode = DrawContest::FLAT; break;
@ -517,7 +516,8 @@ int main(int argc, char *argv[]) {
glColor3f(0.8f, 0.8f, 0.8f); glColor3f(0.8f, 0.8f, 0.8f);
if(extract) { if(extract) {
extraction.frustum.GetView(); // Sould we want a different view from metric and extraction
// extraction.frustum->GetView();
extraction.metric->GetView(); extraction.metric->GetView();
if(!realtime) { if(!realtime) {
extraction.Extract(&nexus); extraction.Extract(&nexus);

View File

@ -24,6 +24,9 @@
History History
$Log: not supported by cvs2svn $ $Log: not supported by cvs2svn $
Revision 1.20 2005/02/19 10:45:04 ponchio
Patch generalized and small fixes.
Revision 1.19 2005/02/18 13:04:12 ponchio Revision 1.19 2005/02/18 13:04:12 ponchio
Added patch reordering. Added patch reordering.
@ -57,6 +60,57 @@ using namespace vcg;
#include "tristripper/tri_stripper.h" #include "tristripper/tri_stripper.h"
using namespace triangle_stripper; using namespace triangle_stripper;
void nxs::TightSphere(vcg::Sphere3f &sphere,
std::vector<vcg::Point3f> &points) {
//test:
//assumes radius is ok.... and try to optimize moving center.
//TODO using a gradiend descent? really a mess.
Point3f center;
float radius;
Point3f pert[14];
while(1) {
radius = sphere.Radius();
float step = radius/40;
pert[0] = Point3f(step, 0, 0);
pert[1] = -pert[0];
pert[2] = Point3f(0, step, 0);
pert[3] = -pert[2];
pert[4] = Point3f(0, 0, step);
pert[5] = -pert[4];
pert[6] = Point3f(step, step, step);
pert[7] = Point3f(step, step, -step);
pert[8] = Point3f(step, -step, step);
pert[9] = Point3f(step, -step, -step);
pert[10] = Point3f(-step, step, step);
pert[11] = Point3f(-step, step, -step);
pert[12] = Point3f(-step, -step, step);
pert[13] = Point3f(-step, -step, -step);
unsigned int best = 14;
float best_radius = sphere.Radius();
for(unsigned int k = 0; k < 14; k++) {
center = sphere.Center() + pert[k];
radius = 0;
for(unsigned int i = 0; i < points.size(); i++) {
float r = 1.01 * Distance(center, points[i]);
if(r > radius)
radius = r;
}
if(radius < best_radius) {
best = k;
best_radius = radius;
}
}
if(best == 14) break;
sphere.Center() = sphere.Center() + pert[best];
sphere.Radius() = best_radius;
}
}
void nxs::ComputeNormals(Nexus &nexus) { void nxs::ComputeNormals(Nexus &nexus) {
assert(nexus.signature.vnorm); assert(nexus.signature.vnorm);
@ -74,9 +128,8 @@ void nxs::ComputeNormals(Nexus &nexus) {
exit(0); exit(0);
} }
//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.borders[p];
tmpb_start.push_back(tmpb_offset); tmpb_start.push_back(tmpb_offset);
tmpb_offset += border.Size(); tmpb_offset += border.Size();
} }
@ -131,6 +184,10 @@ void nxs::ComputeNormals(Nexus &nexus) {
normals[f[2]] += norm; normals[f[2]] += norm;
} }
//compute normalscone (done in building...
// ANCone3f cone;
// cone.AddNormals(normals, cone_threshold);
// nexus[p].cone.Import(cone);
if(nexus.signature.vnorm == Encodings::SHORT4) { if(nexus.signature.vnorm == Encodings::SHORT4) {
short *n = (short *)patch.VNormBegin(); short *n = (short *)patch.VNormBegin();
for(unsigned int i = 0; i < patch.nv; i++, n += 4) { for(unsigned int i = 0; i < patch.nv; i++, n += 4) {

View File

@ -24,6 +24,9 @@
History History
$Log: not supported by cvs2svn $ $Log: not supported by cvs2svn $
Revision 1.6 2005/02/19 10:45:04 ponchio
Patch generalized and small fixes.
Revision 1.5 2005/02/18 13:04:13 ponchio Revision 1.5 2005/02/18 13:04:13 ponchio
Added patch reordering. Added patch reordering.
@ -38,12 +41,14 @@ Added copyright
#include <vector> #include <vector>
#include "patch.h" #include "patch.h"
#include <vcg/space/sphere3.h>
namespace nxs { namespace nxs {
class Nexus; class Nexus;
class Patch; class Patch;
struct ZEntry { struct ZEntry {
unsigned int id; unsigned int id;
unsigned int pos; unsigned int pos;
@ -57,6 +62,7 @@ namespace nxs {
void Unify(Nexus &nexus, float threshold); void Unify(Nexus &nexus, float threshold);
void ZSort(Nexus &nexus, std::vector<unsigned int> &forward, void ZSort(Nexus &nexus, std::vector<unsigned int> &forward,
std::vector<unsigned int> &backward); std::vector<unsigned int> &backward);
void TightSphere(vcg::Sphere3f &sphere, std::vector<vcg::Point3f> &points);
} }
#endif #endif

View File

@ -24,6 +24,9 @@
History History
$Log: not supported by cvs2svn $ $Log: not supported by cvs2svn $
Revision 1.18 2005/02/20 00:43:24 ponchio
Less memory x extraction. (removed frags)
Revision 1.17 2005/02/19 17:14:02 ponchio Revision 1.17 2005/02/19 17:14:02 ponchio
History quick by default. History quick by default.
@ -338,7 +341,8 @@ void ThirdStep(const string &crudefile, const string &output,
assert(vcount == vertices.size()); assert(vcount == vertices.size());
assert(fcount == faces.size()); assert(fcount == faces.size());
//TODO deal with this case adding another patch at the end... its not that difficult! //TODO deal with this case adding another patch at the end...
//its not that difficult!
//This can happen on degenerate cases when we have a lot of detached faces.... //This can happen on degenerate cases when we have a lot of detached faces....
if(vcount > 65000 && fcount > 65000) { if(vcount > 65000 && fcount > 65000) {
@ -359,6 +363,23 @@ void ThirdStep(const string &crudefile, const string &output,
sphere.Add(vertices[i]); sphere.Add(vertices[i]);
sphere.Radius() *= 1.01; sphere.Radius() *= 1.01;
TightSphere(sphere, vertices);
vector<Point3f> normals;
for(unsigned int i = 0; i < patch.nf; i++) {
unsigned short *f = patch.Face(i);
Point3f &v0 = patch.Vert3f(f[0]);
Point3f &v1 = patch.Vert3f(f[1]);
Point3f &v2 = patch.Vert3f(f[2]);
Point3f norm = (v1 - v0) ^ (v2 - v0);
normals.push_back(norm.Normalize());
}
ANCone3f cone;
cone.AddNormals(normals, 0.99f);
nexus[patch_idx].cone.Import(cone);
#ifndef NDEBUG #ifndef NDEBUG
for(int i = 0; i < vertices.size(); i++) { for(int i = 0; i < vertices.size(); i++) {
assert(sphere.IsIn(vertices[i])); assert(sphere.IsIn(vertices[i]));
@ -836,6 +857,7 @@ void SaveFragment(Nexus &nexus, VChain &chain,
nexus.sphere.Add(outpatch.vert[v]); nexus.sphere.Add(outpatch.vert[v]);
} }
entry.sphere.Radius() *= 1.01; entry.sphere.Radius() *= 1.01;
TightSphere(entry.sphere, outpatch.vert);
//remap internal borders //remap internal borders
for(unsigned int k = 0; k < outpatch.bord.size(); k++) { for(unsigned int k = 0; k < outpatch.bord.size(); k++) {

View File

@ -24,6 +24,9 @@
History History
$Log: not supported by cvs2svn $ $Log: not supported by cvs2svn $
Revision 1.22 2005/02/20 00:43:24 ponchio
Less memory x extraction. (removed frags)
Revision 1.21 2005/02/19 17:14:02 ponchio Revision 1.21 2005/02/19 17:14:02 ponchio
History quick by default. History quick by default.
@ -86,21 +89,25 @@ string getSuffix(Signature &signature) {
return suff; return suff;
} }
void printInfo(Nexus &nexus, bool verbose, bool dump_history);
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
string input; string input;
string output; string output;
string plysource; string plysource;
bool info = false; bool info = false;
bool verbose = false; bool verbose = false;
bool dump_history = false; bool dump_history = false;
unsigned int ram_size = 128000000; unsigned int ram_size = 128000000;
unsigned int chunk_size = 0; unsigned int chunk_size = 0;
bool add = false; bool add = false;
bool add_strips = false; bool add_strips = false;
bool add_colors = false; bool add_colors = false;
bool add_normals = false; unsigned char add_normals = 0;
bool add_textures = false; bool add_textures = false;
bool add_data = false; bool add_data = false;
@ -113,45 +120,32 @@ int main(int argc, char *argv[]) {
bool compress = false; bool compress = false;
bool uncompress = false; bool uncompress = false;
bool zsort = false;
float qvertex = 0; float qvertex = 0;
float qnormal = 0; float qnormal = 0;
float qcolor = 0; float qcolor = 0;
float qtexture = 0; float qtexture = 0;
bool zsort = false; float cone_threshold = 0;
int option; int option;
while((option = getopt(argc, argv, "ilho:a:r:zxsv:n:k:t:b:c:")) != EOF) { while((option = getopt(argc, argv, "ilho:a:r:zxsv:n:k:t:b:c:V:")) != EOF) {
switch(option) { switch(option) {
case 'i': info = true; break; case 'i': info = true; break;
case 'l': verbose = true; break; case 'l': verbose = true; break;
case 'h': dump_history = true; break; case 'h': dump_history = true; break;
case 'o': output = optarg; break; case 'o': output = optarg; break;
case 'p': plysource = optarg; break;
case 'a': { case 'a': {
if(strstr(optarg, "strips")) { if(strstr(optarg, "strips")) { add_strips = true; add = true; }
add_strips = true; if(strstr(optarg, "colors")) { add_colors = true; add = true; }
add = true; if(strstr(optarg, "normals")) {
// add |= NXS_STRIP; add_normals = Encodings::SHORT4; add = true; }
// remove |= NXS_FACES; if(strstr(optarg, "normalf")) {
} add_normals = Encodings::FLOAT3; add = true; }
if(strstr(optarg, "colors")) { if(strstr(optarg, "textures")) { add_textures = true; add = true; }
add_colors = true; if(strstr(optarg, "data")) { add_data = true; add = true; }
add = true;
// add |= NXS_COLORS;
}
if(strstr(optarg, "normals")) {
add_normals = true;
add = true;
// add |= NXS_NORMALS_SHORT;
}
if(strstr(optarg, "textures")) {
add_textures = true;
add = true;
// add |= NXS_TEXTURES_SHORT;
}
if(strstr(optarg, "data")) {
add_data = true;
// add |= NXS_DATA32;
}
if(add == false) { if(add == false) {
cerr << "Invalid -a argument: " << optarg << "\n" cerr << "Invalid -a argument: " << optarg << "\n"
<< "Valid options are: strips, colors, normals, textures, data\n"; << "Valid options are: strips, colors, normals, textures, data\n";
@ -159,50 +153,31 @@ int main(int argc, char *argv[]) {
} }
break; break;
} }
case 'r': { case 'r': {
if(strstr(optarg, "strips")) { if(strstr(optarg, "strips")) {
cerr << "Strips removing not supported!\n"; cerr << "Strips removing not supported!\n";
return -1; return -1;
remove_strips = true;
remove = true;
add = true;
// add |= NXS_FACES;
// remove |= NXS_STRIP;
}
if(strstr(optarg, "colors")) {
remove_colors = true;
remove = true;
// remove |= NXS_COLORS;
}
if(strstr(optarg, "normals")) {
remove_normals = true;
remove = true;
// remove |= NXS_NORMALS_SHORT;
}
if(strstr(optarg, "textures")) {
remove_textures = true;
remove = true;
// remove |= NXS_TEXTURES_SHORT;
}
if(strstr(optarg, "data")) {
remove_data = true;
remove = true;
// remove |= NXS_DATA32;
} }
if(strstr(optarg, "colors")) { remove_colors = true; remove = true; }
if(strstr(optarg, "normals")) { remove_normals = true; remove = true; }
if(strstr(optarg, "textures")) { remove_textures = true; remove = true; }
if(strstr(optarg, "data")) { remove_data = true; remove = true; }
if(remove == false) { if(remove == false) {
cerr << "Invalid -a argument: " << optarg << "\n" cerr << "Invalid -a argument: " << optarg << "\n"
<< "Valid options are: strip, colors, normals, textures, data\n"; << "Valid options are: strip, colors, normals, normalf, "
<< "textures, data\n";
return -1; return -1;
} }
break; break;
} }
case 'p': plysource = optarg; break;
case 'z': compress = true; break; case 'z': compress = true; break;
case 'x': uncompress = true; break; case 'x': uncompress = true; break;
case 's': zsort = true; break; case 's': zsort = true; break;
case 'V': cone_threshold = atof(optarg); break;
case 'v': qvertex = (float)atof(optarg); case 'v': qvertex = (float)atof(optarg);
if(qvertex == 0) { if(qvertex == 0) {
cerr << "Invalid value for quantization: " << optarg << endl; cerr << "Invalid value for quantization: " << optarg << endl;
@ -227,6 +202,7 @@ int main(int argc, char *argv[]) {
return -1; return -1;
} }
break; break;
case 'b': ram_size = atoi(optarg); case 'b': ram_size = atoi(optarg);
if(ram_size == 0) { if(ram_size == 0) {
cerr << "Invalid ram_size: " << optarg << endl; cerr << "Invalid ram_size: " << optarg << endl;
@ -244,18 +220,13 @@ int main(int argc, char *argv[]) {
} }
} }
if(compress && uncompress) {
cerr << "x and z are obviously exclusive :P\n";
return -1;
}
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" << " -l : list nodes\n"
<< " -h : list history\n" << " -h : list history\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|strips|textures|data|borders]\n" << " -a <what>: Add [colors|normals|normalf|strips|textures|data|borders]\n"
<< " -r <what>: As add...\n" << " -r <what>: As add...\n"
<< " -p <ply> : Ply source for colors or textures or data\n" << " -p <ply> : Ply source for colors or textures or data\n"
<< " -z : compress\n" << " -z : compress\n"
@ -264,12 +235,34 @@ int main(int argc, char *argv[]) {
<< " -v<float>: Vertex quantization (float is the 0 level amount)\n" << " -v<float>: Vertex quantization (float is the 0 level amount)\n"
<< " -n<float>: Normal quantization\n" << " -n<float>: Normal quantization\n"
<< " -c<float>: Color quantization\n" << " -c<float>: Color quantization\n"
<< " -t<float>: Texture quantization\n\n"; << " -t<float>: Texture quantization\n"
<< " -V<float>: Normal cone threshold [0, 1] (0.95 default)\n\n"
<< " This option will not create a new nexus file\n";
return -1; return -1;
} }
input = argv[optind]; input = argv[optind];
//Sanity test of options...
if(compress && uncompress) {
cerr << "x and z are obviously exclusive :P\n";
return -1;
}
if(add_normals && compress) {
cerr << "Its not possible to add normals and compress in the same step\n"
<< "Because normals requires 2 passes to be calculated\n\n";
return -1;
}
bool compute_cones = false;
if(!add && !remove && !compress && !uncompress && !zsort &&
!qvertex && !qcolor && !qnormal && !qtexture && cone_threshold != 0)
compute_cones = true;
Nexus nexus; Nexus nexus;
if(!nexus.Load(input, true)) { if(!nexus.Load(input, true)) {
@ -301,6 +294,26 @@ int main(int argc, char *argv[]) {
return -1; return -1;
} }
if(add_strips && (nexus.signature.face == Signature::STRIPS)) {
cerr << "Nexus file already has strips\n";
return -1;
}
if(add_colors && nexus.signature.vcolor) {
cerr << "Nexus file already has colors\n";
return -1;
}
if(add_normals && nexus.signature.vnorm) {
cerr << "Nexus file already has normals\n";
return -1;
}
if(add_textures && nexus.signature.vtext) {
cerr << "Nexus file already has textures\n";
return -1;
}
if(add_data && nexus.signature.vdata) {
cerr << "Nexus file already has data\n";
return -1;
}
if(nexus.IsCompressed() && compress) { if(nexus.IsCompressed() && compress) {
cerr << "File already compressed.\n"; cerr << "File already compressed.\n";
@ -314,91 +327,29 @@ int main(int argc, char *argv[]) {
if(info) { if(info) {
//perform locality statistics cout << "Nexus file: " << input << "\n";
double meandist = 0; printInfo(nexus, verbose, dump_history);
vcg::Sphere3f last = nexus[0].sphere;
for(unsigned int i = 1; i < nexus.size(); i++) {
vcg::Sphere3f &sphere = nexus[i].sphere;
double dist = vcg::Distance(last.Center(), sphere.Center());
meandist += dist;
last = sphere;
}
meandist /= nexus.size() -1;
cout << "Nexus file: " << input << "\n"
<< "\n\tCompressed: " << nexus.IsCompressed()
<< "\n\tStripped: "
<< (int)(nexus.signature.face == Signature::STRIPS)
<< "\n\tColor : " << (int)(nexus.signature.vcolor !=0)
<< "\n\tNormal : " << (int)((nexus.signature.vnorm) !=0)
<< "\n\tTexture : " << (int)((nexus.signature.vtext) !=0)
<< "\n\tData : " << (int)((nexus.signature.vdata) !=0)
<< "\n\n\tVertices: " << nexus.totvert
<< "\tFaces: " << nexus.totface
<< "\tPatches: " << nexus.size()
<< "\n\tSphere: "
<< nexus.sphere.Center()[0] << " "
<< nexus.sphere.Center()[1] << " "
<< nexus.sphere.Center()[2] << " R: "
<< nexus.sphere.Radius()
<< "\n\tAverage distance: " << meandist
<< "\n\tChunk size " << nexus.chunk_size << endl;
if(dump_history) {
if(nexus.history.IsQuick()) {
cout << "Quick format\n";
for(unsigned int i = 0; i < nexus.history.n_nodes(); i++) {
cout << "Node: " << i << " out: ";
History::History::Node node = nexus.history.nodes[i];
for(History::Node::iterator l = node.out_begin(); l != node.out_end(); l++) {
cout << ".";
History::Link &link = *l;
for(History::Link::iterator p = link.begin(); p != link.end(); p++) {
cout << p << " ";
}
}
cout << " in: ";
for(History::Node::iterator j = node.in_begin(); j != node.in_end(); j++) {
cout << ".";
History::Link &link = *j;
for(History::Link::iterator p = link.begin(); p != link.end(); p++) {
cout << p << " ";
}
}
cout << endl;
}
} else {
cout << "Update format\n";
for(unsigned int i = 0; i < nexus.history.updates.size(); i++) {
History::Update &update = nexus.history.updates[i];
cout << "Created: ";
for(unsigned int k = 0; k < update.created.size(); k++) {
cout << update.created[k] << " ";
}
cout << "\nErased: ";
for(unsigned int k = 0; k < update.erased.size(); k++) {
cout << update.erased[k] << " ";
}
cout << "\n\n";
}
}
}
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
<< " start: " << entry.patch_start << endl;
}
cout << endl;
}
} }
//determine if we must proceed: //determine if we must proceed:
if(!add && !remove && !compress && !uncompress && !zsort && if(!add && !remove && !compress && !uncompress && !zsort &&
qvertex == 0 && qnormal == 0 && qcolor == 0 && qtexture == 0) { qvertex == 0 && qnormal == 0 && qcolor == 0 && qtexture == 0 &&
cone_threshold == 0) {
nexus.Close();
return 0;
}
if(compute_cones) {//just recalculate normal cones
cerr << "Unimplemented at the moment...\n";
/*vector<NCone3s> cones;
// ComputeCones(Nexus &nexus, float cone_threshold);
nexus.Close();
nexus.Load(intput, false);
for(unsigned int i = 0; i < nexus.size(); i++) {
nexus[i].cone = cones[i];
}*/
nexus.Close(); nexus.Close();
return 0; return 0;
} }
@ -422,15 +373,9 @@ int main(int argc, char *argv[]) {
grid.Set(mesh.face); grid.Set(mesh.face);
} }
if(add_normals && compress) {
cerr << "Its not possible to add normals and compress in the same step\n"
<< "Because normals requires 2 passes to be calculated\n\n";
return -1;
}
Signature signature = nexus.signature; Signature signature = nexus.signature;
if(add_strips) signature.face = Signature::STRIPS; if(add_strips) signature.face = Signature::STRIPS;
if(add_normals) signature.vnorm = Encodings::SHORT4; if(add_normals) signature.vnorm = add_normals;
if(add_colors) signature.vcolor = Encodings::BYTE4; if(add_colors) signature.vcolor = Encodings::BYTE4;
if(remove_normals) signature.vnorm = 0; if(remove_normals) signature.vnorm = 0;
@ -442,6 +387,7 @@ int main(int argc, char *argv[]) {
if(!output.size()) output = input + getSuffix(signature); if(!output.size()) output = input + getSuffix(signature);
if(output == input) { if(output == input) {
cerr << "Output and input files are the same.\n" cerr << "Output and input files are the same.\n"
<< "Use option -o <filename>\n"
<< "You do not want to overwrite your data. Trust me.\n"; << "You do not want to overwrite your data. Trust me.\n";
return -1; return -1;
} }
@ -576,7 +522,7 @@ int main(int argc, char *argv[]) {
//copying entry information; //copying entry information;
dst_entry.sphere = src_entry.sphere; dst_entry.sphere = src_entry.sphere;
dst_entry.error = src_entry.error; dst_entry.error = src_entry.error;
//WARNING copy also normals cone dst_entry.cone = src_entry.cone;
out.borders.ResizeBorder(p, src_border.Size()); out.borders.ResizeBorder(p, src_border.Size());
Border &dst_border = out.GetBorder(p); Border &dst_border = out.GetBorder(p);
@ -623,3 +569,87 @@ int main(int argc, char *argv[]) {
return 0; return 0;
} }
void printInfo(Nexus &nexus, bool verbose, bool dump_history) {
//perform locality statistics
double meandist = 0;
vcg::Sphere3f last = nexus[0].sphere;
for(unsigned int i = 1; i < nexus.size(); i++) {
vcg::Sphere3f &sphere = nexus[i].sphere;
double dist = vcg::Distance(last.Center(), sphere.Center());
meandist += dist;
last = sphere;
}
meandist /= nexus.size() -1;
cout << "\n\tCompressed: " << nexus.IsCompressed()
<< "\n\tStripped: "
<< (int)(nexus.signature.face == Signature::STRIPS)
<< "\n\tColor : " << (int)(nexus.signature.vcolor !=0)
<< "\n\tNormal : " << (int)((nexus.signature.vnorm) !=0)
<< "\n\tTexture : " << (int)((nexus.signature.vtext) !=0)
<< "\n\tData : " << (int)((nexus.signature.vdata) !=0)
<< "\n\n\tVertices: " << nexus.totvert
<< "\tFaces: " << nexus.totface
<< "\tPatches: " << nexus.size()
<< "\n\tSphere: "
<< nexus.sphere.Center()[0] << " "
<< nexus.sphere.Center()[1] << " "
<< nexus.sphere.Center()[2] << " R: "
<< nexus.sphere.Radius()
<< "\n\tAverage distance: " << meandist
<< "\n\tChunk size " << nexus.chunk_size << endl;
if(dump_history) {
if(nexus.history.IsQuick()) {
cout << "Quick format\n";
for(unsigned int i = 0; i < nexus.history.n_nodes(); i++) {
cout << "Node: " << i << " out: ";
History::History::Node node = nexus.history.nodes[i];
for(History::Node::iterator l = node.out_begin();
l != node.out_end(); l++) {
cout << ".";
History::Link &link = *l;
for(History::Link::iterator p = link.begin(); p != link.end(); p++) {
cout << p << " ";
}
}
cout << " in: ";
for(History::Node::iterator j = node.in_begin();
j != node.in_end(); j++) {
cout << ".";
History::Link &link = *j;
for(History::Link::iterator p = link.begin(); p != link.end(); p++) {
cout << p << " ";
}
}
cout << endl;
}
} else {
cout << "Update format\n";
for(unsigned int i = 0; i < nexus.history.updates.size(); i++) {
History::Update &update = nexus.history.updates[i];
cout << "Created: ";
for(unsigned int k = 0; k < update.created.size(); k++) {
cout << update.created[k] << " ";
}
cout << "\nErased: ";
for(unsigned int k = 0; k < update.erased.size(); k++) {
cout << update.erased[k] << " ";
}
cout << "\n\n";
}
}
}
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
<< " start: " << entry.patch_start << endl;
}
cout << endl;
}
}