added split.
This commit is contained in:
parent
2bfda63cc5
commit
d23e12f0a3
|
@ -8,7 +8,7 @@ using namespace vcg;
|
||||||
using namespace nxs;
|
using namespace nxs;
|
||||||
using namespace pt;
|
using namespace pt;
|
||||||
|
|
||||||
void NxsPatch::write(outstm *out) {
|
void NxsPatch::Write(outstm *out) {
|
||||||
int vsize = vert.size();
|
int vsize = vert.size();
|
||||||
int fsize = face.size();
|
int fsize = face.size();
|
||||||
int bsize = bord.size();
|
int bsize = bord.size();
|
||||||
|
@ -23,7 +23,7 @@ void NxsPatch::write(outstm *out) {
|
||||||
out->write(&*bord.begin(), bord.size() * sizeof(Link));
|
out->write(&*bord.begin(), bord.size() * sizeof(Link));
|
||||||
}
|
}
|
||||||
|
|
||||||
void NxsPatch::read(instm *in) {
|
void NxsPatch::Read(instm *in) {
|
||||||
int vsize;
|
int vsize;
|
||||||
int fsize;
|
int fsize;
|
||||||
int bsize;
|
int bsize;
|
||||||
|
@ -40,50 +40,47 @@ void NxsPatch::read(instm *in) {
|
||||||
in->read(&*bord.begin(), bord.size() * sizeof(Link));
|
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(&id, sizeof(unsigned int));
|
||||||
out->write(&error, sizeof(float));
|
out->write(&error, sizeof(float));
|
||||||
|
|
||||||
unsigned int esize = update.erased.size();
|
unsigned int ssize = seeds.size();
|
||||||
unsigned int csize = update.created.size();
|
out->write(&ssize, sizeof(unsigned int));
|
||||||
out->write(&esize, sizeof(unsigned int));
|
|
||||||
out->write(&csize, sizeof(unsigned int));
|
out->write(&*seeds.begin(), ssize * sizeof(Seed));
|
||||||
out->write(&*update.erased.begin(), esize * sizeof(unsigned int));
|
out->write(&*seeds_id.begin(), ssize * sizeof(unsigned int));
|
||||||
out->write(&*update.created.begin(), csize * sizeof(unsigned int));
|
|
||||||
|
|
||||||
unsigned int psize = pieces.size();
|
unsigned int psize = pieces.size();
|
||||||
out->write(&psize, sizeof(unsigned int));
|
out->write(&psize, sizeof(unsigned int));
|
||||||
|
|
||||||
for(unsigned int i = 0; i < pieces.size(); i++)
|
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(&id, sizeof(unsigned int));
|
||||||
in->read(&error, sizeof(float));
|
in->read(&error, sizeof(float));
|
||||||
|
|
||||||
unsigned int esize;
|
unsigned int ssize;
|
||||||
unsigned int csize;
|
in->read(&ssize, sizeof(unsigned int));
|
||||||
in->read(&esize, sizeof(unsigned int));
|
seeds.resize(ssize);
|
||||||
in->read(&csize, sizeof(unsigned int));
|
seeds_id.resize(ssize);
|
||||||
update.erased.resize(esize);
|
in->read(&*seeds.begin(), ssize * sizeof(Seed));
|
||||||
update.created.resize(csize);
|
in->read(&*seeds_id.begin(), ssize * sizeof(unsigned int));
|
||||||
in->read(&*update.erased.begin(), esize * sizeof(unsigned int));
|
|
||||||
in->read(&*update.created.begin(), csize * sizeof(unsigned int));
|
|
||||||
|
|
||||||
unsigned int psize;
|
unsigned int psize;
|
||||||
in->read(&psize, sizeof(unsigned int));
|
in->read(&psize, sizeof(unsigned int));
|
||||||
pieces.resize(psize);
|
pieces.resize(psize);
|
||||||
|
|
||||||
for(unsigned int i = 0; i < psize; i++)
|
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<Point3f> &newvert,
|
||||||
vector<unsigned int> &newface,
|
vector<unsigned int> &newface,
|
||||||
vector<Link> &newbord) {
|
vector<BigLink> &newbord) {
|
||||||
|
|
||||||
map<unsigned int, unsigned int> patch_remap;
|
map<unsigned int, unsigned int> patch_remap;
|
||||||
vector<unsigned int> offsets;
|
vector<unsigned int> offsets;
|
||||||
|
@ -98,7 +95,7 @@ void nxs::join(Fragment &in,
|
||||||
vector<unsigned int> remap;
|
vector<unsigned int> remap;
|
||||||
remap.resize(totvert, 0xffffffff);
|
remap.resize(totvert, 0xffffffff);
|
||||||
|
|
||||||
//TODO what if totvert > 32768?
|
//TODO what if totvert > 1<<22?
|
||||||
//todo we really need a set?
|
//todo we really need a set?
|
||||||
// set<Link> newborders;
|
// set<Link> newborders;
|
||||||
unsigned int vcount = 0;
|
unsigned int vcount = 0;
|
||||||
|
@ -132,31 +129,8 @@ void nxs::join(Fragment &in,
|
||||||
remap[extoffset + link.end_vert] = remap[offset + link.start_vert];
|
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
|
//L(a, b): Exist link between a, b
|
||||||
//An external link L(e, v) where v belongs to the patches (and e not)
|
//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;
|
vector<unsigned int> internal_links;
|
||||||
internal_links.resize(vcount, 0);
|
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++) {
|
for(unsigned int i = 0; i < in.pieces.size(); i++) {
|
||||||
unsigned int offset = offsets[i];
|
unsigned int offset = offsets[i];
|
||||||
vector<Link> &bord = in.pieces[i].bord;
|
vector<Link> &bord = in.pieces[i].bord;
|
||||||
for(unsigned int k = 0; k < bord.size(); k++) {
|
for(unsigned int k = 0; k < bord.size(); k++) {
|
||||||
Link link = bord[k];
|
Link llink = bord[k];
|
||||||
if(link.IsNull()) continue;
|
if(llink.IsNull()) continue;
|
||||||
if(!patch_remap.count(link.end_patch)) {//external...may be erased though
|
if(!patch_remap.count(llink.end_patch)) {//external...may be erased though
|
||||||
link.start_vert = remap[offset + link.start_vert];
|
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))
|
if(!newborders.count(link))
|
||||||
newborders[link] = 1;
|
newborders[link] = 1;
|
||||||
else
|
else
|
||||||
newborders[link]++;
|
newborders[link]++;
|
||||||
} else { //internal
|
} 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++) {
|
for(b = newborders.begin(); b != newborders.end(); b++) {
|
||||||
//test that number of links on this vertex is equal to
|
//test that number of links on this vertex is equal to
|
||||||
//number of internal links of the internal vertex
|
//number of internal links of the internal vertex
|
||||||
const Link &link = (*b).first;
|
const BigLink &link = (*b).first;
|
||||||
unsigned int n = (*b).second;
|
unsigned int n = (*b).second;
|
||||||
if(n * (n-1) == internal_links[link.start_vert])
|
if(n * (n-1) == internal_links[link.start_vert])
|
||||||
newbord.push_back(link);
|
newbord.push_back(link);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void nxs::split(Fragment &out,
|
void nxs::Split(Fragment &out,
|
||||||
vector<Point3f> &newvert,
|
vector<Point3f> &newvert,
|
||||||
vector<unsigned int> &newface,
|
vector<unsigned int> &newface,
|
||||||
vector<Link> &newbord,
|
vector<BigLink> &newbord,
|
||||||
VoronoiPartition &part) {
|
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 <ptypes/pstreams.h>
|
||||||
#include "nexus.h"
|
#include "nexus.h"
|
||||||
|
#include "pvoronoi.h"
|
||||||
|
|
||||||
namespace nxs {
|
namespace nxs {
|
||||||
|
|
||||||
class VoronoiPartition;
|
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 {
|
class NxsPatch {
|
||||||
public:
|
public:
|
||||||
|
//this fields is the patch number in the infragment
|
||||||
|
//and the seeds id in the outfragment
|
||||||
unsigned int patch;
|
unsigned int patch;
|
||||||
std::vector<vcg::Point3f> vert;
|
std::vector<vcg::Point3f> vert;
|
||||||
std::vector<unsigned short> face;
|
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;
|
std::vector<Link> bord;
|
||||||
|
|
||||||
void write(pt::outstm *out);
|
void Write(pt::outstm *out);
|
||||||
void read(pt::instm *in);
|
void Read(pt::instm *in);
|
||||||
};
|
};
|
||||||
|
|
||||||
class Fragment {
|
class Fragment {
|
||||||
|
@ -26,22 +46,28 @@ class Fragment {
|
||||||
unsigned int id;
|
unsigned int id;
|
||||||
|
|
||||||
float error;
|
float error;
|
||||||
Nexus::Update update;
|
|
||||||
|
std::vector<Seed> seeds;
|
||||||
|
std::vector<unsigned int> seeds_id;
|
||||||
|
|
||||||
std::vector<NxsPatch> pieces;
|
std::vector<NxsPatch> pieces;
|
||||||
|
|
||||||
void write(pt::outstm *out);
|
void Write(pt::outstm *out);
|
||||||
void read(pt::instm *in);
|
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<vcg::Point3f> &newvert,
|
||||||
std::vector<unsigned int> &newface,
|
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<vcg::Point3f> &newvert,
|
||||||
std::vector<unsigned int> &newface,
|
std::vector<unsigned int> &newface,
|
||||||
std::vector<Link> &newbord,
|
std::vector<BigLink> &newbord,
|
||||||
VoronoiPartition &part);
|
VoronoiPartition &part);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue