#include "fragment.h" #include "border.h" #include "pvoronoi.h" #include using namespace std; using namespace vcg; using namespace nxs; using namespace pt; void NxsPatch::write(outstm *out) { int vsize = vert.size(); int fsize = face.size(); int bsize = bord.size(); out->write(&patch, sizeof(unsigned int)); out->write(&vsize, sizeof(unsigned int)); out->write(&fsize, sizeof(unsigned int)); out->write(&bsize, sizeof(unsigned int)); out->write(&*vert.begin(), vert.size() * sizeof(Point3f)); out->write(&*face.begin(), face.size() * sizeof(unsigned short)); out->write(&*bord.begin(), bord.size() * sizeof(Link)); } void NxsPatch::read(instm *in) { int vsize; int fsize; int bsize; in->read(&patch, sizeof(unsigned int)); in->read(&vsize, sizeof(unsigned int)); in->read(&fsize, sizeof(unsigned int)); in->read(&bsize, sizeof(unsigned int)); vert.resize(vsize); face.resize(fsize); bord.resize(bsize); in->read(&*vert.begin(), vert.size() * sizeof(Point3f)); in->read(&*face.begin(), face.size() * sizeof(unsigned short)); in->read(&*bord.begin(), bord.size() * sizeof(Link)); } void Fragment::write(outstm *out) { out->write(&id, sizeof(unsigned int)); out->write(&error, sizeof(float)); unsigned int esize = update.erased.size(); unsigned int csize = update.created.size(); out->write(&esize, sizeof(unsigned int)); out->write(&csize, sizeof(unsigned int)); out->write(&*update.erased.begin(), esize * sizeof(unsigned int)); out->write(&*update.created.begin(), csize * sizeof(unsigned int)); unsigned int psize = pieces.size(); out->write(&psize, sizeof(unsigned int)); for(unsigned int i = 0; i < pieces.size(); i++) pieces[i].write(out); } void Fragment::read(instm *in) { in->read(&id, sizeof(unsigned int)); in->read(&error, sizeof(float)); unsigned int esize; unsigned int csize; in->read(&esize, sizeof(unsigned int)); in->read(&csize, sizeof(unsigned int)); update.erased.resize(esize); update.created.resize(csize); in->read(&*update.erased.begin(), esize * sizeof(unsigned int)); in->read(&*update.created.begin(), csize * sizeof(unsigned int)); unsigned int psize; in->read(&psize, sizeof(unsigned int)); pieces.resize(psize); for(unsigned int i = 0; i < psize; i++) pieces[i].read(in); } void nxs::join(Fragment &in, vector &newvert, vector &newface, vector &newbord) { map patch_remap; vector offsets; unsigned int totvert = 0; for(unsigned int i = 0; i < in.pieces.size(); i++) { offsets.push_back(totvert); patch_remap[in.pieces[i].patch] = i; totvert += in.pieces[i].vert.size(); } vector remap; remap.resize(totvert, 0xffffffff); //TODO what if totvert > 32768? //todo we really need a set? // set newborders; unsigned int vcount = 0; unsigned int fcount = 0; unsigned int bcount = 0; for(unsigned int i = 0; i < in.pieces.size(); i++) { unsigned int offset = offsets[i]; vector &vert = in.pieces[i].vert; vector &face = in.pieces[i].face; vector &bord = in.pieces[i].bord; fcount += face.size()/3; for(unsigned int k = 0; k < vert.size(); k++) { assert(offset + k < remap.size()); if(remap[offset + k] == 0xffffffff) remap[offset + k] = vcount++; } for(unsigned int k = 0; k < bord.size(); k++) { Link link = bord[k]; if(link.IsNull()) continue; if(patch_remap.count(link.end_patch)) {//internal unsigned int idx = patch_remap[link.end_patch]; unsigned int extoffset = offsets[idx]; assert(extoffset + link.end_vert < remap.size()); if(remap[extoffset + link.end_vert] == 0xffffffff) //first time remap[extoffset + link.end_vert] = remap[offset + link.start_vert]; } } /* assert(link.start_vert < remap.size()); assert(remap[offset + link.start_vert] != 0xffffffff); if(!patch_remap.count(link.end_patch)) { //external //test if erased in history... in wich case we do not add border // if(!erased.count(link.end_patch)) { ?/???? link.start_vert = remap[offset + link.start_vert]; newborders.insert(link); } else { //internal //TODO unsigned int &rmpv = remap[link.end_patch][link.end_vert]; unsigned int idx = patch_remap[link.end_patch]; unsigned int extoffset = offsets[idx]; if(extoffset + link.end_vert >= remap.size()) { cerr << "extoffset: " << extoffset << endl; cerr << "end_V: " << link.end_vert << endl; cerr << "remsz: " << remap.size() << endl; for(unsigned int i = 0; i < in.pieces.size(); i++) cerr << "size: " << i << " =" << in.pieces[i].vert.size() << endl; } assert(extoffset + link.end_vert < remap.size()); if(remap[extoffset + link.end_vert] == 0xffffffff) //first time remap[extoffset + link.end_vert] = remap[offset + link.start_vert]; } }*/ } //L(a, b): Exist link between a, b //An external link L(e, v) where v belongs to the patches (and e not) //is valid only if: for every x in patches L(v, x) => L(e, x) //this means the number of internal links for the same shared //vertex is E = (n * (n-1)) where n is the number of duplicated vertices //and n must be the number of externa links. vector internal_links; internal_links.resize(vcount, 0); map newborders; for(unsigned int i = 0; i < in.pieces.size(); i++) { unsigned int offset = offsets[i]; vector &bord = in.pieces[i].bord; for(unsigned int k = 0; k < bord.size(); k++) { Link link = bord[k]; if(link.IsNull()) continue; if(!patch_remap.count(link.end_patch)) {//external...may be erased though link.start_vert = remap[offset + link.start_vert]; if(!newborders.count(link)) newborders[link] = 1; else newborders[link]++; } else { //internal internal_links[remap[offset + link.start_vert]]++; } } } newvert.resize(vcount); newface.resize(fcount*3); newbord.resize(0); fcount = 0; for(unsigned int i = 0; i < in.pieces.size(); i++) { unsigned int offset = offsets[i]; vector &vert = in.pieces[i].vert; vector &face = in.pieces[i].face; vector &bord = in.pieces[i].bord; for(unsigned int i = 0; i < vert.size(); i++) { assert(offset + i < remap.size()); assert(remap[offset + i] < vcount); newvert[remap[offset + i]] = vert[i]; } for(unsigned int i = 0; i < face.size(); i++) { assert(offset + face[i] < remap.size()); assert(remap[offset + face[i]] < newvert.size()); assert(fcount < newface.size()); newface[fcount++] = remap[offset + face[i]]; } } map::iterator b; for(b = newborders.begin(); b != newborders.end(); b++) { //test that number of links on this vertex is equal to //number of internal links of the internal vertex const Link &link = (*b).first; unsigned int n = (*b).second; if(n * (n-1) == internal_links[link.start_vert]) newbord.push_back(link); } } void nxs::split(Fragment &out, vector &newvert, vector &newface, vector &newbord, VoronoiPartition &part) { }