From 8f77a2a501b24ec4bc0da0dd94506cbc2e0896c2 Mon Sep 17 00:00:00 2001 From: ponchio Date: Thu, 2 Dec 2004 20:16:13 +0000 Subject: [PATCH] Level 5; --- apps/nexus/decimate.cpp | 4 +- apps/nexus/nxsdispatcher.cpp | 2 +- apps/nexus/nxsdispatcher.h | 8 +-- apps/nexus/remapping.cpp | 98 ++++++++++++++++++++++++++++++++++-- apps/nexus/remapping.h | 12 ++++- 5 files changed, 113 insertions(+), 11 deletions(-) diff --git a/apps/nexus/decimate.cpp b/apps/nexus/decimate.cpp index 190aa459..832e720c 100644 --- a/apps/nexus/decimate.cpp +++ b/apps/nexus/decimate.cpp @@ -14,7 +14,7 @@ #include -#include "pvoronoi.h" +#include "vpartition.h" #include "fragment.h" #include "decimate.h" @@ -176,7 +176,7 @@ float Cluster(MyMesh &mesh, unsigned int target_faces) { vector remap; - VoronoiPartition part; + VPartition part; for(unsigned int i = 0; i < mesh.vert.size(); i++) { const Point3f &p = mesh.vert[i].cP(); if(!mesh.vert[i].IsW()) { diff --git a/apps/nexus/nxsdispatcher.cpp b/apps/nexus/nxsdispatcher.cpp index e0fd0701..12fd8e2e 100644 --- a/apps/nexus/nxsdispatcher.cpp +++ b/apps/nexus/nxsdispatcher.cpp @@ -9,7 +9,7 @@ using namespace vcg; using namespace nxs; using namespace pt; -void SaveFragment(Nexus &nexus, VoronoiChain &chain, +void SaveFragment(Nexus &nexus, VChain &chain, Fragment &fragin, Fragment &fragout); diff --git a/apps/nexus/nxsdispatcher.h b/apps/nexus/nxsdispatcher.h index be4b1c64..4962ba92 100644 --- a/apps/nexus/nxsdispatcher.h +++ b/apps/nexus/nxsdispatcher.h @@ -17,7 +17,7 @@ namespace nxs { class Fragment; class Nexus; - class VoronoiChain; + class VChain; class Server; class FragIO; @@ -50,7 +50,7 @@ namespace nxs { class Dispatcher: public pt::msgqueue { public: - Dispatcher(Nexus *nx, VoronoiChain *ch): + Dispatcher(Nexus *nx, VChain *ch): count(0), maxqueue(3), nexus(nx), chain(ch) {} ~Dispatcher(); @@ -64,7 +64,7 @@ namespace nxs { int count; int maxqueue; Nexus *nexus; - VoronoiChain *chain; + VChain *chain; Decimation mode; float scaling; std::vector servers; @@ -88,4 +88,4 @@ namespace nxs { } -#endif \ No newline at end of file +#endif diff --git a/apps/nexus/remapping.cpp b/apps/nexus/remapping.cpp index a5354ba9..1d0fcdf4 100644 --- a/apps/nexus/remapping.cpp +++ b/apps/nexus/remapping.cpp @@ -187,7 +187,7 @@ void nxs::BuildPartition(VPartition &part, //TODO! Check for duplicates (use the closest :P) part.Init(); - Report report; + vector centroids; vector counts; @@ -198,8 +198,8 @@ void nxs::BuildPartition(VPartition &part, counts.clear(); centroids.resize(part.size(), Point3f(0, 0, 0)); counts.resize(part.size(), 0); - - report.Init(points.Size()); + + Report report(points.Size()); for(unsigned int v = 0; v < points.Size(); v++) { report.Step(v); @@ -223,6 +223,98 @@ void nxs::BuildPartition(VPartition &part, } } +void nxs::BuildLevel(VChain &chain, + Nexus &nexus, + unsigned int offset, + float scaling, + unsigned int target_size, + unsigned int min_size, + unsigned int max_size, + int steps) { + + unsigned int totface = 0; + unsigned int totvert = 0; + for(unsigned int idx = offset; idx < nexus.index.size(); idx++) { + totface += nexus.index[idx].nface; + totvert += nexus.index[idx].nvert; + } + + chain.push_back(VPartition()); + VPartition &coarse = chain[chain.size()-1]; + VPartition &fine = chain[chain.size()-2]; + fine.Init(); + + unsigned int ncells = (unsigned int)(fine.size() * scaling); + + //TODO this method for selecting the seeds is ugly! + float ratio = ncells/(float)(nexus.index.size() - offset); + float cratio = 0; + for(unsigned int idx = offset; idx < nexus.index.size(); idx++) { + cratio += ratio; + if(cratio > 1) { + Patch patch = nexus.GetPatch(idx); + Point3f &v = patch.Vert(0); + coarse.push_back(v); + cratio -= 1; + } + } + + if(coarse.size() == 0) { + Patch patch = nexus.GetPatch(0); + coarse.push_back(patch.Vert(0)); + } + + float coarse_vmean = totface/(float)coarse.size(); + + coarse.Init(); + cerr << "Ncells: " << ncells << endl; + cerr << "Coarse size: " << coarse.size() << endl; + cerr << "Coarse mean: " << coarse_vmean << " mean_size: " << target_size << endl; + + //here goes some optimization pass. + //Coarse optimization. + vector centroids; + vector counts; + + for(int step = 0; step < steps; step++) { + cerr << "Optimization step: " << step+1 << "/" << steps << endl; + centroids.clear(); + counts.clear(); + centroids.resize(coarse.size(), Point3f(0, 0, 0)); + counts.resize(coarse.size(), 0); + + Report report(nexus.index.size()); + for(unsigned int idx = offset; idx < nexus.index.size(); idx++) { + report.Step(idx); + Patch patch = nexus.GetPatch(idx); + for(unsigned int i = 0; i < patch.nf; i++) { + unsigned short *face = patch.Face(i); + Point3f bari = (patch.Vert(face[0]) + + patch.Vert(face[1]) + + patch.Vert(face[2]))/3; + + unsigned int target = coarse.Locate(bari); + assert(target < coarse.size()); + centroids[target] += bari; + counts[target]++; + } + } + + for(unsigned int v = 0; v < centroids.size(); v++) + if(counts[v] != 0) + centroids[v]/= counts[v]; + + if(step == steps-1) { + if(!Optimize(coarse, (int)coarse_vmean, min_size, max_size, + centroids, counts, false)) + step--; + } else + Optimize(coarse, (int)coarse_vmean, min_size, max_size, + centroids, counts, true); + } + chain.newfragments.clear(); +} + int nxs::GetBest(VPartition &part, unsigned int seed, vector &mark, vector &counts) { diff --git a/apps/nexus/remapping.h b/apps/nexus/remapping.h index 0aef8bae..e7fa0318 100644 --- a/apps/nexus/remapping.h +++ b/apps/nexus/remapping.h @@ -5,6 +5,7 @@ #include #include "nxstypes.h" #include "vchain.h" +#include "nexus.h" #include "vfile.h" namespace nxs { @@ -37,7 +38,16 @@ namespace nxs { unsigned int min_size, unsigned int max_size, int steps); - + + void BuildLevel(VChain &chain, + Nexus &nexus, + unsigned int offset, + float scaling, + unsigned int target_size, + unsigned int min_size, + unsigned int max_size, + int steps); + //removes small or really big patches. bool Optimize(VPartition &part, unsigned int target_size,