diff --git a/apps/nexus/nexus.cpp b/apps/nexus/nexus.cpp index a13364b5..000c16ec 100644 --- a/apps/nexus/nexus.cpp +++ b/apps/nexus/nexus.cpp @@ -28,8 +28,8 @@ bool Nexus::Create(const string &file) { cerr << "Could not create file: " << file << ".nxp" << endl; return false; } - if(!borders.Create(file + ".nxb")) { - cerr << "Could not create file: " << file << ".nxp" << endl; + if(!borders.Create(file + ".nxb", 1)) { + cerr << "Could not create file: " << file << ".nxb" << endl; return false; } return true; @@ -59,8 +59,8 @@ bool Nexus::Load(const string &file) { readed = fread(&index[0], sizeof(Entry), size, index_file); if(readed != size) return false; - if(!patches.Load(file + ".nxp")) return false; - if(!borders.Load(file + ".nxb")) return false; + if(!patches.Load(file + ".nxp", 1)) return false; + if(!borders.Load(file + ".nxb", 1)) return false; return true; } @@ -84,6 +84,114 @@ void Nexus::Close() { Patch Nexus::GetPatch(unsigned int patch) { Entry &entry = index[patch]; - Chunk *start = patches.GetRegion(entry.patch_offset, entry.patch_size); - return Patch(start); + Chunk *start = patches.GetRegion(entry.patch_start, entry.patch_size); + return Patch(start, entry.nvert, entry.nface); +} + +Border Nexus::GetBorder(unsigned int patch) { + Entry &entry = index[patch]; + Link *start = borders.GetRegion(entry.border_start, entry.border_size); + return Border(start, entry.border_size); +} + + +unsigned int Nexus::AddPatch(unsigned int nvert, unsigned int nface, + unsigned int nbord) { + Entry entry; + entry.patch_start = patches.Size(); + entry.patch_size = Patch::ChunkSize(nvert, nface); + entry.border_start = borders.Size(); + entry.border_size = nbord; + entry.nvert = nvert; + entry.nface = nface; + + patches.Resize(patches.Size() + entry.patch_size); + borders.Resize(borders.Size() + nbord); + index.push_back(entry); + return index.size() -1; +} + +void Nexus::Join(std::vector &patches, + std::vector &newface, + std::vector &newlinks) { + + map > remap; + + vector::iterator i; + for(i = patches.begin(); i != patches.end(); i++) { + unsigned int patch = *i; + Nexus::Entry &entry = index[patch]; + remap[*i].resize(entry.nvert, 0xffffffff); + } + unsigned int vcount = 0; + unsigned int fcount = 0; + unsigned int bcount = 0; + for(i = patches.begin(); i != patches.end(); i++) { + unsigned int patch = *i; + Nexus::Entry &entry = index[patch]; + fcount += entry.nface; + assert(fcount < 0xffff); + for(unsigned int k = 0; k < entry.nvert; k++) { + if(remap[patch][k] == 0xffffffff) { //first time + remap[patch][k] = vcount++; + } + } + + Border border = GetBorder(patch); + for(unsigned int k = 0; k < border.Size(); k++) { + Link &link = border[k]; + if(!remap.count(link.end_patch)) { + bcount++; + continue; + } + if(remap[link.end_patch][link.end_vert] == 0xffffffff) { //first time + remap[link.end_patch][link.end_vert] = remap[patch][link.start_vert]; + } + } + } + + + + newvert.resize(vcount); + newface.resize(fcount*3); + newbord.resize(bcount); + + fcount = 0; + bcount = 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.VertSize(); i++) + newvert[vmap[i]] = patch.Vert(i); + + for(unsigned int i = 0; i < patch.FaceSize(); i++) { + for(int k = 0; k < 3; k++) { + newface[3*fcount + k] = vmap[patch.Face(i)[k]]; + } + fcount++; + } + for(unsigned int i = 0; i < border.Size(); i++) { + Link &link = border[i]; + if(remap.count(link.end_patch)) continue; + Link newlink = link; + newlink.start_vert = vmap[link.start_vert]; + newbord[bcount++] = newlink; + } + } + 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 newentry; } diff --git a/apps/nexus/nexus.h b/apps/nexus/nexus.h index 16ea789d..495d81c9 100644 --- a/apps/nexus/nexus.h +++ b/apps/nexus/nexus.h @@ -17,12 +17,16 @@ class Nexus { class Entry { public: - Entry(): patch_offset(0xffffffff), border_offset(0xffffffff), - patch_size(0), border_size(0), sphere(vcg::Sphere3f()) {} - unsigned int patch_offset; //granularita' Chunk - unsigned int border_offset; //granuralita' Link + Entry(): patch_start(0xffffffff), border_start(0xffffffff), + patch_size(0), border_size(0), + nvert(0), nface(0), sphere(vcg::Sphere3f()) {} + unsigned int patch_start; //granularita' Chunk + unsigned int border_start; //granuralita' Link unsigned short patch_size; //in cuhnks unsigned short border_size; //in Links + + unsigned short nvert; + unsigned short nface; vcg::Sphere3f sphere; }; @@ -33,10 +37,21 @@ class Nexus { void Close(); Patch GetPatch(unsigned int patch); - void GetBorder(unsigned int border, Border &border); + Border GetBorder(unsigned int patch); - // unsigned int addPatch(Patch *builder); - void AddBorder(unsigned int patch, std::vector &links); + unsigned int AddPatch(unsigned int nvert, unsigned int nface, + unsigned int nbord); + + // unsigned int Join(std::vector &patches); + void Join(std::vector &patches, + std::vector &faces, + std::vector &links); + + //TODO implement theese + void CompactBorder(unsigned int patch); + void CompactBorders(); + void CompactPatches(); unsigned int totvert; unsigned int totface; @@ -46,9 +61,10 @@ class Nexus { std::vector index; - FILE *index_file; VFile patches; VFile borders; + private: + FILE *index_file; }; }