Fixed degenerate faces.
This commit is contained in:
parent
fcfab2d616
commit
4dc937e514
|
@ -17,7 +17,7 @@
|
|||
//#include "border.h"
|
||||
|
||||
#include "decimate.h"
|
||||
//#include <wrap/io_trimesh/export_ply.h>
|
||||
#include <wrap/io_trimesh/export_ply.h>
|
||||
|
||||
using namespace vcg;
|
||||
using namespace tri;
|
||||
|
@ -59,11 +59,10 @@ float nxs::Decimate(Decimation mode,
|
|||
vector<Link> &newbord,
|
||||
vector<int> &vert_remap) {
|
||||
|
||||
//Temporary test:
|
||||
for(unsigned int i = 0; i < newface.size(); i+= 3) {
|
||||
assert(newface[i*3] != newface[i*3+1]);
|
||||
assert(newface[i*3] != newface[i*3+2]);
|
||||
assert(newface[i*3+1] != newface[i*3+2]);
|
||||
assert(newface[i] != newface[i+1]);
|
||||
assert(newface[i] != newface[i+2]);
|
||||
assert(newface[i+1] != newface[i+2]);
|
||||
}
|
||||
|
||||
MyMesh mesh;
|
||||
|
@ -81,7 +80,7 @@ float nxs::Decimate(Decimation mode,
|
|||
MyFace face;
|
||||
face.ClearFlags();
|
||||
for(int k = 0; k < 3; k++) {
|
||||
assert(newface[i+k] < mesh.vn);
|
||||
assert(newface[i+k] < mesh.vert.size());
|
||||
face.V(k) = &mesh.vert[newface[i+k]];
|
||||
}
|
||||
mesh.face.push_back(face);
|
||||
|
@ -92,57 +91,18 @@ float nxs::Decimate(Decimation mode,
|
|||
for(unsigned int i = 0; i < newbord.size(); i++)
|
||||
mesh.vert[newbord[i].start_vert].ClearW();
|
||||
|
||||
|
||||
// int FinalSize = mesh.face.size()/2;
|
||||
// if(FinalSize > target_faces) FinalSize = target_faces;
|
||||
|
||||
|
||||
/* if(target_faces == 2404) {
|
||||
vcg::tri::io::ExporterPLY<MyMesh>::Save(mesh, "bum");
|
||||
}*/
|
||||
printf("mesh loaded %d %d \n",mesh.vn,mesh.fn);
|
||||
printf("reducing it to %i\n", target_faces);
|
||||
|
||||
// if(target_faces == 1446)
|
||||
// vcg::tri::io::ExporterPLY<MyMesh>::Save(mesh, "ribum.ply");
|
||||
|
||||
/*
|
||||
int t0=clock();
|
||||
vcg::tri::UpdateTopology<MyMesh>::VertexFace(mesh);
|
||||
int t1=clock();
|
||||
vcg::LocalOptimization<MyMesh> DeciSession(mesh);
|
||||
MyTriEdgeCollapse::SetDefaultParams();
|
||||
|
||||
DeciSession.Init<MyTriEdgeCollapse>();
|
||||
|
||||
FinalSize = mesh.fn - FinalSize; //number of faces to remove
|
||||
FinalSize/=2; //Number of vertices to remove
|
||||
DeciSession.SetTargetOperations(FinalSize);
|
||||
DeciSession.DoOptimization();
|
||||
float error = DeciSession.currMetric/4;//1; //get error;
|
||||
int t3=clock();
|
||||
*/
|
||||
float error;
|
||||
if(mode == CLUSTER)
|
||||
error = Cluster(mesh, target_faces);
|
||||
else
|
||||
error = Quadric(mesh, target_faces);
|
||||
|
||||
|
||||
|
||||
/* printf(" vol %d \n lkv %d \n lke %d \n lkf %d \n ood %d\n bor %d\n ",
|
||||
MyTriEdgeCollapse::FailStat::Volume() ,
|
||||
MyTriEdgeCollapse::FailStat::LinkConditionFace(),
|
||||
MyTriEdgeCollapse::FailStat::LinkConditionEdge(),
|
||||
MyTriEdgeCollapse::FailStat::LinkConditionVert(),
|
||||
MyTriEdgeCollapse::FailStat::OutOfDate() ,
|
||||
MyTriEdgeCollapse::FailStat::Border()
|
||||
);*/
|
||||
|
||||
// printf("Completed in %i+%i+%i msec\n",t1-t0,t2-t1,t3-t2);
|
||||
// printf("mesh %d %d \n",mesh.vn,mesh.fn);
|
||||
|
||||
//recort vert start.
|
||||
|
||||
|
||||
newvert.clear();
|
||||
newface.clear();
|
||||
|
||||
|
@ -158,10 +118,8 @@ float nxs::Decimate(Decimation mode,
|
|||
for(unsigned int i = 0; i < mesh.face.size(); i++) {
|
||||
MyFace &face = mesh.face[i];
|
||||
if(face.IsD()) continue;
|
||||
for(int k = 0; k < 3; k++) {
|
||||
assert(vert_remap[face.V(k) - vert_start] != -1);
|
||||
for(int k = 0; k < 3; k++)
|
||||
newface.push_back(vert_remap[face.V(k) - vert_start]);
|
||||
}
|
||||
}
|
||||
|
||||
for(unsigned int i = 0; i < newbord.size(); i++) {
|
||||
|
@ -172,9 +130,9 @@ float nxs::Decimate(Decimation mode,
|
|||
|
||||
//Temporary test again:
|
||||
for(unsigned int i = 0; i < newface.size(); i+= 3) {
|
||||
assert(newface[i*3] != newface[i*3+1]);
|
||||
assert(newface[i*3] != newface[i*3+2]);
|
||||
assert(newface[i*3+1] != newface[i*3+2]);
|
||||
assert(newface[i] != newface[i+1]);
|
||||
assert(newface[i] != newface[i+2]);
|
||||
assert(newface[i+1] != newface[i+2]);
|
||||
}
|
||||
|
||||
return error;
|
||||
|
@ -243,6 +201,8 @@ float Cluster(MyMesh &mesh, unsigned int target_faces) {
|
|||
part.SetBox(box);
|
||||
part.Init();
|
||||
|
||||
cerr << "inited points\n";
|
||||
|
||||
vector<Point3f> centroid;
|
||||
vector<unsigned int> count;
|
||||
for(unsigned int i = 0; i < 3; i++) {
|
||||
|
@ -266,12 +226,16 @@ float Cluster(MyMesh &mesh, unsigned int target_faces) {
|
|||
mesh.vert[remap[i]].P() = part[i].p;
|
||||
}
|
||||
|
||||
cerr << "remapping faces\n";
|
||||
|
||||
float error = 0;
|
||||
//rimappiamo le facce.....
|
||||
for(unsigned int i = 0; i < mesh.face.size(); i++) {
|
||||
MyFace &face = mesh.face[i];
|
||||
for(int k = 0; k < 3; k++) {
|
||||
unsigned int target = part.Locate(face.V(k)->cP());
|
||||
assert(target < remap.size());
|
||||
assert(remap[target] < mesh.vert.size());
|
||||
MyVertex &vert = mesh.vert[remap[target]];
|
||||
|
||||
float dist = Distance(vert.cP(), face.V(k)->cP());
|
||||
|
@ -281,6 +245,7 @@ float Cluster(MyMesh &mesh, unsigned int target_faces) {
|
|||
}
|
||||
}
|
||||
|
||||
cerr << "Deleting faces\n";
|
||||
for(unsigned int i = 0; i < mesh.face.size(); i++) {
|
||||
MyFace &face = mesh.face[i];
|
||||
assert(!face.IsD());
|
||||
|
@ -294,6 +259,8 @@ float Cluster(MyMesh &mesh, unsigned int target_faces) {
|
|||
mesh.fn--;
|
||||
}
|
||||
}
|
||||
|
||||
cerr << "deleting vertices\n";
|
||||
|
||||
for(unsigned int i = 0; i < mesh.vert.size(); i++)
|
||||
if(!mesh.vert[i].IsV() && mesh.vert[i].IsW()) {
|
||||
|
|
|
@ -185,7 +185,6 @@ void Nexus::Join(const std::set<unsigned int> &patches,
|
|||
|
||||
Nexus::Entry &entry = index[patch];
|
||||
fcount += entry.nface;
|
||||
// assert(fcount < 0xffff);
|
||||
for(unsigned int k = 0; k < entry.nvert; k++) {
|
||||
if(vmap[k] == 0xffffffff) { //first time
|
||||
vmap[k] = vcount++;
|
||||
|
@ -224,57 +223,45 @@ void Nexus::Join(const std::set<unsigned int> &patches,
|
|||
fcount = 0;
|
||||
for(i = patches.begin(); i != patches.end(); i++) {
|
||||
Patch patch = GetPatch(*i);
|
||||
// Border border = GetBorder(*i);
|
||||
|
||||
vector<unsigned int> &vmap = remap[*i];
|
||||
|
||||
|
||||
for(unsigned int i = 0; i < patch.nv; i++) {
|
||||
assert(vmap[i] < vcount);
|
||||
newvert[vmap[i]] = patch.Vert(i);
|
||||
}
|
||||
|
||||
|
||||
for(unsigned int i = 0; i < patch.nf; i++) {
|
||||
for(int k = 0; k < 3; k++) {
|
||||
newface[3*fcount + k] = vmap[patch.Face(i)[k]];
|
||||
unsigned short *face = patch.Face(i);
|
||||
if(patch.Vert(face[0]) == patch.Vert(face[1]) ||
|
||||
patch.Vert(face[0]) == patch.Vert(face[2]) ||
|
||||
patch.Vert(face[1]) == patch.Vert(face[2])) {
|
||||
cerr << "MALEDETTO!" << endl;
|
||||
Point3f &v0 = patch.Vert(face[0]);
|
||||
Point3f &v1 = patch.Vert(face[1]);
|
||||
Point3f &v2 = patch.Vert(face[2]);
|
||||
cerr << "V0: " << v0[0] << " " << v0[1] << " " << v0[2] << endl;
|
||||
cerr << "V1: " << v1[0] << " " << v1[1] << " " << v1[2] << endl;
|
||||
cerr << "V2: " << v2[0] << " " << v2[1] << " " << v2[2] << endl;
|
||||
}
|
||||
if(patch.Face(i)[0] == patch.Face(i)[1] ||
|
||||
patch.Face(i)[0] == patch.Face(i)[2] ||
|
||||
patch.Face(i)[1] == patch.Face(i)[2]) {
|
||||
cerr << "Damn: " << i << endl;
|
||||
cerr << patch.Face(i)[0] << " " << patch.Face(i)[1]
|
||||
<< patch.Face(i)[2] << endl;
|
||||
}
|
||||
assert(patch.Face(i)[0] != patch.Face(i)[1]);
|
||||
assert(patch.Face(i)[0] != patch.Face(i)[2]);
|
||||
assert(patch.Face(i)[1] != patch.Face(i)[2]);
|
||||
assert(newface[3*fcount + 0] != newface[3*fcount + 1]);
|
||||
assert(newface[3*fcount + 0] != newface[3*fcount + 2]);
|
||||
assert(newface[3*fcount + 1] != newface[3*fcount + 2]);
|
||||
|
||||
fcount++;
|
||||
assert(fcount *3 <= newface.size());
|
||||
}
|
||||
/* for(unsigned int i = 0; i < border.Size(); i++) {
|
||||
Link link = border[i];
|
||||
if(patches.count(link.end_patch)) continue;
|
||||
link.start_vert = vmap[link.start_vert];
|
||||
newbord.push_back(link);*/
|
||||
|
||||
/* if(remap.count(link.end_patch)) continue;
|
||||
Link newlink = link;
|
||||
newlink.start_vert = vmap[link.start_vert];
|
||||
newbord[bcount++] = newlink;*/
|
||||
// }
|
||||
for(unsigned int i = 0; i < patch.nf; i++)
|
||||
for(int k = 0; k < 3; k++)
|
||||
newface[fcount++] = vmap[patch.Face(i)[k]];
|
||||
}
|
||||
assert(fcount == newface.size());
|
||||
|
||||
set<Link>::iterator b;
|
||||
for(b = newborders.begin(); b != newborders.end(); b++)
|
||||
newbord.push_back(*b);
|
||||
|
||||
/* unsigned int newentry = AddPatch(vcount, fcount, bcount);
|
||||
Patch newpatch = GetPatch(newentry);
|
||||
Border newborder = GetBorder(newentry);
|
||||
|
||||
memcpy(newpatch.VertBegin(), &(newvert)[0],
|
||||
newvert.size() * sizeof(Point3f));
|
||||
|
||||
memcpy(newpatch.FaceBegin(), &(newface)[0],
|
||||
newface.size() * sizeof(unsigned short));
|
||||
|
||||
memcpy(&(newborder[0]), &(newbord[0]),
|
||||
newbord.size() * sizeof(Link));*/
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -283,23 +270,25 @@ void Nexus::Unify(float threshold) {
|
|||
//TODO what if colors or normals or strips?
|
||||
//TODO update totvert
|
||||
unsigned int duplicated = 0;
|
||||
unsigned int degenerate = 0;
|
||||
|
||||
for(unsigned int p = 0; p < index.size(); p++) {
|
||||
Nexus::Entry &entry = index[p];
|
||||
Patch patch = GetPatch(p);
|
||||
|
||||
unsigned int vcount = 0;
|
||||
map<Point3f, unsigned short> vertices;
|
||||
|
||||
vector<unsigned short> remap;
|
||||
remap.resize(patch.nv);
|
||||
// map<unsigned short, unsigned short> remap;
|
||||
|
||||
for(unsigned int i = 0; i < patch.nv; i++) {
|
||||
Point3f &point = patch.Vert(i);
|
||||
|
||||
if(!vertices.count(point)) {
|
||||
if(!vertices.count(point))
|
||||
vertices[point] = vcount++;
|
||||
} else {
|
||||
else
|
||||
duplicated++;
|
||||
}
|
||||
|
||||
remap[i] = vertices[point];
|
||||
}
|
||||
|
@ -316,17 +305,29 @@ void Nexus::Unify(float threshold) {
|
|||
|
||||
|
||||
vector<unsigned short> newface;
|
||||
newface.resize(patch.nf * 3);
|
||||
for(unsigned int f = 0; f < newface.size(); f++)
|
||||
newface[f] = remap[patch.FaceBegin()[f]];
|
||||
//check no degenerate faces get created.
|
||||
for(unsigned int f = 0; f < entry.nface; f++) {
|
||||
unsigned short *face = patch.Face(f);
|
||||
if(face[0] != face[1] && face[1] != face[2] && face[0] != face[2] &&
|
||||
newvert[remap[face[0]]] != newvert[remap[face[1]]] &&
|
||||
newvert[remap[face[0]]] != newvert[remap[face[2]]] &&
|
||||
newvert[remap[face[1]]] != newvert[remap[face[2]]]) {
|
||||
newface.push_back(remap[face[0]]);
|
||||
newface.push_back(remap[face[1]]);
|
||||
newface.push_back(remap[face[2]]);
|
||||
} else {
|
||||
degenerate++;
|
||||
}
|
||||
}
|
||||
|
||||
//rewrite patch now.
|
||||
entry.nvert = newvert.size();
|
||||
entry.nface = newface.size()/3;
|
||||
patch.Init(signature, entry.nvert, entry.nface);
|
||||
|
||||
memcpy(patch.VertBegin(), &(newvert[0]), entry.nvert*sizeof(Point3f));
|
||||
memcpy(patch.FaceBegin(), &(newface[0]), entry.nface*3*sizeof(unsigned short));
|
||||
|
||||
memcpy(patch.FaceBegin(), &(newface[0]), entry.nface*3*sizeof(short));
|
||||
|
||||
//fix patch borders now
|
||||
set<unsigned int> close; //bordering pathes
|
||||
Border border = GetBorder(p);
|
||||
|
@ -350,8 +351,6 @@ void Nexus::Unify(float threshold) {
|
|||
//finally: there may be duplicated borders
|
||||
for(unsigned int p = 0; p < index.size(); p++) {
|
||||
Border border = GetBorder(p);
|
||||
//Nexus::Entry &entry = index[p];
|
||||
|
||||
set<Link> links;
|
||||
for(unsigned int b = 0; b < border.Size(); b++) {
|
||||
if(border[b].IsNull()) continue;
|
||||
|
@ -361,7 +360,10 @@ void Nexus::Unify(float threshold) {
|
|||
links.insert(border[b]);
|
||||
}
|
||||
}
|
||||
|
||||
totvert -= duplicated;
|
||||
// cout << "Found " << duplicated << " duplicated vertices" << endl;
|
||||
|
||||
if(duplicated)
|
||||
cerr << "Found " << duplicated << " duplicated vertices" << endl;
|
||||
if(degenerate)
|
||||
cerr << "Found " << degenerate << " degenerate face while unmifying\n";
|
||||
}
|
||||
|
|
|
@ -362,7 +362,6 @@ Patch &NexusMt::LoadPatch(unsigned int p) {
|
|||
if(ram_used > ram_size * 1.5)
|
||||
FlushRam();
|
||||
|
||||
cerr << "Ram: " << ram_used << endl;
|
||||
return *(sgurz.patch);
|
||||
}
|
||||
|
||||
|
|
|
@ -106,12 +106,11 @@ void nxs::NexusFill(Crude &crude,
|
|||
//TODO an hash_map would be faster?
|
||||
unsigned int count = 0;
|
||||
map<unsigned int, unsigned short> remap;
|
||||
|
||||
for(unsigned int k = 0; k < patch.nf; k++) {
|
||||
Crude::Face &face = faces[k];
|
||||
|
||||
for(int j = 0; j < 3; j++) {
|
||||
if(!remap.count(face[j])) {
|
||||
assert(count < patch.nv);
|
||||
Point3f &v = crude.vert[face[j]];
|
||||
patch.VertBegin()[remap.size()] = v;
|
||||
entry.sphere.Add(v);
|
||||
|
@ -119,10 +118,6 @@ void nxs::NexusFill(Crude &crude,
|
|||
}
|
||||
patch.FaceBegin()[k*3 + j] = remap[face[j]];
|
||||
}
|
||||
//test for degenerate faces.
|
||||
assert(patch.FaceBegin()[k*3] != patch.FaceBegin()[k*3+1]);
|
||||
assert(patch.FaceBegin()[k*3] != patch.FaceBegin()[k*3+2]);
|
||||
assert(patch.FaceBegin()[k*3+1] != patch.FaceBegin()[k*3+2]);
|
||||
}
|
||||
assert(count == remap.size());
|
||||
assert(entry.nvert == remap.size());
|
||||
|
@ -157,6 +152,16 @@ void nxs::NexusFill(Crude &crude,
|
|||
//we can now update bounding sphere.
|
||||
for(unsigned int i = 0; i < nexus.index.size(); i++)
|
||||
nexus.sphere.Add(nexus.index[i].sphere);
|
||||
|
||||
//test no duplicated faces:
|
||||
/* for(unsigned int i = 0; i < nexus.index.size(); i++) {
|
||||
Patch patch = nexus.GetPatch(i);
|
||||
for(unsigned int k = 0; k < patch.nf; k++) {
|
||||
assert(patch.Face(k)[0] != patch.Face(k)[1]);
|
||||
assert(patch.Face(k)[0] != patch.Face(k)[2]);
|
||||
assert(patch.Face(k)[1] != patch.Face(k)[2]);
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
void nxs::NexusFixBorder(Nexus &nexus,
|
||||
|
@ -194,19 +199,19 @@ void nxs::NexusFixBorder(Nexus &nexus,
|
|||
for(unsigned int j = 0; j < remote.border_used; j++) {
|
||||
|
||||
RemapLink end_link = border_remap[j + remote_remap_start];
|
||||
assert(end_link.rel_vert < remote.nvert);
|
||||
// assert(end_link.rel_vert < remote.nvert);
|
||||
|
||||
if(start_link.abs_vert == end_link.abs_vert &&
|
||||
end_link.patch == i) { //found the match
|
||||
assert(!found);
|
||||
// assert(!found);
|
||||
nexus.borders[k + local.border_start] = Link(start_link.rel_vert,
|
||||
end_link.rel_vert,
|
||||
start_link.patch);
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
assert(nexus.borders[k + local.border_start].start_vert < local.nvert);
|
||||
assert(found);
|
||||
// assert(nexus.borders[k + local.border_start].start_vert < local.nvert);
|
||||
// assert(found);
|
||||
}
|
||||
}
|
||||
nexus.borders.Flush();
|
||||
|
|
|
@ -24,6 +24,9 @@
|
|||
History
|
||||
|
||||
$Log: not supported by cvs2svn $
|
||||
Revision 1.7 2004/10/04 16:49:54 ponchio
|
||||
Daily backup. Preparing for compression.
|
||||
|
||||
Revision 1.6 2004/10/01 16:54:57 ponchio
|
||||
Daily backup.
|
||||
|
||||
|
@ -282,7 +285,6 @@ int main(int argc, char *argv[]) {
|
|||
|
||||
nexus.Join((*fragment).second, newvert, newface, newbord);
|
||||
|
||||
|
||||
//simplyfy mesh
|
||||
vector<int> vert_remap;
|
||||
float error = Decimate(decimation,
|
||||
|
@ -319,17 +321,6 @@ int main(int argc, char *argv[]) {
|
|||
}
|
||||
nexus.history.push_back(update);
|
||||
ReverseHistory(nexus.history);
|
||||
//debug:
|
||||
/* for(unsigned int i = 0; i < nexus.history.size(); i++) {
|
||||
Nexus::Update &update = nexus.history[i];
|
||||
cerr << "created:";
|
||||
for(unsigned int c = 0; c < update.created.size(); c++)
|
||||
cerr << " " << update.created[c];
|
||||
cerr << "\nerased:";
|
||||
for(unsigned int c = 0; c < update.erased.size(); c++)
|
||||
cerr << " " << update.erased[c];
|
||||
cerr << "\n\n";
|
||||
}*/
|
||||
|
||||
//Clean up:
|
||||
nexus.Close();
|
||||
|
@ -338,203 +329,6 @@ int main(int argc, char *argv[]) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*void RemapVertices(Crude &crude,
|
||||
VertRemap &vert_remap,
|
||||
VFile<unsigned int> &face_remap,
|
||||
vector<unsigned int> &patch_verts) {
|
||||
|
||||
for(unsigned int i = 0; i < crude.Faces(); i++) {
|
||||
Crude::Face &face = crude.GetFace(i);
|
||||
unsigned int patch = face_remap[i];
|
||||
for(int k = 0; k < 3; k++) {
|
||||
set<unsigned int> pp;
|
||||
vert_remap.GetValues(face[k], pp);
|
||||
if(!pp.count(patch)) {
|
||||
vert_remap.Insert(face[k], patch);
|
||||
patch_verts[patch]++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
/*void NexusAllocate(Crude &crude,
|
||||
Nexus &nexus,
|
||||
VFile<unsigned int> &face_remap,
|
||||
vector<unsigned int> &patch_faces,
|
||||
vector<unsigned int> &patch_verts) {
|
||||
|
||||
|
||||
nexus.index.resize(patch_faces.size());
|
||||
|
||||
unsigned int totchunks = 0;
|
||||
//now that we know various sizes, lets allocate space
|
||||
for(unsigned int i = 0; i < nexus.index.size(); i++) {
|
||||
Nexus::Entry &entry = nexus.index[i];
|
||||
|
||||
if(patch_faces[i] == 0 || patch_verts[i] == 0)
|
||||
cerr << "Warning! Empty patch.\n";
|
||||
|
||||
entry.patch_start = totchunks;
|
||||
entry.patch_size = Patch::ChunkSize(nexus.signature,
|
||||
patch_verts[i], patch_faces[i]);
|
||||
|
||||
totchunks += entry.patch_size;
|
||||
entry.border_start = 0xffffffff;
|
||||
entry.nvert = patch_verts[i];
|
||||
entry.nface = 0;
|
||||
entry.error = 0;
|
||||
}
|
||||
|
||||
nexus.patches.Resize(totchunks);
|
||||
|
||||
|
||||
//now we sort the faces into the patches (but still using absolute indexing
|
||||
//instead of relative indexing
|
||||
for(unsigned int i = 0; i < crude.face.Size(); i++) {
|
||||
Crude::Face &face = crude.face[i];
|
||||
unsigned int npatch = face_remap[i];
|
||||
|
||||
Nexus::Entry &entry = nexus.index[npatch];
|
||||
|
||||
//TODO this is slow because we have to initialize patch.
|
||||
//just get patch.start.
|
||||
Patch patch = nexus.GetPatch(npatch);
|
||||
|
||||
Crude::Face *faces = (Crude::Face *)patch.start;
|
||||
faces[entry.nface] = face;
|
||||
entry.nface++;
|
||||
}
|
||||
}*/
|
||||
|
||||
|
||||
/*void NexusFill(Crude &crude,
|
||||
Nexus &nexus,
|
||||
VertRemap &vert_remap,
|
||||
VFile<RemapLink> &border_remap) {
|
||||
|
||||
|
||||
//finally for every patch we collect the vertices
|
||||
//and fill the patch.
|
||||
//we need to remember start and size in border_remap;
|
||||
// vector<unsigned int> border_start;
|
||||
// vector<unsigned int> border_size;
|
||||
|
||||
for(unsigned int i = 0; i < nexus.index.size(); i++) {
|
||||
Patch patch = nexus.GetPatch(i);
|
||||
Nexus::Entry &entry = nexus.index[i];
|
||||
|
||||
//make a copy of faces (we need to write there :P)
|
||||
Crude::Face *faces = new Crude::Face[patch.nf];
|
||||
memcpy(faces, (Crude::Face *)patch.start,
|
||||
patch.nf * sizeof(Crude::Face));
|
||||
|
||||
//collect all vertices we need.
|
||||
//TODO an hash_map would be faster?
|
||||
unsigned int count = 0;
|
||||
map<unsigned int, unsigned short> remap;
|
||||
for(unsigned int k = 0; k < patch.nf; k++) {
|
||||
Crude::Face &face = faces[k];
|
||||
|
||||
for(int j = 0; j < 3; j++) {
|
||||
if(!remap.count(face[j])) {
|
||||
assert(count < patch.nv);
|
||||
Point3f &v = crude.vert[face[j]];
|
||||
patch.VertBegin()[remap.size()] = v;
|
||||
entry.sphere.Add(v);
|
||||
remap[face[j]] = count++;
|
||||
}
|
||||
patch.FaceBegin()[k*3 + j] = remap[face[j]];
|
||||
}
|
||||
}
|
||||
assert(count == remap.size());
|
||||
assert(entry.nvert == remap.size());
|
||||
|
||||
//record start of border:
|
||||
entry.border_start = border_remap.Size();
|
||||
|
||||
//TODO hash_set?
|
||||
set<unsigned int> border_patches;
|
||||
map<unsigned int, unsigned short>::iterator m;
|
||||
for(m = remap.begin(); m != remap.end(); m++) {
|
||||
RemapLink link;
|
||||
link.abs_vert = (*m).first;
|
||||
link.rel_vert = (*m).second;
|
||||
|
||||
vert_remap.GetValues(link.abs_vert, border_patches);
|
||||
assert(border_patches.size() >= 1);
|
||||
if(border_patches.size() == 1) continue; //its not a border
|
||||
|
||||
set<unsigned int>::iterator s;
|
||||
for(s = border_patches.begin(); s != border_patches.end(); s++) {
|
||||
if((*s) == i) continue;
|
||||
link.patch = *s;
|
||||
border_remap.PushBack(link);
|
||||
}
|
||||
}
|
||||
//and number of borders:
|
||||
entry.border_used = border_remap.Size() - entry.border_start;
|
||||
delete []faces;
|
||||
}
|
||||
|
||||
//we can now update bounding sphere.
|
||||
for(unsigned int i = 0; i < nexus.index.size(); i++)
|
||||
nexus.sphere.Add(nexus.index[i].sphere);
|
||||
}*/
|
||||
|
||||
/*void NexusFixBorder(Nexus &nexus,
|
||||
VFile<RemapLink> &border_remap) {
|
||||
|
||||
//and last convert RemapLinks into Links
|
||||
nexus.borders.Resize(border_remap.Size() * 2);
|
||||
//* 2 is to accomodate future borders
|
||||
|
||||
for(unsigned int i = 0; i < nexus.index.size(); i++) {
|
||||
Nexus::Entry &local = nexus.index[i];
|
||||
local.border_start *= 2;
|
||||
local.border_size = local.border_used * 2;
|
||||
}
|
||||
|
||||
for(unsigned int i = 0; i < nexus.index.size(); i++) {
|
||||
Nexus::Entry &local = nexus.index[i];
|
||||
|
||||
unsigned int remap_start = local.border_start/2;
|
||||
//* 2 is to accomodate future borders
|
||||
|
||||
|
||||
// K is the main iterator (where we write to in nexus.borders)
|
||||
for(unsigned int k = 0; k < local.border_used; k++) {
|
||||
|
||||
|
||||
RemapLink start_link = border_remap[k + remap_start];
|
||||
assert(start_link.rel_vert < local.nvert);
|
||||
|
||||
Nexus::Entry &remote = nexus.index[start_link.patch];
|
||||
|
||||
bool found = false;
|
||||
|
||||
unsigned int remote_remap_start = remote.border_start/2;
|
||||
for(unsigned int j = 0; j < remote.border_used; j++) {
|
||||
|
||||
RemapLink end_link = border_remap[j + remote_remap_start];
|
||||
assert(end_link.rel_vert < remote.nvert);
|
||||
|
||||
if(start_link.abs_vert == end_link.abs_vert &&
|
||||
end_link.patch == i) { //found the match
|
||||
assert(!found);
|
||||
nexus.borders[k + local.border_start] = Link(start_link.rel_vert,
|
||||
end_link.rel_vert,
|
||||
start_link.patch);
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
assert(nexus.borders[k + local.border_start].start_vert < local.nvert);
|
||||
assert(found);
|
||||
}
|
||||
}
|
||||
nexus.borders.Flush();
|
||||
} */
|
||||
|
||||
|
||||
void NexusSplit(Nexus &nexus, VoronoiChain &vchain,
|
||||
unsigned int level,
|
||||
vector<Point3f> &newvert,
|
||||
|
|
Loading…
Reference in New Issue