added split.
This commit is contained in:
parent
2bfda63cc5
commit
d23e12f0a3
|
@ -8,7 +8,7 @@ using namespace vcg;
|
|||
using namespace nxs;
|
||||
using namespace pt;
|
||||
|
||||
void NxsPatch::write(outstm *out) {
|
||||
void NxsPatch::Write(outstm *out) {
|
||||
int vsize = vert.size();
|
||||
int fsize = face.size();
|
||||
int bsize = bord.size();
|
||||
|
@ -23,7 +23,7 @@ void NxsPatch::write(outstm *out) {
|
|||
out->write(&*bord.begin(), bord.size() * sizeof(Link));
|
||||
}
|
||||
|
||||
void NxsPatch::read(instm *in) {
|
||||
void NxsPatch::Read(instm *in) {
|
||||
int vsize;
|
||||
int fsize;
|
||||
int bsize;
|
||||
|
@ -40,50 +40,47 @@ void NxsPatch::read(instm *in) {
|
|||
in->read(&*bord.begin(), bord.size() * sizeof(Link));
|
||||
}
|
||||
|
||||
void Fragment::write(outstm *out) {
|
||||
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 ssize = seeds.size();
|
||||
out->write(&ssize, sizeof(unsigned int));
|
||||
|
||||
out->write(&*seeds.begin(), ssize * sizeof(Seed));
|
||||
out->write(&*seeds_id.begin(), ssize * 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);
|
||||
pieces[i].Write(out);
|
||||
}
|
||||
|
||||
void Fragment::read(instm *in) {
|
||||
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 ssize;
|
||||
in->read(&ssize, sizeof(unsigned int));
|
||||
seeds.resize(ssize);
|
||||
seeds_id.resize(ssize);
|
||||
in->read(&*seeds.begin(), ssize * sizeof(Seed));
|
||||
in->read(&*seeds_id.begin(), ssize * 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);
|
||||
pieces[i].Read(in);
|
||||
}
|
||||
|
||||
void nxs::join(Fragment &in,
|
||||
void nxs::Join(Fragment &in,
|
||||
vector<Point3f> &newvert,
|
||||
vector<unsigned int> &newface,
|
||||
vector<Link> &newbord) {
|
||||
vector<BigLink> &newbord) {
|
||||
|
||||
map<unsigned int, unsigned int> patch_remap;
|
||||
vector<unsigned int> offsets;
|
||||
|
@ -98,7 +95,7 @@ void nxs::join(Fragment &in,
|
|||
vector<unsigned int> remap;
|
||||
remap.resize(totvert, 0xffffffff);
|
||||
|
||||
//TODO what if totvert > 32768?
|
||||
//TODO what if totvert > 1<<22?
|
||||
//todo we really need a set?
|
||||
// set<Link> newborders;
|
||||
unsigned int vcount = 0;
|
||||
|
@ -132,31 +129,8 @@ void nxs::join(Fragment &in,
|
|||
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];
|
||||
}
|
||||
}*/
|
||||
}
|
||||
assert(vcount < (1<<16));
|
||||
|
||||
//L(a, b): Exist link between a, b
|
||||
//An external link L(e, v) where v belongs to the patches (and e not)
|
||||
|
@ -167,21 +141,24 @@ void nxs::join(Fragment &in,
|
|||
vector<unsigned int> internal_links;
|
||||
internal_links.resize(vcount, 0);
|
||||
|
||||
map<Link, unsigned int> newborders;
|
||||
map<BigLink, 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];
|
||||
Link llink = bord[k];
|
||||
if(llink.IsNull()) continue;
|
||||
if(!patch_remap.count(llink.end_patch)) {//external...may be erased though
|
||||
BigLink link;
|
||||
link.start_vert = remap[offset + llink.start_vert];
|
||||
link.end_patch = llink.end_patch;
|
||||
link.end_vert = llink.end_vert;
|
||||
if(!newborders.count(link))
|
||||
newborders[link] = 1;
|
||||
else
|
||||
newborders[link]++;
|
||||
} else { //internal
|
||||
internal_links[remap[offset + link.start_vert]]++;
|
||||
internal_links[remap[offset + llink.start_vert]]++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -211,22 +188,170 @@ void nxs::join(Fragment &in,
|
|||
}
|
||||
}
|
||||
|
||||
map<Link, unsigned int>::iterator b;
|
||||
map<BigLink, 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;
|
||||
const BigLink &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,
|
||||
void nxs::Split(Fragment &out,
|
||||
vector<Point3f> &newvert,
|
||||
vector<unsigned int> &newface,
|
||||
vector<Link> &newbord,
|
||||
vector<BigLink> &newbord,
|
||||
VoronoiPartition &part) {
|
||||
|
||||
unsigned int nseeds = out.seeds.size();
|
||||
vector<Seed> &seeds = out.seeds;
|
||||
vector<unsigned int> &seeds_id = out.seeds_id;
|
||||
//preliminary count
|
||||
vector<unsigned int> count;
|
||||
count.resize(nseeds, 0);
|
||||
for(unsigned int f = 0; f < newface.size(); f += 3) {
|
||||
Point3f bari = (newvert[newface[f]] +
|
||||
newvert[newface[f+1]] +
|
||||
newvert[newface[f+2]])/3;
|
||||
unsigned int seed = out.Locate(bari);
|
||||
assert(seed < nseeds);
|
||||
count[seed]++;
|
||||
}
|
||||
|
||||
//pruning small patches
|
||||
float min_size = (newface.size()/3) / 20.0f;
|
||||
vector<Seed> newseeds;
|
||||
vector<unsigned int> newseeds_id;
|
||||
|
||||
for(unsigned int seed = 0; seed < nseeds; seed++) {
|
||||
if(count[seed] > min_size) {
|
||||
newseeds.push_back(seeds[seed]);
|
||||
newseeds_id.push_back(seeds_id[seed]);
|
||||
}
|
||||
if(count[seed] > (1<<16)) {
|
||||
cerr << "Ooops a cell came too big... quitting\n";
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
seeds = newseeds;
|
||||
seeds_id = newseeds_id;
|
||||
|
||||
nseeds = seeds.size();
|
||||
|
||||
//if != -1 remap global index to cell index (first arg)
|
||||
vector< vector<int> > vert_remap;
|
||||
vector< vector<int> > face_remap;
|
||||
|
||||
vector<int> vert_count;
|
||||
vector<int> face_count;
|
||||
|
||||
vert_remap.resize(nseeds);
|
||||
face_remap.resize(nseeds);
|
||||
vert_count.resize(nseeds, 0);
|
||||
face_count.resize(nseeds, 0);
|
||||
|
||||
for(unsigned int seed = 0; seed < nseeds; seed++)
|
||||
vert_remap[seed].resize(newvert.size(), -1);
|
||||
|
||||
for(unsigned int f = 0; f < newface.size(); f += 3) {
|
||||
Point3f bari = (newvert[newface[f]] +
|
||||
newvert[newface[f+1]] +
|
||||
newvert[newface[f+2]])/3;
|
||||
|
||||
unsigned int seed = out.Locate(bari);
|
||||
|
||||
vector<int> &f_remap = face_remap[seed];
|
||||
|
||||
f_remap.push_back(newface[f]);
|
||||
f_remap.push_back(newface[f+1]);
|
||||
f_remap.push_back(newface[f+2]);
|
||||
face_count[seed]++;
|
||||
|
||||
|
||||
vector<int> &v_remap = vert_remap[seed];
|
||||
|
||||
for(int i = 0; i < 3; i++)
|
||||
if(v_remap[newface[f+i]] == -1)
|
||||
v_remap[newface[f+i]] = vert_count[seed]++;
|
||||
}
|
||||
|
||||
//TODO assure no big ones.
|
||||
|
||||
out.pieces.resize(nseeds);
|
||||
|
||||
for(unsigned int seed = 0; seed != nseeds; seed++) {
|
||||
NxsPatch &patch = out.pieces[seed];
|
||||
patch.patch = seeds_id[seed];
|
||||
|
||||
//vertices first
|
||||
vector<int> &v_remap = vert_remap[seed];
|
||||
|
||||
assert(vert_count[seed] > 0);
|
||||
vector<Point3f> &verts = patch.vert;
|
||||
verts.resize(vert_count[seed]);
|
||||
for(unsigned int i = 0; i < newvert.size(); i++) {
|
||||
if(v_remap[i] != -1)
|
||||
verts[v_remap[i]] = newvert[i];
|
||||
}
|
||||
|
||||
//faces now
|
||||
vector<int> &f_remap = face_remap[seed];
|
||||
|
||||
vector<unsigned short> &faces = patch.face;
|
||||
faces.resize(face_count[seed]*3);
|
||||
for(unsigned int i = 0; i < f_remap.size(); i++) {
|
||||
assert(v_remap[f_remap[i]] != -1);
|
||||
faces[i] = v_remap[f_remap[i]];
|
||||
}
|
||||
|
||||
//borders last
|
||||
vector<Link> &bords = patch.bord;
|
||||
|
||||
//process external borders
|
||||
//for every esternal link we must update external patches!
|
||||
for(unsigned int i = 0; i < newbord.size(); i++) {
|
||||
BigLink link = newbord[i];
|
||||
if(v_remap[link.start_vert] == -1) continue;
|
||||
link.start_vert = v_remap[link.start_vert];
|
||||
assert(link.start_vert < (1<<16));
|
||||
Link llink;
|
||||
llink.start_vert = link.start_vert;
|
||||
llink.end_patch = link.end_patch;
|
||||
llink.end_vert = link.end_vert;
|
||||
bords.push_back(llink);
|
||||
}
|
||||
|
||||
//process internal borders;
|
||||
//TODO higly inefficient!!!
|
||||
for(unsigned int rseed = 0; rseed < nseeds; rseed++) {
|
||||
if(seed == rseed) continue;
|
||||
|
||||
vector<int> &vremapclose = vert_remap[rseed];
|
||||
for(unsigned int i = 0; i < newvert.size(); i++) {
|
||||
if(v_remap[i] != -1 && vremapclose[i] != -1) {
|
||||
Link link;
|
||||
link.end_patch = rseed + (1<<31);
|
||||
link.start_vert = v_remap[i];
|
||||
link.end_vert = vremapclose[i];
|
||||
bords.push_back(link);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int Fragment::Locate(const Point3f &p) {
|
||||
float max_dist = 1e20;
|
||||
unsigned int id = 0xffffffff;
|
||||
for(unsigned int i = 0; i < seeds.size(); i++) {
|
||||
float dist = seeds[i].Dist(p);
|
||||
if(dist < max_dist) {
|
||||
max_dist = dist;
|
||||
id = i;
|
||||
}
|
||||
}
|
||||
assert(id != 0xffffffff);
|
||||
return id;
|
||||
}
|
||||
|
||||
|
|
|
@ -5,20 +5,40 @@
|
|||
|
||||
#include <ptypes/pstreams.h>
|
||||
#include "nexus.h"
|
||||
#include "pvoronoi.h"
|
||||
|
||||
namespace nxs {
|
||||
|
||||
class VoronoiPartition;
|
||||
|
||||
struct BigLink {
|
||||
unsigned int start_vert;
|
||||
unsigned int end_patch;
|
||||
unsigned int end_vert;
|
||||
bool operator<(const BigLink &l) const {
|
||||
if(end_patch == l.end_patch) {
|
||||
if(start_vert == l.start_vert) {
|
||||
return end_vert < l.end_vert;
|
||||
} else
|
||||
return start_vert < l.start_vert;
|
||||
} else
|
||||
return end_patch < l.end_patch;
|
||||
}
|
||||
};
|
||||
|
||||
class NxsPatch {
|
||||
public:
|
||||
//this fields is the patch number in the infragment
|
||||
//and the seeds id in the outfragment
|
||||
unsigned int patch;
|
||||
std::vector<vcg::Point3f> vert;
|
||||
std::vector<unsigned short> face;
|
||||
//when this is an outfragment link.end_patch is (1<<31) + end_patch
|
||||
//when it is an internal border!
|
||||
std::vector<Link> bord;
|
||||
|
||||
void write(pt::outstm *out);
|
||||
void read(pt::instm *in);
|
||||
void Write(pt::outstm *out);
|
||||
void Read(pt::instm *in);
|
||||
};
|
||||
|
||||
class Fragment {
|
||||
|
@ -26,22 +46,28 @@ class Fragment {
|
|||
unsigned int id;
|
||||
|
||||
float error;
|
||||
Nexus::Update update;
|
||||
|
||||
std::vector<Seed> seeds;
|
||||
std::vector<unsigned int> seeds_id;
|
||||
|
||||
std::vector<NxsPatch> pieces;
|
||||
|
||||
void write(pt::outstm *out);
|
||||
void read(pt::instm *in);
|
||||
void Write(pt::outstm *out);
|
||||
void Read(pt::instm *in);
|
||||
|
||||
//returns the index of the seed
|
||||
unsigned int Locate(const vcg::Point3f &p);
|
||||
};
|
||||
|
||||
void join(Fragment &in,
|
||||
void Join(Fragment &in,
|
||||
std::vector<vcg::Point3f> &newvert,
|
||||
std::vector<unsigned int> &newface,
|
||||
std::vector<Link> &newbord);
|
||||
std::vector<BigLink> &newbord);
|
||||
|
||||
void split(Fragment &out,
|
||||
void Split(Fragment &out,
|
||||
std::vector<vcg::Point3f> &newvert,
|
||||
std::vector<unsigned int> &newface,
|
||||
std::vector<Link> &newbord,
|
||||
std::vector<BigLink> &newbord,
|
||||
VoronoiPartition &part);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue