Different splitting optimization.
This commit is contained in:
parent
43d86a873b
commit
da1f904ea4
|
@ -1,6 +1,5 @@
|
|||
#include <vector>
|
||||
#include <map>
|
||||
#include <hash_map>
|
||||
#include <iostream>
|
||||
|
||||
//#include <wrap/strip/tristrip.h>
|
||||
|
@ -22,7 +21,7 @@ void nxs::ComputeNormals(Nexus &nexus) {
|
|||
|
||||
//setting borders readonly:
|
||||
|
||||
assert(!nexus.borders.IsReadonly());
|
||||
assert(!nexus.borders.IsReadOnly());
|
||||
nexus.borders.SetReadOnly(true);
|
||||
|
||||
bool use_short = (nexus.signature & NXS_NORMALS_SHORT) != 0;
|
||||
|
|
|
@ -24,6 +24,9 @@
|
|||
History
|
||||
|
||||
$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
|
||||
Fixed a couple of memory leak...
|
||||
|
||||
|
@ -59,7 +62,11 @@ Level 0.
|
|||
#else
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
#include <hash_map>
|
||||
#endif
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include "nxstypes.h"
|
||||
|
@ -407,8 +414,11 @@ void FourthStep(const string &crudefile, const string &output,
|
|||
Nexus::PatchInfo &s_entry = nexus.index[start];
|
||||
|
||||
vector<Link> links;
|
||||
|
||||
#ifdef WIN32
|
||||
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++) {
|
||||
unsigned int global = vert_remap[vert_index[start].offset + i];
|
||||
vremap[global] = i;
|
||||
|
|
|
@ -175,6 +175,8 @@ void nxs::BuildPartition(VPartition &part,
|
|||
|
||||
//TODO: improve quality of patches and implement threshold.
|
||||
unsigned int ncells = points.Size()/target_size;
|
||||
cerr << "Target partition size: " << ncells
|
||||
<< " mean: " << points.Size()/ncells << endl;
|
||||
srand(0);
|
||||
|
||||
for(unsigned int i = 0; i < points.Size(); i++) {
|
||||
|
@ -214,14 +216,22 @@ void nxs::BuildPartition(VPartition &part,
|
|||
if(counts[v] != 0)
|
||||
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(!Optimize(part, target_size, min_size, max_size,
|
||||
if(!Optimize(part, ncells, target_size, min_size, max_size,
|
||||
centroids, counts, false))
|
||||
step--;
|
||||
} else
|
||||
Optimize(part, target_size, min_size, max_size,
|
||||
Optimize(part, ncells, target_size, min_size, max_size,
|
||||
centroids, counts, true);
|
||||
}
|
||||
cerr << "Partition size: " << part.size()
|
||||
<< " mean: " << (float)(points.Size()/part.size()) << endl << endl;
|
||||
}
|
||||
|
||||
void nxs::BuildLevel(VChain &chain,
|
||||
|
@ -308,11 +318,11 @@ void nxs::BuildLevel(VChain &chain,
|
|||
centroids[v]/= counts[v];
|
||||
|
||||
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))
|
||||
step--;
|
||||
} else
|
||||
Optimize(*coarse, (int)coarse_vmean, min_size, max_size,
|
||||
Optimize(*coarse, ncells, (int)coarse_vmean, min_size, max_size,
|
||||
centroids, counts, true);
|
||||
}
|
||||
chain.newfragments.clear();
|
||||
|
@ -350,6 +360,7 @@ int nxs::GetBest(VPartition &part, unsigned int seed,
|
|||
}
|
||||
|
||||
bool nxs::Optimize(VPartition &part,
|
||||
unsigned int target_cells,
|
||||
unsigned int target_size,
|
||||
unsigned int min_size,
|
||||
unsigned int max_size,
|
||||
|
@ -357,75 +368,153 @@ bool nxs::Optimize(VPartition &part,
|
|||
vector<unsigned int> &counts,
|
||||
bool join) {
|
||||
|
||||
unsigned int failed = 0;
|
||||
vector<Point3f> seeds;
|
||||
vector<bool> mark;
|
||||
mark.resize(part.size(), false);
|
||||
if(max_size > target_size *3)
|
||||
max_size = target_size * 3;
|
||||
min_size = target_size * 0.3;
|
||||
|
||||
//first pass we check only big ones
|
||||
for(unsigned int i = 0; i < part.size(); i++) {
|
||||
if(counts[i] > max_size || counts[i] > 2 * target_size) {
|
||||
failed++;
|
||||
float radius;
|
||||
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--;
|
||||
}
|
||||
|
||||
if(part.size() == 1)
|
||||
radius = 0.00001;
|
||||
else
|
||||
radius = part.Radius(i);
|
||||
unsigned int close = part.size()/2;
|
||||
if(close < 1) close = 1;
|
||||
if(close > 10) close = 10;
|
||||
|
||||
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];
|
||||
}
|
||||
unsigned int failed = 0;
|
||||
vector<Point3f> seeds;
|
||||
vector<bool> mark;
|
||||
mark.resize(part.size(), false);
|
||||
|
||||
vector<int> nears;
|
||||
vector<float> dists;
|
||||
//removing small ones.
|
||||
for(unsigned int i = 0; i < part.size(); i++) {
|
||||
if(counts[i] > max_size) {
|
||||
float radius;
|
||||
if(part.size() == 1)
|
||||
radius = 0.00001;
|
||||
else
|
||||
radius = part.Radius(i)/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);
|
||||
continue;
|
||||
}
|
||||
if(failed > 0)
|
||||
cerr << "Found " << failed << " patches too big.\n";
|
||||
if(counts[i] < min_size)
|
||||
continue;
|
||||
|
||||
if(join) {
|
||||
for(unsigned int i = 0; i < part.size(); i++) {
|
||||
if(mark[i] || counts[i] >= min_size) continue;
|
||||
part.Closest(part[i], close, nears, dists);
|
||||
Point3f dir(0,0,0);
|
||||
|
||||
failed++;
|
||||
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);
|
||||
}
|
||||
for(unsigned int k = 0; k < close; k++) {
|
||||
unsigned int n = nears[k];
|
||||
float c = (target_size - (float)counts[n])/
|
||||
((float)target_size * close);
|
||||
|
||||
dir += (centroids[i] - part[n]) * c;
|
||||
}
|
||||
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++) {
|
||||
if(mark[i]) continue;
|
||||
if(counts[i] == 0) continue;
|
||||
if(join) {
|
||||
// if(counts[i] < min_size) {
|
||||
// cerr << "Could not fix: " << i << endl;
|
||||
// } else {
|
||||
part[i] = centroids[i];
|
||||
// }
|
||||
if(counts[i] >= min_size && counts[i] >= smallthresh * target_size) continue;
|
||||
|
||||
failed++;
|
||||
int best = GetBest(part, i, mark, counts);
|
||||
if(best < 0) {
|
||||
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++)
|
||||
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));
|
||||
for(unsigned int i = 0; i < part.size(); i++) {
|
||||
if(mark[i]) continue;
|
||||
if(counts[i] == 0) continue;
|
||||
if(join) {
|
||||
// if(counts[i] < min_size) {
|
||||
// cerr << "Could not fix: " << i << endl;
|
||||
// } else {
|
||||
part[i] = centroids[i];
|
||||
// }
|
||||
}
|
||||
part.Init();
|
||||
return failed == 0;
|
||||
seeds.push_back(part[i]);
|
||||
}
|
||||
|
||||
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;*/
|
||||
}
|
||||
|
|
|
@ -50,6 +50,7 @@ namespace nxs {
|
|||
|
||||
//removes small or really big patches.
|
||||
bool Optimize(VPartition &part,
|
||||
unsigned int target_cells,
|
||||
unsigned int target_size,
|
||||
unsigned int min_size,
|
||||
unsigned int max_size,
|
||||
|
|
Loading…
Reference in New Issue