Backup. (lot of changes).
This commit is contained in:
parent
4033168ecc
commit
ad6b893cae
|
@ -10,16 +10,19 @@ Nexus::~Nexus() {
|
|||
Close();
|
||||
}
|
||||
|
||||
bool Nexus::Create(const string &file) {
|
||||
bool Nexus::Create(const string &file, Patch::Signature sig) {
|
||||
index_file = fopen((file + ".nxs").c_str(), "wb+");
|
||||
if(!index_file) {
|
||||
cerr << "Could not create file: " << file << ".nxs\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
signature = sig;
|
||||
totvert = 0;
|
||||
totface = 0;
|
||||
sphere = Sphere3f();
|
||||
|
||||
index.clear();
|
||||
|
||||
//Important: chunk_size must be 1 so that i can use Region in VFile.
|
||||
if(!patches.Create(file + ".nxp", 1)) {
|
||||
|
@ -30,6 +33,7 @@ bool Nexus::Create(const string &file) {
|
|||
cerr << "Could not create file: " << file << ".nxb" << endl;
|
||||
return false;
|
||||
}
|
||||
history.clear();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -38,6 +42,8 @@ bool Nexus::Load(const string &file) {
|
|||
if(!index_file) return false;
|
||||
|
||||
unsigned int readed;
|
||||
readed = fread(&signature, sizeof(unsigned int), 1, index_file);
|
||||
if(!readed) return false;
|
||||
readed = fread(&totvert, sizeof(unsigned int), 1, index_file);
|
||||
if(!readed) return false;
|
||||
readed = fread(&totface, sizeof(unsigned int), 1, index_file);
|
||||
|
@ -53,6 +59,28 @@ bool Nexus::Load(const string &file) {
|
|||
readed = fread(&index[0], sizeof(Entry), size, index_file);
|
||||
if(readed != size) return false;
|
||||
|
||||
//history size;
|
||||
fread(&size, sizeof(unsigned int), 1, index_file);
|
||||
vector<unsigned int> buffer;
|
||||
buffer.resize(size);
|
||||
fread(&(buffer[0]), sizeof(unsigned int), size, index_file);
|
||||
|
||||
//number of history updates
|
||||
size = buffer[0];
|
||||
history.resize(size);
|
||||
|
||||
unsigned int pos = 1;
|
||||
for(unsigned int i = 0; i < size; i++) {
|
||||
unsigned int erased = buffer[pos++];
|
||||
unsigned int created = buffer[pos++];
|
||||
history[i].erased.resize(erased);
|
||||
history[i].created.resize(created);
|
||||
for(unsigned int e = 0; e < erased; e++)
|
||||
history[i].erased[e] = buffer[pos++];
|
||||
for(unsigned int e = 0; e < created; e++)
|
||||
history[i].created[e] = buffer[pos++];
|
||||
}
|
||||
|
||||
if(!patches.Load(file + ".nxp", 1)) return false;
|
||||
if(!borders.Load(file + ".nxb", 1)) return false;
|
||||
return true;
|
||||
|
@ -61,7 +89,8 @@ bool Nexus::Load(const string &file) {
|
|||
void Nexus::Close() {
|
||||
if(!index_file) return;
|
||||
rewind(index_file);
|
||||
|
||||
|
||||
fwrite(&signature, sizeof(unsigned int), 1, index_file);
|
||||
fwrite(&totvert, sizeof(unsigned int), 1, index_file);
|
||||
fwrite(&totface, sizeof(unsigned int), 1, index_file);
|
||||
fwrite(&sphere, sizeof(Sphere3f), 1, index_file);
|
||||
|
@ -69,6 +98,24 @@ void Nexus::Close() {
|
|||
unsigned int size = index.size(); //size of index
|
||||
fwrite(&size, sizeof(unsigned int), 1, index_file);
|
||||
fwrite(&(index[0]), sizeof(Entry), size, index_file);
|
||||
|
||||
vector<unsigned int> buffer;
|
||||
buffer.push_back(history.size());
|
||||
for(unsigned int i = 0; i < history.size(); i++) {
|
||||
Update &update = history[i];
|
||||
buffer.push_back(update.erased.size());
|
||||
buffer.push_back(update.created.size());
|
||||
for(unsigned int e = 0; e < update.erased.size(); e++)
|
||||
buffer.push_back(update.erased[e]);
|
||||
for(unsigned int e = 0; e < update.created.size(); e++)
|
||||
buffer.push_back(update.created[e]);
|
||||
}
|
||||
|
||||
size = buffer.size();
|
||||
fwrite(&size, sizeof(unsigned int), 1, index_file);
|
||||
fwrite(&(buffer[0]), sizeof(unsigned int), size, index_file);
|
||||
|
||||
|
||||
fclose(index_file);
|
||||
index_file = NULL;
|
||||
|
||||
|
@ -79,7 +126,7 @@ void Nexus::Close() {
|
|||
Patch Nexus::GetPatch(unsigned int patch) {
|
||||
Entry &entry = index[patch];
|
||||
Chunk *start = patches.GetRegion(entry.patch_start, entry.patch_size);
|
||||
return Patch(start, entry.nvert, entry.nface);
|
||||
return Patch(signature, start, entry.nvert, entry.nface);
|
||||
}
|
||||
|
||||
Border Nexus::GetBorder(unsigned int patch) {
|
||||
|
@ -93,7 +140,7 @@ unsigned int Nexus::AddPatch(unsigned int nvert, unsigned int nface,
|
|||
unsigned int nbord) {
|
||||
Entry entry;
|
||||
entry.patch_start = patches.Size();
|
||||
entry.patch_size = Patch::ChunkSize(nvert, nface);
|
||||
entry.patch_size = Patch::ChunkSize(signature, nvert, nface);
|
||||
entry.border_start = borders.Size();
|
||||
entry.border_size = nbord;
|
||||
entry.nvert = nvert;
|
||||
|
|
|
@ -17,8 +17,7 @@ namespace nxs {
|
|||
class Nexus {
|
||||
public:
|
||||
|
||||
class Entry {
|
||||
public:
|
||||
struct Entry {
|
||||
Entry(): patch_start(0xffffffff), border_start(0xffffffff),
|
||||
patch_size(0), border_size(0),
|
||||
nvert(0), nface(0), sphere(vcg::Sphere3f()) {}
|
||||
|
@ -30,11 +29,21 @@ class Nexus {
|
|||
unsigned short nvert;
|
||||
unsigned short nface;
|
||||
vcg::Sphere3f sphere;
|
||||
|
||||
float error;
|
||||
unsigned short ram;
|
||||
unsigned short agp;
|
||||
};
|
||||
|
||||
struct Update {
|
||||
std::vector<unsigned int> erased;
|
||||
std::vector<unsigned int> created;
|
||||
};
|
||||
|
||||
|
||||
Nexus();
|
||||
~Nexus();
|
||||
bool Create(const std::string &filename);
|
||||
bool Create(const std::string &filename, Patch::Signature signature);
|
||||
bool Load(const std::string &filename);
|
||||
void Close();
|
||||
|
||||
|
@ -54,6 +63,8 @@ class Nexus {
|
|||
void CompactBorder(unsigned int patch);
|
||||
void CompactBorders();
|
||||
void CompactPatches();
|
||||
|
||||
Patch::Signature signature;
|
||||
|
||||
unsigned int totvert;
|
||||
unsigned int totface;
|
||||
|
@ -63,6 +74,8 @@ class Nexus {
|
|||
|
||||
VFile<Chunk> patches;
|
||||
VFile<Link> borders;
|
||||
|
||||
std::vector<Update> history;
|
||||
private:
|
||||
FILE *index_file;
|
||||
};
|
||||
|
|
|
@ -88,6 +88,22 @@ int main(int argc, char *argv[]) {
|
|||
cerr << endl;
|
||||
|
||||
nexus.Join((*k).second, newvert, newface, newbord);
|
||||
|
||||
|
||||
|
||||
|
||||
/* unsigned int patch_idx = test.AddPatch(newvert.size(),
|
||||
newface.size()/3,0);
|
||||
Patch patch = test.GetPatch(patch_idx);
|
||||
for(unsigned int v = 0; v < newface.size(); v++)
|
||||
patch.FaceBegin()[v] = (unsigned short)newface[v];
|
||||
memcpy(patch.VertBegin(), &newvert[0], newvert.size() * sizeof(Point3f));
|
||||
|
||||
Nexus::Entry &entry = test.index[patch_idx];
|
||||
for(int v = 0; v < newvert.size(); v++) {
|
||||
entry.sphere.Add(newvert[v]);
|
||||
test.sphere.Add(newvert[v]);
|
||||
}*/
|
||||
|
||||
//simplify(mesh);
|
||||
|
||||
|
@ -140,9 +156,11 @@ int main(int argc, char *argv[]) {
|
|||
vector<int> &v_remap = vert_remap[cell];
|
||||
vector<int> &f_remap = face_remap[cell];
|
||||
|
||||
verts.resize(vert_count[cell]);
|
||||
for(unsigned int i = 0; i < newvert.size(); i++) {
|
||||
if(v_remap[i] != -1)
|
||||
verts.push_back(newvert[v_remap[i]]);
|
||||
verts[v_remap[i]] = newvert[i];
|
||||
// verts.push_back(newvert[v_remap[i]]);
|
||||
}
|
||||
|
||||
assert(verts.size() == vert_count[cell]);
|
||||
|
@ -181,25 +199,32 @@ int main(int argc, char *argv[]) {
|
|||
}
|
||||
}
|
||||
}
|
||||
unsigned int patch_idx = test.AddPatch(verts.size(),faces.size()/3,0);
|
||||
Patch patch = test.GetPatch(patch_idx);
|
||||
//create new nexus patch
|
||||
unsigned int patch_idx = nexus.AddPatch(verts.size(),
|
||||
faces.size()/3,
|
||||
bords.size());
|
||||
|
||||
Nexus::Entry &entry = nexus.index[patch_idx];
|
||||
|
||||
Patch patch = nexus.GetPatch(patch_idx);
|
||||
memcpy(patch.FaceBegin(), &faces[0],
|
||||
faces.size() * sizeof(unsigned short));
|
||||
memcpy(patch.VertBegin(), &verts[0], verts.size() * sizeof(Point3f));
|
||||
|
||||
Nexus::Entry &entry = test.index[patch_idx];
|
||||
|
||||
for(int v = 0; v < verts.size(); v++) {
|
||||
entry.sphere.Add(verts[v]);
|
||||
test.sphere.Add(verts[v]);
|
||||
}
|
||||
nexus.sphere.Add(verts[v]);
|
||||
}
|
||||
|
||||
Border border = nexus.GetBorder(patch_idx);
|
||||
memcpy(&border[0], &bords[0], bords.size());
|
||||
|
||||
//create new nexus patch
|
||||
//collect external borders
|
||||
}
|
||||
|
||||
|
||||
|
||||
//fix borders
|
||||
//fix external borders?
|
||||
|
||||
|
||||
cell_offset += vert_remap.size();
|
||||
|
|
|
@ -24,6 +24,9 @@
|
|||
History
|
||||
|
||||
$Log: not supported by cvs2svn $
|
||||
Revision 1.4 2004/08/27 00:38:34 ponchio
|
||||
Minor changes.
|
||||
|
||||
Revision 1.3 2004/07/15 14:32:49 ponchio
|
||||
Debug.
|
||||
|
||||
|
@ -51,6 +54,12 @@ Created
|
|||
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef WIN32
|
||||
#include "getopt.h"
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
|
@ -59,7 +68,7 @@ using namespace std;
|
|||
#include <GL/gl.h>
|
||||
#include <GL/glu.h>
|
||||
|
||||
#include <apps/nexus/nexus.h>
|
||||
#include <apps/nexus/nexusmt.h>
|
||||
|
||||
using namespace vcg;
|
||||
using namespace nxs;
|
||||
|
@ -112,26 +121,38 @@ bool init() {
|
|||
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
char file[64];
|
||||
if(argc < 2 || argc > 4) {
|
||||
cerr << "Usage: " << argv[0] << " <nexus file> [start] [end]\n";
|
||||
return -1;
|
||||
int level = 0;
|
||||
int apatch = -1;
|
||||
float geo_error = -1;
|
||||
float screen_error = -1;
|
||||
int option;
|
||||
|
||||
while((option = getopt(argc, argv, "l:p:g:s:")) != EOF) {
|
||||
switch(option) {
|
||||
case 'l': level = atoi(optarg); break;
|
||||
case 'p': apatch = atoi(optarg); break;
|
||||
case 'g': geo_error = (float)atof(optarg); break;
|
||||
case 's': screen_error = (float)atof(optarg); break;
|
||||
default: cerr << "Unknown option: " << (char)option << endl;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int start = 0;
|
||||
unsigned int end = 0xffffffff;
|
||||
|
||||
if(argc >= 3)
|
||||
start = atoi(argv[2]);
|
||||
if(optind != argc - 1) {
|
||||
cerr << "Usage: " << argv[0] << " <nexus file> [options]\n"
|
||||
<< " -l <n>: show level n\n"
|
||||
<< " -p <n>: show patch n\n"
|
||||
<< " -g <e>: extract at geometry error e\n"
|
||||
<< " -s <e>: extract at screen error e\n\n";
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(argc >= 4)
|
||||
end = atoi(argv[3]);
|
||||
|
||||
Nexus nexus;
|
||||
if(!nexus.Load(argv[1])) {
|
||||
NexusMt nexus;
|
||||
if(!nexus.Load(argv[optind])) {
|
||||
cerr << "Could not load nexus file: " << argv[1] << endl;
|
||||
return -1;
|
||||
}
|
||||
nexus.LoadHistory();
|
||||
Sphere3f sphere = nexus.sphere;
|
||||
|
||||
if(!init()) {
|
||||
|
@ -200,13 +221,24 @@ int main(int argc, char *argv[]) {
|
|||
Point3f center = sphere.Center();
|
||||
glTranslatef(-center[0], -center[1], -center[2]);
|
||||
|
||||
vector<unsigned int> cells;
|
||||
if(apatch != -1) {
|
||||
cells.push_back(apatch);
|
||||
} else if(geo_error != -1) {
|
||||
nexus.ExtractFixed(cells, geo_error);
|
||||
} else {
|
||||
for(int i = 0; i < nexus.index.size(); i++) {
|
||||
if(nexus.index[i].error == 0)
|
||||
cells.push_back(i);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for(unsigned int i = 0; i < nexus.index.size(); i++) {
|
||||
if(i < start) continue;
|
||||
if(i >= end) continue;
|
||||
Patch patch = nexus.GetPatch(i);
|
||||
for(unsigned int i = 0; i < cells.size(); i++) {
|
||||
unsigned int cell = cells[i];
|
||||
Patch patch = nexus.GetPatch(cell);
|
||||
|
||||
unsigned int val = i + 1;
|
||||
unsigned int val = cell + 1;
|
||||
glColor3ub(((val * 27)%128) + 128,
|
||||
((val * 37)%128) + 128,
|
||||
((val * 87)%128) + 128);
|
||||
|
@ -229,8 +261,9 @@ int main(int argc, char *argv[]) {
|
|||
//drawing borders
|
||||
glColor3f(1, 1, 1);
|
||||
|
||||
Border border = nexus.GetBorder(i);
|
||||
glPointSize(1);
|
||||
Border border = nexus.GetBorder(cell);
|
||||
glPointSize(2);
|
||||
glDisable(GL_LIGHTING);
|
||||
glBegin(GL_POINTS);
|
||||
for(unsigned int k = 0; k < border.Size(); k++) {
|
||||
if(border[k].IsNull()) continue;
|
||||
|
@ -238,6 +271,7 @@ int main(int argc, char *argv[]) {
|
|||
glVertex3f(p[0], p[1], p[2]);
|
||||
}
|
||||
glEnd();
|
||||
glEnable(GL_LIGHTING);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -11,18 +11,53 @@ struct Chunk {
|
|||
|
||||
class Patch {
|
||||
public:
|
||||
|
||||
Patch(Chunk *s = NULL, unsigned short nv = 0, unsigned short nf = 0):
|
||||
|
||||
enum Signature { DEFAULT = 0,
|
||||
HAS_STRIP = 0x002, //if true faces saved as strip
|
||||
HAS_COLORS = 0x004,
|
||||
HAS_NORMALS_SHORT = 0x008,
|
||||
HAS_NORMALS_FLOAT = 0x008,
|
||||
HAS_TEXTURES_SHORT = 0x010,
|
||||
HAS_TEXTURES_FLOAT = 0x020,
|
||||
HAS_DATA8 = 0x040,
|
||||
HAS_DATA16 = 0x080,
|
||||
HAS_DATA32 = 0x100,
|
||||
HAS_DATA64 = 0x200 };
|
||||
|
||||
Patch(Signature signature, Chunk *s = NULL,
|
||||
unsigned short nv = 0, unsigned short nf = 0):
|
||||
start(s) {
|
||||
Resize(nv, nf);
|
||||
Resize(signature, nv, nf);
|
||||
}
|
||||
|
||||
void Resize(unsigned short nv, unsigned short nf) {
|
||||
void Resize(Signature signature, unsigned short nv, unsigned short nf) {
|
||||
nvert = nv;
|
||||
nface = nf;
|
||||
fstart = (unsigned short *)(((char *)start) +
|
||||
VertSize() * sizeof(vcg::Point3f));
|
||||
|
||||
unsigned int size = nf * sizeof(unsigned short);
|
||||
if(!(signature & HAS_STRIP)) size *= 3;
|
||||
cstart = (void *)(((char *)fstart) + size);
|
||||
|
||||
if(signature & HAS_COLORS) size = nv * sizeof(unsigned int);
|
||||
else size = 0;
|
||||
|
||||
nstart = (void *)(((char *)cstart) + size);
|
||||
|
||||
size = 0;
|
||||
if(signature & HAS_NORMALS_SHORT) size = nv * 4*sizeof(short);
|
||||
if(signature & HAS_NORMALS_FLOAT) size = nv * 4*sizeof(float);
|
||||
|
||||
tstart = (void *)(((char *)cstart) + size);
|
||||
|
||||
size = 0;
|
||||
if(signature & HAS_TEXTURES_SHORT) size = nv * 2*sizeof(short);
|
||||
if(signature & HAS_TEXTURES_FLOAT) size = nv * 2*sizeof(float);
|
||||
|
||||
dstart = (void *)(((char *)tstart) + size);
|
||||
}
|
||||
|
||||
unsigned short VertSize() { return nvert; }
|
||||
|
||||
vcg::Point3f *VertBegin() { return (vcg::Point3f *)(start); }
|
||||
|
@ -35,19 +70,49 @@ class Patch {
|
|||
|
||||
unsigned short *Face(unsigned int f) { return FaceBegin() + f * 3; }
|
||||
|
||||
unsigned int ChunkSize() { return ChunkSize(VertSize(), FaceSize()); }
|
||||
// unsigned int ChunkSize() { return ChunkSize(VertSize(), FaceSize()); }
|
||||
|
||||
unsigned int ByteSize() { return ByteSize(VertSize(), FaceSize()); }
|
||||
// unsigned int ByteSize() { return ByteSize(VertSize(), FaceSize()); }
|
||||
|
||||
static unsigned int ChunkSize(unsigned short nvert, unsigned short nface) {
|
||||
unsigned int size = ByteSize(nvert, nface);
|
||||
static unsigned int ChunkSize(Signature signature,
|
||||
unsigned short nvert, unsigned short nface) {
|
||||
unsigned int size = ByteSize(signature, nvert, nface);
|
||||
size = (size/sizeof(Chunk) + 1);
|
||||
return size;
|
||||
}
|
||||
|
||||
static unsigned int ByteSize(unsigned short nvert, unsigned short nface) {
|
||||
static unsigned int ByteSize(Signature signature,
|
||||
unsigned short nvert, unsigned short nface) {
|
||||
unsigned int size = nvert * sizeof(vcg::Point3f);
|
||||
size += nface * 3 * sizeof(unsigned short);
|
||||
if(signature & HAS_STRIP)
|
||||
size += nface * sizeof(unsigned short);
|
||||
else
|
||||
size += nface * 3 * sizeof(unsigned short);
|
||||
|
||||
if(signature & HAS_COLORS)
|
||||
size += nvert * sizeof(unsigned int);
|
||||
|
||||
if(signature & HAS_NORMALS_SHORT)
|
||||
size += nvert * 4 * sizeof(short);
|
||||
|
||||
if(signature & HAS_NORMALS_FLOAT)
|
||||
size += nvert * 3 * sizeof(float);
|
||||
|
||||
if(signature & HAS_TEXTURES_SHORT)
|
||||
size += nvert * 2 * sizeof(short);
|
||||
|
||||
if(signature & HAS_TEXTURES_FLOAT)
|
||||
size += nvert * 2 * sizeof(float);
|
||||
|
||||
if(signature & HAS_DATA8)
|
||||
size += nvert * sizeof(char);
|
||||
if(signature & HAS_DATA16)
|
||||
size += nvert * 2 * sizeof(char);
|
||||
if(signature & HAS_DATA32)
|
||||
size += nvert * 4 * sizeof(char);
|
||||
if(signature & HAS_DATA64)
|
||||
size += nvert * 8 * sizeof(char);
|
||||
|
||||
|
||||
//this condition should really rarely happen but helps save space
|
||||
//during construction
|
||||
|
@ -57,10 +122,15 @@ class Patch {
|
|||
return size;
|
||||
}
|
||||
// private:
|
||||
Chunk *start;
|
||||
unsigned short *fstart;
|
||||
unsigned short nvert;
|
||||
unsigned short nface;
|
||||
|
||||
Chunk *start;
|
||||
unsigned short *fstart;
|
||||
void *cstart;
|
||||
void *nstart;
|
||||
void *tstart;
|
||||
void *dstart;
|
||||
};
|
||||
|
||||
};
|
||||
|
|
|
@ -24,6 +24,9 @@
|
|||
History
|
||||
|
||||
$Log: not supported by cvs2svn $
|
||||
Revision 1.1 2004/08/26 18:03:47 ponchio
|
||||
First draft.
|
||||
|
||||
|
||||
****************************************************************************/
|
||||
|
||||
|
@ -162,7 +165,7 @@ void VoronoiChain::BuildLevel(Nexus &nexus, unsigned int offset) {
|
|||
unsigned int target_faces = (int)(patch_size *
|
||||
pow(scaling, (float)levels.size()));
|
||||
|
||||
float rad = radius * pow(1.4f, (float)levels.size());
|
||||
float rad = radius * pow(sqrt(1/scaling), (float)levels.size());
|
||||
|
||||
levels.push_back(VoronoiPartition());
|
||||
VoronoiPartition &part = levels[levels.size()-1];
|
||||
|
@ -179,6 +182,7 @@ void VoronoiChain::BuildLevel(Nexus &nexus, unsigned int offset) {
|
|||
part.Add(v, rad);
|
||||
}
|
||||
}
|
||||
cerr << "radius: " << rad << endl;
|
||||
cerr << "radius: " << rad << " ... cells: " << part.size() << endl;
|
||||
newfragments.clear();
|
||||
//TODO add some optimization
|
||||
}
|
||||
|
|
|
@ -24,6 +24,9 @@
|
|||
History
|
||||
|
||||
$Log: not supported by cvs2svn $
|
||||
Revision 1.1 2004/08/26 18:03:48 ponchio
|
||||
First draft.
|
||||
|
||||
|
||||
****************************************************************************/
|
||||
|
||||
|
@ -61,7 +64,7 @@ class VoronoiChain: public PChain {
|
|||
// coarse partition -> associated patches
|
||||
std::map<unsigned int, std::set<unsigned int> > newfragments;
|
||||
std::map<unsigned int, std::set<unsigned int> > oldfragments;
|
||||
private:
|
||||
// private:
|
||||
float scaling;
|
||||
unsigned int patch_size;
|
||||
unsigned int patch_threshold;
|
||||
|
|
|
@ -24,11 +24,16 @@
|
|||
History
|
||||
|
||||
$Log: not supported by cvs2svn $
|
||||
Revision 1.1 2004/08/26 18:03:48 ponchio
|
||||
First draft.
|
||||
|
||||
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef WIN32
|
||||
#include "getopt.h"
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <iostream>
|
||||
|
@ -77,16 +82,27 @@ void NexusSplit(Nexus &nexus, VoronoiChain &vchain,
|
|||
unsigned int level,
|
||||
vector<Point3f> &newvert,
|
||||
vector<unsigned int> &newface,
|
||||
vector<Link> &newbord);
|
||||
vector<Link> &newbord,
|
||||
Nexus::Update &update,
|
||||
float error);
|
||||
|
||||
float Decimate(unsigned int target_faces,
|
||||
vector<Point3f> &newvert,
|
||||
vector<unsigned int> &newface,
|
||||
vector<Link> &newbord,
|
||||
vector<int> &vert_remap);
|
||||
|
||||
void ReverseHistory(vector<Nexus::Update> &history);
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
|
||||
unsigned int patch_size = 1000;
|
||||
unsigned int patch_threshold = 200;
|
||||
unsigned int max_level = 0xffffffff;
|
||||
float scaling = 0.5;
|
||||
|
||||
int option;
|
||||
while((option = getopt(argc, argv, "f:t:l:")) != EOF) {
|
||||
while((option = getopt(argc, argv, "f:t:l:s:")) != EOF) {
|
||||
switch(option) {
|
||||
case 'f': patch_size = atoi(optarg);
|
||||
if(patch_size == 0 || patch_size > 32000) {
|
||||
|
@ -106,6 +122,12 @@ int main(int argc, char *argv[]) {
|
|||
return -1;
|
||||
}
|
||||
break;
|
||||
case 's': scaling = atof(optarg);
|
||||
if(scaling <= 0 || scaling >= 1) {
|
||||
cerr << "Invalid scaling: " << optarg << endl;
|
||||
cerr << "Must be 0 < scaling < 1" << endl;
|
||||
}
|
||||
break;
|
||||
default: cerr << "Unknown option: " << (char)option << endl;
|
||||
return -1;
|
||||
}
|
||||
|
@ -117,7 +139,8 @@ int main(int argc, char *argv[]) {
|
|||
cerr << " Options:\n";
|
||||
cerr << " -f N: use N faces per patch (default 1000, max 32000)\n";
|
||||
cerr << " -t N: mini faces per patch (default 200)\n";
|
||||
cerr << " -l N: number of levels\n\n";
|
||||
cerr << " -l N: number of levels\n";
|
||||
cerr << " -s F: scaling factor (0 < F < 1, default 0.5)\n\n";
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -134,14 +157,17 @@ int main(int argc, char *argv[]) {
|
|||
}
|
||||
|
||||
string output = argv[optind+1];
|
||||
|
||||
Patch::Signature signature = Patch::DEFAULT;
|
||||
Nexus nexus;
|
||||
if(!nexus.Create(output)) {
|
||||
if(!nexus.Create(output, signature)) {
|
||||
cerr << "Could not create nexus output: " << output << endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
VoronoiChain vchain;
|
||||
vchain.Initialize(patch_size, patch_threshold);
|
||||
vchain.scaling = scaling;
|
||||
|
||||
//Now building level 0 of the Nexus
|
||||
|
||||
|
@ -186,6 +212,11 @@ int main(int argc, char *argv[]) {
|
|||
|
||||
NexusFixBorder(nexus, border_remap);
|
||||
|
||||
//filling history
|
||||
Nexus::Update update;
|
||||
for(unsigned int i = 0; i < nexus.index.size(); i++)
|
||||
update.created.push_back(i);
|
||||
nexus.history.push_back(update);
|
||||
|
||||
/* BUILDING OTHER LEVELS */
|
||||
unsigned int oldoffset = 0;
|
||||
|
@ -195,35 +226,74 @@ int main(int argc, char *argv[]) {
|
|||
|
||||
unsigned int newoffset = nexus.index.size();
|
||||
vchain.BuildLevel(nexus, oldoffset);
|
||||
|
||||
|
||||
map<unsigned int, set<unsigned int> >::iterator fragment;
|
||||
for(fragment = vchain.oldfragments.begin();
|
||||
fragment != vchain.oldfragments.end(); fragment++) {
|
||||
|
||||
|
||||
update.created.clear();
|
||||
update.erased.clear();
|
||||
|
||||
cerr << "Joining: ";
|
||||
set<unsigned int> &fcells = (*fragment).second;
|
||||
set<unsigned int>::iterator s;
|
||||
for(s = fcells.begin(); s != fcells.end(); s++)
|
||||
for(s = fcells.begin(); s != fcells.end(); s++) {
|
||||
update.erased.push_back(*s);
|
||||
cerr << " " << (*s) << endl;
|
||||
}
|
||||
cerr << endl;
|
||||
|
||||
vector<Point3f> newvert;
|
||||
vector<unsigned int> newface;
|
||||
vector<Link> newbord;
|
||||
|
||||
|
||||
nexus.Join((*fragment).second, newvert, newface, newbord);
|
||||
|
||||
|
||||
//simplyfy mesh
|
||||
vector<int> vert_remap;
|
||||
float error = Decimate(newface.size() * scaling/3, newvert,
|
||||
newface, newbord, vert_remap);
|
||||
|
||||
NexusSplit(nexus, vchain, level, newvert, newface, newbord);
|
||||
|
||||
NexusSplit(nexus, vchain, level, newvert, newface, newbord,
|
||||
update, error);
|
||||
|
||||
|
||||
nexus.history.push_back(update);
|
||||
}
|
||||
|
||||
|
||||
//if(vchain.levels.back().size() == 1) break;
|
||||
if(vchain.oldfragments.size() == 1) break;
|
||||
|
||||
vchain.oldfragments = vchain.newfragments;
|
||||
oldoffset = newoffset;
|
||||
}
|
||||
//last level clean history:
|
||||
update.created.clear();
|
||||
update.erased.clear();
|
||||
map<unsigned int, set<unsigned int> >::iterator fragment;
|
||||
for(fragment = vchain.newfragments.begin();
|
||||
fragment != vchain.newfragments.end(); fragment++) {
|
||||
set<unsigned int> &fcells = (*fragment).second;
|
||||
set<unsigned int>::iterator s;
|
||||
for(s = fcells.begin(); s != fcells.end(); s++)
|
||||
update.erased.push_back(*s);
|
||||
}
|
||||
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();
|
||||
|
@ -269,12 +339,14 @@ void NexusAllocate(Crude &crude,
|
|||
cerr << "Warning! Empty patch.\n";
|
||||
|
||||
entry.patch_start = totchunks;
|
||||
entry.patch_size = Patch::ChunkSize(patch_verts[i], patch_faces[i]);
|
||||
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);
|
||||
|
@ -436,7 +508,9 @@ void NexusSplit(Nexus &nexus, VoronoiChain &vchain,
|
|||
unsigned int level,
|
||||
vector<Point3f> &newvert,
|
||||
vector<unsigned int> &newface,
|
||||
vector<Link> &newbord) {
|
||||
vector<Link> &newbord,
|
||||
Nexus::Update &update,
|
||||
float error) {
|
||||
|
||||
//if != -1 remap global index to cell index
|
||||
map<unsigned int, vector<int> > vert_remap;
|
||||
|
@ -452,7 +526,6 @@ void NexusSplit(Nexus &nexus, VoronoiChain &vchain,
|
|||
newvert[newface[f+2]])/3;
|
||||
|
||||
unsigned int cell = vchain.Locate(level+1, bari);
|
||||
|
||||
vector<int> &f_remap = face_remap[cell];
|
||||
f_remap.push_back(newface[f]);
|
||||
f_remap.push_back(newface[f+1]);
|
||||
|
@ -500,9 +573,6 @@ void NexusSplit(Nexus &nexus, VoronoiChain &vchain,
|
|||
faces.resize(face_count[cell]*3);
|
||||
|
||||
for(unsigned int i = 0; i < f_remap.size(); i++) {
|
||||
if(v_remap[f_remap[i]] == -1) {
|
||||
cerr << "i: " << i << " f_remap[i]: " << f_remap[i] << endl;
|
||||
}
|
||||
assert(v_remap[f_remap[i]] != -1);
|
||||
faces[i] = v_remap[f_remap[i]];
|
||||
}
|
||||
|
@ -534,8 +604,12 @@ void NexusSplit(Nexus &nexus, VoronoiChain &vchain,
|
|||
unsigned int patch_idx = nexus.AddPatch(verts.size(),
|
||||
faces.size()/3,
|
||||
bords.size());
|
||||
|
||||
vchain.newfragments[cell].insert(patch_idx);
|
||||
update.created.push_back(patch_idx);
|
||||
|
||||
Nexus::Entry &entry = nexus.index[patch_idx];
|
||||
// entry.error = error;
|
||||
entry.error = level;
|
||||
|
||||
Patch patch = nexus.GetPatch(patch_idx);
|
||||
memcpy(patch.FaceBegin(), &faces[0],
|
||||
|
@ -550,7 +624,13 @@ void NexusSplit(Nexus &nexus, VoronoiChain &vchain,
|
|||
|
||||
Border border = nexus.GetBorder(patch_idx);
|
||||
memcpy(&border[0], &bords[0], bords.size());
|
||||
|
||||
}
|
||||
cerr << "newfrag: " << vchain.newfragments.size() << endl;
|
||||
}
|
||||
|
||||
void ReverseHistory(vector<Nexus::Update> &history) {
|
||||
reverse(history.begin(), history.end());
|
||||
vector<Nexus::Update>::iterator i;
|
||||
for(i = history.begin(); i != history.end(); i++)
|
||||
swap((*i).erased, (*i).created);
|
||||
}
|
||||
|
|
|
@ -24,6 +24,9 @@
|
|||
History
|
||||
|
||||
$Log: not supported by cvs2svn $
|
||||
Revision 1.4 2004/07/20 14:05:45 ponchio
|
||||
Inserted report on progress.
|
||||
|
||||
Revision 1.3 2004/07/15 14:32:49 ponchio
|
||||
Debug.
|
||||
|
||||
|
@ -153,7 +156,7 @@ int main(int argc, char *argv[]) {
|
|||
face_remap.Resize(crude.Faces());
|
||||
|
||||
|
||||
PIntersect<VoronoiPartition> inter(chain.levels[0], chain.levels[1]);
|
||||
PIntersect<VoronoiPartition> inter(&(chain.levels[0]), &(chain.levels[1]));
|
||||
|
||||
report.Start(crude.Faces(), 100000);
|
||||
cerr << "Splitting faces... ";
|
||||
|
@ -170,6 +173,8 @@ int main(int argc, char *argv[]) {
|
|||
|
||||
//TODO Prune inter to threshold and relocate faces
|
||||
|
||||
inter.Save(output);
|
||||
|
||||
VertRemap vert_remap;
|
||||
if(!vert_remap.Create(output)) {
|
||||
cerr << "Could not create remap files: " << output << ".rmv and .rmb\n";
|
||||
|
@ -195,7 +200,7 @@ int main(int argc, char *argv[]) {
|
|||
}
|
||||
cerr << "done in " << report.Elapsed() << " secs\n";
|
||||
cerr << "Tot vertices: " << totvert << endl;
|
||||
chain.Save(output + ".chn");
|
||||
chain.Save(output);
|
||||
|
||||
for(unsigned int i = 0; i < vert_remap.all.Size(); i++) {
|
||||
unsigned int patch = vert_remap.all[i];
|
||||
|
|
Loading…
Reference in New Issue