From a61bf20e4c88150e2dee2e24f637bbcfec0d0b31 Mon Sep 17 00:00:00 2001 From: ponchio Date: Fri, 18 Feb 2005 13:04:13 +0000 Subject: [PATCH] Added patch reordering. --- apps/nexus/nxsalgo.cpp | 43 ++++++++++++++++++++++++++++ apps/nexus/nxsalgo.h | 11 +++++++ apps/nexus/nxsedit.cpp | 65 +++++++++++++++++++++++++++++++++++------- 3 files changed, 108 insertions(+), 11 deletions(-) diff --git a/apps/nexus/nxsalgo.cpp b/apps/nexus/nxsalgo.cpp index 8afadb0d..fcd43f7b 100644 --- a/apps/nexus/nxsalgo.cpp +++ b/apps/nexus/nxsalgo.cpp @@ -24,6 +24,9 @@ History $Log: not supported by cvs2svn $ +Revision 1.18 2005/02/17 16:40:35 ponchio +Optimized BuildLevels. + Revision 1.17 2005/02/08 12:43:03 ponchio Added copyright @@ -33,6 +36,7 @@ Added copyright #include #include #include +#include #include //#include @@ -40,6 +44,7 @@ Added copyright #include "nxsalgo.h" #include "vfile.h" #include "nexus.h" +#include "zcurve.h" #include "watch.h" using namespace std; @@ -458,3 +463,41 @@ void nxs::Unify(Nexus &nexus, float threshold) { cerr << "Found " << degenerate << " degenerate face while unmifying\n"; } +void nxs::ZSort(Nexus &nexus, vector &forward, + vector &backward) { + //lets get a bounding box from the sphere: + ZCurve zcurve; + float r = nexus.sphere.Radius(); + Point3f radius(r, r, r); + zcurve.Set(nexus.sphere.Center()); + zcurve.Add(nexus.sphere.Center() - radius); + zcurve.Add(nexus.sphere.Center() + radius); + + vector levels; + nexus.history.BuildLevels(levels); + + forward.clear(); + + vector< vector > entries; + + for(unsigned int i = 0; i < nexus.size(); i++) { + int level = levels[i]; + while(level >= entries.size()) entries.push_back(vector()); + + ZEntry e; + e.id = i; + e.pos = zcurve.Pos(nexus[i].sphere.Center()); + entries[level].push_back(e); + } + + for(unsigned int i = 0; i < entries.size(); i++) { + vector &lev = entries[i]; + std::sort(lev.begin(), lev.end()); + for(unsigned int k = 0; k < lev.size(); k++) + forward.push_back(lev[k].id); + } + + backward.resize(forward.size()); + for(unsigned int i = 0; i < backward.size(); i++) + backward[forward[i]] = i; +} diff --git a/apps/nexus/nxsalgo.h b/apps/nexus/nxsalgo.h index 8ae8079f..5d62cd97 100644 --- a/apps/nexus/nxsalgo.h +++ b/apps/nexus/nxsalgo.h @@ -24,6 +24,9 @@ History $Log: not supported by cvs2svn $ +Revision 1.4 2005/02/08 12:43:03 ponchio +Added copyright + ****************************************************************************/ @@ -37,11 +40,19 @@ namespace nxs { class Nexus; class Patch; + struct ZEntry { + unsigned int id; + unsigned int pos; + bool operator<(const ZEntry &e) const { return pos < e.pos; } + }; + void ComputeNormals(Nexus &nexus); void ComputeTriStrip(unsigned short nfaces, unsigned short *faces, std::vector &strip); void Reorder(unsigned int signature, nxs::Patch &patch); void Unify(Nexus &nexus, float threshold); + void ZSort(Nexus &nexus, std::vector &forward, + std::vector &backward); } #endif diff --git a/apps/nexus/nxsedit.cpp b/apps/nexus/nxsedit.cpp index 8e4b5212..d9152886 100644 --- a/apps/nexus/nxsedit.cpp +++ b/apps/nexus/nxsedit.cpp @@ -24,6 +24,9 @@ History $Log: not supported by cvs2svn $ +Revision 1.18 2005/02/08 12:43:03 ponchio +Added copyright + ****************************************************************************/ @@ -104,9 +107,10 @@ int main(int argc, char *argv[]) { float qnormal = 0; float qcolor = 0; float qtexture = 0; + bool zsort = false; int option; - while((option = getopt(argc, argv, "ilo:a:r:zxv:n:k:t:b:c:")) != EOF) { + while((option = getopt(argc, argv, "ilo:a:r:zxsv:n:k:t:b:c:")) != EOF) { switch(option) { case 'i': info = true; break; case 'l': verbose = true; break; @@ -176,6 +180,7 @@ int main(int argc, char *argv[]) { case 'p': plysource = optarg; break; case 'z': compress = true; break; case 'x': uncompress = true; break; + case 's': zsort = true; break; case 'v': qvertex = (float)atof(optarg); if(qvertex == 0) { @@ -233,6 +238,7 @@ int main(int argc, char *argv[]) { << " -p : Ply source for colors or textures or data\n" << " -z : compress\n" << " -x : uncompress\n" + << " -s : sort using zcurve\n" << " -v: Vertex quantization (float is the 0 level amount)\n" << " -n: Normal quantization\n" << " -c: Color quantization\n" @@ -286,7 +292,17 @@ int main(int argc, char *argv[]) { if(info) { - cout << "Nexus file: " << input << "\n\n" + //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 << "Nexus file: " << input << "\n" << "\n\tCompressed: " << nexus.IsCompressed() << "\n\tStripped: " << (int)((nexus.signature&NXS_STRIP) !=0) << "\n\tColor : " << (int)((nexus.signature&NXS_COLORS) !=0) @@ -301,24 +317,27 @@ int main(int argc, char *argv[]) { << nexus.sphere.Center()[1] << " " << nexus.sphere.Center()[2] << " R: " << nexus.sphere.Radius() + << "\n\tAverage distance: " << meandist << "\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; + << " error: " << entry.error + << " disk_size: " << entry.disk_size << endl; } cout << endl; } } //determine if we must proceed: - if(add == 0 && remove == 0 && !compress && !uncompress && + if(add == 0 && remove == 0 && !compress && !uncompress && !zsort && qvertex == 0 && qnormal == 0 && qcolor == 0 && qtexture == 0) { nexus.Close(); return 0; } + CMesh mesh; GridStaticPtr grid; if(add_colors) { @@ -361,19 +380,44 @@ int main(int argc, char *argv[]) { cerr << "Could not open output: " << output << endl; return -1; } + out.MaxRam() = ram_size / out.chunk_size; - //TODO set rambuffer low (or even direct access!) + vector forward; + vector backward; + if(zsort) + ZSort(nexus, forward, backward); + //Fixing history unsigned int h_size; char *buffer = nexus.history.Save(h_size); out.history.Load(h_size, buffer); + if(zsort) { + if(out.history.IsQuick()) { + for(unsigned int i = 0; i < out.history.n_frags(); i++) + out.history.frags[i].patch = backward[out.history.frags[i].patch]; + } else { + for(unsigned int i = 0; i < out.history.updates.size(); i++) { + History::Update &update = out.history.updates[i]; + for(unsigned int k = 0; k < update.created.size(); k++) + update.created[k] = backward[update.created[k]]; + + for(unsigned int k = 0; k < update.erased.size(); k++) + update.erased[k] = backward[update.erased[k]]; + } + } + } + Report report(nexus.size()); cout << "Copying and allocating...\n"; - for(unsigned int patch = 0; patch < nexus.size(); patch++) { + for(unsigned int p = 0; p < nexus.size(); p++) { + unsigned int patch = p; report.Step(patch); + + if(zsort) patch = forward[patch]; + Entry &src_entry = nexus[patch]; Patch &src_patch = nexus.GetPatch(patch); Border &src_border = nexus.GetBorder(patch); @@ -388,9 +432,8 @@ int main(int argc, char *argv[]) { out.AddPatch(src_entry.nvert, src_entry.nface, src_border.Available()); - Entry &dst_entry = out[patch]; - - Patch &dst_patch = out.GetPatch(patch); + Entry &dst_entry = out[p]; + Patch &dst_patch = out.GetPatch(p); //copy vertices: memcpy(dst_patch.VertBegin(), src_patch.VertBegin(), @@ -441,8 +484,8 @@ int main(int argc, char *argv[]) { if(link.IsNull()) continue; assert(link.end_patch < nexus.index.size()); }*/ - out.borders.ResizeBorder(patch, src_border.Size()); - Border &dst_border = out.GetBorder(patch); + out.borders.ResizeBorder(p, src_border.Size()); + Border &dst_border = out.GetBorder(p); memcpy(dst_border.Start(), src_border.Start(), src_border.Size() * sizeof(Link)); }