From d9f8e55d90e433e4d52c07ae22f75e7cb79c9e18 Mon Sep 17 00:00:00 2001 From: ponchio Date: Thu, 30 Sep 2004 00:27:42 +0000 Subject: [PATCH] Lot of changes. Backup. --- apps/nexus/decimate.cpp | 3 +- apps/nexus/nexus.cpp | 2 +- apps/nexus/nexus.h | 7 +- apps/nexus/nexusmt.cpp | 143 ++++++++++++++++++++++++++ apps/nexus/nexusmt.h | 56 ++++++++++- apps/nexus/nexusview.cpp | 194 ++++++++++++++++++++---------------- apps/nexus/patch.cpp | 41 ++++---- apps/nexus/patch.h | 42 +++++--- apps/nexus/voronoichain.cpp | 101 ++++++++++--------- apps/nexus/voronoichain.h | 7 +- apps/nexus/voronoinxs.cpp | 9 +- 11 files changed, 430 insertions(+), 175 deletions(-) diff --git a/apps/nexus/decimate.cpp b/apps/nexus/decimate.cpp index 1a862510..3278ea25 100644 --- a/apps/nexus/decimate.cpp +++ b/apps/nexus/decimate.cpp @@ -185,7 +185,7 @@ float Cluster(MyMesh &mesh, unsigned int target_faces) { } unsigned int nborder = part.size(); //Dovrei supersamplare prima.... - while(nseeds > 0) { + while(nseeds > 0 && part.size() < mesh.vn) { unsigned int i = rand() % mesh.vert.size(); if(mesh.vert[i].IsW() && !mesh.vert[i].IsV()) { const Point3f &p = mesh.vert[i].cP(); @@ -198,7 +198,6 @@ float Cluster(MyMesh &mesh, unsigned int target_faces) { part.SetBox(box); part.Init(); - vector centroid; vector count; for(unsigned int i = 0; i < 3; i++) { diff --git a/apps/nexus/nexus.cpp b/apps/nexus/nexus.cpp index a263fbc4..b89168fb 100644 --- a/apps/nexus/nexus.cpp +++ b/apps/nexus/nexus.cpp @@ -133,7 +133,7 @@ Patch Nexus::GetPatch(unsigned int patch) { Border Nexus::GetBorder(unsigned int patch) { Entry &entry = index[patch]; Link *start = borders.GetRegion(entry.border_start, entry.border_size); - return Border(start, entry.border_used); + return Border(start, entry.border_used, entry.border_size); } diff --git a/apps/nexus/nexus.h b/apps/nexus/nexus.h index 17e53ffa..f8160b74 100644 --- a/apps/nexus/nexus.h +++ b/apps/nexus/nexus.h @@ -44,14 +44,15 @@ class Nexus { Nexus(); - ~Nexus(); + virtual ~Nexus(); bool Create(const std::string &filename, Signature signature); - bool Load(const std::string &filename); - void Close(); + virtual bool Load(const std::string &filename); + virtual void Close(); Patch GetPatch(unsigned int patch); Border GetBorder(unsigned int patch); + bool IsCompressed() { return signature & NXS_COMPRESSED; } //MOVE to nexus_build.cpp diff --git a/apps/nexus/nexusmt.cpp b/apps/nexus/nexusmt.cpp index a120d483..efe66a28 100644 --- a/apps/nexus/nexusmt.cpp +++ b/apps/nexus/nexusmt.cpp @@ -1,8 +1,11 @@ +#include #include "nexusmt.h" #include #include + using namespace nxs; +using namespace vcg; using namespace std; void Policy::Visit(Node *node, std::queue &qnode) { @@ -30,6 +33,146 @@ bool FrustumPolicy::Expand(unsigned int patch, Nexus::Entry &entry) { } +NexusMt::NexusMt(): vbo(VBO_AUTO), vbo_size(0), + policy(NULL), error(4), realtime(true), + mode(SMOOTH) { + policy = new FrustumPolicy(); +} + +bool NexusMt::Load(const string &filename) { + if(!Nexus::Load(filename)) return false; + LoadHistory(); + + use_colors = false; + use_normals = false; + use_textures = false; + use_data = false; + + SetComponent(COLOR, true); + SetComponent(NORMAL, true); + SetComponent(TEXTURE, true); + SetComponent(DATA, true); + + return true; +} + +bool NexusMt::InitGL() { + GLenum ret = glewInit(); + if(ret != GLEW_OK) return false; + if(!GLEW_ARB_vertex_buffer_object) + vbo = VBO_OFF; + return true; +} + +void NexusMt::Render() { + Frustumf frustum; + frustum.GetView(); + + vector cells; + if(policy) { + policy->GetView(); + Extract(cells, policy); + } else { + ExtractFixed(cells, error); + } + + glEnableClientState(GL_VERTEX_ARRAY); + if(use_colors) + glEnableClientState(GL_COLOR_ARRAY); + if(use_normals) + glEnableClientState(GL_NORMAL_ARRAY); + //TODO textures and data. + + for(unsigned int i = 0; i < cells.size(); i++) { + Nexus::Entry &entry = index[cells[i]]; + //frustum culling + // if(frustum.Outside(entry.sphere.center, entry.sphere.radius)) + // continue; + Patch patch = GetPatch(cells[i]); + glVertexPointer(3, GL_FLOAT, 0, patch.VertBegin()); + if(use_colors) + glColorPointer(4, GL_UNSIGNED_BYTE, 0, patch.ColorBegin()); + if(use_normals) + glNormalPointer(GL_SHORT, 8, patch.Norm16Begin()); + switch(mode) { + case POINTS: + glDrawArrays(GL_POINTS, 0, patch.nv); break; + case SMOOTH: + if(signature & NXS_FACES) + glDrawElements(GL_TRIANGLES, patch.nf * 3, + GL_UNSIGNED_SHORT, patch.FaceBegin()); + else if(signature & NXS_STRIP) + glDrawElements(GL_TRIANGLE_STRIP, patch.nf, + GL_UNSIGNED_SHORT, patch.FaceBegin()); + break; + default: + cerr << "Unsupported rendering mode sorry\n"; + exit(0); + break; + } + } + glDisableClientState(GL_VERTEX_ARRAY); + glDisableClientState(GL_COLOR_ARRAY); + glDisableClientState(GL_NORMAL_ARRAY); +} + +void NexusMt::SetPolicy(Policy *_policy, bool _realtime) { + policy = _policy; + realtime = _realtime; +} + +void NexusMt::SetPolicy(PolicyKind kind, float _error, bool _realtime) { + if(policy) delete policy; + switch(kind) { + case FRUSTUM: policy = new FrustumPolicy(error); break; + case GEOMETRY: policy = NULL; break; + default: policy = NULL; break; + } + error = _error; + realtime = _realtime; +} + +void NexusMt::SetVbo(Vbo _vbo, unsigned int _vbo_size) { + vbo = _vbo; + if(!GLEW_ARB_vertex_buffer_object) + vbo = VBO_OFF; + vbo_size = _vbo_size; +} + +bool NexusMt::SetMode(Mode _mode) { + mode = _mode; +} + +bool NexusMt::SetComponent(Component c, bool on) { + if(c == COLOR && (signature & NXS_COLORS)) + use_colors = on; + if(c == NORMAL && (signature & NXS_NORMALS_SHORT)) + use_normals = on; + if(c == TEXTURE && (signature & NXS_TEXTURES_SHORT)) + use_textures = on; + if(c == DATA && (signature & NXS_DATA32)) + use_data = on; + + components = COLOR * use_colors + NORMAL * use_normals + + TEXTURE * use_textures + DATA * use_data; +} + +bool NexusMt::SetComponents(unsigned int mask) { + SetComponent(COLOR, mask & COLOR); + SetComponent(NORMAL, mask & NORMAL); + SetComponent(TEXTURE, mask & TEXTURE); + SetComponent(DATA, mask & DATA); + + components = mask; + + if( ((mask & COLOR) && !(signature & NXS_COLORS)) || + ((mask & NORMAL) && !(signature & NXS_NORMALS_SHORT)) || + ((mask & TEXTURE) && !(signature & NXS_TEXTURES_SHORT)) || + ((mask & DATA) && !(signature & NXS_DATA32)) ) + return false; + return true; +} + void NexusMt::LoadHistory() { //The last update erases everything. assert(history[0].erased.size() == 0); diff --git a/apps/nexus/nexusmt.h b/apps/nexus/nexusmt.h index 60116cd6..e2b91659 100644 --- a/apps/nexus/nexusmt.h +++ b/apps/nexus/nexusmt.h @@ -24,6 +24,7 @@ namespace nxs { class Policy { public: virtual bool Expand(unsigned int patch, Nexus::Entry &entry) = 0; + virtual void GetView() {} virtual void Visit(Node *node, std::queue &qnode); }; @@ -31,6 +32,8 @@ namespace nxs { public: vcg::Frustumf frustum; float error; + + FrustumPolicy(float _err = 4): error(_err) {} void GetView() { frustum.GetView(); } bool Expand(unsigned int patch, Nexus::Entry &entry); }; @@ -40,13 +43,62 @@ class NexusMt: public Nexus { std::vector nodes; public: - void LoadHistory(); - void ClearHistory(); + //Vertex buffer object mode + enum Vbo { VBO_AUTO, //autodetect best size (fallback if not VBO) + VBO_AUTO_ON, //autodetect best size must use VBO + VBO_OFF, //no vertex buffer object + VBO_FIXED }; //user supplied size + + enum PolicyKind { FRUSTUM, //screen error extraction + GEOMETRY }; //geometry error extraction + enum Mode { POINTS, + SMOOTH, + XRAY, + HIDDEN_LINE, + FLAT_WIRE, + FLAT}; + + enum Component { COLOR = 0x1, + NORMAL = 0x2, + TEXTURE = 0x4, + DATA = 0x8}; + + Vbo vbo; + unsigned int vbo_size; + + Policy *policy; + float error; + bool realtime; + + Mode mode; + + unsigned int components; + bool use_normals; + bool use_colors; + bool use_textures; + bool use_data; + + + NexusMt(); + + bool Load(const std::string &filename); + bool InitGL(); + + void Render(); + void SetPolicy(Policy *policy, bool realtime = true); + void SetPolicy(PolicyKind kind, float error, bool realtime = true); + void SetVbo(Vbo mode, unsigned int vbo_size = 0); + bool SetMode(Mode mode); + bool SetComponent(Component c, bool on); + bool SetComponents(unsigned int mask); + void ExtractFixed(std::vector &selected, float error); void Extract(std::vector &selected, Policy *policy); protected: + void LoadHistory(); + void ClearHistory(); void Select(std::vector &selected); }; diff --git a/apps/nexus/nexusview.cpp b/apps/nexus/nexusview.cpp index 96483f57..910f170d 100644 --- a/apps/nexus/nexusview.cpp +++ b/apps/nexus/nexusview.cpp @@ -24,6 +24,9 @@ History $Log: not supported by cvs2svn $ +Revision 1.7 2004/09/28 10:26:35 ponchio +Backup + Revision 1.6 2004/09/17 15:25:09 ponchio First working (hopefully) release. @@ -163,7 +166,6 @@ int main(int argc, char *argv[]) { cerr << "Could not load nexus file: " << argv[1] << endl; return -1; } - nexus.LoadHistory(); Sphere3f sphere = nexus.sphere; if(!init()) { @@ -171,11 +173,13 @@ int main(int argc, char *argv[]) { return -1; } - FrustumPolicy frustum_policy; + // FrustumPolicy frustum_policy; bool rotate = true; bool show_borders = true; + bool show_colors = true; + bool show_normals = true; glClearColor(0, 0, 0, 0); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); @@ -186,13 +190,21 @@ int main(int argc, char *argv[]) { int x, y; float alpha = 0; while( !quit ) { - while( SDL_PollEvent( &event ) ){ + while( SDL_WaitEvent( &event ) ){ switch( event.type ) { case SDL_QUIT: quit = 1; break; case SDL_KEYDOWN: switch(event.key.keysym.sym) { case SDLK_q: exit(0); break; case SDLK_b: show_borders = !show_borders;break; + case SDLK_c: + show_colors = !show_colors; + + break; + case SDLK_n: + show_normals = !show_normals; + break; + case SDLK_r: case SDLK_SPACE: rotate = !rotate; break; @@ -234,106 +246,120 @@ int main(int argc, char *argv[]) { break; default: break; } - } - - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - gluPerspective(40, 1, 0.1, 100); - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - gluLookAt(0,0,5, 0,0,0, 0,1,0); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective(40, 1, 0.1, 100); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + gluLookAt(0,0,5, 0,0,0, 0,1,0); - track.GetView(); - track.Apply(); - - float scale = 2/sphere.Radius(); - // glRotatef(alpha, 0, 1, 0); - // if(rotate) - // alpha++; - // if(alpha > 360) alpha = 0; - glScalef(scale, scale, scale); - Point3f center = sphere.Center(); - glTranslatef(-center[0], -center[1], -center[2]); + track.GetView(); + track.Apply(); + float scale = 2/sphere.Radius(); + // glRotatef(alpha, 0, 1, 0); + // if(rotate) + // alpha++; + // if(alpha > 360) alpha = 0; + glScalef(scale, scale, scale); + Point3f center = sphere.Center(); + glTranslatef(-center[0], -center[1], -center[2]); + nexus.SetPolicy(NexusMt::FRUSTUM, error); + nexus.SetComponent(NexusMt::COLOR, show_colors); + nexus.SetComponent(NexusMt::NORMAL, show_normals); - vector cells; - if(apatch != -1) { - cells.push_back(apatch); - } else if(mode == GEO) { - nexus.ExtractFixed(cells, error); - } else if(mode == SCREEN) { - frustum_policy.error = error; - frustum_policy.GetView(); - nexus.Extract(cells, &frustum_policy); - } else { - for(int i = 0; i < nexus.index.size(); i++) { - if(nexus.index[i].error == 0) - cells.push_back(i); + nexus.Render(); + + /* vector cells; + if(apatch != -1) { + cells.push_back(apatch); + } else if(mode == GEO) { + nexus.ExtractFixed(cells, error); + } else if(mode == SCREEN) { + frustum_policy.error = error; + frustum_policy.GetView(); + nexus.Extract(cells, &frustum_policy); + } else { + for(int i = 0; i < nexus.index.size(); i++) { + if(nexus.index[i].error == 0) + cells.push_back(i); + } } - } + glColor3f(1, 1, 1); - for(unsigned int i = 0; i < cells.size(); i++) { - unsigned int cell = cells[i]; - Patch patch = nexus.GetPatch(cell); - - unsigned int val = cell + 1; - glColor3ub(((val * 27)%128) + 128, - ((val * 37)%128) + 128, - ((val * 87)%128) + 128); - - /* Nexus::Entry &entry = nexus.index[cell]; - float error = entry.error; - if(error < 1) error = 0; - glColor3ub(log(error) * 50, 128, 128);*/ - - glBegin(GL_TRIANGLES); - unsigned short *f = patch.FaceBegin(); - for(unsigned int j = 0; j < patch.nf*3; j+= 3) { - Point3f &p1 = patch.Vert(f[j]); - Point3f &p2 = patch.Vert(f[j+1]); - Point3f &p3 = patch.Vert(f[j+2]); - Point3f n = ((p2 - p1) ^ (p3 - p1)); - - glNormal3f(n[0], n[1], n[2]); - glVertex3f(p1[0], p1[1], p1[2]); - glVertex3f(p2[0], p2[1], p2[2]); - glVertex3f(p3[0], p3[1], p3[2]); - } - glEnd(); - } - if(show_borders) { for(unsigned int i = 0; i < cells.size(); i++) { unsigned int cell = cells[i]; Patch patch = nexus.GetPatch(cell); - //drawing borders - glColor3f(1, 1, 1); + + if(show_color) { + unsigned int val = cell + 1; + glColor3ub(((val * 27)%128) + 128, + ((val * 37)%128) + 128, + ((val * 87)%128) + 128); + } + + glBegin(GL_TRIANGLES); + unsigned short *f = patch.FaceBegin(); + for(unsigned int j = 0; j < patch.nf*3; j+= 3) { + Point3f &p1 = patch.Vert(f[j]); + Point3f &p2 = patch.Vert(f[j+1]); + Point3f &p3 = patch.Vert(f[j+2]); + Point3f n = ((p2 - p1) ^ (p3 - p1)); - Border border = nexus.GetBorder(cell); - glPointSize(4); - glDisable(GL_LIGHTING); - glDisable(GL_DEPTH_TEST); - glBegin(GL_POINTS); - for(unsigned int k = 0; k < border.Size(); k++) { - if(border[k].IsNull()) continue; - Point3f &p = patch.Vert(border[k].start_vert); - glVertex3f(p[0], p[1], p[2]); + if(!show_normals) { + glNormal3f(n[0], n[1], n[2]); + glVertex3f(p1[0], p1[1], p1[2]); + glVertex3f(p2[0], p2[1], p2[2]); + glVertex3f(p3[0], p3[1], p3[2]); + } else { + short *n1 = patch.Norm16(f[j]); + short *n2 = patch.Norm16(f[j+1]); + short *n3 = patch.Norm16(f[j+2]); + glNormal3s(n1[0], n1[1], n1[2]); + glVertex3f(p1[0], p1[1], p1[2]); + glNormal3s(n2[0], n2[1], n2[2]); + glVertex3f(p2[0], p2[1], p2[2]); + glNormal3s(n3[0], n3[1], n3[2]); + glVertex3f(p3[0], p3[1], p3[2]); + } + } glEnd(); - glEnable(GL_DEPTH_TEST); - glEnable(GL_LIGHTING); } - } - + if(show_borders) { + for(unsigned int i = 0; i < cells.size(); i++) { + unsigned int cell = cells[i]; + Patch patch = nexus.GetPatch(cell); + //drawing borders + glColor3f(1, 1, 1); + + Border border = nexus.GetBorder(cell); + glPointSize(4); + glDisable(GL_LIGHTING); + glDisable(GL_DEPTH_TEST); + glBegin(GL_POINTS); + for(unsigned int k = 0; k < border.Size(); k++) { + if(border[k].IsNull()) continue; + Point3f &p = patch.Vert(border[k].start_vert); + glVertex3f(p[0], p[1], p[2]); + } + glEnd(); + glEnable(GL_DEPTH_TEST); + glEnable(GL_LIGHTING); + } + } +*/ - SDL_GL_SwapBuffers(); + SDL_GL_SwapBuffers(); + } } - // Clean up + // Clean up SDL_Quit(); return -1; diff --git a/apps/nexus/patch.cpp b/apps/nexus/patch.cpp index 73f75bac..bd9ad177 100644 --- a/apps/nexus/patch.cpp +++ b/apps/nexus/patch.cpp @@ -14,9 +14,9 @@ void Patch::Init(Signature signature, nv = nvert; nf = nface; - if(signature & HAS_FACES) + if(signature & NXS_FACES) vstart = (float *)(((char *)start) + nf * sizeof(unsigned short) * 3); - else if(signature & HAS_STRIP) + else if(signature & NXS_STRIP) vstart = (float *)(((char *)start) + nf * sizeof(unsigned short)); else vstart = (float *)start; @@ -25,18 +25,21 @@ void Patch::Init(Signature signature, if(((int)vstart) & 0x2) vstart = (float *)(((char *)vstart) + 2); cstart = nv * sizeof(float) * 3; - nstart = cstart + nv * sizeof(unsigned int) * (signature & HAS_COLORS); + if(signature & NXS_COLORS) + nstart = cstart + nv * sizeof(unsigned int); + else + nstart = cstart; - if(signature & HAS_NORMALS_SHORT) - tstart = nstart + nv * sizeof(short) * 3; - else if(signature & HAS_NORMALS_FLOAT) + if(signature & NXS_NORMALS_SHORT) + tstart = nstart + nv * sizeof(short) * 4; + else if(signature & NXS_NORMALS_FLOAT) tstart = nstart + nv * sizeof(float) * 3; else tstart = nstart; - if(signature & HAS_TEXTURES_SHORT) + if(signature & NXS_TEXTURES_SHORT) dstart = tstart + nv * sizeof(short) * 2; - else if(signature & HAS_TEXTURES_FLOAT) + else if(signature & NXS_TEXTURES_FLOAT) dstart = tstart + nv * sizeof(float) * 2; else dstart = tstart; @@ -54,9 +57,9 @@ unsigned int Patch::ByteSize(Signature signature, unsigned short nvert, unsigned short nface) { unsigned int size = 0; - if(signature & HAS_STRIP) + if(signature & NXS_STRIP) size += nface * sizeof(unsigned short); - else if(signature & HAS_FACES) + else if(signature & NXS_FACES) size += nface * 3 * sizeof(unsigned short); //memory alignment @@ -64,28 +67,28 @@ unsigned int Patch::ByteSize(Signature signature, size += nvert * sizeof(vcg::Point3f); - if(signature & HAS_COLORS) + if(signature & NXS_COLORS) size += nvert * sizeof(unsigned int); - if(signature & HAS_NORMALS_SHORT) + if(signature & NXS_NORMALS_SHORT) size += nvert * 4 * sizeof(short); - if(signature & HAS_NORMALS_FLOAT) + if(signature & NXS_NORMALS_FLOAT) size += nvert * 3 * sizeof(float); - if(signature & HAS_TEXTURES_SHORT) + if(signature & NXS_TEXTURES_SHORT) size += nvert * 2 * sizeof(short); - if(signature & HAS_TEXTURES_FLOAT) + if(signature & NXS_TEXTURES_FLOAT) size += nvert * 2 * sizeof(float); - if(signature & HAS_DATA8) + if(signature & NXS_DATA8) size += nvert * sizeof(char); - if(signature & HAS_DATA16) + if(signature & NXS_DATA16) size += nvert * 2 * sizeof(char); - if(signature & HAS_DATA32) + if(signature & NXS_DATA32) size += nvert * 4 * sizeof(char); - if(signature & HAS_DATA64) + if(signature & NXS_DATA64) size += nvert * 8 * sizeof(char); diff --git a/apps/nexus/patch.h b/apps/nexus/patch.h index ddc01182..d4b0e7be 100644 --- a/apps/nexus/patch.h +++ b/apps/nexus/patch.h @@ -5,18 +5,19 @@ #include namespace nxs { -enum Signature { - HAS_FACES = 0x00000001, - HAS_STRIP = 0x00000002, - HAS_COLORS = 0x00000010, - HAS_NORMALS_SHORT = 0x00000100, - HAS_NORMALS_FLOAT = 0x00000200, - HAS_TEXTURES_SHORT = 0x00001000, - HAS_TEXTURES_FLOAT = 0x00002000, - HAS_DATA8 = 0x00010000, - HAS_DATA16 = 0x00020000, - HAS_DATA32 = 0x00040000, - HAS_DATA64 = 0x00080000 }; +enum Signature { NXS_DEFAULT = 0x00000000, + NXS_FACES = 0x00000001, + NXS_STRIP = 0x00000002, + NXS_COLORS = 0x00000010, + NXS_NORMALS_SHORT = 0x00000100, + NXS_NORMALS_FLOAT = 0x00000200, + NXS_TEXTURES_SHORT = 0x00001000, + NXS_TEXTURES_FLOAT = 0x00002000, + NXS_DATA8 = 0x00010000, + NXS_DATA16 = 0x00020000, + NXS_DATA32 = 0x00040000, + NXS_DATA64 = 0x00080000, + NXS_COMPRESSED = 0x10000000}; struct Chunk { unsigned char p[4096]; @@ -36,6 +37,10 @@ class Patch { inline vcg::Point3f &Vert(unsigned short v); inline unsigned short *Face(unsigned short f); + + inline unsigned int *ColorBegin(); + inline short *Norm16Begin(); + inline short *Norm16(unsigned short v); static unsigned int ChunkSize(Signature signature, unsigned short nvert, @@ -52,6 +57,7 @@ class Patch { unsigned short nf; float *vstart; + //these offset are from vstart! unsigned short cstart; unsigned short nstart; unsigned short tstart; @@ -72,6 +78,18 @@ inline unsigned short *Patch::Face(unsigned short f) { return FaceBegin() + f * 3; } +inline unsigned int *Patch::ColorBegin() { + return (unsigned int *)(((char *)vstart) + cstart); +} + +inline short *Patch::Norm16Begin() { + return (short *)(((char *)vstart) + nstart); +} + +inline short *Patch::Norm16(unsigned short v) { + return Norm16Begin() + 4 * v; +} + } //namespace #endif diff --git a/apps/nexus/voronoichain.cpp b/apps/nexus/voronoichain.cpp index e5a47424..5ee4170b 100644 --- a/apps/nexus/voronoichain.cpp +++ b/apps/nexus/voronoichain.cpp @@ -24,6 +24,9 @@ History $Log: not supported by cvs2svn $ +Revision 1.5 2004/09/28 10:26:07 ponchio +Voronoi partition changes. + Revision 1.4 2004/09/21 00:53:23 ponchio Lotsa changes. @@ -85,12 +88,6 @@ void VoronoiChain::Init(Crude &crude, float scaling, int steps) { fine.Init(); coarse.Init(); - for(int i = 0; i < fine.size(); i ++) { - unsigned int target = 0xffffffff; - fine.Closest(fine[i].p, target); - assert(target == i); - - } //here goes some optimization pass. //Fine optimization. vector fcentroids; @@ -110,22 +107,22 @@ void VoronoiChain::Init(Crude &crude, float scaling, int steps) { fcount[ftarget]++; } for(unsigned int v = 0; v < fine.size(); v++) { - if(fcount[v] == 0) { - unsigned int target; - float dist = fine.Closest(fine[v].p, target); - } - assert(fcount[v] != 0); - - + if(fcount[v] == 0) continue; fine[v].p = fcentroids[v]/fcount[v]; - //0.3 is related to the fact is doubled the box size. fine[v].weight = pow(fcount[v]/(float)fine_vmean, 0.3f); - // fine.bbox.Add(fine[v].p); } - // fine.Init(fine.bbox); fine.Init(); } + //remove small or zero patches. + vector seeds; + for(unsigned int i = 0; i < fine.size(); i++) { + if(fcount[i] > min_size) + seeds.push_back(fine[i]); + } + swap(fine, seeds); + fine.Init(); + //here goes some optimization pass. //Coarse optimization. vector ccentroids; @@ -145,24 +142,24 @@ void VoronoiChain::Init(Crude &crude, float scaling, int steps) { ccount[ctarget]++; } for(unsigned int v = 0; v < coarse.size(); v++) { - if(ccount[v] == 0) { - unsigned int target; - float dist = coarse.Closest(fine[v].p, target); - assert(target == v); - } - assert(ccount[v] != 0); + if(ccount[v] == 0) continue; - coarse[v].p = ccentroids[v]/ccount[v]; - //0.3 is related to the fact is doubled the box size. coarse[v].weight = pow(ccount[v]/(float)coarse_vmean, 0.3f); - // fine.bbox.Add(fine[v].p); } - // fine.Init(fine.bbox); coarse.Init(); } + //remove small or zero patches. + seeds.clear(); + for(unsigned int i = 0; i < coarse.size(); i++) { + if(ccount[i] > (int)min_size) + seeds.push_back(coarse[i]); + } + swap(coarse, seeds); + coarse.Init(); + //Coarse optimization /* vector< map > ccentroids; @@ -319,39 +316,46 @@ void VoronoiChain::RemapFaces(Crude &crude, VFile &face_r void VoronoiChain::BuildLevel(Nexus &nexus, unsigned int offset, float scaling, int steps) { - // unsigned int target_faces = (int)(mean_size * - // pow(0.5f, (float)levels.size())); - unsigned int totface = 0; - for(unsigned int idx = offset; idx < nexus.index.size(); idx++) + unsigned int totvert = 0; + unsigned int totbord = 0; + for(unsigned int idx = offset; idx < nexus.index.size(); idx++) { totface += nexus.index[idx].nface; + totvert += nexus.index[idx].nvert; + totbord += nexus.index[idx].border_size; + } + levels.push_back(VoronoiPartition()); VoronoiPartition &coarse = levels[levels.size()-1]; VoronoiPartition &fine = levels[levels.size()-2]; coarse.SetBox(fine.box); - srand(0); - float coarse_vmean = (totface/2)/(fine.size() * scaling); - cerr << "initing random seeds\n"; - + unsigned int tot_coarse = (unsigned int)(fine.size() * scaling); + + float ratio = tot_coarse/(float)(nexus.index.size() - offset); + float cratio = 0; for(unsigned int idx = offset; idx < nexus.index.size(); idx++) { - Patch patch = nexus.GetPatch(idx); - for(unsigned int i = 0; i < patch.nv; i++) { - int c = (int)(coarse_vmean*rand()/(RAND_MAX + 1.0)); - if(c == 1) { - Point3f &v = patch.Vert(i); - coarse.push_back(v); - } + cratio += ratio; + if(cratio > 1) { + Patch patch = nexus.GetPatch(idx); + Point3f &v = patch.Vert(0); + coarse.push_back(v); + cratio -= 1; } } + if(coarse.size() == 0) { Patch patch = nexus.GetPatch(0); coarse.push_back(patch.Vert(0)); } + + float coarse_vmean = totvert/(float)coarse.size(); + coarse.Init(); cerr << "Coarse size: " << coarse.size() << endl; + cerr << "Coarse mean: " << coarse_vmean << " mean_size: " << mean_size << endl; //here goes some optimization pass. //Coarse optimization. vector ccentroids; @@ -375,12 +379,7 @@ void VoronoiChain::BuildLevel(Nexus &nexus, unsigned int offset, } } for(unsigned int v = 0; v < coarse.size(); v++) { - if(ccount[v] == 0) { - unsigned int target = 0xffffffff; - float dist = coarse.Closest(fine[v].p, target); - assert(target == v); - } - assert(ccount[v] != 0); + if(ccount[v] == 0) continue; coarse[v].p = ccentroids[v]/ccount[v]; //0.3 is related to the fact is doubled the box size. @@ -390,7 +389,13 @@ void VoronoiChain::BuildLevel(Nexus &nexus, unsigned int offset, // fine.Init(fine.bbox); coarse.Init(); } - + vector seeds; + for(unsigned int i = 0; i < coarse.size(); i++) { + if(ccount[i] > (int)min_size) + seeds.push_back(coarse[i]); + } + swap(coarse, seeds); + coarse.Init(); //Coarse optimization /* vector< map > ccentroids; diff --git a/apps/nexus/voronoichain.h b/apps/nexus/voronoichain.h index 5d242d56..fdddfb67 100644 --- a/apps/nexus/voronoichain.h +++ b/apps/nexus/voronoichain.h @@ -24,6 +24,9 @@ History $Log: not supported by cvs2svn $ +Revision 1.3 2004/09/21 00:53:23 ponchio +Lotsa changes. + Revision 1.2 2004/09/16 14:25:16 ponchio Backup. (lot of changes). @@ -55,8 +58,8 @@ class VoronoiChain: public PChain { unsigned int min_size; //minimum number of faces per patch (soft) unsigned int max_size; //max number of faces per patch (hard); - VoronoiChain(unsigned int mean_s = 1000, - unsigned int min_s = 300, + VoronoiChain(unsigned int mean_s, + unsigned int min_s, unsigned int max_s = 32000): mean_size(mean_s), min_size(min_s), max_size(max_s) {} virtual ~VoronoiChain() {} diff --git a/apps/nexus/voronoinxs.cpp b/apps/nexus/voronoinxs.cpp index a7bd37fc..95b42045 100644 --- a/apps/nexus/voronoinxs.cpp +++ b/apps/nexus/voronoinxs.cpp @@ -24,6 +24,9 @@ History $Log: not supported by cvs2svn $ +Revision 1.4 2004/09/21 00:53:23 ponchio +Lotsa changes. + Revision 1.3 2004/09/17 15:25:09 ponchio First working (hopefully) release. @@ -106,7 +109,7 @@ int main(int argc, char *argv[]) { Decimation decimation = QUADRIC; unsigned int patch_size = 1000; - unsigned int patch_threshold = 200; + unsigned int patch_threshold = 0xffffffff; unsigned int optimization_steps = 5; bool stop_after_remap = false; unsigned int max_level = 0xffffffff; @@ -183,11 +186,13 @@ int main(int argc, char *argv[]) { string output = argv[optind+1]; Nexus nexus; - if(!nexus.Create(output, HAS_FACES)) { + if(!nexus.Create(output, NXS_FACES)) { cerr << "Could not create nexus output: " << output << endl; return -1; } + if(patch_threshold == 0xffffffff) + patch_threshold = patch_size/4; VoronoiChain vchain(patch_size, patch_threshold); // vchain.scaling = scaling;