Different splitting optimization.

This commit is contained in:
Federico Ponchio 2004-12-09 22:33:28 +00:00
parent 43d86a873b
commit da1f904ea4
4 changed files with 166 additions and 67 deletions

View File

@ -1,6 +1,5 @@
#include <vector> #include <vector>
#include <map> #include <map>
#include <hash_map>
#include <iostream> #include <iostream>
//#include <wrap/strip/tristrip.h> //#include <wrap/strip/tristrip.h>
@ -22,7 +21,7 @@ void nxs::ComputeNormals(Nexus &nexus) {
//setting borders readonly: //setting borders readonly:
assert(!nexus.borders.IsReadonly()); assert(!nexus.borders.IsReadOnly());
nexus.borders.SetReadOnly(true); nexus.borders.SetReadOnly(true);
bool use_short = (nexus.signature & NXS_NORMALS_SHORT) != 0; bool use_short = (nexus.signature & NXS_NORMALS_SHORT) != 0;

View File

@ -24,6 +24,9 @@
History History
$Log: not supported by cvs2svn $ $Log: not supported by cvs2svn $
Revision 1.9 2004/12/04 13:22:55 ponchio
*** empty log message ***
Revision 1.8 2004/12/03 21:19:00 ponchio Revision 1.8 2004/12/03 21:19:00 ponchio
Fixed a couple of memory leak... Fixed a couple of memory leak...
@ -59,7 +62,11 @@ Level 0.
#else #else
#include <unistd.h> #include <unistd.h>
#endif #endif
#ifdef WIN32
#include <hash_map> #include <hash_map>
#endif
#include <iostream> #include <iostream>
#include "nxstypes.h" #include "nxstypes.h"
@ -407,8 +414,11 @@ void FourthStep(const string &crudefile, const string &output,
Nexus::PatchInfo &s_entry = nexus.index[start]; Nexus::PatchInfo &s_entry = nexus.index[start];
vector<Link> links; vector<Link> links;
#ifdef WIN32
hash_map<unsigned int, unsigned short> vremap; hash_map<unsigned int, unsigned short> vremap;
#else
map<unsigned int, unsigned short> vremap;
#endif
for(unsigned int i = 0; i < vert_index[start].size; i++) { for(unsigned int i = 0; i < vert_index[start].size; i++) {
unsigned int global = vert_remap[vert_index[start].offset + i]; unsigned int global = vert_remap[vert_index[start].offset + i];
vremap[global] = i; vremap[global] = i;

View File

@ -175,6 +175,8 @@ void nxs::BuildPartition(VPartition &part,
//TODO: improve quality of patches and implement threshold. //TODO: improve quality of patches and implement threshold.
unsigned int ncells = points.Size()/target_size; unsigned int ncells = points.Size()/target_size;
cerr << "Target partition size: " << ncells
<< " mean: " << points.Size()/ncells << endl;
srand(0); srand(0);
for(unsigned int i = 0; i < points.Size(); i++) { for(unsigned int i = 0; i < points.Size(); i++) {
@ -214,14 +216,22 @@ void nxs::BuildPartition(VPartition &part,
if(counts[v] != 0) if(counts[v] != 0)
centroids[v]/= counts[v]; centroids[v]/= counts[v];
double quality = 0;
for(int i = 0; i < part.size(); i++)
quality += (counts[i] - target_size) * (counts[i] - target_size);
cerr << "Quality: " << quality << endl;
if(step == steps-1) { if(step == steps-1) {
if(!Optimize(part, target_size, min_size, max_size, if(!Optimize(part, ncells, target_size, min_size, max_size,
centroids, counts, false)) centroids, counts, false))
step--; step--;
} else } else
Optimize(part, target_size, min_size, max_size, Optimize(part, ncells, target_size, min_size, max_size,
centroids, counts, true); centroids, counts, true);
} }
cerr << "Partition size: " << part.size()
<< " mean: " << (float)(points.Size()/part.size()) << endl << endl;
} }
void nxs::BuildLevel(VChain &chain, void nxs::BuildLevel(VChain &chain,
@ -308,11 +318,11 @@ void nxs::BuildLevel(VChain &chain,
centroids[v]/= counts[v]; centroids[v]/= counts[v];
if(step == steps-1) { if(step == steps-1) {
if(!Optimize(*coarse, (int)coarse_vmean, min_size, max_size, if(!Optimize(*coarse, ncells, (int)coarse_vmean, min_size, max_size,
centroids, counts, false)) centroids, counts, false))
step--; step--;
} else } else
Optimize(*coarse, (int)coarse_vmean, min_size, max_size, Optimize(*coarse, ncells, (int)coarse_vmean, min_size, max_size,
centroids, counts, true); centroids, counts, true);
} }
chain.newfragments.clear(); chain.newfragments.clear();
@ -350,82 +360,161 @@ int nxs::GetBest(VPartition &part, unsigned int seed,
} }
bool nxs::Optimize(VPartition &part, bool nxs::Optimize(VPartition &part,
unsigned int target_cells,
unsigned int target_size, unsigned int target_size,
unsigned int min_size, unsigned int min_size,
unsigned int max_size, unsigned int max_size,
vector<Point3f> &centroids, vector<Point3f> &centroids,
vector<unsigned int> &counts, vector<unsigned int> &counts,
bool join) { bool join) {
if(max_size > target_size *3)
max_size = target_size * 3;
min_size = target_size * 0.3;
unsigned int toobig = 0;
unsigned int toosmall = 0;
for(unsigned int i = 0; i < part.size(); i++) {
if(counts[i] > max_size) toobig++;
if(counts[i] < min_size) toosmall--;
}
unsigned int failed = 0; unsigned int close = part.size()/2;
vector<Point3f> seeds; if(close < 1) close = 1;
vector<bool> mark; if(close > 10) close = 10;
mark.resize(part.size(), false);
//first pass we check only big ones unsigned int failed = 0;
for(unsigned int i = 0; i < part.size(); i++) { vector<Point3f> seeds;
if(counts[i] > max_size || counts[i] > 2 * target_size) { vector<bool> mark;
failed++; mark.resize(part.size(), false);
float radius;
vector<int> nears;
if(part.size() == 1) vector<float> dists;
radius = 0.00001; //removing small ones.
else for(unsigned int i = 0; i < part.size(); i++) {
radius = part.Radius(i); if(counts[i] > max_size) {
float radius;
if(radius == 0) { if(part.size() == 1)
cerr << "Radius zero???\n"; radius = 0.00001;
exit(0); else
} radius = part.Radius(i)/4;
radius /= 4; seeds.push_back(centroids[i] + Point3f(1, -1, 1) * radius);
seeds.push_back(centroids[i] + Point3f(1, -1, 1) * radius); seeds.push_back(centroids[i] + Point3f(-1, 1, 1) * radius);
seeds.push_back(centroids[i] + Point3f(-1, 1, 1) * radius); seeds.push_back(centroids[i] + Point3f(-1, -1, -1) * radius);
seeds.push_back(centroids[i] + Point3f(-1, -1, -1) * radius); seeds.push_back(centroids[i] + Point3f(1, 1, -1) * radius);
seeds.push_back(centroids[i] + Point3f(1, 1, -1) * radius); continue;
mark[i];
}
} }
if(failed > 0) if(counts[i] < min_size)
cerr << "Found " << failed << " patches too big.\n"; continue;
part.Closest(part[i], close, nears, dists);
Point3f dir(0,0,0);
if(join) { for(unsigned int k = 0; k < close; k++) {
for(unsigned int i = 0; i < part.size(); i++) { unsigned int n = nears[k];
if(mark[i] || counts[i] >= min_size) continue; float c = (target_size - (float)counts[n])/
((float)target_size * close);
failed++; dir += (centroids[i] - part[n]) * c;
int best = GetBest(part, i, mark, counts);
if(best < 0) {
cerr << "Best not found! while looking for: " << i << "\n";
continue;
}
assert(mark[best] == false);
mark[best] = true;
mark[i] = true;
seeds.push_back((part[i] + part[best])/2);
}
} }
seeds.push_back(centroids[i] + dir);
}
part.clear();
for(unsigned int i = 0; i < seeds.size(); i++)
part.push_back(seeds[i]);
if(part.size() == 0) {
cerr << "OOOPS i accidentally deleted all seeds... backup :P\n";
part.push_back(Point3f(0,0,0));
}
part.Init();
return true;
// for(unsigned int i = 0; i < part.size(); i++) {
// if(counts[i] > max_size || counts[i] > max_size) {
// failed++;
// } else {
// }
// }
//PREPHASE:
/* if(join) {
// float bigthresh = 1.2f;
// float smallthresh = 0.5f;
float bigthresh = 10.0f;
float smallthresh = 0.1f;
unsigned int failed = 0;
vector<Point3f> seeds;
vector<bool> mark;
mark.resize(part.size(), false);
//first pass we check only big ones
for(unsigned int i = 0; i < part.size(); i++) {
if(counts[i] > max_size || counts[i] > bigthresh * target_size) {
failed++;
float radius;
if(part.size() == 1)
radius = 0.00001;
else
radius = part.Radius(i);
if(radius == 0) {
cerr << "Radius zero???\n";
exit(0);
}
radius /= 4;
seeds.push_back(centroids[i] + Point3f(1, -1, 1) * radius);
seeds.push_back(centroids[i] + Point3f(-1, 1, 1) * radius);
seeds.push_back(centroids[i] + Point3f(-1, -1, -1) * radius);
seeds.push_back(centroids[i] + Point3f(1, 1, -1) * radius);
mark[i] = true;
}
}
if(failed > 0)
cerr << "Found " << failed << " patches too big.\n";
if(join) {
for(unsigned int i = 0; i < part.size(); i++) { for(unsigned int i = 0; i < part.size(); i++) {
if(mark[i]) continue; if(mark[i]) continue;
if(counts[i] == 0) continue; if(counts[i] >= min_size && counts[i] >= smallthresh * target_size) continue;
if(join) {
// if(counts[i] < min_size) { failed++;
// cerr << "Could not fix: " << i << endl; int best = GetBest(part, i, mark, counts);
// } else { if(best < 0) {
part[i] = centroids[i]; cerr << "Best not found! while looking for: " << i << "\n";
// } continue;
} }
seeds.push_back(part[i]); assert(mark[best] == false);
mark[best] = true;
mark[i] = true;
seeds.push_back((part[i] + part[best])/2);
} }
}
part.clear();
for(unsigned int i = 0; i < seeds.size(); i++) for(unsigned int i = 0; i < part.size(); i++) {
part.push_back(seeds[i]); if(mark[i]) continue;
if(counts[i] == 0) continue;
if(part.size() == 0) { if(join) {
cerr << "OOOPS i accidentally deleted all seeds... backup :P\n"; // if(counts[i] < min_size) {
part.push_back(Point3f(0,0,0)); // cerr << "Could not fix: " << i << endl;
// } else {
part[i] = centroids[i];
// }
} }
part.Init(); seeds.push_back(part[i]);
return failed == 0; }
part.clear();
for(unsigned int i = 0; i < seeds.size(); i++)
part.push_back(seeds[i]);
if(part.size() == 0) {
cerr << "OOOPS i accidentally deleted all seeds... backup :P\n";
part.push_back(Point3f(0,0,0));
}
part.Init();
return failed == 0;*/
} }

View File

@ -50,6 +50,7 @@ namespace nxs {
//removes small or really big patches. //removes small or really big patches.
bool Optimize(VPartition &part, bool Optimize(VPartition &part,
unsigned int target_cells,
unsigned int target_size, unsigned int target_size,
unsigned int min_size, unsigned int min_size,
unsigned int max_size, unsigned int max_size,