Lotsa changes.
This commit is contained in:
parent
96f9a33c92
commit
51f13ef53c
|
@ -45,7 +45,14 @@ using namespace tri;
|
|||
using namespace nxs;
|
||||
using namespace std;
|
||||
|
||||
void Cluster(MyMesh &mesh, unsigned int target_faces);
|
||||
float Clustering(unsigned int target_faces,
|
||||
vector<Point3f> &newvert,
|
||||
vector<unsigned int> &newface,
|
||||
vector<Link> &newbord,
|
||||
vector<int> &vert_remap) {
|
||||
}
|
||||
|
||||
float Cluster(MyMesh &mesh, unsigned int target_faces);
|
||||
|
||||
float Decimate(unsigned int target_faces,
|
||||
vector<Point3f> &newvert,
|
||||
|
@ -128,8 +135,9 @@ float Decimate(unsigned int target_faces,
|
|||
FinalSize = mesh.fn - FinalSize; //number of faces to remove
|
||||
FinalSize/=2; //Number of vertices to remove
|
||||
DeciSession.SetTargetOperations(FinalSize);
|
||||
DeciSession.DoOptimization();
|
||||
float error = 1; //get error;
|
||||
// DeciSession.DoOptimization();
|
||||
float error = Cluster(mesh, target_faces);
|
||||
// float error = DeciSession.currMetric/4;//1; //get error;
|
||||
int t3=clock();
|
||||
|
||||
/* printf(" vol %d \n lkv %d \n lke %d \n lkf %d \n ood %d\n bor %d\n ",
|
||||
|
@ -176,7 +184,7 @@ float Decimate(unsigned int target_faces,
|
|||
return error;
|
||||
}
|
||||
|
||||
void Cluster(MyMesh &mesh, unsigned int target_faces) {
|
||||
float Cluster(MyMesh &mesh, unsigned int target_faces) {
|
||||
unsigned int starting = mesh.vn;
|
||||
cerr << "starting face: " << mesh.fn << endl;
|
||||
//veramente brutale
|
||||
|
@ -200,6 +208,7 @@ void Cluster(MyMesh &mesh, unsigned int target_faces) {
|
|||
}
|
||||
}
|
||||
|
||||
float error = 0;
|
||||
cerr << "done" << endl;
|
||||
map<float, pair<int, int> >::iterator s;
|
||||
for(s = dist.begin(); s != dist.end(); s++) {
|
||||
|
@ -214,6 +223,7 @@ void Cluster(MyMesh &mesh, unsigned int target_faces) {
|
|||
assert(!mesh.vert[source].IsD());
|
||||
|
||||
mesh.vert[source].SetD();
|
||||
error = (*s).first;
|
||||
remap[source] = target;
|
||||
remap[target] = target;
|
||||
toremove -= 2;
|
||||
|
@ -238,5 +248,5 @@ void Cluster(MyMesh &mesh, unsigned int target_faces) {
|
|||
}
|
||||
}
|
||||
cerr << "Ending faces: " << mesh.fn << endl;
|
||||
|
||||
return error;
|
||||
}
|
||||
|
|
|
@ -24,6 +24,9 @@
|
|||
History
|
||||
|
||||
$Log: not supported by cvs2svn $
|
||||
Revision 1.4 2004/08/27 00:39:28 ponchio
|
||||
Rewrote.
|
||||
|
||||
Revision 1.3 2004/07/20 14:06:02 ponchio
|
||||
Changed filename saving.
|
||||
|
||||
|
@ -60,7 +63,8 @@ class PChain {
|
|||
|
||||
|
||||
virtual void RemapFaces(Crude &crude, VFile<unsigned int> &face_remap,
|
||||
std::vector<unsigned int> &patch_faces) = 0;
|
||||
std::vector<unsigned int> &patch_faces,
|
||||
float scaling, int steps) = 0;
|
||||
|
||||
/* virtual unsigned int Levels() = 0;
|
||||
|
||||
|
|
|
@ -24,6 +24,9 @@
|
|||
History
|
||||
|
||||
$Log: not supported by cvs2svn $
|
||||
Revision 1.3 2004/08/27 00:39:28 ponchio
|
||||
Rewrote.
|
||||
|
||||
Revision 1.2 2004/07/01 21:35:34 ponchio
|
||||
int -> Key
|
||||
|
||||
|
@ -50,7 +53,7 @@ using namespace nxs;
|
|||
|
||||
bool Seed::Dist(const Point3f &point, float &mindist,
|
||||
Point3f &res) {
|
||||
float newdist = Distance(p, point);
|
||||
float newdist = Distance(p, point) * weight;
|
||||
if(newdist < mindist) {
|
||||
mindist = newdist;
|
||||
res = p;
|
||||
|
|
|
@ -24,6 +24,9 @@
|
|||
History
|
||||
|
||||
$Log: not supported by cvs2svn $
|
||||
Revision 1.5 2004/08/27 00:39:28 ponchio
|
||||
Rewrote.
|
||||
|
||||
Revision 1.4 2004/07/20 14:17:51 ponchio
|
||||
*** empty log message ***
|
||||
|
||||
|
@ -113,6 +116,7 @@ namespace nxs {
|
|||
unsigned int count(unsigned int key);
|
||||
Seed &operator[](unsigned int key);
|
||||
void clear();
|
||||
void reload() { ug_seeds = all_seeds; ug.Set(ug_seeds); }
|
||||
unsigned int Locate(const vcg::Point3f &p);
|
||||
float Priority(const vcg::Point3f &p, unsigned int key);
|
||||
|
||||
|
@ -184,7 +188,7 @@ namespace nxs {
|
|||
return radius;
|
||||
}
|
||||
|
||||
private:
|
||||
// private:
|
||||
vcg::Box3f bbox;
|
||||
vcg::GridStaticPtr< std::vector<Seed> > ug;
|
||||
std::vector<Seed> all_seeds;
|
||||
|
|
|
@ -24,6 +24,9 @@
|
|||
History
|
||||
|
||||
$Log: not supported by cvs2svn $
|
||||
Revision 1.3 2004/09/17 15:25:09 ponchio
|
||||
First working (hopefully) release.
|
||||
|
||||
Revision 1.2 2004/09/16 14:25:16 ponchio
|
||||
Backup. (lot of changes).
|
||||
|
||||
|
@ -41,40 +44,144 @@ using namespace std;
|
|||
using namespace vcg;
|
||||
using namespace nxs;
|
||||
|
||||
void VoronoiChain::Initialize(unsigned int psize, unsigned int pthreshold) {
|
||||
patch_size = psize;
|
||||
patch_threshold = pthreshold;
|
||||
}
|
||||
|
||||
void VoronoiChain::Init(Crude &crude) {
|
||||
void VoronoiChain::Init(Crude &crude, float scaling, int steps) {
|
||||
box = crude.GetBox();
|
||||
radius = VoronoiPartition::OptimalRadius(crude, patch_size);
|
||||
float radius0 = radius;
|
||||
float radius1 = radius * 1.4;
|
||||
// float radius1 = VoronoiPartition::OptimalRadius(crude, patch_size*2);
|
||||
box.Offset(box.max - box.min);
|
||||
//how many cells do i need?
|
||||
cerr << "scaling: " << scaling << endl;
|
||||
unsigned int f_cells = crude.Faces() / mean_size;
|
||||
unsigned int c_cells = (unsigned int)(scaling * f_cells);
|
||||
|
||||
cerr << "mean size: " << mean_size << endl;
|
||||
cerr << "f cells: " << f_cells << endl;
|
||||
cerr << "c_cells: " << c_cells << endl;
|
||||
|
||||
levels.push_back(VoronoiPartition());
|
||||
levels.push_back(VoronoiPartition());
|
||||
VoronoiPartition &part0 = levels[0];
|
||||
VoronoiPartition &part1 = levels[1];
|
||||
part0.Init(crude.GetBox());
|
||||
part1.Init(crude.GetBox());
|
||||
VoronoiPartition &fine = levels[0];
|
||||
VoronoiPartition &coarse = levels[1];
|
||||
|
||||
VFile<Point3f>::iterator iter;
|
||||
for(iter = crude.vert.Begin(); iter != crude.vert.End(); ++iter) {
|
||||
Point3f &v = *iter;
|
||||
unsigned int target_patch;
|
||||
fine.Init(box);
|
||||
coarse.Init(box);
|
||||
|
||||
float dist = part0.Closest(v, target_patch);
|
||||
if(dist >= radius0 || dist == -1)
|
||||
part0.Add(v, radius0);
|
||||
srand(0);
|
||||
|
||||
vector<Seed> fine_seeds;
|
||||
vector<Seed> coarse_seeds;
|
||||
|
||||
dist = part1.Closest(v, target_patch);
|
||||
if(dist >= radius1 || dist == -1)
|
||||
part1.Add(v, radius1);
|
||||
float fine_vmean = mean_size/2;
|
||||
float coarse_vmean = (mean_size/scaling)/2;
|
||||
for(unsigned int i = 0; i < crude.Vertices(); i++) {
|
||||
int f = (int)(fine_vmean*rand()/(RAND_MAX + 1.0));
|
||||
int c = (int)(coarse_vmean *rand()/(RAND_MAX + 1.0));
|
||||
if(f == 1) {
|
||||
Point3f &point = crude.GetVertex(i);
|
||||
fine_seeds.push_back(Seed(point, 1));
|
||||
}
|
||||
if(c == 1) {
|
||||
Point3f &point = crude.GetVertex(i);
|
||||
coarse_seeds.push_back(Seed(point, 1));
|
||||
}
|
||||
}
|
||||
cerr << "fine_seeds.size: " << fine_seeds.size() << endl;
|
||||
cerr << "coarse_seeds.size: " << coarse_seeds.size() << endl;
|
||||
fine.all_seeds = fine_seeds;
|
||||
coarse.all_seeds = coarse_seeds;
|
||||
fine.reload();
|
||||
coarse.reload();
|
||||
|
||||
//here goes some optimization pass.
|
||||
//Fine optimization.
|
||||
vector<Point3f> fcentroids;
|
||||
vector<unsigned int> fcount;
|
||||
for(unsigned int i = 0; i < steps; i++) {
|
||||
cerr << "Optimization step 0: " << i << "/" << steps << endl;
|
||||
fcentroids.clear();
|
||||
fcount.clear();
|
||||
fcentroids.resize(fine.size(), Point3f(0, 0, 0));
|
||||
fcount.resize(fine.size(), 0);
|
||||
|
||||
for(unsigned int v = 0; v < crude.Vertices(); v++) {
|
||||
unsigned int ftarget;
|
||||
float dist = fine.Closest(crude.vert[v], ftarget);
|
||||
assert(ftarget != -1);
|
||||
fcentroids[ftarget] += crude.vert[v];
|
||||
fcount[ftarget]++;
|
||||
}
|
||||
for(unsigned int v = 0; v < fine.size(); v++) {
|
||||
assert(fcount[v] != 0);
|
||||
|
||||
fine[v].p = fcentroids[v]/fcount[v];
|
||||
//0.3 is related to the fact is doubled the box size.
|
||||
fine[v].weight = pow(fcount[v]/fine_vmean, 0.3f);
|
||||
// fine.bbox.Add(fine[v].p);
|
||||
}
|
||||
// fine.Init(fine.bbox);
|
||||
fine.reload();
|
||||
}
|
||||
|
||||
//Coarse optimization
|
||||
vector< map<unsigned int, Point3f> > ccentroids;
|
||||
vector< map<unsigned int, unsigned int> > ccount;
|
||||
|
||||
for(unsigned int i = 0; i < steps; i++) {
|
||||
cerr << "Optimization step 1: " << i << "/" << steps << endl;
|
||||
ccentroids.clear();
|
||||
ccount.clear();
|
||||
ccentroids.resize(coarse.size());
|
||||
ccount.resize(coarse.size());
|
||||
|
||||
for(unsigned int v = 0; v < crude.Vertices(); v++) {
|
||||
unsigned int ftarget;
|
||||
float dist = fine.Closest(crude.vert[v], ftarget);
|
||||
assert(ftarget != -1);
|
||||
|
||||
unsigned int ctarget;
|
||||
dist = coarse.Closest(crude.vert[v], ctarget);
|
||||
assert(ctarget != -1);
|
||||
|
||||
map<unsigned int, Point3f> ¢roids = ccentroids[ctarget];
|
||||
map<unsigned int, unsigned int> &count = ccount[ctarget];
|
||||
|
||||
if(!centroids.count(ftarget))
|
||||
centroids[ftarget]= Point3f(0, 0, 0);
|
||||
|
||||
if(!count.count(ftarget))
|
||||
count[ftarget] = 0;
|
||||
|
||||
centroids[ftarget] += crude.vert[v];
|
||||
count[ftarget]++;
|
||||
}
|
||||
|
||||
for(unsigned int v = 0; v < coarse.size(); v++) {
|
||||
|
||||
map<unsigned int, Point3f> ¢roids = ccentroids[v];
|
||||
map<unsigned int, unsigned int> &count = ccount[v];
|
||||
|
||||
|
||||
coarse[v].p = Point3f(0, 0, 0);
|
||||
float weight = 0;
|
||||
unsigned int tot_size =0;
|
||||
map<unsigned int, Point3f>::iterator k;
|
||||
for(k = centroids.begin();k != centroids.end(); k++) {
|
||||
unsigned int size = count[(*k).first];
|
||||
tot_size += size;
|
||||
//coarse[v].p += (*k).second / (size * size);
|
||||
//weight += 1/(float)size;
|
||||
coarse[v].p += (*k).second / size;
|
||||
weight += 1;
|
||||
// coarse[v].p += (*k).second;
|
||||
// weight += size;
|
||||
}
|
||||
assert(weight > 0);
|
||||
coarse[v].p /= weight;
|
||||
//TODO find a solution
|
||||
// coarse[v].weight = pow(tot_size/coarse_vmean, 0.25f);
|
||||
|
||||
}
|
||||
coarse.reload();
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int VoronoiChain::Locate(unsigned int level,
|
||||
|
@ -86,11 +193,11 @@ unsigned int VoronoiChain::Locate(unsigned int level,
|
|||
return fine + coarse * levels[level].size();*/
|
||||
}
|
||||
|
||||
void VoronoiChain::RemapFaces(Crude &crude,
|
||||
VFile<unsigned int> &face_remap,
|
||||
vector<unsigned int> &patch_faces) {
|
||||
void VoronoiChain::RemapFaces(Crude &crude, VFile<unsigned int> &face_remap,
|
||||
vector<unsigned int> &patch_faces,
|
||||
float scaling, int steps) {
|
||||
|
||||
Init(crude);
|
||||
Init(crude, scaling, steps);
|
||||
|
||||
//TODO: improve quality of patches and implement threshold.
|
||||
typedef map<pair<unsigned int, unsigned int>, unsigned int> FragIndex;
|
||||
|
@ -115,7 +222,10 @@ void VoronoiChain::RemapFaces(Crude &crude,
|
|||
} else
|
||||
patch = patches[make_pair(coarse, fine)];
|
||||
|
||||
//BEWARE unkomment this!
|
||||
face_remap[i] = patch;
|
||||
//face_remap[i] = fine;
|
||||
// face_remap[i] = coarse;
|
||||
if(patch_faces.size() <= patch)
|
||||
patch_faces.resize(patch+1, 0);
|
||||
patch_faces[patch]++;
|
||||
|
@ -164,28 +274,109 @@ void VoronoiChain::RemapFaces(Crude &crude,
|
|||
patch_faces.resize(tot_patches);
|
||||
}
|
||||
|
||||
void VoronoiChain::BuildLevel(Nexus &nexus, unsigned int offset) {
|
||||
unsigned int target_faces = (int)(patch_size *
|
||||
pow(scaling, (float)levels.size()));
|
||||
|
||||
float rad = radius * pow(sqrt(1/scaling), (float)levels.size());
|
||||
void VoronoiChain::BuildLevel(Nexus &nexus, unsigned int offset,
|
||||
float scaling, int steps) {
|
||||
// unsigned int target_faces = (int)(mean_size *
|
||||
// pow(0.5f, (float)levels.size()));
|
||||
|
||||
unsigned int totface = 0;
|
||||
for(unsigned int idx = offset; idx < nexus.index.size(); idx++)
|
||||
totface += nexus.index[idx].nface;
|
||||
|
||||
levels.push_back(VoronoiPartition());
|
||||
VoronoiPartition &part = levels[levels.size()-1];
|
||||
part.Init(box);
|
||||
VoronoiPartition &coarse = levels[levels.size()-1];
|
||||
VoronoiPartition &fine = levels[levels.size()-2];
|
||||
|
||||
coarse.Init(box);
|
||||
|
||||
fine.reload();
|
||||
|
||||
srand(0);
|
||||
float coarse_vmean = (totface/2)/(fine.size() * scaling);
|
||||
|
||||
cerr << "initing random seeds\n";
|
||||
|
||||
vector<Seed> coarse_seeds;
|
||||
|
||||
for(unsigned int idx = offset; idx < nexus.index.size(); idx++) {
|
||||
Patch patch = nexus.GetPatch(idx);
|
||||
for(unsigned int i = 0; i < patch.nv; i++) {
|
||||
Point3f &v = patch.Vert(i);
|
||||
unsigned int target_patch;
|
||||
|
||||
float dist = part.Closest(v, target_patch);
|
||||
if(dist >= rad || dist == -1)
|
||||
part.Add(v, rad);
|
||||
int c = (int)(coarse_vmean*rand()/(RAND_MAX + 1.0));
|
||||
if(c == 1) {
|
||||
Point3f &v = patch.Vert(i);
|
||||
coarse_seeds.push_back(v);
|
||||
}
|
||||
}
|
||||
}
|
||||
cerr << "radius: " << rad << " ... cells: " << part.size() << endl;
|
||||
if(coarse_seeds.size() == 0)
|
||||
coarse_seeds.push_back(Point3f(0, 0, 0));
|
||||
coarse.all_seeds = coarse_seeds;
|
||||
coarse.reload();
|
||||
|
||||
//Coarse optimization
|
||||
vector< map<unsigned int, Point3f> > ccentroids;
|
||||
vector< map<unsigned int, unsigned int> > ccount;
|
||||
|
||||
for(unsigned int step = 0; step < steps; step++) {
|
||||
cerr << "Optimization step " << levels.size()-1 << ":"
|
||||
<< step << "/" << steps << endl;
|
||||
ccentroids.clear();
|
||||
ccount.clear();
|
||||
ccentroids.resize(coarse.size());
|
||||
ccount.resize(coarse.size());
|
||||
|
||||
for(unsigned int idx = offset; idx < nexus.index.size(); idx++) {
|
||||
Patch patch = nexus.GetPatch(idx);
|
||||
|
||||
for(unsigned int i = 0; i < patch.nv; i++) {
|
||||
Point3f &v = patch.Vert(i);
|
||||
unsigned int ftarget;
|
||||
float dist = fine.Closest(Point3f(1,1,1), ftarget);
|
||||
|
||||
dist = fine.Closest(v, ftarget);
|
||||
assert(ftarget != -1);
|
||||
|
||||
unsigned int ctarget;
|
||||
dist = coarse.Closest(v, ctarget);
|
||||
assert(ctarget != -1);
|
||||
|
||||
map<unsigned int, Point3f> ¢roids = ccentroids[ctarget];
|
||||
map<unsigned int, unsigned int> &count = ccount[ctarget];
|
||||
|
||||
if(!centroids.count(ftarget))
|
||||
centroids[ftarget]= Point3f(0, 0, 0);
|
||||
|
||||
if(!count.count(ftarget))
|
||||
count[ftarget] = 0;
|
||||
|
||||
centroids[ftarget] += v;
|
||||
count[ftarget]++;
|
||||
}
|
||||
}
|
||||
|
||||
cerr << "recentring" << endl;
|
||||
for(unsigned int v = 0; v < coarse.size(); v++) {
|
||||
|
||||
map<unsigned int, Point3f> ¢roids = ccentroids[v];
|
||||
map<unsigned int, unsigned int> &count = ccount[v];
|
||||
|
||||
coarse[v].p = Point3f(0, 0, 0);
|
||||
float weight = 0;
|
||||
unsigned int tot_size =0;
|
||||
map<unsigned int, Point3f>::iterator k;
|
||||
for(k = centroids.begin();k != centroids.end(); k++) {
|
||||
unsigned int size = count[(*k).first];
|
||||
tot_size += size;
|
||||
coarse[v].p += (*k).second / size;
|
||||
weight += 1;
|
||||
}
|
||||
assert(weight > 0);
|
||||
coarse[v].p /= weight;
|
||||
//TODO find a solution!
|
||||
// coarse[v].weight = pow(tot_size/coarse_vmean, 0.25f);
|
||||
}
|
||||
coarse.reload();
|
||||
}
|
||||
newfragments.clear();
|
||||
//TODO add some optimization
|
||||
}
|
||||
|
|
|
@ -24,6 +24,9 @@
|
|||
History
|
||||
|
||||
$Log: not supported by cvs2svn $
|
||||
Revision 1.2 2004/09/16 14:25:16 ponchio
|
||||
Backup. (lot of changes).
|
||||
|
||||
Revision 1.1 2004/08/26 18:03:48 ponchio
|
||||
First draft.
|
||||
|
||||
|
@ -48,16 +51,23 @@ namespace nxs {
|
|||
|
||||
class VoronoiChain: public PChain {
|
||||
public:
|
||||
VoronoiChain():scaling(0.5), patch_size(1000), patch_threshold(300) {}
|
||||
virtual ~VoronoiChain() {}
|
||||
void Initialize(unsigned int psize, unsigned int pthreshold);
|
||||
void Init(Crude &crude);
|
||||
unsigned int mean_size; //mean number of faces per patch
|
||||
unsigned int min_size; //minimum number of faces per patch (soft)
|
||||
unsigned int max_size; //max number of faces per patch (hard);
|
||||
|
||||
VoronoiChain(unsigned int mean_s = 1000,
|
||||
unsigned int min_s = 300,
|
||||
unsigned int max_s = 32000):
|
||||
mean_size(mean_s), min_size(min_s), max_size(max_s) {}
|
||||
virtual ~VoronoiChain() {}
|
||||
|
||||
void Init(Crude &crude, float scaling, int steps);
|
||||
virtual unsigned int Locate(unsigned int level, const vcg::Point3f &p);
|
||||
void RemapFaces(Crude &crude, VFile<unsigned int> &face_remap,
|
||||
std::vector<unsigned int> &patch_faces);
|
||||
std::vector<unsigned int> &patch_faces, float scaling,
|
||||
int steps);
|
||||
|
||||
void BuildLevel(Nexus &nexus, unsigned int offset);
|
||||
void BuildLevel(Nexus &nexus, unsigned int offset, float scaling, int steps);
|
||||
|
||||
std::vector<VoronoiPartition> levels;
|
||||
|
||||
|
@ -65,9 +75,6 @@ class VoronoiChain: public PChain {
|
|||
std::map<unsigned int, std::set<unsigned int> > newfragments;
|
||||
std::map<unsigned int, std::set<unsigned int> > oldfragments;
|
||||
// private:
|
||||
float scaling;
|
||||
unsigned int patch_size;
|
||||
unsigned int patch_threshold;
|
||||
|
||||
float radius;
|
||||
vcg::Box3f box;
|
||||
|
|
|
@ -24,6 +24,9 @@
|
|||
History
|
||||
|
||||
$Log: not supported by cvs2svn $
|
||||
Revision 1.3 2004/09/17 15:25:09 ponchio
|
||||
First working (hopefully) release.
|
||||
|
||||
Revision 1.2 2004/09/16 14:25:16 ponchio
|
||||
Backup. (lot of changes).
|
||||
|
||||
|
@ -97,15 +100,20 @@ float Decimate(unsigned int target_faces,
|
|||
|
||||
void ReverseHistory(vector<Nexus::Update> &history);
|
||||
|
||||
enum Decimation { QUADRIC, CLUSTER };
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
|
||||
Decimation decimation = QUADRIC;
|
||||
unsigned int patch_size = 1000;
|
||||
unsigned int patch_threshold = 200;
|
||||
unsigned int optimization_steps = 5;
|
||||
bool stop_after_remap = false;
|
||||
unsigned int max_level = 0xffffffff;
|
||||
float scaling = 0.5;
|
||||
|
||||
int option;
|
||||
while((option = getopt(argc, argv, "f:t:l:s:")) != EOF) {
|
||||
while((option = getopt(argc, argv, "f:t:l:s:d:ro:")) != EOF) {
|
||||
switch(option) {
|
||||
case 'f': patch_size = atoi(optarg);
|
||||
if(patch_size == 0 || patch_size > 32000) {
|
||||
|
@ -131,12 +139,24 @@ int main(int argc, char *argv[]) {
|
|||
cerr << "Must be 0 < scaling < 1" << endl;
|
||||
}
|
||||
break;
|
||||
case 'd':
|
||||
if(!strcmp("quadric", optarg))
|
||||
decimation = QUADRIC;
|
||||
else if(!strcmp("cluster", optarg))
|
||||
decimation = CLUSTER;
|
||||
else {
|
||||
cerr << "Unknown decimation method: " << optarg << endl;
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
case 'r': stop_after_remap = true; break;
|
||||
case 'o': optimization_steps = atoi(optarg); break;
|
||||
default: cerr << "Unknown option: " << (char)option << endl;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
//Test there are still 2 arguments
|
||||
//Test that there are still 2 arguments
|
||||
if(optind != argc - 2) {
|
||||
cerr << "Usage: " << argv[0] << " <crude> <output> [options]\n";
|
||||
cerr << " Options:\n";
|
||||
|
@ -144,6 +164,7 @@ int main(int argc, char *argv[]) {
|
|||
cerr << " -t N: mini faces per patch (default 200)\n";
|
||||
cerr << " -l N: number of levels\n";
|
||||
cerr << " -s F: scaling factor (0 < F < 1, default 0.5)\n\n";
|
||||
cerr << " -d <method>: decimation method: quadric, cluster. (default quadric)\n";
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -154,23 +175,21 @@ int main(int argc, char *argv[]) {
|
|||
}
|
||||
|
||||
if(patch_size > crude.vert.Size()/2) {
|
||||
cerr << "Patch size too big: " << patch_size << " ~ " << crude.vert.Size()
|
||||
cerr << "Patch size too big: " << patch_size << " * 2 > " << crude.vert.Size()
|
||||
<< endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
string output = argv[optind+1];
|
||||
|
||||
Signature signature = HAS_FACES;
|
||||
Nexus nexus;
|
||||
if(!nexus.Create(output, signature)) {
|
||||
if(!nexus.Create(output, HAS_FACES)) {
|
||||
cerr << "Could not create nexus output: " << output << endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
VoronoiChain vchain;
|
||||
vchain.Initialize(patch_size, patch_threshold);
|
||||
vchain.scaling = scaling;
|
||||
VoronoiChain vchain(patch_size, patch_threshold);
|
||||
// vchain.scaling = scaling;
|
||||
|
||||
//Now building level 0 of the Nexus
|
||||
|
||||
|
@ -200,12 +219,13 @@ int main(int argc, char *argv[]) {
|
|||
//Remapping faces and vertices using level 0 and 1 of the chain
|
||||
|
||||
vector<unsigned int> patch_faces;
|
||||
vchain.RemapFaces(crude, face_remap, patch_faces);
|
||||
vchain.RemapFaces(crude, face_remap, patch_faces, scaling, optimization_steps);
|
||||
|
||||
vector<unsigned int> patch_verts;
|
||||
patch_verts.resize(patch_faces.size(), 0);
|
||||
RemapVertices(crude, vert_remap, face_remap, patch_verts);
|
||||
|
||||
if(stop_after_remap) return 0;
|
||||
|
||||
//allocate chunks for patches and copy faces (absoklute indexing) into them.
|
||||
NexusAllocate(crude, nexus, face_remap, patch_faces, patch_verts);
|
||||
|
@ -231,8 +251,9 @@ int main(int argc, char *argv[]) {
|
|||
cerr << "Level: " << level << endl;
|
||||
|
||||
unsigned int newoffset = nexus.index.size();
|
||||
vchain.BuildLevel(nexus, oldoffset);
|
||||
vchain.BuildLevel(nexus, oldoffset, scaling, optimization_steps);
|
||||
|
||||
cerr << "Level built\n";
|
||||
vector<Nexus::Update> level_history;
|
||||
map<unsigned int, set<unsigned int> >::iterator fragment;
|
||||
for(fragment = vchain.oldfragments.begin();
|
||||
|
@ -662,13 +683,24 @@ void NexusSplit(Nexus &nexus, VoronoiChain &vchain,
|
|||
|
||||
Nexus::Entry &rentry = nexus.index[link.end_patch];
|
||||
//TODO if !true reallocate borders.
|
||||
|
||||
Border rborder = nexus.GetBorder(link.end_patch);
|
||||
if(rentry.border_used >= rentry.border_size) {
|
||||
cerr << "patch: " << link.end_patch << endl;
|
||||
cerr << "used: " << rentry.border_used << endl;
|
||||
cerr << "size: " << rentry.border_size << endl;
|
||||
unsigned int start = nexus.borders.Size();
|
||||
nexus.borders.Resize(nexus.borders.Size() + 2 * rentry.border_size);
|
||||
Link *tmp = new Link[rentry.border_size];
|
||||
memcpy(tmp, &rborder[0], sizeof(Link) * rentry.border_size);
|
||||
rentry.border_start = start;
|
||||
rentry.border_size *= 2;
|
||||
rborder = nexus.GetBorder(link.end_patch);
|
||||
memcpy(&rborder[0], tmp, sizeof(Link) * rentry.border_used);
|
||||
delete []tmp;
|
||||
}
|
||||
assert(rentry.border_used < rentry.border_size);
|
||||
Border rborder = nexus.GetBorder(link.end_patch);
|
||||
|
||||
|
||||
Link &newlink = rborder[rentry.border_used++];
|
||||
newlink.start_vert = link.end_vert;
|
||||
|
@ -695,8 +727,7 @@ void NexusSplit(Nexus &nexus, VoronoiChain &vchain,
|
|||
|
||||
|
||||
Nexus::Entry &entry = nexus.index[patch_idx];
|
||||
// entry.error = error;
|
||||
entry.error = level;
|
||||
entry.error = error;
|
||||
|
||||
Patch patch = nexus.GetPatch(patch_idx);
|
||||
memcpy(patch.FaceBegin(), &faces[0],
|
||||
|
|
Loading…
Reference in New Issue