diff --git a/apps/nexus/decimate.cpp b/apps/nexus/decimate.cpp index 41b38422..be20552e 100644 --- a/apps/nexus/decimate.cpp +++ b/apps/nexus/decimate.cpp @@ -193,8 +193,13 @@ float Cluster(MyMesh &mesh, unsigned int target_faces) { nseeds--; } } + if(part.size() == 0) { + cerr << "WARNING: could not simplyfiy... everything was border.\n"; + return 0; //everything is locked... + } part.Init(); + vector centroid; vector count; for(unsigned int i = 0; i < 3; i++) { diff --git a/apps/nexus/normalscone.cpp b/apps/nexus/normalscone.cpp index 7b9d963b..20f80a2d 100644 --- a/apps/nexus/normalscone.cpp +++ b/apps/nexus/normalscone.cpp @@ -62,14 +62,14 @@ void ANCone3f::AddNormals(vector &normal, vector &area, float th break; } double alpha = M_PI * (best + 1) / 50; - if(alpha > M_PI/ 2 - 0.1) + if(alpha >= M_PI/ 2 - 0.1) scaledNormal = Point3f(0,0,0); else scaledNormal /= cos(M_PI/2 - alpha); } void ANCone3f::AddNormals(vector &normal, float threshold) { - //assert(normal.size() > 0); + assert(normal.size() > 0); scaledNormal = Point3f(0,0,0); int count = 0; vector::iterator i; @@ -81,7 +81,9 @@ void ANCone3f::AddNormals(vector &normal, float threshold) { count++; } scaledNormal /= count; - scaledNormal.Normalize(); + float len = scaledNormal.Norm(); + if(len == 0) return; + scaledNormal /= len; int distr[50]; for(int k = 0; k < 50; k++) @@ -93,16 +95,13 @@ void ANCone3f::AddNormals(vector &normal, float threshold) { } int tot = 0; int best; - // cerr << "Distr: "; for(best = 0; best < 50; best++) { - // cerr << distr[best] << " "; tot += distr[best]; if(tot >= threshold * normal.size()) break; } double alpha = M_PI * (best +1) / 50; - // cerr << "best: " << best << " alpha: " << alpha << endl; - if(alpha > M_PI/ 2) { + if(alpha >= M_PI/ 2 - 0.1) { scaledNormal = Point3f(0,0,0); } else { scaledNormal /= cos(M_PI/2 - alpha); @@ -138,8 +137,12 @@ void NCone3s::Import(const ANCone3f &c) { if(len != 0) normal /= len; - assert(normal[0] <= 1 && normal[1] <= 1 && normal[2] <= 1); - assert(normal[0] >= -1 && normal[1] >= -1 && normal[2] >= -1); + for(int i = 0; i < 3; i++) { + assert(normal[i] < 1.01 && normal[i] > -1.01); + + if(normal[i] > 1.0f) normal[i] = 1; + if(normal[i] < -1.0f) normal[i] = -1; + } n[0] = (short)(normal[0] * 32766); n[1] = (short)(normal[1] * 32766); n[2] = (short)(normal[2] * 32766); diff --git a/apps/nexus/nxsalgo.cpp b/apps/nexus/nxsalgo.cpp index f9736f17..d726517f 100644 --- a/apps/nexus/nxsalgo.cpp +++ b/apps/nexus/nxsalgo.cpp @@ -24,6 +24,9 @@ History $Log: not supported by cvs2svn $ +Revision 1.23 2005/02/22 10:38:10 ponchio +Debug, cleaning and optimization. + Revision 1.22 2005/02/21 17:55:36 ponchio debug debug debug @@ -422,8 +425,7 @@ void nxs::ComputeNormals(Nexus &nexus) { /* - //TODO why i created this function? wonder... -void nxs::Reorder(Signature &signature, Patch &patch) { + //TODO why i created this function? wonder...void nxs::Reorder(Signature &signature, Patch &patch) { vector remap; remap.resize(patch.nv, 0xffff); @@ -461,8 +463,56 @@ void nxs::Reorder(Signature &signature, Patch &patch) { //TODO actually use threshold -void nxs::Unify(Nexus &nexus, float threshold) { - /* threshold = 0.00001; +void nxs::Unify(vector &points, vector &faces, + vector &remap, float threshold) { + vector newfaces = faces; + + VPartition grid; + for(unsigned int i = 0; i < points.size(); i++) + grid.push_back(points[i]); + grid.Init(); + + remap.resize(points.size()); + vector targets; + vector dists; + + points.clear(); + unsigned int count = 0; + for(unsigned int i = 0; i < grid.size(); i++) { + + grid.Closest(grid[i], targets, dists, threshold); + + if(targets.size() > 1) { + unsigned int p; + for(p = 0; p < targets.size(); p++) { + if(targets[p] < i) { + remap[i] = remap[targets[p]]; + break; + } + } + if(p < targets.size()) continue; + } + remap[i] = count++; + points.push_back(grid[i]); + } + + //fixing faces now + faces.clear(); + for(unsigned int i = 0; i < newfaces.size(); i += 3) { + unsigned short f[3]; + f[0] = remap[newfaces[i]]; + f[1] = remap[newfaces[i+1]]; + f[2] = remap[newfaces[i+2]]; + if(f[0] == f[1] || f[0] == f[2] || f[1] == f[2]) + continue; + + for(int k = 0; k < 3; k++) + faces.push_back(f[k]); + } +} + +/*void nxs::Unify(Nexus &nexus, float threshold) { + threshold = 0.00001; unsigned int duplicated = 0; unsigned int degenerate = 0; @@ -485,8 +535,8 @@ void nxs::Unify(Nexus &nexus, float threshold) { for(k = normals.begin(); k != normals.end(); k++) { Patch &patch = nexus.GetPatch((*k).first); } + } }*/ -} /* void nxs::Unify(Nexus &nexus, float threshold) { diff --git a/apps/nexus/nxsalgo.h b/apps/nexus/nxsalgo.h index 993a618f..91b1b77c 100644 --- a/apps/nexus/nxsalgo.h +++ b/apps/nexus/nxsalgo.h @@ -24,6 +24,9 @@ History $Log: not supported by cvs2svn $ +Revision 1.9 2005/02/22 10:38:11 ponchio +Debug, cleaning and optimization. + Revision 1.8 2005/02/21 17:55:36 ponchio debug debug debug @@ -69,7 +72,10 @@ namespace nxs { void ComputeNormals(Nexus &nexus); - void Unify(Nexus &nexus, float threshold); + void Unify(std::vector &points, + std::vector &faces, + std::vector &vremap, float threshold); +// void Unify(Nexus &nexus, float threshold); void ZSort(Nexus &nexus, std::vector &forward, std::vector &backward); // void TightSphere(vcg::Sphere3f &sphere, std::vector &points); diff --git a/apps/nexus/nxsbuilder.cpp b/apps/nexus/nxsbuilder.cpp index b8b34d71..6c564d39 100644 --- a/apps/nexus/nxsbuilder.cpp +++ b/apps/nexus/nxsbuilder.cpp @@ -24,6 +24,9 @@ History $Log: not supported by cvs2svn $ +Revision 1.21 2005/02/22 10:38:11 ponchio +Debug, cleaning and optimization. + Revision 1.20 2005/02/21 17:55:47 ponchio debug debug debug @@ -111,6 +114,7 @@ Level 0. #include "nxsalgo.h" #include "nxsdispatcher.h" #include "watch.h" +#include "nexus.h" using namespace std; @@ -236,7 +240,6 @@ void SecondStep(const string &crudefile, const string &output) { cerr << "Could not load index\n"; exit(0); } - // cerr << "Face index size: " << face_index.size() << endl; //Sorting now. vector done; @@ -249,11 +252,6 @@ void SecondStep(const string &crudefile, const string &output) { sorted[offset] = crude.GetFace(i); } -#ifndef NDEBUG - for(int i = 0; i < done.size(); i++) - assert(done[i] == face_index[i].size); -#endif - //once sorted crude.Close(); sorted.Close(); @@ -329,31 +327,37 @@ void ThirdStep(const string &crudefile, const string &output, unsigned int size = face_index[patch].size; for(unsigned int i = offset; i < offset + size; i++) { //TODO fix this after debug - // Crude::Face face = crude.GetFace(i); Crude::Face face = sorted[i]; if(face[0] == face[1] || face[1] == face[2] || face[0] == face[2]) - continue; //degenerate + continue; //degenerate for(int j = 0; j < 3; j++) { - assert(face[j] < crude.Vertices()); - if(!vremap.count(face[j])) { - Point3f &v = crude.vert[face[j]]; - vertices.push_back(v); - vremap[face[j]] = vcount++; - } - faces.push_back(vremap[face[j]]); - fcount++; + assert(face[j] < crude.Vertices()); + if(!vremap.count(face[j])) { + Point3f &v = crude.vert[face[j]]; + vertices.push_back(v); + vremap[face[j]] = vcount++; + } + faces.push_back(vremap[face[j]]); + fcount++; } } - assert(vcount == vertices.size()); - assert(fcount == faces.size()); + vector remap; + nxs::Unify(vertices, faces, remap, 0.0001); + //fixing vremap + map::iterator q; + for(q = vremap.begin(); q != vremap.end(); q++) + (*q).second = remap[(*q).second]; + vcount = vertices.size(); + fcount = faces.size(); + //TODO deal with this case adding another patch at the end... //its not that difficult! - //This can happen on degenerate cases when we have a lot of detached faces.... + //This can happen on degenerate cases when we have a lot of detached faces. if(vcount > 65000 && fcount > 65000) { - cerr << "Too many vertices or faces in patch: " << patch << " v: " << vcount - << " f: " << fcount << endl; + cerr << "Too many vertices or faces in patch: " << patch + << " v: " << vcount << " f: " << fcount << endl; exit(0); } @@ -364,10 +368,15 @@ void ThirdStep(const string &crudefile, const string &output, memcpy(patch.FaceBegin(), &*faces.begin(), fcount * sizeof(short)); memcpy(patch.Vert3fBegin(), &*vertices.begin(), vcount * sizeof(Point3f)); + + //Fixing sphere Sphere3f &sphere = nexus[patch_idx].sphere; sphere.CreateTight(vertices.size(), &*vertices.begin()); + + //Fixing normalscone vector normals; + normals.reserve(patch.nf); for(unsigned int i = 0; i < patch.nf; i++) { unsigned short *f = patch.Face(i); Point3f &v0 = patch.Vert3f(f[0]); @@ -375,17 +384,22 @@ void ThirdStep(const string &crudefile, const string &output, Point3f &v2 = patch.Vert3f(f[2]); Point3f norm = (v1 - v0) ^ (v2 - v0); - normals.push_back(norm.Normalize()); + float len = norm.Norm(); + if(len == 0) { + cerr << "Degenerate face... should not be here.\n"; + continue; + } + norm /= len; + if(isnan(norm[0]) || isnan(norm[1]) || isnan(norm[2])) { + cerr << "Invalid normal computation. Strange.\n"; + continue; + } + normals.push_back(norm); } ANCone3f cone; cone.AddNormals(normals, 0.99f); nexus[patch_idx].cone.Import(cone); -#ifndef NDEBUG - for(int i = 0; i < vertices.size(); i++) { - assert(sphere.IsIn(vertices[i])); - } -#endif //saving vert_remap int64 vroffset = vert_remap.Size(); @@ -408,16 +422,14 @@ void ThirdStep(const string &crudefile, const string &output, nexus.sphere.Add(nexus[i].sphere); History::Update update; - for(unsigned int i = 1; i < nexus.size(); i++) { + for(unsigned int i = 1; i < nexus.size(); i++) update.created.push_back(i); - } nexus.history.updates.push_back(update); update.created.clear(); update.created.push_back(0); - for(unsigned int i = 1; i < nexus.size(); i++) { + for(unsigned int i = 1; i < nexus.size(); i++) update.erased.push_back(i); - } nexus.history.updates.push_back(update); if(!vert_index.Save(output + ".rvi")) { @@ -429,6 +441,8 @@ void ThirdStep(const string &crudefile, const string &output, void FourthStep(const string &crudefile, const string &output, unsigned int ram_buffer) { + float threshold = 0.0001; + cerr << "Creating borders\n"; Nexus nexus; if(!nexus.Load(output)) { cerr << "Could not load nexus " << output << endl; @@ -453,11 +467,50 @@ void FourthStep(const string &crudefile, const string &output, Report report(nexus.size()); + //WARNING this is not robust at all!!!! + //TO make all this work we should neeed to quantize + //vertex position with 2 * threshold step (at least) for(int start = 0; start < nexus.size(); start++) { report.Step(start); - // Entry &s_entry = nexus[start]; - // Sphere3f &sphere = s_entry.sphere; + vector links; + set::iterator t; + for(t = close[start].begin(); t != close[start].end(); t++) { + unsigned int end = (*t); + Patch &pend = nexus.GetPatch(end); + VPartition grid; + for(int i = 0; i < pend.nv; i++) { + grid.push_back(pend.Vert3f(i)); + } + grid.Init(); + + vector targets; + vector dists; + Patch &patch = nexus.GetPatch(start); + for(int i = 0; i < patch.nv; i++) { + grid.Closest(patch.Vert3f(i), targets, dists, threshold); + for(unsigned int k = 0; k < targets.size(); k++) { + Link link; + link.start_vert = i; + link.end_vert = targets[k]; + link.end_patch = end; + links.push_back(link); + patch.Vert3f(i) = grid[targets[k]]; + } + } + + } + + Border &border = nexus.GetBorder(start); + nexus.borders.ResizeBorder(start, 3 * links.size()); + border.used = links.size(); + memcpy(&(border[0]), &*links.begin(), links.size() * sizeof(Link)); + } + + /*old way.. + for(int start = 0; start < nexus.size(); start++) { + report.Step(start); + vector links; map vremap; for(unsigned int i = 0; i < vert_index[start].size; i++) { @@ -465,20 +518,10 @@ void FourthStep(const string &crudefile, const string &output, vremap[global] = i; } - // for(int end = 0; end < nexus.size(); end++) { - // if(start == end) continue; set::iterator t; for(t = close[start].begin(); t != close[start].end(); t++) { unsigned int end = (*t); - // Entry &e_entry = nexus[end]; - // float dist = Distance(s_entry.sphere.Center(), e_entry.sphere.Center()); - - // if(dist > s_entry.sphere.Radius() + e_entry.sphere.Radius()) { - // continue; - // } - // assert(close[start].count(end)); - for(unsigned int i = 0; i < vert_index[end].size; i++) { unsigned int global = vert_remap[vert_index[end].offset + i]; if(vremap.count(global)) { @@ -489,12 +532,14 @@ void FourthStep(const string &crudefile, const string &output, links.push_back(link); } } - } + } + + Border &border = nexus.GetBorder(start); nexus.borders.ResizeBorder(start, 3 * links.size()); border.used = links.size(); memcpy(&(border[0]), &*links.begin(), links.size() * sizeof(Link)); - } + }*/ } void FifthStep(const string &crudefile, const string &output, @@ -525,7 +570,7 @@ void FifthStep(const string &crudefile, const string &output, patch_levels.push_back(0); } nexus.history.updates.push_back(update); - Unify(nexus, 0.0f); + // Unify(nexus, 0.0f); // nexus.Unify(); nexus.Flush(); @@ -757,6 +802,7 @@ void BuildFragment(Nexus &nexus, VPartition &part, } } + //TODO Use the closest with threshold here instead of a cracnut number?? set seeds; vector nears; vector dists; diff --git a/apps/nexus/remapping.cpp b/apps/nexus/remapping.cpp index 915df4d3..2f118a13 100644 --- a/apps/nexus/remapping.cpp +++ b/apps/nexus/remapping.cpp @@ -24,6 +24,9 @@ History $Log: not supported by cvs2svn $ +Revision 1.11 2005/02/19 14:00:43 ponchio +Small opt. + Revision 1.10 2005/02/19 10:45:05 ponchio Patch generalized and small fixes. @@ -390,7 +393,7 @@ void nxs::BuildLevel(VChain &chain, Point3f bari = (patch.Vert3f(face[0]) + patch.Vert3f(face[1]) + patch.Vert3f(face[2]))/3; - + assert(coarse->size() > 0); unsigned int target = coarse->Locate(bari); assert(target < coarse->size()); centroids[target] += bari; diff --git a/apps/nexus/vpartition.cpp b/apps/nexus/vpartition.cpp index 0cfc6e4b..a4b8e027 100644 --- a/apps/nexus/vpartition.cpp +++ b/apps/nexus/vpartition.cpp @@ -24,6 +24,9 @@ History $Log: not supported by cvs2svn $ +Revision 1.5 2005/02/22 10:38:17 ponchio +Debug, cleaning and optimization. + Revision 1.4 2005/02/21 17:55:48 ponchio debug debug debug @@ -158,7 +161,6 @@ float VPartition::Radius(unsigned int seed) { point[0] = p[0]; point[1] = p[1]; point[2] = p[2]; - bd->annkSearch(&point[0], 2, nears, dists); if(dists[1] == 0) return 0.0f;