diff --git a/apps/nexus/decimate.cpp b/apps/nexus/decimate.cpp index 8d2207a8..b18f911c 100644 --- a/apps/nexus/decimate.cpp +++ b/apps/nexus/decimate.cpp @@ -17,7 +17,7 @@ //#include "border.h" #include "decimate.h" -//#include +#include using namespace vcg; using namespace tri; @@ -59,11 +59,10 @@ float nxs::Decimate(Decimation mode, vector &newbord, vector &vert_remap) { - //Temporary test: for(unsigned int i = 0; i < newface.size(); i+= 3) { - assert(newface[i*3] != newface[i*3+1]); - assert(newface[i*3] != newface[i*3+2]); - assert(newface[i*3+1] != newface[i*3+2]); + assert(newface[i] != newface[i+1]); + assert(newface[i] != newface[i+2]); + assert(newface[i+1] != newface[i+2]); } MyMesh mesh; @@ -81,7 +80,7 @@ float nxs::Decimate(Decimation mode, MyFace face; face.ClearFlags(); for(int k = 0; k < 3; k++) { - assert(newface[i+k] < mesh.vn); + assert(newface[i+k] < mesh.vert.size()); face.V(k) = &mesh.vert[newface[i+k]]; } mesh.face.push_back(face); @@ -92,57 +91,18 @@ float nxs::Decimate(Decimation mode, for(unsigned int i = 0; i < newbord.size(); i++) mesh.vert[newbord[i].start_vert].ClearW(); - - // int FinalSize = mesh.face.size()/2; - // if(FinalSize > target_faces) FinalSize = target_faces; - - - /* if(target_faces == 2404) { - vcg::tri::io::ExporterPLY::Save(mesh, "bum"); - }*/ printf("mesh loaded %d %d \n",mesh.vn,mesh.fn); printf("reducing it to %i\n", target_faces); + // if(target_faces == 1446) + // vcg::tri::io::ExporterPLY::Save(mesh, "ribum.ply"); - /* - int t0=clock(); - vcg::tri::UpdateTopology::VertexFace(mesh); - int t1=clock(); - vcg::LocalOptimization DeciSession(mesh); - MyTriEdgeCollapse::SetDefaultParams(); - - DeciSession.Init(); - - FinalSize = mesh.fn - FinalSize; //number of faces to remove - FinalSize/=2; //Number of vertices to remove - DeciSession.SetTargetOperations(FinalSize); - DeciSession.DoOptimization(); - float error = DeciSession.currMetric/4;//1; //get error; - int t3=clock(); - */ float error; if(mode == CLUSTER) error = Cluster(mesh, target_faces); else error = Quadric(mesh, target_faces); - - - /* printf(" vol %d \n lkv %d \n lke %d \n lkf %d \n ood %d\n bor %d\n ", - MyTriEdgeCollapse::FailStat::Volume() , - MyTriEdgeCollapse::FailStat::LinkConditionFace(), - MyTriEdgeCollapse::FailStat::LinkConditionEdge(), - MyTriEdgeCollapse::FailStat::LinkConditionVert(), - MyTriEdgeCollapse::FailStat::OutOfDate() , - MyTriEdgeCollapse::FailStat::Border() - );*/ - - // printf("Completed in %i+%i+%i msec\n",t1-t0,t2-t1,t3-t2); - // printf("mesh %d %d \n",mesh.vn,mesh.fn); - - //recort vert start. - - newvert.clear(); newface.clear(); @@ -158,10 +118,8 @@ float nxs::Decimate(Decimation mode, for(unsigned int i = 0; i < mesh.face.size(); i++) { MyFace &face = mesh.face[i]; if(face.IsD()) continue; - for(int k = 0; k < 3; k++) { - assert(vert_remap[face.V(k) - vert_start] != -1); + for(int k = 0; k < 3; k++) newface.push_back(vert_remap[face.V(k) - vert_start]); - } } for(unsigned int i = 0; i < newbord.size(); i++) { @@ -172,9 +130,9 @@ float nxs::Decimate(Decimation mode, //Temporary test again: for(unsigned int i = 0; i < newface.size(); i+= 3) { - assert(newface[i*3] != newface[i*3+1]); - assert(newface[i*3] != newface[i*3+2]); - assert(newface[i*3+1] != newface[i*3+2]); + assert(newface[i] != newface[i+1]); + assert(newface[i] != newface[i+2]); + assert(newface[i+1] != newface[i+2]); } return error; @@ -243,6 +201,8 @@ float Cluster(MyMesh &mesh, unsigned int target_faces) { part.SetBox(box); part.Init(); + cerr << "inited points\n"; + vector centroid; vector count; for(unsigned int i = 0; i < 3; i++) { @@ -266,12 +226,16 @@ float Cluster(MyMesh &mesh, unsigned int target_faces) { mesh.vert[remap[i]].P() = part[i].p; } + cerr << "remapping faces\n"; + float error = 0; //rimappiamo le facce..... for(unsigned int i = 0; i < mesh.face.size(); i++) { MyFace &face = mesh.face[i]; for(int k = 0; k < 3; k++) { unsigned int target = part.Locate(face.V(k)->cP()); + assert(target < remap.size()); + assert(remap[target] < mesh.vert.size()); MyVertex &vert = mesh.vert[remap[target]]; float dist = Distance(vert.cP(), face.V(k)->cP()); @@ -281,6 +245,7 @@ float Cluster(MyMesh &mesh, unsigned int target_faces) { } } + cerr << "Deleting faces\n"; for(unsigned int i = 0; i < mesh.face.size(); i++) { MyFace &face = mesh.face[i]; assert(!face.IsD()); @@ -294,6 +259,8 @@ float Cluster(MyMesh &mesh, unsigned int target_faces) { mesh.fn--; } } + + cerr << "deleting vertices\n"; for(unsigned int i = 0; i < mesh.vert.size(); i++) if(!mesh.vert[i].IsV() && mesh.vert[i].IsW()) { diff --git a/apps/nexus/nexus.cpp b/apps/nexus/nexus.cpp index 5b33ffb0..be9fb36b 100644 --- a/apps/nexus/nexus.cpp +++ b/apps/nexus/nexus.cpp @@ -185,7 +185,6 @@ void Nexus::Join(const std::set &patches, Nexus::Entry &entry = index[patch]; fcount += entry.nface; - // assert(fcount < 0xffff); for(unsigned int k = 0; k < entry.nvert; k++) { if(vmap[k] == 0xffffffff) { //first time vmap[k] = vcount++; @@ -224,57 +223,45 @@ void Nexus::Join(const std::set &patches, fcount = 0; for(i = patches.begin(); i != patches.end(); i++) { Patch patch = GetPatch(*i); - // Border border = GetBorder(*i); vector &vmap = remap[*i]; - + for(unsigned int i = 0; i < patch.nv; i++) { assert(vmap[i] < vcount); newvert[vmap[i]] = patch.Vert(i); } - + for(unsigned int i = 0; i < patch.nf; i++) { - for(int k = 0; k < 3; k++) { - newface[3*fcount + k] = vmap[patch.Face(i)[k]]; + unsigned short *face = patch.Face(i); + if(patch.Vert(face[0]) == patch.Vert(face[1]) || + patch.Vert(face[0]) == patch.Vert(face[2]) || + patch.Vert(face[1]) == patch.Vert(face[2])) { + cerr << "MALEDETTO!" << endl; + Point3f &v0 = patch.Vert(face[0]); + Point3f &v1 = patch.Vert(face[1]); + Point3f &v2 = patch.Vert(face[2]); + cerr << "V0: " << v0[0] << " " << v0[1] << " " << v0[2] << endl; + cerr << "V1: " << v1[0] << " " << v1[1] << " " << v1[2] << endl; + cerr << "V2: " << v2[0] << " " << v2[1] << " " << v2[2] << endl; + } + if(patch.Face(i)[0] == patch.Face(i)[1] || + patch.Face(i)[0] == patch.Face(i)[2] || + patch.Face(i)[1] == patch.Face(i)[2]) { + cerr << "Damn: " << i << endl; + cerr << patch.Face(i)[0] << " " << patch.Face(i)[1] + << patch.Face(i)[2] << endl; } - assert(patch.Face(i)[0] != patch.Face(i)[1]); - assert(patch.Face(i)[0] != patch.Face(i)[2]); - assert(patch.Face(i)[1] != patch.Face(i)[2]); - assert(newface[3*fcount + 0] != newface[3*fcount + 1]); - assert(newface[3*fcount + 0] != newface[3*fcount + 2]); - assert(newface[3*fcount + 1] != newface[3*fcount + 2]); - - fcount++; - assert(fcount *3 <= newface.size()); } - /* for(unsigned int i = 0; i < border.Size(); i++) { - Link link = border[i]; - if(patches.count(link.end_patch)) continue; - link.start_vert = vmap[link.start_vert]; - newbord.push_back(link);*/ - - /* if(remap.count(link.end_patch)) continue; - Link newlink = link; - newlink.start_vert = vmap[link.start_vert]; - newbord[bcount++] = newlink;*/ - // } + for(unsigned int i = 0; i < patch.nf; i++) + for(int k = 0; k < 3; k++) + newface[fcount++] = vmap[patch.Face(i)[k]]; } + assert(fcount == newface.size()); + set::iterator b; for(b = newborders.begin(); b != newborders.end(); b++) newbord.push_back(*b); - /* unsigned int newentry = AddPatch(vcount, fcount, bcount); - Patch newpatch = GetPatch(newentry); - Border newborder = GetBorder(newentry); - - memcpy(newpatch.VertBegin(), &(newvert)[0], - newvert.size() * sizeof(Point3f)); - - memcpy(newpatch.FaceBegin(), &(newface)[0], - newface.size() * sizeof(unsigned short)); - - memcpy(&(newborder[0]), &(newbord[0]), - newbord.size() * sizeof(Link));*/ return; } @@ -283,23 +270,25 @@ void Nexus::Unify(float threshold) { //TODO what if colors or normals or strips? //TODO update totvert unsigned int duplicated = 0; + unsigned int degenerate = 0; + for(unsigned int p = 0; p < index.size(); p++) { Nexus::Entry &entry = index[p]; Patch patch = GetPatch(p); unsigned int vcount = 0; map vertices; + vector remap; remap.resize(patch.nv); - // map remap; + for(unsigned int i = 0; i < patch.nv; i++) { Point3f &point = patch.Vert(i); - if(!vertices.count(point)) { + if(!vertices.count(point)) vertices[point] = vcount++; - } else { + else duplicated++; - } remap[i] = vertices[point]; } @@ -316,17 +305,29 @@ void Nexus::Unify(float threshold) { vector newface; - newface.resize(patch.nf * 3); - for(unsigned int f = 0; f < newface.size(); f++) - newface[f] = remap[patch.FaceBegin()[f]]; + //check no degenerate faces get created. + for(unsigned int f = 0; f < entry.nface; f++) { + unsigned short *face = patch.Face(f); + if(face[0] != face[1] && face[1] != face[2] && face[0] != face[2] && + newvert[remap[face[0]]] != newvert[remap[face[1]]] && + newvert[remap[face[0]]] != newvert[remap[face[2]]] && + newvert[remap[face[1]]] != newvert[remap[face[2]]]) { + newface.push_back(remap[face[0]]); + newface.push_back(remap[face[1]]); + newface.push_back(remap[face[2]]); + } else { + degenerate++; + } + } //rewrite patch now. entry.nvert = newvert.size(); + entry.nface = newface.size()/3; patch.Init(signature, entry.nvert, entry.nface); memcpy(patch.VertBegin(), &(newvert[0]), entry.nvert*sizeof(Point3f)); - memcpy(patch.FaceBegin(), &(newface[0]), entry.nface*3*sizeof(unsigned short)); - + memcpy(patch.FaceBegin(), &(newface[0]), entry.nface*3*sizeof(short)); + //fix patch borders now set close; //bordering pathes Border border = GetBorder(p); @@ -350,8 +351,6 @@ void Nexus::Unify(float threshold) { //finally: there may be duplicated borders for(unsigned int p = 0; p < index.size(); p++) { Border border = GetBorder(p); - //Nexus::Entry &entry = index[p]; - set links; for(unsigned int b = 0; b < border.Size(); b++) { if(border[b].IsNull()) continue; @@ -361,7 +360,10 @@ void Nexus::Unify(float threshold) { links.insert(border[b]); } } + totvert -= duplicated; - // cout << "Found " << duplicated << " duplicated vertices" << endl; - + if(duplicated) + cerr << "Found " << duplicated << " duplicated vertices" << endl; + if(degenerate) + cerr << "Found " << degenerate << " degenerate face while unmifying\n"; } diff --git a/apps/nexus/nexusmt.cpp b/apps/nexus/nexusmt.cpp index 03bbdbbc..d569252d 100644 --- a/apps/nexus/nexusmt.cpp +++ b/apps/nexus/nexusmt.cpp @@ -362,7 +362,6 @@ Patch &NexusMt::LoadPatch(unsigned int p) { if(ram_used > ram_size * 1.5) FlushRam(); - cerr << "Ram: " << ram_used << endl; return *(sgurz.patch); } diff --git a/apps/nexus/nxsbuild.cpp b/apps/nexus/nxsbuild.cpp index a8a0c3c2..312d93ad 100644 --- a/apps/nexus/nxsbuild.cpp +++ b/apps/nexus/nxsbuild.cpp @@ -106,12 +106,11 @@ void nxs::NexusFill(Crude &crude, //TODO an hash_map would be faster? unsigned int count = 0; map remap; + for(unsigned int k = 0; k < patch.nf; k++) { Crude::Face &face = faces[k]; - for(int j = 0; j < 3; j++) { if(!remap.count(face[j])) { - assert(count < patch.nv); Point3f &v = crude.vert[face[j]]; patch.VertBegin()[remap.size()] = v; entry.sphere.Add(v); @@ -119,10 +118,6 @@ void nxs::NexusFill(Crude &crude, } patch.FaceBegin()[k*3 + j] = remap[face[j]]; } - //test for degenerate faces. - assert(patch.FaceBegin()[k*3] != patch.FaceBegin()[k*3+1]); - assert(patch.FaceBegin()[k*3] != patch.FaceBegin()[k*3+2]); - assert(patch.FaceBegin()[k*3+1] != patch.FaceBegin()[k*3+2]); } assert(count == remap.size()); assert(entry.nvert == remap.size()); @@ -157,6 +152,16 @@ void nxs::NexusFill(Crude &crude, //we can now update bounding sphere. for(unsigned int i = 0; i < nexus.index.size(); i++) nexus.sphere.Add(nexus.index[i].sphere); + + //test no duplicated faces: + /* for(unsigned int i = 0; i < nexus.index.size(); i++) { + Patch patch = nexus.GetPatch(i); + for(unsigned int k = 0; k < patch.nf; k++) { + assert(patch.Face(k)[0] != patch.Face(k)[1]); + assert(patch.Face(k)[0] != patch.Face(k)[2]); + assert(patch.Face(k)[1] != patch.Face(k)[2]); + } + }*/ } void nxs::NexusFixBorder(Nexus &nexus, @@ -194,19 +199,19 @@ void nxs::NexusFixBorder(Nexus &nexus, for(unsigned int j = 0; j < remote.border_used; j++) { RemapLink end_link = border_remap[j + remote_remap_start]; - assert(end_link.rel_vert < remote.nvert); + // assert(end_link.rel_vert < remote.nvert); if(start_link.abs_vert == end_link.abs_vert && end_link.patch == i) { //found the match - assert(!found); + // assert(!found); nexus.borders[k + local.border_start] = Link(start_link.rel_vert, end_link.rel_vert, start_link.patch); found = true; } } - assert(nexus.borders[k + local.border_start].start_vert < local.nvert); - assert(found); + // assert(nexus.borders[k + local.border_start].start_vert < local.nvert); + // assert(found); } } nexus.borders.Flush(); diff --git a/apps/nexus/voronoinxs.cpp b/apps/nexus/voronoinxs.cpp index 0f01cda1..711ef833 100644 --- a/apps/nexus/voronoinxs.cpp +++ b/apps/nexus/voronoinxs.cpp @@ -24,6 +24,9 @@ History $Log: not supported by cvs2svn $ +Revision 1.7 2004/10/04 16:49:54 ponchio +Daily backup. Preparing for compression. + Revision 1.6 2004/10/01 16:54:57 ponchio Daily backup. @@ -282,7 +285,6 @@ int main(int argc, char *argv[]) { nexus.Join((*fragment).second, newvert, newface, newbord); - //simplyfy mesh vector vert_remap; float error = Decimate(decimation, @@ -319,17 +321,6 @@ int main(int argc, char *argv[]) { } nexus.history.push_back(update); ReverseHistory(nexus.history); - //debug: - /* for(unsigned int i = 0; i < nexus.history.size(); i++) { - Nexus::Update &update = nexus.history[i]; - cerr << "created:"; - for(unsigned int c = 0; c < update.created.size(); c++) - cerr << " " << update.created[c]; - cerr << "\nerased:"; - for(unsigned int c = 0; c < update.erased.size(); c++) - cerr << " " << update.erased[c]; - cerr << "\n\n"; - }*/ //Clean up: nexus.Close(); @@ -338,203 +329,6 @@ int main(int argc, char *argv[]) { return 0; } -/*void RemapVertices(Crude &crude, - VertRemap &vert_remap, - VFile &face_remap, - vector &patch_verts) { - - for(unsigned int i = 0; i < crude.Faces(); i++) { - Crude::Face &face = crude.GetFace(i); - unsigned int patch = face_remap[i]; - for(int k = 0; k < 3; k++) { - set pp; - vert_remap.GetValues(face[k], pp); - if(!pp.count(patch)) { - vert_remap.Insert(face[k], patch); - patch_verts[patch]++; - } - } - } - }*/ - -/*void NexusAllocate(Crude &crude, - Nexus &nexus, - VFile &face_remap, - vector &patch_faces, - vector &patch_verts) { - - - nexus.index.resize(patch_faces.size()); - - unsigned int totchunks = 0; - //now that we know various sizes, lets allocate space - for(unsigned int i = 0; i < nexus.index.size(); i++) { - Nexus::Entry &entry = nexus.index[i]; - - if(patch_faces[i] == 0 || patch_verts[i] == 0) - cerr << "Warning! Empty patch.\n"; - - entry.patch_start = totchunks; - entry.patch_size = Patch::ChunkSize(nexus.signature, - patch_verts[i], patch_faces[i]); - - totchunks += entry.patch_size; - entry.border_start = 0xffffffff; - entry.nvert = patch_verts[i]; - entry.nface = 0; - entry.error = 0; - } - - nexus.patches.Resize(totchunks); - - - //now we sort the faces into the patches (but still using absolute indexing - //instead of relative indexing - for(unsigned int i = 0; i < crude.face.Size(); i++) { - Crude::Face &face = crude.face[i]; - unsigned int npatch = face_remap[i]; - - Nexus::Entry &entry = nexus.index[npatch]; - - //TODO this is slow because we have to initialize patch. - //just get patch.start. - Patch patch = nexus.GetPatch(npatch); - - Crude::Face *faces = (Crude::Face *)patch.start; - faces[entry.nface] = face; - entry.nface++; - } - }*/ - - -/*void NexusFill(Crude &crude, - Nexus &nexus, - VertRemap &vert_remap, - VFile &border_remap) { - - - //finally for every patch we collect the vertices - //and fill the patch. - //we need to remember start and size in border_remap; - // vector border_start; - // vector border_size; - - for(unsigned int i = 0; i < nexus.index.size(); i++) { - Patch patch = nexus.GetPatch(i); - Nexus::Entry &entry = nexus.index[i]; - - //make a copy of faces (we need to write there :P) - Crude::Face *faces = new Crude::Face[patch.nf]; - memcpy(faces, (Crude::Face *)patch.start, - patch.nf * sizeof(Crude::Face)); - - //collect all vertices we need. - //TODO an hash_map would be faster? - unsigned int count = 0; - map remap; - for(unsigned int k = 0; k < patch.nf; k++) { - Crude::Face &face = faces[k]; - - for(int j = 0; j < 3; j++) { - if(!remap.count(face[j])) { - assert(count < patch.nv); - Point3f &v = crude.vert[face[j]]; - patch.VertBegin()[remap.size()] = v; - entry.sphere.Add(v); - remap[face[j]] = count++; - } - patch.FaceBegin()[k*3 + j] = remap[face[j]]; - } - } - assert(count == remap.size()); - assert(entry.nvert == remap.size()); - - //record start of border: - entry.border_start = border_remap.Size(); - - //TODO hash_set? - set border_patches; - map::iterator m; - for(m = remap.begin(); m != remap.end(); m++) { - RemapLink link; - link.abs_vert = (*m).first; - link.rel_vert = (*m).second; - - vert_remap.GetValues(link.abs_vert, border_patches); - assert(border_patches.size() >= 1); - if(border_patches.size() == 1) continue; //its not a border - - set::iterator s; - for(s = border_patches.begin(); s != border_patches.end(); s++) { - if((*s) == i) continue; - link.patch = *s; - border_remap.PushBack(link); - } - } - //and number of borders: - entry.border_used = border_remap.Size() - entry.border_start; - delete []faces; - } - - //we can now update bounding sphere. - for(unsigned int i = 0; i < nexus.index.size(); i++) - nexus.sphere.Add(nexus.index[i].sphere); - }*/ - -/*void NexusFixBorder(Nexus &nexus, - VFile &border_remap) { - - //and last convert RemapLinks into Links - nexus.borders.Resize(border_remap.Size() * 2); - //* 2 is to accomodate future borders - - for(unsigned int i = 0; i < nexus.index.size(); i++) { - Nexus::Entry &local = nexus.index[i]; - local.border_start *= 2; - local.border_size = local.border_used * 2; - } - - for(unsigned int i = 0; i < nexus.index.size(); i++) { - Nexus::Entry &local = nexus.index[i]; - - unsigned int remap_start = local.border_start/2; - //* 2 is to accomodate future borders - - - // K is the main iterator (where we write to in nexus.borders) - for(unsigned int k = 0; k < local.border_used; k++) { - - - RemapLink start_link = border_remap[k + remap_start]; - assert(start_link.rel_vert < local.nvert); - - Nexus::Entry &remote = nexus.index[start_link.patch]; - - bool found = false; - - unsigned int remote_remap_start = remote.border_start/2; - for(unsigned int j = 0; j < remote.border_used; j++) { - - RemapLink end_link = border_remap[j + remote_remap_start]; - assert(end_link.rel_vert < remote.nvert); - - if(start_link.abs_vert == end_link.abs_vert && - end_link.patch == i) { //found the match - assert(!found); - nexus.borders[k + local.border_start] = Link(start_link.rel_vert, - end_link.rel_vert, - start_link.patch); - found = true; - } - } - assert(nexus.borders[k + local.border_start].start_vert < local.nvert); - assert(found); - } - } - nexus.borders.Flush(); -} */ - - void NexusSplit(Nexus &nexus, VoronoiChain &vchain, unsigned int level, vector &newvert,