Trying to fix big patches.

This commit is contained in:
Federico Ponchio 2004-10-29 16:33:29 +00:00
parent e250430b09
commit 21ee08ab67
1 changed files with 139 additions and 98 deletions

View File

@ -24,6 +24,9 @@
History History
$Log: not supported by cvs2svn $ $Log: not supported by cvs2svn $
Revision 1.16 2004/10/22 14:31:56 ponchio
Some controls added.
Revision 1.15 2004/10/21 12:22:21 ponchio Revision 1.15 2004/10/21 12:22:21 ponchio
Small changes. Small changes.
@ -122,14 +125,14 @@ void VoronoiChain::Init(Crude &crude, float scaling, int steps) {
//here goes some optimization pass. //here goes some optimization pass.
//Fine optimization. //Fine optimization.
Report report; Report report;
vector<Point3f> fcentroids; vector<Point3f> centroids;
vector<unsigned int> fcount; vector<unsigned int> counts;
for(int i = 0; i < steps; i++) { for(int step = 0; step < steps; step++) {
cerr << "Optimization step: " << i+1 << "/" << steps << endl; cerr << "Optimization step: " << step+1 << "/" << steps << endl;
fcentroids.clear(); centroids.clear();
fcount.clear(); counts.clear();
fcentroids.resize(fine.size(), Point3f(0, 0, 0)); centroids.resize(fine.size(), Point3f(0, 0, 0));
fcount.resize(fine.size(), 0); counts.resize(fine.size(), 0);
report.Init(crude.Vertices()); report.Init(crude.Vertices());
for(unsigned int v = 0; v < crude.Vertices(); v++) { for(unsigned int v = 0; v < crude.Vertices(); v++) {
@ -137,22 +140,32 @@ void VoronoiChain::Init(Crude &crude, float scaling, int steps) {
unsigned int ftarget; unsigned int ftarget;
float dist = fine.Closest(crude.vert[v], ftarget); float dist = fine.Closest(crude.vert[v], ftarget);
assert(ftarget != -1); assert(ftarget != -1);
fcentroids[ftarget] += crude.vert[v]; centroids[ftarget] += crude.vert[v];
fcount[ftarget]++; counts[ftarget]++;
}
for(unsigned int v = 0; v < fine.size(); v++) {
if(fcount[v] == 0) continue;
fine[v].p = fcentroids[v]/(float)fcount[v];
fine[v].weight = (float)pow(fcount[v]/(float)fine_vmean, 0.2f);
}
fine.Init();
} }
//remove small or zero patches. //remove small or really big patches.
unsigned int failed = 0;
vector<Seed> seeds; vector<Seed> seeds;
for(unsigned int i = 0; i < fine.size(); i++) { for(unsigned int i = 0; i < fine.size(); i++) {
if(fcount[i] > min_size) if(counts[i] == 0 || (counts[i] < min_size && step != steps -3)) {
failed++;
} else if(counts[i] > max_size) {
cerr << "Failed: " << i << " tot: " << counts[i] << endl;
failed++;
Seed s = fine[i];
s.p = centroids[i]/(float)counts[i] + Point3f(1, 0, 0);
fine[i].weight = (float)pow((counts[i]/2)/(float)fine_vmean, 0.2f);
s.weight = fine[i].weight;
seeds.push_back(fine[i]); seeds.push_back(fine[i]);
seeds.push_back(s);
} else {
if(step != steps-1) {
fine[i].p = centroids[i]/(float)counts[i];
fine[i].weight = (float)pow(counts[i]/(float)fine_vmean, 0.2f);
}
seeds.push_back(fine[i]);
}
} }
fine.clear(); fine.clear();
for(unsigned int i = 0; i < seeds.size(); i++) for(unsigned int i = 0; i < seeds.size(); i++)
@ -160,19 +173,21 @@ void VoronoiChain::Init(Crude &crude, float scaling, int steps) {
if(fine.size() == 0) fine.push_back(Point3f(0,0,0)); if(fine.size() == 0) fine.push_back(Point3f(0,0,0));
fine.Init(); fine.Init();
if(step == steps-1 && failed) step--;
}
//here goes some optimization pass. //here goes some optimization pass.
//Coarse optimization. //Coarse optimization.
vector<Point3f> ccentroids; //vector<float> radius;
vector<unsigned int> ccount; for(int step = 0; step < steps; step++) {
vector<float> radius; cerr << "Optimization step: " << step+1 << "/" << steps << endl;
for(int i = 0; i < steps; i++) { centroids.clear();
cerr << "Optimization step: " << i+1 << "/" << steps << endl; counts.clear();
ccentroids.clear(); centroids.resize(coarse.size(), Point3f(0, 0, 0));
ccount.clear(); counts.resize(coarse.size(), 0);
ccentroids.resize(coarse.size(), Point3f(0, 0, 0)); //radius.resize(coarse.size(), 0);
ccount.resize(coarse.size(), 0);
radius.resize(coarse.size(), 0);
report.Init(crude.Vertices()); report.Init(crude.Vertices());
for(unsigned int v = 0; v < crude.Vertices(); v++) { for(unsigned int v = 0; v < crude.Vertices(); v++) {
@ -180,29 +195,48 @@ void VoronoiChain::Init(Crude &crude, float scaling, int steps) {
unsigned int ctarget = 0xffffffff; unsigned int ctarget = 0xffffffff;
float dist = coarse.Closest(crude.vert[v], ctarget); float dist = coarse.Closest(crude.vert[v], ctarget);
assert(ctarget != 0xffffffff); assert(ctarget != 0xffffffff);
ccentroids[ctarget] += crude.vert[v]; centroids[ctarget] += crude.vert[v];
ccount[ctarget]++; counts[ctarget]++;
if(dist > radius[ctarget]) radius[ctarget] = dist; //if(dist > radius[ctarget]) radius[ctarget] = dist;
} }
for(unsigned int v = 0; v < coarse.size(); v++) {
if(ccount[v] == 0) continue;
coarse[v].p = ccentroids[v]/(float)ccount[v]; //remove small or really big patches.
coarse[v].weight = (float)pow(ccount[v]/(float)coarse_vmean, 0.2f); unsigned int failed = 0;
vector<Seed> seeds;
if(radius[v] == 0) continue; for(unsigned int i = 0; i < coarse.size(); i++) {
if(counts[i] == 0 || (counts[i] < min_size && step != steps-3)) {
//repel from fine seeds failed++;
// coarse[v].p = fine.FindBorder(coarse[v].p, radius[v]); } else if(counts[i] > max_size) {
cerr << "Failed: " << i << " tot: " << counts[i] << endl;
failed++;
Seed s = coarse[i];
s.p = centroids[i]/(float)counts[i] + Point3f(1, 0, 0);
coarse[i].weight = (float)pow((counts[i]/2)/(float)coarse_vmean, 0.2f);
s.weight = coarse[i].weight;
seeds.push_back(coarse[i]);
seeds.push_back(s);
} else {
if(step != steps -1) {
coarse[i].p = centroids[i]/(float)counts[i];
coarse[i].weight = (float)pow(counts[i]/(float)coarse_vmean, 0.2f);
} }
seeds.push_back(coarse[i]);
}
}
coarse.clear();
for(unsigned int i = 0; i < seeds.size(); i++)
coarse.push_back(seeds[i]);
if(coarse.size() == 0) coarse.push_back(Point3f(0,0,0));
coarse.Init(); coarse.Init();
if(step == steps-1 && failed) step--;
} }
//remove small or zero patches. //remove small or zero patches.
seeds.clear(); vector<Seed> seeds;
for(unsigned int i = 0; i < coarse.size(); i++) { for(unsigned int i = 0; i < coarse.size(); i++) {
if(ccount[i] > (int)min_size) if(counts[i] > (int)min_size)
seeds.push_back(coarse[i]); seeds.push_back(coarse[i]);
} }
coarse.clear(); coarse.clear();
@ -214,15 +248,15 @@ void VoronoiChain::Init(Crude &crude, float scaling, int steps) {
//Coarse optimization //Coarse optimization
/* vector< map<unsigned int, Point3f> > ccentroids; /* vector< map<unsigned int, Point3f> > centroids;
vector< map<unsigned int, unsigned int> > ccount; vector< map<unsigned int, unsigned int> > counts;
for(unsigned int i = 0; i < steps; i++) { for(unsigned int i = 0; i < steps; i++) {
cerr << "Optimization step 1: " << i << "/" << steps << endl; cerr << "Optimization step 1: " << i << "/" << steps << endl;
ccentroids.clear(); centroids.clear();
ccount.clear(); counts.clear();
ccentroids.resize(coarse.size()); centroids.resize(coarse.size());
ccount.resize(coarse.size()); counts.resize(coarse.size());
for(unsigned int v = 0; v < crude.Vertices(); v++) { for(unsigned int v = 0; v < crude.Vertices(); v++) {
unsigned int ftarget; unsigned int ftarget;
@ -233,8 +267,8 @@ void VoronoiChain::Init(Crude &crude, float scaling, int steps) {
dist = coarse.Closest(crude.vert[v], ctarget); dist = coarse.Closest(crude.vert[v], ctarget);
assert(ctarget != -1); assert(ctarget != -1);
map<unsigned int, Point3f> &centroids = ccentroids[ctarget]; map<unsigned int, Point3f> &centroids = centroids[ctarget];
map<unsigned int, unsigned int> &count = ccount[ctarget]; map<unsigned int, unsigned int> &count = counts[ctarget];
if(!centroids.count(ftarget)) if(!centroids.count(ftarget))
centroids[ftarget]= Point3f(0, 0, 0); centroids[ftarget]= Point3f(0, 0, 0);
@ -248,8 +282,8 @@ void VoronoiChain::Init(Crude &crude, float scaling, int steps) {
for(unsigned int v = 0; v < coarse.size(); v++) { for(unsigned int v = 0; v < coarse.size(); v++) {
map<unsigned int, Point3f> &centroids = ccentroids[v]; map<unsigned int, Point3f> &centroids = centroids[v];
map<unsigned int, unsigned int> &count = ccount[v]; map<unsigned int, unsigned int> &count = counts[v];
coarse[v].p = Point3f(0, 0, 0); coarse[v].p = Point3f(0, 0, 0);
@ -416,16 +450,16 @@ void VoronoiChain::BuildLevel(Nexus &nexus, unsigned int offset,
Report report; Report report;
//here goes some optimization pass. //here goes some optimization pass.
//Coarse optimization. //Coarse optimization.
vector<Point3f> ccentroids; vector<Point3f> centroids;
vector<unsigned int> ccount; vector<unsigned int> counts;
vector<float> radius; //vector<float> radius;
for(int i = 0; i < steps; i++) { for(int step = 0; step < steps; step++) {
cerr << "Optimization step: " << i+1 << "/" << steps << endl; cerr << "Optimization step: " << step+1 << "/" << steps << endl;
ccentroids.clear(); centroids.clear();
ccount.clear(); counts.clear();
ccentroids.resize(coarse.size(), Point3f(0, 0, 0)); centroids.resize(coarse.size(), Point3f(0, 0, 0));
ccount.resize(coarse.size(), 0); counts.resize(coarse.size(), 0);
radius.resize(coarse.size(), 0); //radius.resize(coarse.size(), 0);
report.Init(nexus.index.size()); report.Init(nexus.index.size());
for(unsigned int idx = offset; idx < nexus.index.size(); idx++) { for(unsigned int idx = offset; idx < nexus.index.size(); idx++) {
@ -436,35 +470,42 @@ void VoronoiChain::BuildLevel(Nexus &nexus, unsigned int offset,
unsigned int ctarget = 0xffffffff; unsigned int ctarget = 0xffffffff;
float dist = coarse.Closest(patch.Vert(i), ctarget); float dist = coarse.Closest(patch.Vert(i), ctarget);
assert(ctarget != 0xffffffff); assert(ctarget != 0xffffffff);
ccentroids[ctarget] += patch.Vert(i); centroids[ctarget] += patch.Vert(i);
ccount[ctarget]++; counts[ctarget]++;
if(dist > radius[ctarget]) radius[ctarget] = dist; //if(dist > radius[ctarget]) radius[ctarget] = dist;
} }
} }
for(unsigned int v = 0; v < coarse.size(); v++) { //remove small or really big patches.
if(ccount[v] == 0) continue; unsigned int failed = 0;
coarse[v].p = ccentroids[v]/(float)ccount[v];
//0.3 is related to the fact is doubled the box size.
coarse[v].weight = (float)pow(ccount[v]/(float)coarse_vmean, 0.2f);
if(radius[v] == 0) continue;
//coarse[v].p = fine.FindBorder(coarse[v].p, radius[v]);
}
coarse.Init();
}
vector<Seed> seeds; vector<Seed> seeds;
for(unsigned int i = 0; i < coarse.size(); i++) { for(unsigned int i = 0; i < coarse.size(); i++) {
if(ccount[i] > (int)min_size) if(counts[i] == 0 || (counts[i] < min_size && step != steps -3)) {
failed++;
} else if(counts[i] > max_size) {
cerr << "Failed: " << i << " tot: " << counts[i] << endl;
failed++;
Seed s = coarse[i];
s.p = centroids[i]/(float)counts[i] + Point3f(1, 0, 0);
coarse[i].weight = (float)pow((counts[i]/2)/(float)coarse_vmean, 0.2f);
s.weight = coarse[i].weight;
seeds.push_back(coarse[i]);
seeds.push_back(s);
} else {
if(step != steps-1) {
coarse[i].p = centroids[i]/(float)counts[i];
coarse[i].weight = (float)pow(counts[i]/(float)coarse_vmean, 0.2f);
}
seeds.push_back(coarse[i]); seeds.push_back(coarse[i]);
} }
}
coarse.clear(); coarse.clear();
for(unsigned int i = 0; i < seeds.size(); i++) for(unsigned int i = 0; i < seeds.size(); i++)
coarse.push_back(seeds[i]); coarse.push_back(seeds[i]);
if(coarse.size() == 0) coarse.push_back(Point3f(0,0,0)); if(coarse.size() == 0) coarse.push_back(Point3f(0,0,0));
coarse.Init(); coarse.Init();
if(step == steps-1 && failed) step--;
}
newfragments.clear(); newfragments.clear();
//TODO add some optimization //TODO add some optimization
} }