From bb0cd9ff64fabd866795054c9c18001f737b1e9d Mon Sep 17 00:00:00 2001 From: ponchio Date: Tue, 19 Oct 2004 01:19:46 +0000 Subject: [PATCH] First draft --- apps/nexus/fragment.cpp | 233 ++++++++++++++++++++++++++++++++++++++++ apps/nexus/fragment.h | 48 +++++++++ 2 files changed, 281 insertions(+) create mode 100644 apps/nexus/fragment.cpp create mode 100644 apps/nexus/fragment.h diff --git a/apps/nexus/fragment.cpp b/apps/nexus/fragment.cpp new file mode 100644 index 00000000..9970f091 --- /dev/null +++ b/apps/nexus/fragment.cpp @@ -0,0 +1,233 @@ +#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? + cerr << "Totvert " << totvert << endl; + //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) { + +} + diff --git a/apps/nexus/fragment.h b/apps/nexus/fragment.h new file mode 100644 index 00000000..fc529745 --- /dev/null +++ b/apps/nexus/fragment.h @@ -0,0 +1,48 @@ +#ifndef NXS_FRAGMENT_H +#define NXS_FRAGMENT_H + +#include + +#include +#include "nexus.h" + +namespace nxs { + +class VoronoiPartition; + +class NxsPatch { + public: + unsigned int patch; + std::vector vert; + std::vector face; + std::vector bord; + + void write(pt::outstm *out); + void read(pt::instm *in); +}; + +class Fragment { + public: + unsigned int id; + + float error; + Nexus::Update update; + std::vector pieces; + + void write(pt::outstm *out); + void read(pt::instm *in); +}; + + void join(Fragment &in, + std::vector &newvert, + std::vector &newface, + std::vector &newbord); + + void split(Fragment &out, + std::vector &newvert, + std::vector &newface, + std::vector &newbord, + VoronoiPartition &part); +} + +#endif