vcglib/apps/nexus/fragment.cpp

233 lines
7.2 KiB
C++

#include "fragment.h"
#include "border.h"
#include "pvoronoi.h"
#include <iostream>
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<Point3f> &newvert,
vector<unsigned int> &newface,
vector<Link> &newbord) {
map<unsigned int, unsigned int> patch_remap;
vector<unsigned int> 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<unsigned int> remap;
remap.resize(totvert, 0xffffffff);
//TODO what if totvert > 32768?
//todo we really need a set?
// set<Link> 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<Point3f> &vert = in.pieces[i].vert;
vector<unsigned short> &face = in.pieces[i].face;
vector<Link> &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<unsigned int> internal_links;
internal_links.resize(vcount, 0);
map<Link, unsigned int> newborders;
for(unsigned int i = 0; i < in.pieces.size(); i++) {
unsigned int offset = offsets[i];
vector<Link> &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<Point3f> &vert = in.pieces[i].vert;
vector<unsigned short> &face = in.pieces[i].face;
vector<Link> &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<Link, unsigned int>::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<Point3f> &newvert,
vector<unsigned int> &newface,
vector<Link> &newbord,
VoronoiPartition &part) {
}