diff --git a/apps/nexus/border.h b/apps/nexus/border.h deleted file mode 100644 index 25e0fc77..00000000 --- a/apps/nexus/border.h +++ /dev/null @@ -1,97 +0,0 @@ -/**************************************************************************** -* VCGLib o o * -* Visual and Computer Graphics Library o o * -* _ O _ * -* Copyright(C) 2004 \/)\/ * -* Visual Computing Lab /\/| * -* ISTI - Italian National Research Council | * -* \ * -* All rights reserved. * -* * -* This program is free software; you can redistribute it and/or modify * -* it under the terms of the GNU General Public License as published by * -* the Free Software Foundation; either version 2 of the License, or * -* (at your option) any later version. * -* * -* This program is distributed in the hope that it will be useful, * -* but WITHOUT ANY WARRANTY; without even the implied warranty of * -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * -* GNU General Public License (http://www.gnu.org/licenses/gpl.txt) * -* for more details. * -* * -****************************************************************************/ -/**************************************************************************** - History - -$Log: not supported by cvs2svn $ -Revision 1.6 2005/01/21 17:09:12 ponchio -Porting and debug. - -Revision 1.5 2004/10/08 14:46:26 ponchio -Working version. - -Revision 1.4 2004/09/30 00:27:08 ponchio -Added used counter. - -Revision 1.3 2004/07/05 17:02:17 ponchio -Couple of const missing. - -Revision 1.2 2004/07/04 14:21:31 ponchio -Added operator< to Link - -Revision 1.1 2004/07/02 13:00:02 ponchio -Created. - - -****************************************************************************/ -#ifndef NXS_BORDER_H -#define NXS_BORDER_H - -namespace nxs { - -struct Link { - Link(): start_vert(0xffff), end_vert(0xffff), end_patch(0xffffffff) {} - Link(unsigned short sv, unsigned short ev, unsigned int ep): - start_vert(sv), end_vert(ev), end_patch(ep) {} - unsigned short start_vert; - unsigned short end_vert; - unsigned int end_patch; - bool IsNull() { return end_patch == 0xffffffff; } - - bool operator==(const Link &l) const { - return end_patch == l.end_patch && - end_vert == l.end_vert && - start_vert == l.start_vert; - } - bool operator<(const Link &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 Border { - public: - Border(Link *l = NULL, unsigned short _used = 0, unsigned short _size = 0): - links(l), used(_used), size(_size), start(0) {} - unsigned int Size() { return used; } - //TODO rename available to capacity. - unsigned int Capacity() { return size; } - Link &operator[](unsigned int i) { return links[i]; } - Link *Start() { return links; } - - //TODO implement an iterator! - Link *links; - unsigned int used; - unsigned int size; - unsigned int start; -}; - -} - - -#endif diff --git a/apps/nexus/borderserver.cpp b/apps/nexus/borderserver.cpp deleted file mode 100644 index f5c726d8..00000000 --- a/apps/nexus/borderserver.cpp +++ /dev/null @@ -1,176 +0,0 @@ -/**************************************************************************** -* VCGLib o o * -* Visual and Computer Graphics Library o o * -* _ O _ * -* Copyright(C) 2004 \/)\/ * -* Visual Computing Lab /\/| * -* ISTI - Italian National Research Council | * -* \ * -* All rights reserved. * -* * -* This program is free software; you can redistribute it and/or modify * -* it under the terms of the GNU General Public License as published by * -* the Free Software Foundation; either version 2 of the License, or * -* (at your option) any later version. * -* * -* This program is distributed in the hope that it will be useful, * -* but WITHOUT ANY WARRANTY; without even the implied warranty of * -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * -* GNU General Public License (http://www.gnu.org/licenses/gpl.txt) * -* for more details. * -* * -****************************************************************************/ -/**************************************************************************** - History - -$Log: not supported by cvs2svn $ -Revision 1.10 2005/02/08 12:43:03 ponchio -Added copyright - - -****************************************************************************/ - -#include "borderserver.h" -#include - -using namespace std; -using namespace nxs; - -bool BorderServer::Create(const string &file) { - ram_used = 0; - return IndexFile::Create(file, 2 * sizeof(Link)); -} - -bool BorderServer::Load(const string &file, bool rdonly) { - ram_used = 0; - bool success = IndexFile::Load(file, rdonly); - if(!success) return false; - for(unsigned int i = 0; i < size(); i++) - operator[](i).links = NULL; - return true; -} - -void BorderServer::Close() { - if(!Opened()) return; - Flush(); - IndexFile::Close(); -} - -void BorderServer::Flush() { - std::map::iterator>::iterator i; - for(i = index.begin(); i != index.end(); i++) { - unsigned int patch = (*i).first; - FlushBorder(patch); - } - pqueue.clear(); - index.clear(); -} - -void BorderServer::AddBorder(unsigned short _size, unsigned int used) { - Border entry; - assert((Length() % sizeof(Link)) == 0); - - entry.start = Length()/ sizeof(Link); - entry.size = _size; - entry.used = used; - entry.links = NULL; - push_back(entry); - Redim((int64)entry.start * (int64)sizeof(Link) + (int64)_size * (int64)sizeof(Link)); -} - -Border &BorderServer::GetBorder(unsigned int border, bool flush) { - Border &entry = operator[](border); - //assert(entry.size != 0); - if(index.count(border)) { - //assert(entry.links); - list::iterator i = index[border]; - pqueue.erase(i); - pqueue.push_front(border); - index[border] = pqueue.begin(); - } else { - while(flush && ram_used > ram_max) { - if(!pqueue.size()) { - cerr << "Ram used: " << ram_used << " ram max: " << ram_max << endl; - } - assert(pqueue.size()); - unsigned int to_flush = pqueue.back(); - pqueue.pop_back(); - index.erase(to_flush); - FlushBorder(to_flush); - } - entry.links = GetRegion(entry.start, entry.size); - pqueue.push_front(border); - index[border] = pqueue.begin(); - ram_used += entry.size; - } - return entry; -} -//TODO Change when remving borderentry class. -void BorderServer::ResizeBorder(unsigned int border, unsigned int used) { - assert(border < size()); - Border &entry = GetBorder(border); - if(used <= entry.size) { - entry.used = used; - return; - } - - int capacity = used; - if(capacity < entry.size * 2) - capacity = entry.size * 2; - - unsigned int newstart = Length()/sizeof(Link); - Redim((int64)(newstart + capacity) * (int64)sizeof(Link)); - Link *newlinks = new Link[capacity]; - ram_used += (capacity - entry.size); - - if(entry.used > 0) { - assert(entry.links); - memcpy(newlinks, entry.links, entry.used * sizeof(Link)); - delete []entry.links; - entry.links = NULL; - } - assert(entry.links == NULL); - entry.links = newlinks; - entry.start = newstart; - entry.size = capacity; - entry.used = used; -} - -void BorderServer::FlushBorder(unsigned int border) { - Border &entry = operator[](border); - //assert(entry.links); - if(entry.size && !MFile::IsReadOnly()) { //write back patch - MFile::SetPosition((int64)entry.start * (int64)sizeof(Link)); - MFile::WriteBuffer(entry.links, entry.used * (int64)sizeof(Link)); - } - if(entry.links) - delete [](entry.links); - entry.links = NULL; - ram_used -= entry.size; -} - -Link *BorderServer::GetRegion(unsigned int start, unsigned int size) { - if(size == 0) return NULL; - SetPosition((int64)start * (int64)sizeof(Link)); - Link *buf = new Link[size]; - assert(buf); - ReadBuffer(buf, (int64)size * (int64)sizeof(Link)); - return buf; -} - -bool BorderServer::LoadHeader() { - unsigned int magic; - ReadBuffer(&magic, sizeof(unsigned int)); - if(magic != 0x3042584e) { //NXB0 - cerr << "Invalid magic. Not a nxs file\n"; - return false; - } - ReadBuffer(&offset, sizeof(int64)); - return true; -} - -void BorderServer::SaveHeader() { - unsigned int magic = 0x3042584e; // NXB0 - WriteBuffer(&magic, sizeof(unsigned int)); - WriteBuffer(&offset, sizeof(int64)); -} diff --git a/apps/nexus/borderserver.h b/apps/nexus/borderserver.h deleted file mode 100644 index c47b72b5..00000000 --- a/apps/nexus/borderserver.h +++ /dev/null @@ -1,77 +0,0 @@ -/**************************************************************************** -* VCGLib o o * -* Visual and Computer Graphics Library o o * -* _ O _ * -* Copyright(C) 2004 \/)\/ * -* Visual Computing Lab /\/| * -* ISTI - Italian National Research Council | * -* \ * -* All rights reserved. * -* * -* This program is free software; you can redistribute it and/or modify * -* it under the terms of the GNU General Public License as published by * -* the Free Software Foundation; either version 2 of the License, or * -* (at your option) any later version. * -* * -* This program is distributed in the hope that it will be useful, * -* but WITHOUT ANY WARRANTY; without even the implied warranty of * -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * -* GNU General Public License (http://www.gnu.org/licenses/gpl.txt) * -* for more details. * -* * -****************************************************************************/ -/**************************************************************************** - History - -$Log: not supported by cvs2svn $ -Revision 1.5 2005/02/08 12:43:03 ponchio -Added copyright - -****************************************************************************/ - -#ifndef NXS_BORDERSERVER_H -#define NXS_BORDERSERVER_H - -#include -#include - -#include "index_file.h" -#include "border.h" - - -/*nell'header ci sta scritto solo: - spazio riservato: 2 * sizeof(Link); - magic: nxb0 (4 bytes) - offset: (int64) */ - -namespace nxs { - -class BorderServer: public IndexFile { - public: - BorderServer(): ram_max(1000000), ram_used(0) {} - ~BorderServer() { Close(); } - bool Create(const std::string &file); - bool Load(const std::string &file, bool readonly = true); - void Close(); - void Flush(); - - void AddBorder(unsigned short size, unsigned int used = 0); - Border &GetBorder(unsigned int border, bool flush = true); - void ResizeBorder(unsigned int border, unsigned int size); - - unsigned int ram_max; - unsigned int ram_used; - protected: - std::list pqueue; - std::map::iterator> index; - - bool LoadHeader(); - void SaveHeader(); - - void FlushBorder(unsigned int border); - Link *GetRegion(unsigned int start, unsigned int size); //size in links. -}; - -} - -#endif diff --git a/apps/nexus/crude.cpp b/apps/nexus/crude.cpp deleted file mode 100644 index 23814db2..00000000 --- a/apps/nexus/crude.cpp +++ /dev/null @@ -1,147 +0,0 @@ -/**************************************************************************** -* VCGLib o o * -* Visual and Computer Graphics Library o o * -* _ O _ * -* Copyright(C) 2004 \/)\/ * -* Visual Computing Lab /\/| * -* ISTI - Italian National Research Council | * -* \ * -* All rights reserved. * -* * -* This program is free software; you can redistribute it and/or modify * -* it under the terms of the GNU General Public License as published by * -* the Free Software Foundation; either version 2 of the License, or * -* (at your option) any later version. * -* * -* This program is distributed in the hope that it will be useful, * -* but WITHOUT ANY WARRANTY; without even the implied warranty of * -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * -* GNU General Public License (http://www.gnu.org/licenses/gpl.txt) * -* for more details. * -* * -****************************************************************************/ -/**************************************************************************** - History - -$Log: not supported by cvs2svn $ -Revision 1.3 2004/11/30 22:50:30 ponchio -Level 0. - -Revision 1.2 2004/07/02 13:08:11 ponchio -Changed extension to .cri, crv, crf - -Revision 1.1 2004/06/24 14:32:45 ponchio -Moved from wrap/nexus - -Revision 1.1 2004/06/22 15:31:54 ponchio -Created - - -****************************************************************************/ - -#include -#include "crude.h" - -using namespace std; -using namespace vcg; -using namespace nxs; - - -Crude::~Crude() { - if(fp) - Close(); -} - -bool Crude::Create(const std::string &file, unsigned int nv, unsigned int nf) { - if(!vert.Create(file + ".crv")) return false; - if(!face.Create(file + ".crf")) return false; - - fp = fopen((file + ".cri").c_str(), "wb+"); - if(!fp) return false; - Resize(nv, nf); - return true; -} - -bool Crude::Load(const std::string &file, bool rdonly) { - if(!vert.Load(file + ".crv", rdonly)) return false; - if(!face.Load(file + ".crf", rdonly)) return false; - - fp = fopen((file + ".cri").c_str(), "rb+"); - if(!fp) return false; - fread(&nvert, sizeof(unsigned int), 1, fp); - fread(&nface, sizeof(unsigned int), 1, fp); - fread(&box, sizeof(Box3f), 1, fp); - return true; -} -void Crude::Close() { - vert.Close(); - face.Close(); - rewind(fp); - fwrite(&nvert, sizeof(unsigned int), 1, fp); - fwrite(&nface, sizeof(unsigned int), 1, fp); - fwrite(&box, sizeof(Box3f), 1, fp); - fclose(fp); - fp = NULL; -} - -void Crude::Resize(unsigned int nv, unsigned int nf) { - nvert = nv; - nface = nf; - vert.Resize(nv); - face.Resize(nf); -} - -unsigned int Crude::Vertices() { - return nvert; -} -unsigned int Crude::Faces() { - return nface; -} - -void Crude::SetVertex(unsigned int i, Point3f &f) { - Point3f &p = vert[i]; - p[0] = f[0]; - p[1] = f[1]; - p[2] = f[2]; -} - -void Crude::SetVertex(unsigned int i, float *f) { - Point3f &p = vert[i]; - p[0] = f[0]; - p[1] = f[1]; - p[2] = f[2]; -} - -Point3f Crude::GetVertex(unsigned int i) { - return vert[i]; -} -Crude::Face Crude::GetFace(unsigned int i) { - return face[i]; -} -void Crude::SetFace(unsigned int i, Face &f) { - Face &ff = face[i]; - ff[0] = f[0]; - ff[1] = f[1]; - ff[2] = f[2]; -} -void Crude::SetFace(unsigned int i, unsigned int *f) { - Face &ff = face[i]; - ff[0] = f[0]; - ff[1] = f[1]; - ff[2] = f[2]; -} - -vcg::Point3f Crude::GetBari(unsigned int i) { - Point3f bari(0, 0, 0); - Face &f = face[i]; - for(int k = 0; k < 3; k++) - bari += vert[f[k]]; - bari /= 3; - return bari; -} - -vcg::Box3f &Crude::GetBox() { - return box; -} - - diff --git a/apps/nexus/crude.h b/apps/nexus/crude.h deleted file mode 100644 index a286a492..00000000 --- a/apps/nexus/crude.h +++ /dev/null @@ -1,129 +0,0 @@ -/**************************************************************************** -* VCGLib o o * -* Visual and Computer Graphics Library o o * -* _ O _ * -* Copyright(C) 2004 \/)\/ * -* Visual Computing Lab /\/| * -* ISTI - Italian National Research Council | * -* \ * -* All rights reserved. * -* * -* This program is free software; you can redistribute it and/or modify * -* it under the terms of the GNU General Public License as published by * -* the Free Software Foundation; either version 2 of the License, or * -* (at your option) any later version. * -* * -* This program is distributed in the hope that it will be useful, * -* but WITHOUT ANY WARRANTY; without even the implied warranty of * -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * -* GNU General Public License (http://www.gnu.org/licenses/gpl.txt) * -* for more details. * -* * -****************************************************************************/ -/**************************************************************************** - History - -$Log: not supported by cvs2svn $ -Revision 1.5 2004/11/30 22:50:30 ponchio -Level 0. - -Revision 1.4 2004/07/05 15:49:38 ponchio -Windows (DevCpp, mingw) port. - -Revision 1.3 2004/07/04 15:25:33 ponchio -Backup (work in progress) - -Revision 1.2 2004/06/25 16:47:13 ponchio -Various debug - -Revision 1.1 2004/06/24 14:32:45 ponchio -Moved from wrap/nexus - -Revision 1.1 2004/06/22 15:31:40 ponchio -Created - - -****************************************************************************/ - -#ifndef NXS_CRUDE_H -#define NXS_CRUDE_H - - -#include -#include -#include - -#include "vfile.h" - -namespace nxs { - -class Crude { -public: - - struct Face { - Face() {} - Face(unsigned int a, unsigned int b, unsigned int c) { - v[0] = a; v[1] = b; v[2] = c; - } - unsigned int v[3]; - unsigned int &operator[](int k) { return v[k]; } - unsigned int *ptr() { return v; } - }; - - VFile vert; - VFile face; - - Crude(): fp(NULL), nvert(0), nface(0) {} - ~Crude(); - - bool Create(const std::string &file, unsigned int nvert = 0, - unsigned int nface = 0); - bool Load(const std::string &file, bool rdonly = false); - void Close(); - void Resize(unsigned int nvert, unsigned int nface); - - unsigned int Vertices(); - unsigned int Faces(); - - vcg::Point3f GetVertex(unsigned int i); - void SetVertex(unsigned int i, vcg::Point3f &p); - void SetVertex(unsigned int i, float *p); - - Face GetFace(unsigned int i); - void SetFace(unsigned int i, Face &f); - void SetFace(unsigned int i, unsigned int *f); - - vcg::Point3f GetBari(unsigned int i); - - vcg::Box3f &GetBox(); - - /*template void Export(MESH &mesh) { - MESH::VertexType v; - v.ClearFlags(); - for(unsigned int i = 0; i < on the top - -Revision 1.4 2004/10/19 04:23:57 ponchio -Added trackball. - -Revision 1.3 2004/09/17 15:25:09 ponchio -First working (hopefully) release. - -Revision 1.2 2004/07/05 15:49:39 ponchio -Windows (DevCpp, mingw) port. - -Revision 1.1 2004/07/04 15:30:00 ponchio -Changed directory structure. - -Revision 1.3 2004/07/02 13:03:34 ponchio -*** empty log message *** - -Revision 1.2 2004/07/01 21:33:46 ponchio -Added remap reading. - -Revision 1.1 2004/06/23 00:10:38 ponchio -Created - - -****************************************************************************/ - -#include -using namespace std; - -#include - -#include - -#ifdef WIN32 -#include -#endif - -#include -#include - -#include - -using namespace vcg; -using namespace nxs; - -bool fullscreen = false; -int width =1024; -int height = 768; - -SDL_Surface *screen = NULL; - -bool init() { - - if(SDL_Init(SDL_INIT_VIDEO) != 0) { - return false; - } - - const SDL_VideoInfo *info = SDL_GetVideoInfo(); - int bpp = info->vfmt->BitsPerPixel; - - SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5); - SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); - - int flags = SDL_OPENGL; - if(fullscreen) - flags |= SDL_FULLSCREEN; - - screen = SDL_SetVideoMode(width, height, bpp, flags); - if(!screen) { - return false; - } - - SDL_WM_SetCaption("Crudeview", "Crudeview"); - - - glDisable(GL_DITHER); - glShadeModel(GL_SMOOTH); - glHint( GL_FOG_HINT, GL_NICEST ); - glEnable(GL_DEPTH_TEST); - glDepthFunc( GL_LEQUAL ); - glDisable(GL_LIGHTING); - - glEnableClientState(GL_VERTEX_ARRAY); - return true; -} - - - - -int main(int argc, char *argv[]) { - - if(argc < 2) { - cerr << "Usage: " << argv[0] << " \n"; - return -1; - } - - Crude crude; - if(!crude.Load(argv[1])) { - cerr << "Could not load crude file: " << argv[1] << endl; - return -1; - } - Box3f box = crude.GetBox(); - - bool vremap = false; - bool fremap = false; - - VFile face_remap; - if(face_remap.Load(argv[1] + string(".rfm"), true)) { - cerr << "Found face remap.\n"; - fremap = true; - } else { - cerr << "Face remap not found.\n"; - } - - if(!init()) { - cerr << "Could not init SDL window\n"; - return -1; - } - - Trackball track; - - glClearColor(0, 0, 0, 0); - glEnable(GL_LIGHTING); - glEnable(GL_LIGHT0); - glEnable(GL_NORMALIZE); - glEnable(GL_COLOR_MATERIAL); - - bool redraw = false; - bool show_normals = true; - int quit = 0; - SDL_Event event; - int x, y; - float alpha = 0; - while( !quit ) { - bool first = true; - SDL_WaitEvent(&event); - while( first || SDL_PollEvent( &event ) ){ - first = false; - switch( event.type ) { - case SDL_QUIT: quit = 1; break; - case SDL_KEYDOWN: - switch(event.key.keysym.sym) { - case SDLK_RCTRL: - case SDLK_LCTRL: - track.ButtonDown(Trackball::KEY_CTRL); break; - case SDLK_q: exit(0); break; - } - break; - case SDL_MOUSEBUTTONDOWN: - x = event.button.x; - y = event.button.y; - if(event.button.button == SDL_BUTTON_WHEELUP) - track.MouseWheel(1); - else if(event.button.button == SDL_BUTTON_WHEELDOWN) - track.MouseWheel(-1); - else if(event.button.button == SDL_BUTTON_LEFT) - track.MouseDown(x, y, Trackball::BUTTON_LEFT); - else if(event.button.button == SDL_BUTTON_RIGHT) - track.MouseDown(x, y, Trackball::BUTTON_RIGHT); - break; - case SDL_MOUSEBUTTONUP: - x = event.button.x; - y = event.button.y; - if(event.button.button == SDL_BUTTON_LEFT) - track.MouseUp(x, y, Trackball::BUTTON_LEFT); - else if(event.button.button == SDL_BUTTON_RIGHT) - track.MouseUp(x, y, Trackball::BUTTON_RIGHT); - break; - case SDL_MOUSEMOTION: - while(SDL_PeepEvents(&event, 1, SDL_GETEVENT, SDL_MOUSEMOTIONMASK)); - x = event.motion.x; - y = event.motion.y; - track.MouseMove(x, y); - break; - default: break; - } - redraw = true; - } - - if(!redraw) continue; - redraw = false; - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - gluPerspective(60, 1, 0.1, 100); - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - gluLookAt(0,0,3, 0,0,0, 0,1,0); - - track.GetView(); - track.Apply(); - - float scale = 3/box.Diag(); - glScalef(0.4, 0.4, 0.4); - glScalef(scale, scale, scale); - Point3f center = box.Center(); - glTranslatef(-center[0], -center[1], -center[2]); - - glColor3f(0, 1, 0); - - glBegin(GL_TRIANGLES); - - for(unsigned int i = 0;i < crude.Faces(); i++) { - Crude::Face face = crude.GetFace(i); - if(fremap) { - unsigned int val = face_remap[i]; - glColor3ub((val * 27)%255, (val * 37)%255, (val * 87)%255); - } - Point3f p0 = crude.GetVertex(face[0]); - Point3f p1 = crude.GetVertex(face[1]); - Point3f p2 = crude.GetVertex(face[2]); - - if(show_normals) { - Point3f n = ((p1 - p0) ^ (p2 - p0)); - glNormal3f(n[0], n[1], n[2]); - } - glVertex3f(p0[0], p0[1], p0[2]); - glVertex3f(p1[0], p1[1], p1[2]); - glVertex3f(p2[0], p2[1], p2[2]); - - } - glEnd(); - - SDL_GL_SwapBuffers(); - } - - SDL_Quit(); - return -1; -} - - diff --git a/apps/nexus/decimate.cpp b/apps/nexus/decimate.cpp deleted file mode 100644 index be20552e..00000000 --- a/apps/nexus/decimate.cpp +++ /dev/null @@ -1,265 +0,0 @@ -#include - -// stuff to define the mesh -#include -#include -#include -#include -#include - -#include - -#include -#include - -#include - -#include "vpartition.h" -#include "fragment.h" - -#include "decimate.h" -#include - -using namespace vcg; -using namespace tri; -using namespace nxs; -using namespace std; - -class MyEdge; -class MyFace; -class MyVertex: - public vcg::VertexAFVMVNf { -public: - ScalarType w; - vcg::math::Quadric q; - ScalarType & W() { return w; } -}; - -struct MyEdge: public Edge { - inline MyEdge():Edge(){UberFlags()=0;} - inline MyEdge(MyVertex* a,MyVertex* b):Edge(a,b){ - UberFlags()=0;} -}; -class MyFace : public vcg::FaceAV {}; - -class MyMesh: - public vcg::tri::TriMesh< std::vector, std::vector > {}; - -class MyTriEdgeCollapse: public vcg::tri::TriEdgeCollapseQuadric< MyMesh, MyTriEdgeCollapse > { - public: - typedef vcg::tri::TriEdgeCollapseQuadric< MyMesh, MyTriEdgeCollapse > TECQ; - typedef TECQ::EdgeType EdgeType; - inline MyTriEdgeCollapse( EdgeType p, int i) :TECQ(p,i){} -}; - -float Cluster(MyMesh &mesh, unsigned int target_faces); -float Quadric(MyMesh &mesh, unsigned int target_faces); - -float nxs::Decimate(Decimation mode, - unsigned int target_faces, - vector &newvert, - vector &newface, - vector &newbord) { - - for(unsigned int i = 0; i < newface.size(); i+= 3) { - assert(newface[i] != newface[i+1]); - assert(newface[i] != newface[i+2]); - assert(newface[i+1] != newface[i+2]); - } - - MyMesh mesh; - - //build mesh - for(unsigned int i = 0; i < newvert.size(); i++) { - MyVertex vertex; - vertex.ClearFlags(); - vertex.P() = newvert[i]; - mesh.vert.push_back(vertex); - } - mesh.vn = mesh.vert.size(); - - for(unsigned int i = 0; i < newface.size(); i+=3) { - MyFace face; - face.ClearFlags(); - for(int k = 0; k < 3; k++) { - assert(newface[i+k] < mesh.vert.size()); - face.V(k) = &mesh.vert[newface[i+k]]; - } - mesh.face.push_back(face); - } - mesh.fn = mesh.face.size(); - - //mark borders - for(unsigned int i = 0; i < newbord.size(); i++) - mesh.vert[newbord[i].start_vert].ClearW(); - - float error; - switch(mode) { - case CLUSTER: error = Cluster(mesh, target_faces); break; - case QUADRIC: error = Quadric(mesh, target_faces); break; - default: cerr << "Unknown simplification mode: " << mode << endl; - exit(0); - } - - newvert.clear(); - newface.clear(); - - unsigned int totvert = 0; - vector vert_remap; - vert_remap.resize(mesh.vert.size(), -1); - for(unsigned int i = 0; i < mesh.vert.size(); i++) { - if(mesh.vert[i].IsD()) continue; - newvert.push_back(mesh.vert[i].cP()); - vert_remap[i] = totvert++; - } - - MyMesh::VertexPointer vert_start = &mesh.vert[0]; - 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++) - newface.push_back(vert_remap[face.V(k) - vert_start]); - } - - for(unsigned int i = 0; i < newbord.size(); i++) { - unsigned int &v = newbord[i].start_vert; - assert(vert_remap[v] != -1); - v = vert_remap[v]; - } - - return error; -} - - -float Quadric(MyMesh &mesh, unsigned int target_faces) { - vcg::tri::UpdateTopology::VertexFace(mesh); - vcg::tri::UpdateBounding::Box(mesh); - - vcg::LocalOptimization DeciSession(mesh); - - MyTriEdgeCollapse::SetDefaultParams(); - - DeciSession.Init(); - - DeciSession.SetTargetSimplices(target_faces); - DeciSession.DoOptimization(); - - float error = 0; - int count = 0; - 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++) { - error += (face.cV(k)->cP() - face.cV((k+1)%3)->cP()).Norm(); - count++; - } - } - error /= count; - return error; - return 0; -} - -float Cluster(MyMesh &mesh, unsigned int target_faces) { - unsigned int starting = mesh.vn; - - unsigned int nseeds = target_faces/2; -#ifndef NDEBUG - if(nseeds >= mesh.vert.size()) { - cerr << "Strange! nseeds > vert.size(): " << nseeds - << " >= "<< mesh.vert.size() << endl; - } -#endif - - vector remap; - - VPartition part; - for(unsigned int i = 0; i < mesh.vert.size(); i++) { - const Point3f &p = mesh.vert[i].cP(); - if(!mesh.vert[i].IsW()) { - part.push_back(p); - remap.push_back(i); - nseeds--; - } - } - unsigned int nborder = part.size(); - //Todo I should supersample before - 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(); - part.push_back(p); - mesh.vert[i].SetV(); - remap.push_back(i); - nseeds--; - } - } - if(part.size() == 0) { - cerr << "WARNING: could not simplyfiy... everything was border.\n"; - return 0; //everything is locked... - } - part.Init(); - - - vector centroid; - vector count; - for(unsigned int i = 0; i < 3; i++) { - centroid.clear(); - centroid.resize(mesh.vert.size(), Point3f(0, 0, 0)); - count.clear(); - count.resize(mesh.vert.size(), 0); - for(unsigned int i = 0; i < mesh.vert.size(); i++) { - unsigned int target = part.Locate(mesh.vert[i].cP()); - centroid[target] += mesh.vert[i].cP(); - count[target]++; - } - for(unsigned int i = nborder; i < part.size(); i++) { - if(count[i] > 0) - part[i] = centroid[i]/count[i]; - } - } - - for(unsigned int i = nborder; i < part.size(); i++) { - assert(mesh.vert[remap[i]].IsV()); - mesh.vert[remap[i]].P() = part[i]; - } - - 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()); - if(dist > error) error = dist; - - face.V(k) = | - } - } - - for(unsigned int i = 0; i < mesh.face.size(); i++) { - MyFace &face = mesh.face[i]; - assert(!face.IsD()); - for(int k = 0; k < 3; k++) { - assert(face.cV(k)->IsV() || !face.cV(k)->IsW()); - } - if(face.cV(0) == face.cV(1) || - face.cV(0) == face.cV(2) || - face.cV(1) == face.cV(2)) { - face.SetD(); - mesh.fn--; - } - } - - for(unsigned int i = 0; i < mesh.vert.size(); i++) - if(!mesh.vert[i].IsV() && mesh.vert[i].IsW()) { - mesh.vert[i].SetD(); - mesh.vn--; - } - return error; - -} - diff --git a/apps/nexus/decimate.h b/apps/nexus/decimate.h deleted file mode 100644 index cd55a011..00000000 --- a/apps/nexus/decimate.h +++ /dev/null @@ -1,49 +0,0 @@ -/**************************************************************************** -* VCGLib o o * -* Visual and Computer Graphics Library o o * -* _ O _ * -* Copyright(C) 2004 \/)\/ * -* Visual Computing Lab /\/| * -* ISTI - Italian National Research Council | * -* \ * -* All rights reserved. * -* * -* This program is free software; you can redistribute it and/or modify * -* it under the terms of the GNU General Public License as published by * -* the Free Software Foundation; either version 2 of the License, or * -* (at your option) any later version. * -* * -* This program is distributed in the hope that it will be useful, * -* but WITHOUT ANY WARRANTY; without even the implied warranty of * -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * -* GNU General Public License (http://www.gnu.org/licenses/gpl.txt) * -* for more details. * -* * -****************************************************************************/ -/**************************************************************************** - History - -$Log: not supported by cvs2svn $ - -****************************************************************************/ - -#ifndef NXS_DECIMATE_H -#define NXS_DECIMATE_H - -#include -#include "border.h" -#include "fragment.h" -#include -namespace nxs { - - enum Decimation { QUADRIC, CLUSTER }; - class BigLink; - float Decimate(Decimation mode, - unsigned int target_faces, - std::vector &newvert, - std::vector &newface, - std::vector &newbord); - -} - -#endif diff --git a/apps/nexus/exploder.cpp b/apps/nexus/exploder.cpp deleted file mode 100644 index b5126591..00000000 --- a/apps/nexus/exploder.cpp +++ /dev/null @@ -1,108 +0,0 @@ -#include -#include - -#include "nexus.h" - -using namespace nxs; -using namespace vcg; -using namespace std; - -Point3f explode(Point3f &v, Point3f ¢er, Point3f &dir, float mag) { - v = ((v - center) * mag + center) + dir; - return v; -} - -int main(int argc, char *argv[]) { - if(argc < 3) { - cerr << "Usage: " << argv[0] << " [factor]\n"; - return -1; - } - string input = argv[1]; - string output = argv[2]; - float factor = 2; - if(argc == 4) { - factor = atoi(argv[3]); - if(factor == 0) { - cerr << "Invalid factor: " << argv[3] << endl; - return -1; - } - } - Nexus in; - if(!in.Load(input, true)) { - cerr << "Could not load nexus: " << input << endl; - return -1; - } - - Nexus out; - if(!out.Create(output, in.signature, in.chunk_size)) { - cerr << "Could not create nexus: " << output << endl; - return -1; - } - - out.sphere = in.sphere; - out.history = in.history; - for(unsigned int i = 0; i < in.index.size(); i++) { - unsigned int patch = i; - Nexus::PatchInfo &src_entry = in.index[patch]; - Patch &src_patch = in.GetPatch(patch); - Border src_border = in.GetBorder(patch); - - out.AddPatch(src_entry.nvert, src_entry.nface, src_border.Available()); - - Nexus::PatchInfo &dst_entry = out.index[patch]; - - Patch dst_patch = out.GetPatch(patch); - - Point3f dir = src_entry.sphere.Center() - in.sphere.Center(); - dir.Normalize(); - dir *= 10 * src_entry.error; - - memcpy(dst_patch.VertBegin(), src_patch.VertBegin(), - src_patch.nv * sizeof(Point3f)); - - Point3f *ptr = dst_patch.VertBegin(); - for(int i = 0; i < dst_patch.nv; i++) { - ptr[i] = explode(ptr[i], src_entry.sphere.Center(), dir, - 0.5 *src_entry.error); - } - - - if(in.signature & NXS_STRIP) { - memcpy(dst_patch.FaceBegin(), src_patch.FaceBegin(), - src_patch.nf * sizeof(unsigned short)); - } else { - memcpy(dst_patch.FaceBegin(), src_patch.FaceBegin(), - src_patch.nf * sizeof(unsigned short) * 3); - } - - if((in.signature & NXS_COLORS) && (out.signature & NXS_COLORS)) - memcpy(dst_patch.ColorBegin(), src_patch.ColorBegin(), - src_patch.nv * sizeof(unsigned int)); - - if((in.signature & NXS_NORMALS_SHORT) && - (out.signature & NXS_NORMALS_SHORT)) - memcpy(dst_patch.Norm16Begin(), src_patch.Norm16Begin(), - src_patch.nv * sizeof(short)*4); - - //reordering - //WATCH OUT BORDERS! - // Reorder(out.signature, dst_patch); - //copying entry information; - dst_entry.sphere = src_entry.sphere; - dst_entry.error = src_entry.error; - - //adding borders. - for(unsigned int i = 0; i < src_border.Size(); i++) { - Link &link = src_border[i]; - if(link.IsNull()) continue; - assert(link.end_patch < in.index.size()); - } - Border dst_border = out.GetBorder(patch); - out.borders.ResizeBorder(patch, src_border.Size()); - memcpy(dst_border.Start(), src_border.Start(), - src_border.Size() * sizeof(Link)); - } - in.Close(); - out.Close(); - return 0; -} diff --git a/apps/nexus/extraction.cpp b/apps/nexus/extraction.cpp deleted file mode 100644 index c015cf6a..00000000 --- a/apps/nexus/extraction.cpp +++ /dev/null @@ -1,485 +0,0 @@ -/**************************************************************************** -* VCGLib o o * -* Visual and Computer Graphics Library o o * -* _ O _ * -* Copyright(C) 2004 \/)\/ * -* Visual Computing Lab /\/| * -* ISTI - Italian National Research Council | * -* \ * -* All rights reserved. * -* * -* This program is free software; you can redistribute it and/or modify * -* it under the terms of the GNU General Public License as published by * -* the Free Software Foundation; either version 2 of the License, or * -* (at your option) any later version. * -* * -* This program is distributed in the hope that it will be useful, * -* but WITHOUT ANY WARRANTY; without even the implied warranty of * -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * -* GNU General Public License (http://www.gnu.org/licenses/gpl.txt) * -* for more details. * -* * -****************************************************************************/ -/**************************************************************************** - History - -$Log: not supported by cvs2svn $ -Revision 1.12 2005/03/02 10:40:17 ponchio -Extraction rewrittten (to fix recusive problems). - -Revision 1.11 2005/02/20 19:49:44 ponchio -cleaning (a bit more). - -Revision 1.10 2005/02/20 18:07:00 ponchio -cleaning. - -Revision 1.9 2005/02/20 00:43:23 ponchio -Less memory x extraction. (removed frags) - -Revision 1.8 2005/02/19 16:22:45 ponchio -Minor changes (visited and Cell) - -Revision 1.7 2005/02/10 09:18:20 ponchio -Statistics. - -Revision 1.6 2005/02/08 12:43:03 ponchio -Added copyright - - -****************************************************************************/ - -#include "extraction.h" -#include "metric.h" -#include "nexus.h" - -#include - -using namespace std; -using namespace nxs; - - /* Updateing strategy: - if i can refine (not at leaves, - have draw and extr buffer, - not past target_error) - i try to refine BUT - i can fail because i finish some buffer - (then i put the operation back on the stack) - if i have finished disk i should just quit - if i cannot refine i consider coarsening: - i need 1) not be at root (eheh) - 2) have finished draw and extr buffer - (unless i am at error < target so i want to coarse - 3) do not make global error worse - (unless it is error < target_error...) - a stability term is added (1.1) so that we do not flip - nodes in and out quickly - i try to coarse BUT - i can fail because i need disk - (then i put the operation back on the stack) - if i cannt coarse i just quit - */ - - - -Extraction::Extraction(): target_error(4.0f), extr_max(10000), - draw_max(10000), disk_max(100) { - metric = new FrustumMetric; -} - -Extraction::~Extraction() { - if(metric) delete metric; -} - -void Extraction::SetMetric(Metric *m) { - if(metric) - delete metric; - metric = m; -} - -void Extraction::Extract(Nexus *_mt) { - mt = _mt; - root = mt->history.Root(); - sink = root + (mt->history.n_nodes()-1); - - //clear statistics - extr_used = draw_used = disk_used = 0; - - //first we clear the visited flags - visited.clear(); - visited.resize(mt->history.n_nodes(), false); - visible.clear(); - visible.resize(mt->size(), true); - node_errors.clear(); - node_errors.resize(mt->history.n_nodes(), -1); - - front.clear(); - - Visit(root); - - while(front.size()) { - pop_heap(front.begin(), front.end()); - HeapNode hnode = front.back(); - front.pop_back(); - - Node *node = hnode.node; - if(Visited(node)) continue; - - if(Expand(hnode)) - Visit(node); - } - Select(); - draw_size = selected.size(); -} - -void Extraction::Init() { - //I want to add all coarsable nodes - //and all refinable node (being careful about recursive dependencies) - for(Node *node = root; node != sink; node++) { - if(!Visited(node)) continue; - if(node != root && CanCoarse(node)) - back.push_back(HeapNode(node, GetNodeError(node))); - - for(Node::iterator n = node->out_begin; n != node->out_end; n++) { - Node *child = n->node; - if(Visited(child)) continue; - if(node_errors[child - root] != -1) continue; //already visited - - float *error = GetNodeError(child); - if(CanRefine(node)) // TODO? && error > target_error - front.push_back(HeapNode(child, error)); - - if(*error > max_error) max_error = *error; - } - } - - //recursively fix error - for(Node *node = root; node != sink; node++) - if(node_errors[node - root] != -1) - SetError(node, node_errors[node-root]); - - - //estimate cost of all the cut arcs (i need the visible info) - Cost cost; - for(Node *node = root; node != sink; node++) { - if(!Visited(node)) continue; - - for(Node::iterator n = node->out_begin; n != node->out_end; n++) { - Link &link = *n; - if(Visited((*n).node)) continue; - for(unsigned int patch = link.begin; patch != link.end; patch++) { - Entry &entry = (*mt)[patch]; - cost.extr += entry.ram_size; - if(Visible(patch)) cost.draw += entry.ram_size; - if(!entry.patch) cost.disk += entry.disk_size; - } - } - } - - make_heap(front.begin(), front.end()); - make_heap(back.begin(), back.end(), greater()); - - extr_used = cost.extr; - draw_used = cost.draw; - disk_used = cost.disk; -} - -void Extraction::Update(Nexus *_mt) { - mt = _mt; - root = mt->history.Root(); - sink = mt->history.Sink(); - - if(!visited.size()) { - visited.resize(mt->history.n_nodes(), false); - SetVisited(root, true); - } - visible.clear(); - visible.resize(mt->size(), true); - node_errors.clear(); - node_errors.resize(mt->history.n_nodes(), -1); - - front.clear(); - back.clear(); - - max_error = -1; - - Init(); - - bool can_refine = true; - - while(1) { - while(can_refine) { //we have available budget - if(!front.size()) break; //we are at max level - if(*front[0].error < target_error) break; //already at target_error - - max_error = *front[0].error; - pop_heap(front.begin(), front.end()); - HeapNode hnode = front.back(); - front.pop_back(); - - if(!Visited(hnode.node) && CanRefine(hnode.node)) { - if(!Refine(hnode)) { - can_refine = false; - front.push_back(hnode); - push_heap(front.begin(), front.end()); - } - } - } - - if(!back.size()) //nothing to coarse (happen only on extr_max < root.extr) - break; - - if(*back.front().error >= target_error && - (!front.size() || - (*back.front().error * 1.4) >= *front.front().error)) - break; - - pop_heap(back.begin(), back.end(), greater()); - HeapNode hnode = back.back(); - back.pop_back(); - - if(Visited(hnode.node) && //not already coarsed - CanCoarse(hnode.node) && //all children !visited - !Coarse(hnode)) { //no more disk - back.push_back(hnode); - push_heap(back.begin(), back.end(), greater()); - break; - } - can_refine = true; - } - - Select(); - draw_size = selected.size(); - - //Preloading now - for(unsigned int i = 0; i < 1000; i++) { - if(!front.size() && !back.size()) break; - if((i%2) && front.size()) { - pop_heap(front.begin(), front.end()); - HeapNode hnode = front.back(); - Node *node = hnode.node; - front.pop_back(); - Node::iterator l; - for(l = node->out_begin; l != node->out_end; l++) { - Link &link = (*l); - for(unsigned int k = link.begin; k != link.end; k++) { - selected.push_back(Item(k, i)); - } - } - } else if(back.size()) { - pop_heap(back.begin(), back.end(), greater()); - HeapNode hnode = back.back(); - Node *node = hnode.node; - back.pop_back(); - - for(Node::iterator l = node->in_begin; l != node->in_end; l++) { - Link &link = (*l); - for(unsigned int k = link.begin; k != link.end; k++) { - selected.push_back(Item(k, i)); - } - } - } - } -} - - -float *Extraction::GetNodeError(Node *node) { - float &maxerror = node_errors[node-root]; - for(Node::iterator i = node->in_begin; i != node->in_end; i++) { - Link &link = *i; - for(unsigned int p = link.begin; p != link.end; p++) { - Entry &entry = (*mt)[p]; - bool visible; - float error = metric->GetError(entry, visible); - // cerr << "Error for patch: " << p << " -> " << error << endl; - if(error > maxerror) maxerror = error; - SetVisible(p, visible); - } - } - return &maxerror; -} - -bool Extraction::Refine(HeapNode hnode) { - - Node *node = hnode.node; - - Cost cost; - Diff(node, cost); - - if(disk_used + cost.disk > disk_max || - extr_used + cost.extr > extr_max || - draw_used + cost.draw > draw_max) - return false; - - extr_used += cost.extr; - draw_used += cost.draw; - disk_used += cost.disk; - - SetVisited(node, true); - - //now add to the front children (unless sink node) - - for(Node::iterator i = node->out_begin; i != node->out_end; i++) { - Link &link = *i; - if(link.node == sink) continue; - - float *error = &node_errors[link.node - root]; - if(*error == -1) - error = GetNodeError(link.node); - if(*hnode.error < *error) *hnode.error = *error; - //TODO if(maxerror > target_error) - if(CanRefine((*i).node)) { - front.push_back(HeapNode((*i).node, error)); - push_heap(front.begin(), front.end()); - } - } - - back.push_back(hnode); - push_heap(back.begin(), back.end(), greater()); - return true; -} - -bool Extraction::Coarse(HeapNode hnode) { - Node *node = hnode.node; - - Cost cost; - Diff(node, cost); - - extr_used -= cost.extr; - draw_used -= cost.draw; - disk_used -= cost.disk; - - if(disk_used > disk_max) return false; - - SetVisited(node, false); - - //now add to the back parents (unless root node) - for(Node::iterator i = node->in_begin; i != node->in_end; i++) { - Link &link = *i; - if(link.node == root) continue; - - float *error = &node_errors[link.node - root]; - if(*error == -1) - error = GetNodeError(link.node); - if(*error < *hnode.error) *error = *hnode.error; - - if(CanCoarse(link.node)) { - back.push_back(HeapNode(link.node, error)); - push_heap(back.begin(), back.end(), greater()); - } - } - - front.push_back(hnode); - push_heap(front.begin(), front.end()); - return true; -} - -void Extraction::Select() { - selected.clear(); - Node *root = mt->history.Root(); - - Node *nodes = mt->history.nodes; - for(unsigned int i = 0; i < visited.size(); i++) { - if(!visited[i]) continue; - Node &node = nodes[i]; - - Node::iterator n; - for(n = node.out_begin; n != node.out_end; n++) { - unsigned int n_out = (*n).node - root; - if(!visited[n_out]) { - Link &link = *n; - for(unsigned int p = link.begin; p != link.end; p++) { - selected.push_back(Item(p, 0)); - } - } - } - } -} - -void Extraction::Visit(Node *node) { - assert(!Visited(node)); - - SetVisited(node, true); - - for(Node::iterator i = node->in_begin; i != node->in_end; i++) { - if(Visited((*i).node)) continue; - Visit((*i).node); - } - - Cost cost; - Diff(node, cost); - extr_used += cost.extr; - draw_used += cost.draw; - disk_used += cost.disk; - - for(Node::iterator i = node->out_begin; i != node->out_end; i++) { - float maxerror = -1; - Link &link = *i; - for(unsigned int p = link.begin; p != link.end; p++) { - Entry &entry = (*mt)[p]; - bool visible; - float error = metric->GetError(entry, visible); - if(error > maxerror) maxerror = error; - SetVisible(p, visible); - } - //TODO this check may be dangerous for non saturating things... - if(maxerror > target_error) { - node_errors[(*i).node - root] = maxerror; - HeapNode hnode((*i).node, &node_errors[(*i).node - root]); - front.push_back(hnode); - push_heap(front.begin(), front.end()); - } - } -} - -bool Extraction::Expand(HeapNode &node) { - if(extr_used >= extr_max) return false; - if(draw_used >= draw_max) return false; - // if(disk_used >= disk_max) return false; - return *node.error > target_error; -} - -void Extraction::Diff(Node *node, Cost &cost) { - Node::iterator i; - for(i = node->in_begin; i != node->in_end; i++) { - Link &link = *i; - for(unsigned int p = link.begin; p != link.end; p++) { - Entry &entry = (*mt)[p]; - cost.extr -= entry.ram_size; - if(Visible(p)) cost.draw -= entry.ram_size; - if(!entry.patch) cost.disk -= entry.disk_size; - } - } - - for(i = node->out_begin; i != node->out_end; i++) { - Link &link = *i; - for(unsigned int p = link.begin; p != link.end; p++) { - Entry &entry = (*mt)[p]; - cost.extr += entry.ram_size; - if(Visible(p)) cost.draw += entry.ram_size; - if(!entry.patch) cost.disk += entry.disk_size; - } - } -} - - void Extraction::SetError(Node *node, float error) { - for(Node::iterator i = node->in_begin; i != node->in_end; i++) - if(node_errors[(*i).node - root] != -1 && - node_errors[(*i).node - root] < error) { - node_errors[(*i).node - root] = error; - SetError((*i).node, error); - } - } - - bool Extraction::CanRefine(Node *node) { - for(Node::iterator i = node->in_begin; i != node->in_end; i++) - if(!Visited((*i).node)) - return false; - return true; - } - - bool Extraction::CanCoarse(Node *node) { - for(Node::iterator i = node->out_begin; i != node->out_end; i++) - if(Visited((*i).node)) - return false; - return true; - } diff --git a/apps/nexus/extraction.h b/apps/nexus/extraction.h deleted file mode 100644 index 4edcba54..00000000 --- a/apps/nexus/extraction.h +++ /dev/null @@ -1,155 +0,0 @@ -/**************************************************************************** -* VCGLib o o * -* Visual and Computer Graphics Library o o * -* _ O _ * -* Copyright(C) 2004 \/)\/ * -* Visual Computing Lab /\/| * -* ISTI - Italian National Research Council | * -* \ * -* All rights reserved. * -* * -* This program is free software; you can redistribute it and/or modify * -* it under the terms of the GNU General Public License as published by * -* the Free Software Foundation; either version 2 of the License, or * -* (at your option) any later version. * -* * -* This program is distributed in the hope that it will be useful, * -* but WITHOUT ANY WARRANTY; without even the implied warranty of * -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * -* GNU General Public License (http://www.gnu.org/licenses/gpl.txt) * -* for more details. * -* * -****************************************************************************/ -/**************************************************************************** - History - -$Log: not supported by cvs2svn $ -Revision 1.10 2005/03/02 10:40:17 ponchio -Extraction rewrittten (to fix recusive problems). - -Revision 1.9 2005/02/20 18:07:01 ponchio -cleaning. - -Revision 1.8 2005/02/19 16:22:45 ponchio -Minor changes (visited and Cell) - -Revision 1.7 2005/02/10 09:18:20 ponchio -Statistics. - -Revision 1.6 2005/02/08 12:43:03 ponchio -Added copyright - - -****************************************************************************/ - -#ifndef NXS_EXTRACTION_H -#define NXS_EXTRACTION_H - -#include -#include - -#include - -#include "history.h" - -namespace nxs { - -class Metric; -class Nexus; - -struct Item { - float error; - unsigned int id; - Item(unsigned int i = 0, float e = 0): id(i), error(e) {} - bool operator<(const Item &item) const { - return error < item.error; - } -}; - -class Extraction { - public: - typedef History::Node Node; - typedef History::Link Link; - - struct Cost { - unsigned int extr; - unsigned int draw; - unsigned int disk; - Cost(): extr(0), draw(0), disk(0) {} - }; - - struct HeapNode { - Node *node; - float *error; - - HeapNode(Node *_node, float *_error): node(_node), error(_error) {} - bool operator<(const HeapNode &node) const { - return *error < *node.error; } - bool operator>(const HeapNode &node) const { - return *error > *node.error; } - }; - - Metric *metric; - float target_error; - - float max_error; //actual error at end of extraction - unsigned int extr_used, extr_max; - unsigned int draw_used, draw_max; - unsigned int disk_used, disk_max; - - std::vector visited; - std::vector visible; - std::vector node_errors; - - std::vector selected; - unsigned int draw_size; //first in selected should be drawn - - // std::vector heap; //no realtime extraxtion TODO (use front) - - - std::vector front; //nodes that i can expand to - std::vector back; //nodes that i can contract - - - Extraction(); - ~Extraction(); - - void Extract(Nexus *mt); - void Update(Nexus *mt); - - bool Visible(unsigned int p) { return visible[p]; } - void SetVisible(unsigned int p, bool v) { visible[p] = v; } - - void SetMetric(Metric *m); - - protected: - - void Select(); - void Visit(Node *node); - - bool Expand(HeapNode &node); - void Diff(Node *node, Cost &cost); - - void Init(); - bool Refine(HeapNode node); - bool Coarse(HeapNode node); - - bool Visited(Node *node) { return visited[node - root]; } - void SetVisited(Node *node, bool v) { visited[node - root] = v; } - - private: - Nexus *mt; - Node *root; - Node *sink; - - //return inbound links max error. remember to update patch visibility - float *GetNodeError(Node *node); - //this look for parent nodes with error and fix it should be < - void SetError(Node *node, float error); - bool CanCoarse(Node *node); - bool CanRefine(Node *node); -}; - - -}//namespace -#endif diff --git a/apps/nexus/file.cpp b/apps/nexus/file.cpp deleted file mode 100644 index d1ca0826..00000000 --- a/apps/nexus/file.cpp +++ /dev/null @@ -1,130 +0,0 @@ -#include "file.h" -#include - -using namespace std; -using namespace nxs; - -bool File::Create(const string &filename) { - size = 0; - readonly = false; -#ifdef WIN32 - fp = CreateFile(filename.c_str(), GENERIC_READ | GENERIC_WRITE, 0, - NULL, CREATE_ALWAYS, 0, NULL); - if(fp == INVALID_HANDLE_VALUE) return false; -#else - fp = fopen(filename.c_str(), "wb+"); - if(!fp) return false; -#endif - return true; -} - -bool File::Load(const string &filename, bool ronly) { - readonly = ronly; -#ifdef WIN32 - fp = CreateFile(filename.c_str(), GENERIC_READ | GENERIC_WRITE, - 0, NULL, OPEN_EXISTING, 0, NULL); - if(fp == INVALID_HANDLE_VALUE) return false; -#else - if(readonly) - fp = fopen(filename.c_str(), "rb"); - else - fp = fopen(filename.c_str(), "rb+"); - if(!fp) return false; -#endif - -#ifdef WIN32 - size = GetFileSize(fp, NULL); -#else - //TODO use stat() - fseek(fp, 0, SEEK_END); - size = ftell(fp); -#endif - return true; -} - -void File::Close() { - if(fp) { -#ifdef WIN32 - CloseHandle(fp); -#else - fclose(fp); -#endif - fp = NULL; - } -} - -void File::Redim(unsigned int elem) { - assert(fp); - assert(!readonly); - if(elem > size) { - -#ifdef WIN32 - LONG zero = 0; - if(INVALID_SET_FILE_POINTER == - SetFilePointer(fp, elem - 1, &zero, FILE_BEGIN)) -#else - if(-1 == fseek(fp, elem - 1, SEEK_SET)) -#endif - assert(0 && "Could not resize"); - - unsigned char a; -#ifdef WIN32 - DWORD tmp; - WriteFile(fp, &a, 1, &tmp, NULL); -#else - fwrite(&a, sizeof(unsigned char), 1, fp); -#endif - } else { - //TODO optimize: we do not need flush for buffers over elem. -#ifndef WIN32 - int fd = fileno(fp); - ftruncate(fd, elem); -#else - LONG zero = 0; - SetFilePointer(fp, elem, &zero, FILE_BEGIN); - SetEndOfFile(fp); -#endif - } - size = elem; -} - -void File::SetPosition(unsigned int pos) { -#ifdef WIN32 - LONG zero = 0; - SetFilePointer(fp, pos, &zero, FILE_BEGIN); -#else - fseek(fp, pos, SEEK_SET); -#endif -} - -void File::ReadBuffer(void *data, unsigned int sz) { -#ifdef WIN32 - DWORD tmp; - ReadFile(fp, data, sz, &tmp, NULL); - if(tmp != sz) - assert(0 && "Could not read"); -#else - if(sz != fread(data, 1, sz, fp)) - assert(0 && "Could not read"); -#endif -} - -void File::WriteBuffer(void *data, unsigned int sz) { - assert(!readonly); -#ifdef WIN32 - DWORD tmp; - WriteFile(fp, data, sz, &tmp, NULL); - assert(tmp == sz); -#else - if(sz != fwrite(data, 1, sz, fp)) - assert(0 && "Could not write"); -#endif -} - -void File::Delete(const string &filename) { -#ifdef WIN32 - DeleteFile(filename.c_str()); -#else - unlink(filename.c_str()); -#endif -} diff --git a/apps/nexus/file.h b/apps/nexus/file.h deleted file mode 100644 index e13a3a00..00000000 --- a/apps/nexus/file.h +++ /dev/null @@ -1,58 +0,0 @@ -#ifndef NXS_FILE_H -#define NXS_FILE_H - -//TODO move includes in cpp - -#ifdef WIN32 -#ifndef _WINDOWS_ -#define _WINSOCKAPI_ -#include -#endif -#else -#include -#endif - -#include -#include - -namespace nxs { - -class File { - public: - - File(): fp(NULL) {} - ~File() { Close(); } - - File(const File &file) { - fp = file.fp; - size = file.size; - readonly = file.readonly; - ((File &)file).fp = NULL; - } - bool Create(const std::string &filename); - bool Load(const std::string &filename, bool readonly = false); - void Close(); - - unsigned int Length() { return size; } - void Redim(unsigned int elem); - - void SetPosition(unsigned int chunk); - void ReadBuffer(void *data, unsigned int size); - void WriteBuffer(void *data, unsigned int size); - - bool IsReadOnly() { return readonly; } - - static void Delete(const std::string &filename); - -#ifdef WIN32 - HANDLE fp; -#else - FILE *fp; -#endif - unsigned int size; - bool readonly; -}; - -} - -#endif diff --git a/apps/nexus/fragment.cpp b/apps/nexus/fragment.cpp deleted file mode 100644 index ace2374f..00000000 --- a/apps/nexus/fragment.cpp +++ /dev/null @@ -1,431 +0,0 @@ -/**************************************************************************** -* VCGLib o o * -* Visual and Computer Graphics Library o o * -* _ O _ * -* Copyright(C) 2004 \/)\/ * -* Visual Computing Lab /\/| * -* ISTI - Italian National Research Council | * -* \ * -* All rights reserved. * -* * -* This program is free software; you can redistribute it and/or modify * -* it under the terms of the GNU General Public License as published by * -* the Free Software Foundation; either version 2 of the License, or * -* (at your option) any later version. * -* * -* This program is distributed in the hope that it will be useful, * -* but WITHOUT ANY WARRANTY; without even the implied warranty of * -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * -* GNU General Public License (http://www.gnu.org/licenses/gpl.txt) * -* for more details. * -* * -****************************************************************************/ -/**************************************************************************** - History - -$Log: not supported by cvs2svn $ -Revision 1.9 2005/02/08 12:43:03 ponchio -Added copyright - - -****************************************************************************/ - -#include -#include - -#include "fragment.h" -#include "border.h" -#include "nxsalgo.h" -//#include "pvoronoi.h" - - -using namespace std; -using namespace vcg; -using namespace nxs; -using namespace pt; - - - -void NxsPatch::Write(outstm *out) { - out->write(&sphere, sizeof(Sphere3f)); - out->write(&cone, sizeof(ANCone3f)); - int vsize = vert.size(); - int fsize = face.size(); - int bsize = bord.size(); - - out->write(&patch, sizeof(unsigned int)); - out->write(&vsize, sizeof(unsigned int)); - out->write(&fsize, sizeof(unsigned int)); - out->write(&bsize, sizeof(unsigned int)); - - out->write(&*vert.begin(), vert.size() * sizeof(Point3f)); - out->write(&*face.begin(), face.size() * sizeof(unsigned short)); - out->write(&*bord.begin(), bord.size() * sizeof(Link)); -} - -void NxsPatch::Read(instm *in) { - in->read(&sphere, sizeof(Sphere3f)); - in->read(&cone, sizeof(ANCone3f)); - int vsize; - int fsize; - int bsize; - - in->read(&patch, sizeof(unsigned int)); - in->read(&vsize, sizeof(unsigned int)); - in->read(&fsize, sizeof(unsigned int)); - in->read(&bsize, sizeof(unsigned int)); - vert.resize(vsize); - face.resize(fsize); - bord.resize(bsize); - in->read(&*vert.begin(), vert.size() * sizeof(Point3f)); - in->read(&*face.begin(), face.size() * sizeof(unsigned short)); - in->read(&*bord.begin(), bord.size() * sizeof(Link)); -} - -bool Fragment::Write(outstm *out) { - try { - out->write(&id, sizeof(unsigned int)); - out->write(&error, sizeof(float)); - unsigned int ssize = seeds.size(); - out->write(&ssize, sizeof(unsigned int)); - out->write(&*seeds.begin(), ssize * sizeof(Point3f)); - out->write(&*seeds_id.begin(), ssize * sizeof(unsigned int)); - unsigned int psize = pieces.size(); - out->write(&psize, sizeof(unsigned int)); - - for(unsigned int i = 0; i < pieces.size(); i++) - pieces[i].Write(out); - return true; - } catch (estream *e) { - perr.putf("Error: %s\n", pconst(e->get_message())); - delete e; - return false; - } -} - -bool Fragment::Read(instm *in) { - try { - in->read(&id, sizeof(unsigned int)); - in->read(&error, sizeof(float)); - - //TODO move this control to all read! - unsigned int ssize; - if(sizeof(int) != in->read(&ssize, sizeof(unsigned int))) - return false; - seeds.resize(ssize); - seeds_id.resize(ssize); - in->read(&*seeds.begin(), ssize * sizeof(Point3f)); - in->read(&*seeds_id.begin(), ssize * sizeof(unsigned int)); - - unsigned int psize; - in->read(&psize, sizeof(unsigned int)); - pieces.resize(psize); - - for(unsigned int i = 0; i < psize; i++) { - pieces[i].Read(in); - } - return true; - } catch (estream *e) { - perr.putf("Error: %s\n", pconst(e->get_message())); - delete e; - return false; - } -} - -void nxs::Join(Fragment &in, - vector &newvert, - vector &newface, - vector &newbord) { - - map patch_remap; - vector offsets; - - unsigned int totvert = 0; - for(unsigned int i = 0; i < in.pieces.size(); i++) { - offsets.push_back(totvert); - patch_remap[in.pieces[i].patch] = i; - totvert += in.pieces[i].vert.size(); - } - - vector remap; - remap.resize(totvert, 0xffffffff); - - //TODO what if totvert > 1<<22? - //todo we really need a set? - // set newborders; - unsigned int vcount = 0; - unsigned int fcount = 0; - unsigned int bcount = 0; - - for(unsigned int i = 0; i < in.pieces.size(); i++) { - unsigned int offset = offsets[i]; - vector &vert = in.pieces[i].vert; - vector &face = in.pieces[i].face; - vector &bord = in.pieces[i].bord; - - for(unsigned int k = 0; k < face.size(); k+=3) { - assert(face[k] != face[k+1]); - assert(face[k] != face[k+2]); - assert(face[k+1] != face[k+2]); - } - - fcount += face.size()/3; - - for(unsigned int k = 0; k < vert.size(); k++) { - assert(offset + k < remap.size()); - if(remap[offset + k] == 0xffffffff) - remap[offset + k] = vcount++; - } - - for(unsigned int k = 0; k < bord.size(); k++) { - Link link = bord[k]; - if(link.IsNull()) continue; - - if(patch_remap.count(link.end_patch)) {//internal - unsigned int idx = patch_remap[link.end_patch]; - assert(link.end_patch != in.pieces[i].patch); - unsigned int extoffset = offsets[idx]; - - 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)); - - set newborders; - for(unsigned int i = 0; i < in.pieces.size(); i++) { - unsigned int offset = offsets[i]; - vector &bord = in.pieces[i].bord; - for(unsigned int k = 0; k < bord.size(); k++) { - Link llink = bord[k]; - if(llink.IsNull()) continue; - if(!patch_remap.count(llink.end_patch)) {//external - BigLink link; - link.start_vert = remap[offset + llink.start_vert]; - link.end_patch = in.pieces[i].patch; - link.end_vert = llink.start_vert; - newborders.insert(link); - } - } - } - - newvert.resize(vcount); - newface.resize(fcount*3); - newbord.resize(newborders.size()); - - fcount = 0; - for(unsigned int i = 0; i < in.pieces.size(); i++) { - unsigned int offset = offsets[i]; - vector &vert = in.pieces[i].vert; - vector &face = in.pieces[i].face; - vector &bord = in.pieces[i].bord; - - for(unsigned int i = 0; i < vert.size(); i++) { - assert(offset + i < remap.size()); - assert(remap[offset + i] < vcount); - newvert[remap[offset + i]] = vert[i]; - } - - for(unsigned int i = 0; i < face.size(); i++) { - assert(offset + face[i] < remap.size()); - assert(remap[offset + face[i]] < newvert.size()); - assert(fcount < newface.size()); - newface[fcount++] = remap[offset + face[i]]; - } - } - set::iterator b; - for(b = newborders.begin(); b != newborders.end(); b++) { - newbord[bcount++] = *b; - } - - for(unsigned int i = 0; i < newface.size(); i+= 3) { - if(newface[i] == newface[i+1] || - newface[i] == newface[i+2] || - newface[i+1] == newface[i+2]) { - cerr << "i: " << i << endl; - for(unsigned int k = 0; k < newface.size(); k+=3) { - cerr << k << ": " << newface[k] << " " - << newface[k+1] << " " - << newface[k+2] << endl; - } - exit(0); - } - } -} - -void nxs::Split(Fragment &out, - vector &newvert, - vector &newface, - vector &newbord) { - - unsigned int nseeds = out.seeds.size(); - vector &seeds = out.seeds; - vector &seeds_id = out.seeds_id; - //preliminary count - vector 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 newseeds; - vector 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 > vert_remap; - vector< vector > face_remap; - - vector vert_count; - vector 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 &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 &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 &v_remap = vert_remap[seed]; - - assert(vert_count[seed] > 0); - vector &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 &f_remap = face_remap[seed]; - - vector &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 &bords = patch.bord; - - //process downward borders - for(unsigned int i = 0; i < newbord.size(); i++) { - BigLink link = newbord[i]; - /* cerr << "Newbord: " << link.start_vert << " " - << link.end_patch << " " - << link.end_vert << endl;*/ - if(v_remap[link.start_vert] == -1) continue; - Link llink; - llink.start_vert = v_remap[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 &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); - } - } - } - } - //process Cone and sphere - for(unsigned int seed = 0; seed != nseeds; seed++) { - NxsPatch &patch = out.pieces[seed]; - Sphere3f &sphere = patch.sphere; - sphere.CreateTight(patch.vert.size(), &*patch.vert.begin()); - - //NORMALS CONE - vector normals; - for(unsigned int i = 0; i < patch.face.size(); i += 3) { - unsigned short *f = &(patch.face[i]); - Point3f &v0 = patch.vert[f[0]]; - Point3f &v1 = patch.vert[f[1]]; - Point3f &v2 = patch.vert[f[2]]; - - Point3f norm = (v1 - v0) ^ (v2 - v0); - normals.push_back(norm.Normalize()); - } - patch.cone.AddNormals(normals, 0.99f); - } -} - -unsigned int Fragment::Locate(const Point3f &p) { - float max_dist = 1e20f; - unsigned int id = 0xffffffff; - for(unsigned int i = 0; i < seeds.size(); i++) { - float dist = Distance(seeds[i], p); - if(dist < max_dist) { - max_dist = dist; - id = i; - } - } - assert(id != 0xffffffff); - return id; -} diff --git a/apps/nexus/fragment.h b/apps/nexus/fragment.h deleted file mode 100644 index a1dfae84..00000000 --- a/apps/nexus/fragment.h +++ /dev/null @@ -1,106 +0,0 @@ -/**************************************************************************** -* VCGLib o o * -* Visual and Computer Graphics Library o o * -* _ O _ * -* Copyright(C) 2004 \/)\/ * -* Visual Computing Lab /\/| * -* ISTI - Italian National Research Council | * -* \ * -* All rights reserved. * -* * -* This program is free software; you can redistribute it and/or modify * -* it under the terms of the GNU General Public License as published by * -* the Free Software Foundation; either version 2 of the License, or * -* (at your option) any later version. * -* * -* This program is distributed in the hope that it will be useful, * -* but WITHOUT ANY WARRANTY; without even the implied warranty of * -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * -* GNU General Public License (http://www.gnu.org/licenses/gpl.txt) * -* for more details. * -* * -****************************************************************************/ -/**************************************************************************** - History - -$Log: not supported by cvs2svn $ -Revision 1.6 2005/02/08 12:43:03 ponchio -Added copyright - - -****************************************************************************/ - -#ifndef NXS_FRAGMENT_H -#define NXS_FRAGMENT_H - -#include - -#include -#include "nexus.h" - -namespace nxs { - -class VoronoiPartition; - -struct BigLink { - unsigned int start_vert; - unsigned int end_patch; - unsigned int end_vert; - bool operator<(const BigLink &l) const { - if(end_patch == l.end_patch) { - if(start_vert == l.start_vert) { - return end_vert < l.end_vert; - } else - return start_vert < l.start_vert; - } else - return end_patch < l.end_patch; - } -}; - -class NxsPatch { - public: - //this fields is the patch number in the infragment - //and the seeds id in the outfragment - unsigned int patch; - vcg::Sphere3f sphere; - ANCone3f cone; - - std::vector vert; - std::vector face; - - std::vector bord; - - void Write(pt::outstm *out); - void Read(pt::instm *in); -}; - -class Fragment { - public: - unsigned int id; - - float error; - - std::vector seeds; - std::vector seeds_id; - - std::vector pieces; - - bool Write(pt::outstm *out); - bool Read(pt::instm *in); - - //returns the index of the seed - unsigned int Locate(const vcg::Point3f &p); -}; - - void Join(Fragment &in, - std::vector &newvert, - std::vector &newface, - std::vector &newbord); - - void Split(Fragment &out, - std::vector &newvert, - std::vector &newface, - std::vector &newbord); -} - -#endif diff --git a/apps/nexus/history.cpp b/apps/nexus/history.cpp deleted file mode 100644 index c05298b4..00000000 --- a/apps/nexus/history.cpp +++ /dev/null @@ -1,400 +0,0 @@ -/**************************************************************************** -* VCGLib o o * -* Visual and Computer Graphics Library o o * -* _ O _ * -* Copyright(C) 2004 \/)\/ * -* Visual Computing Lab /\/| * -* ISTI - Italian National Research Council | * -* \ * -* All rights reserved. * -* * -* This program is free software; you can redistribute it and/or modify * -* it under the terms of the GNU General Public License as published by * -* the Free Software Foundation; either version 2 of the License, or * -* (at your option) any later version. * -* * -* This program is distributed in the hope that it will be useful, * -* but WITHOUT ANY WARRANTY; without even the implied warranty of * -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * -* GNU General Public License (http://www.gnu.org/licenses/gpl.txt) * -* for more details. * -* * -****************************************************************************/ -/**************************************************************************** - History - -$Log: not supported by cvs2svn $ -Revision 1.9 2005/02/20 00:43:23 ponchio -Less memory x extraction. (removed frags) - -Revision 1.8 2005/02/19 17:14:02 ponchio -History quick by default. - -Revision 1.7 2005/02/19 16:22:45 ponchio -Minor changes (visited and Cell) - -Revision 1.6 2005/02/17 16:40:35 ponchio -Optimized BuildLevels. - -Revision 1.5 2005/02/08 12:43:03 ponchio -Added copyright - - -****************************************************************************/ - -#include -#include -#include - -#include "history.h" -#include "nexus.h" - - -using namespace std; -using namespace nxs; - -History::~History() { - if(buffer) delete []buffer; - nodes = NULL; - in_links= NULL; - out_links = NULL; -} - -void History::Clear() { - if(buffer) delete []buffer; - buffer = NULL; - updates.clear(); -} - -void History::ClearQuick() { - if(buffer) delete []buffer; - buffer = NULL; -} - -void History::ClearUpdates() { - updates.clear(); -} - -bool History::Load(unsigned int _size, char *mem) { - if(buffer) delete []buffer; - unsigned int is_quick = *(unsigned int *)mem; - bool success; - if(is_quick == 53) { - success = LoadQuick(_size, mem); - } else if(is_quick == 32) { - success = LoadUpdates(_size, mem); - } else { - cerr << "Invalid history: " << is_quick << "\n"; - return false; - } - return success; -} - -bool History::LoadQuick(unsigned int _size, char *mem) { - buffer = mem; - nodes = (Node *)(buffer + 4 * sizeof(int)); - in_links = (Link *)(nodes + n_nodes()); - out_links = in_links + n_in_links(); - - //check size is ok; - assert(n_nodes() * sizeof(Node) + - (n_in_links() + n_out_links()) * sizeof(Link) + - 4 * sizeof(int) == _size); - size = _size; - return LoadPointers(); -} - -bool History::LoadUpdates(unsigned int _size, char *mem) { - unsigned int *tmp = (unsigned int *)mem; - updates.resize(tmp[1]); - - unsigned int pos = 2; - for(unsigned int i = 0; i < updates.size(); i++) { - unsigned int erased = tmp[pos++]; - unsigned int created = tmp[pos++]; - updates[i].erased.resize(erased); - updates[i].created.resize(created); - for(unsigned int e = 0; e < erased; e++) - updates[i].erased[e] = tmp[pos++]; - for(unsigned int e = 0; e < created; e++) - updates[i].created[e] = tmp[pos++]; - } - delete []mem; - buffer = 0; - return true; -} - -bool History::LoadPointers() { - //now convert integer to pointers - for(unsigned int i = 0; i < n_nodes(); i++) { - Node &node = nodes[i]; - assert(((unsigned int)node.in_begin) <= n_in_links()); - assert(((unsigned int)node.out_begin) <= n_out_links()); - node.in_begin = in_links + (unsigned int)(node.in_begin); - node.in_end = in_links + (unsigned int)(node.in_end); - node.out_begin = out_links + (unsigned int)(node.out_begin); - node.out_end = out_links + (unsigned int)(node.out_end); - } - - for(unsigned int i = 0; i < n_in_links(); i++) { - Link &link = in_links[i]; - assert(((unsigned int)link.node) <= n_nodes()); - link.node = nodes + (unsigned int)(link.node); - } - - for(unsigned int i = 0; i < n_out_links(); i++) { - Link &link = out_links[i]; - assert(((unsigned int)link.node) <= n_nodes()); - link.node = nodes + (unsigned int)(link.node); - } - return true; -} - -char *History::Save(unsigned int &_size) { - if(buffer) - return SaveQuick(_size); - else - return SaveUpdates(_size); -} - -char *History::SaveQuick(unsigned int &_size) { - assert(buffer); - for(unsigned int i = 0; i < n_nodes(); i++) { - Node &node = nodes[i]; - node.in_begin = (Link *)(node.in_begin - in_links); - node.in_end = (Link *)(node.in_end - in_links); - node.out_begin = (Link *)(node.out_begin - out_links); - node.out_end = (Link *)(node.out_end - out_links); - } - - for(unsigned int i = 0; i < n_in_links(); i++) { - Link &link = in_links[i]; - link.node = (Node *)(link.node - nodes); - } - - for(unsigned int i = 0; i < n_out_links(); i++) { - Link &link = out_links[i]; - link.node = (Node *)(link.node - nodes); - } - - assert(n_nodes() * sizeof(Node) + - (n_in_links() + n_out_links()) * sizeof(Link) + - 4 * sizeof(int) == size); - - _size = size; - char *tmp = buffer; - buffer = NULL; - return tmp; -} - -char *History::SaveUpdates(unsigned int &_size) { - vector buf; - buf.push_back(32); - buf.push_back(updates.size()); - for(unsigned int i = 0; i < updates.size(); i++) { - Update &update = updates[i]; - buf.push_back(update.erased.size()); - buf.push_back(update.created.size()); - for(unsigned int e = 0; e < update.erased.size(); e++) - buf.push_back(update.erased[e]); - for(unsigned int e = 0; e < update.created.size(); e++) - buf.push_back(update.created[e]); - } - - _size = buf.size() * sizeof(unsigned int); - char *mem = new char[_size]; - memcpy(mem, &*buf.begin(), _size); - return mem; -} - -bool History::UpdatesToQuick(Nexus &nexus) { - //maps cell -> node containing it - map cell_node; - //maps node -> Links - map > node_inlinks; - map > node_outlinks; - - vector tmp_nodes; - tmp_nodes.resize(updates.size()); - - vector tmp_in_links; - vector tmp_out_links; - vector tmp_frags; - - unsigned int current_node = 0; - - vector::iterator u; - for(u = updates.begin(); u != updates.end(); u++) { - Node &node = tmp_nodes[current_node]; - - //created cells belong to this node, - for(unsigned int i = 0; i < (*u).created.size(); i++) { - unsigned int cell = (*u).created[i]; - cell_node[cell] = current_node; - } - - //Every erased cell already belonged to a node //node -> its cells - map > node_erased; - - for(unsigned int i = 0; i < (*u).erased.size(); i++) { - unsigned int cell = (*u).erased[i]; - assert(cell_node.count(cell)); - node_erased[cell_node[cell]].push_back(cell); - } - - //for every node with erased cells we build a fragment and - //put the corresponding cells in it. - map >::iterator e; - for(e = node_erased.begin(); e != node_erased.end(); e++) { - - unsigned int floor_node = (*e).first; - vector &cells = (*e).second; - - Node &parent = tmp_nodes[floor_node]; - - Link inlink; - inlink.node = (Node *)floor_node; - inlink.begin = tmp_frags.size(); - inlink.end = inlink.begin + cells.size(); - - Link outlink; - outlink.node = (Node *)current_node; - outlink.begin = tmp_frags.size(); - outlink.end = outlink.begin + cells.size(); - - //Fill it with erased cells. - vector::iterator k; - for(k = cells.begin(); k != cells.end(); k++) - tmp_frags.push_back(*k); - - //Add the new Frag to the nodes (in and out) - node_outlinks[floor_node].push_back(outlink); - node_inlinks[current_node].push_back(inlink); - } - current_node++; - } - - map >::iterator k; - for(k = node_outlinks.begin(); k != node_outlinks.end(); k++) { - unsigned int inode = (*k).first; - vector &links = (*k).second; - tmp_nodes[inode].out_begin = (Link *)(tmp_out_links.size()); - tmp_nodes[inode].out_end = (Link *)(tmp_out_links.size() + links.size()); - // tmp_nodes[inode].out_link_begin = (Link *)(tmp_out_links.size()); - // tmp_nodes[inode].out_link_size = links.size(); - - for(unsigned int i = 0; i < links.size(); i++) - tmp_out_links.push_back(links[i]); - } - - for(k = node_inlinks.begin(); k != node_inlinks.end(); k++) { - unsigned int inode = (*k).first; - vector &links = (*k).second; - // tmp_nodes[inode].in_link_begin = (Link *)(tmp_in_links.size()); - // tmp_nodes[inode].in_link_size = links.size(); - tmp_nodes[inode].in_begin = (Link *)(tmp_in_links.size()); - tmp_nodes[inode].in_end = (Link *)(tmp_in_links.size() + links.size()); - - for(unsigned int i = 0; i < links.size(); i++) - tmp_in_links.push_back(links[i]); - } - - //Here we reorder entries in nexus... - nexus.Flush(); - - vector entries; - entries.resize(nexus.size()); - for(unsigned int i = 0; i < nexus.size(); i++) { - assert(!nexus[i].patch); - entries[i] = nexus[i]; - } - assert(tmp_frags.size() == nexus.size()); - for(unsigned int i = 0; i < tmp_frags.size(); i++) { - nexus[i] = entries[tmp_frags[i]]; - } - //WARNING CRITICAL TODOHey we should do the same on the borders! - vector backward; - backward.resize(tmp_frags.size()); - for(unsigned int i = 0; i < backward.size(); i++) - backward[tmp_frags[i]] = i; - - for(unsigned int i = 0; i < nexus.borders.size(); i++) { - Border &border = nexus.borders.GetBorder(i); - for(unsigned int k = 0; k < border.Size(); k++) - border[k].end_patch = backward[border[k].end_patch]; - } - nexus.borders.Flush(); - vector borders; - borders.resize(nexus.borders.size()); - for(unsigned int i = 0; i < nexus.borders.size(); i++) { - borders[i] = nexus.borders[i]; - } - assert(tmp_frags.size() == nexus.borders.size()); - for(unsigned int i = 0; i < tmp_frags.size(); i++) { - nexus.borders[i] = borders[tmp_frags[i]]; - } - - - size = tmp_nodes.size() * sizeof(Node) + - tmp_in_links.size() * sizeof(Link) + - tmp_out_links.size() * sizeof(Link) + - 4 * sizeof(int); - - if(buffer) delete []buffer; - buffer = new char[size]; - - quick() = 53; - n_nodes() = tmp_nodes.size(); - n_in_links() = tmp_in_links.size(); - n_out_links() = tmp_out_links.size(); - - nodes = (Node *)(buffer + 4 * sizeof(int)); - in_links = (Link *)(nodes + n_nodes()); - out_links = in_links + n_in_links(); - - memcpy(nodes, &*tmp_nodes.begin(), tmp_nodes.size()*sizeof(Node)); - memcpy(in_links, &*tmp_in_links.begin(), tmp_in_links.size()*sizeof(Link)); - memcpy(out_links, &*tmp_out_links.begin(), - tmp_out_links.size()*sizeof(Link)); - - return LoadPointers(); -} - -void History::BuildLevels(vector &levels) { - levels.clear(); - if(buffer) { - //Saved in quick mode: - for(unsigned int n = 0; n < n_nodes(); n++) { - Node *node = nodes+n; - Node::iterator l; - unsigned int current = 0; - if(node != nodes) { //not root - Link *inlink = node->in_begin; - unsigned int p = inlink->begin; - assert(p < levels.size()); - assert(p >= 0); - current = levels[p]+1; - } - for(l = node->out_begin; l != node->out_end; l++) { - Link &link = *l; - for(unsigned int p = link.begin; p != link.end; p++) { - while(p >= levels.size()) levels.push_back(-1); - levels[p] = current; - } - } - } - } else { - //Saved in updates mode: - for(unsigned int i = 0; i < updates.size(); i++) { - Update &u = updates[i]; - unsigned int current = 0; - if(!u.erased.size()) current = 0; - else current = levels[u.erased[0]] + 1; - for(unsigned int i = 0; i < u.created.size(); i++) { - unsigned int p = u.created[i]; - while(p >= levels.size()) levels.push_back(-1); - levels[p] = current; - } - } - } -} diff --git a/apps/nexus/history.h b/apps/nexus/history.h deleted file mode 100644 index 2807b7b1..00000000 --- a/apps/nexus/history.h +++ /dev/null @@ -1,130 +0,0 @@ -/**************************************************************************** -* VCGLib o o * -* Visual and Computer Graphics Library o o * -* _ O _ * -* Copyright(C) 2004 \/)\/ * -* Visual Computing Lab /\/| * -* ISTI - Italian National Research Council | * -* \ * -* All rights reserved. * -* * -* This program is free software; you can redistribute it and/or modify * -* it under the terms of the GNU General Public License as published by * -* the Free Software Foundation; either version 2 of the License, or * -* (at your option) any later version. * -* * -* This program is distributed in the hope that it will be useful, * -* but WITHOUT ANY WARRANTY; without even the implied warranty of * -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * -* GNU General Public License (http://www.gnu.org/licenses/gpl.txt) * -* for more details. * -* * -****************************************************************************/ -/**************************************************************************** - History - -$Log: not supported by cvs2svn $ -Revision 1.7 2005/02/20 19:49:44 ponchio -cleaning (a bit more). - -Revision 1.6 2005/02/20 00:43:23 ponchio -Less memory x extraction. (removed frags) - -Revision 1.5 2005/02/19 16:22:45 ponchio -Minor changes (visited and Cell) - -Revision 1.4 2005/02/17 16:40:35 ponchio -Optimized BuildLevels. - -Revision 1.3 2005/02/08 12:43:03 ponchio -Added copyright - - -****************************************************************************/ - -#ifndef NXS_HISTORY_H -#define NXS_HISTORY_H - -#include -#include - -//TODO fix a bit better the quick <-> updates duality - -namespace nxs { - - class Nexus; - class History { - public: - - enum Mode { QUICK = 1, UPDATES = 2 }; - - struct Update { - std::vector erased; - std::vector created; - }; - - struct Node; - - struct Link { - Node *node; - unsigned int begin; //begin patch of the fragment - unsigned int end; //end patch of the fragment - - typedef unsigned int iterator; - unsigned int size() { return end - begin; } - }; - - struct Node { - typedef Link *iterator; - Link *in_begin, *in_end; - Link *out_begin, *out_end; - }; - - Node *nodes; - Link *in_links; - Link *out_links; - - std::vector updates; - - History(): nodes(NULL), in_links(NULL), out_links(NULL),// frags(NULL), - buffer(NULL) {} - ~History(); - - Node *Root() { return &nodes[0]; } - Node *Sink() { return Root() + n_nodes() -1; } - void Clear(); - void ClearQuick(); - void ClearUpdates(); - //Owns memory afterwards.. do not free mem. - bool Load(unsigned int size, char *mem); - bool LoadQuick(unsigned int size, char *mem); - bool LoadUpdates(unsigned int size, char *mem); - - //after these call history is invalid! and memory returned must be freed... - char *Save(unsigned int &size); //autodetect - char *SaveQuick(unsigned int &size); - char *SaveUpdates(unsigned int &size); - - bool QuickToUpdates(); - bool UpdatesToQuick(Nexus &nexus); - bool IsQuick() { return buffer != NULL; } - - void BuildLevels(std::vector &levels); - - int &quick() { return ((int *)buffer)[0]; } - int &n_nodes() { return ((int *)buffer)[1]; } - int &n_in_links() { return ((int *)buffer)[2]; } - int &n_out_links() { return ((int *)buffer)[3]; } - - // typedef Node *iterator; - // iterator begin() { return nodes; } - // iterator end() { return nodes + n_nodes(); } - protected: - unsigned int size; - char *buffer; - - bool LoadPointers(); - }; - -} -#endif diff --git a/apps/nexus/index_file.h b/apps/nexus/index_file.h deleted file mode 100644 index 8053bca3..00000000 --- a/apps/nexus/index_file.h +++ /dev/null @@ -1,108 +0,0 @@ -/**************************************************************************** -* VCGLib o o * -* Visual and Computer Graphics Library o o * -* _ O _ * -* Copyright(C) 2004 \/)\/ * -* Visual Computing Lab /\/| * -* ISTI - Italian National Research Council | * -* \ * -* All rights reserved. * -* * -* This program is free software; you can redistribute it and/or modify * -* it under the terms of the GNU General Public License as published by * -* the Free Software Foundation; either version 2 of the License, or * -* (at your option) any later version. * -* * -* This program is distributed in the hope that it will be useful, * -* but WITHOUT ANY WARRANTY; without even the implied warranty of * -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * -* GNU General Public License (http://www.gnu.org/licenses/gpl.txt) * -* for more details. * -* * -****************************************************************************/ -/**************************************************************************** - History - -$Log: not supported by cvs2svn $ - -****************************************************************************/ - -#ifndef NXS_INDEX_FILE_H -#define NXS_INDEX_FILE_H - -#include - -#include - -#include "mfile.h" - -namespace nxs { - - /* WARINING when subclassing this class you must add a Close() - in the destructor! */ - -template -class IndexFile: public MFile, public std::vector { - - public: - virtual ~IndexFile() {} - - bool Create(const std::string &filename, unsigned int header_size, - unsigned int max_file_size = MFILE_MAX_SIZE) { - clear(); - if(!MFile::Create(filename, max_file_size)) return false; - MFile::Redim(header_size); - offset = header_size; - return true; - } - - bool Load(const std::string &filename, bool readonly = false) { - clear(); - if(!MFile::Load(filename, readonly)) return false; - SetPosition(0); - LoadHeader(); - - SetPosition(offset); - unsigned int tot; - ReadBuffer(&tot, sizeof(unsigned int)); - resize(tot); - ReadBuffer(&*begin(), size() * sizeof(T)); - return true; - } - - void Close() { - if(IsReadOnly()) return; - if(files.size() == 0) return; //not loaded, not created or closed - - MFile::Redim(offset + size() * sizeof(T)); - SetPosition(offset); - unsigned int tot = size(); - WriteBuffer(&tot, sizeof(unsigned int)); - WriteBuffer(&*begin(), size() * sizeof(T)); - SetPosition(0); - SaveHeader(); - MFile::Close(); - } - - int64 Length() { //count the header but not the index... - return offset; - } - - void Redim(int64 size) { - MFile::Redim(size); - offset = size; - assert(MFile::Length() == offset); - } - - protected: - int64 offset; - - //MUST set offset to its correct value - virtual bool LoadHeader() = 0; - //MUST save offset somewhere - virtual void SaveHeader() = 0; -}; - -} //namespace - -#endif diff --git a/apps/nexus/metric.h b/apps/nexus/metric.h deleted file mode 100644 index 387afebf..00000000 --- a/apps/nexus/metric.h +++ /dev/null @@ -1,109 +0,0 @@ -/**************************************************************************** -* VCGLib o o * -* Visual and Computer Graphics Library o o * -* _ O _ * -* Copyright(C) 2004 \/)\/ * -* Visual Computing Lab /\/| * -* ISTI - Italian National Research Council | * -* \ * -* All rights reserved. * -* * -* This program is free software; you can redistribute it and/or modify * -* it under the terms of the GNU General Public License as published by * -* the Free Software Foundation; either version 2 of the License, or * -* (at your option) any later version. * -* * -* This program is distributed in the hope that it will be useful, * -* but WITHOUT ANY WARRANTY; without even the implied warranty of * -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * -* GNU General Public License (http://www.gnu.org/licenses/gpl.txt) * -* for more details. * -* * -****************************************************************************/ -/**************************************************************************** - History - -$Log: not supported by cvs2svn $ -Revision 1.9 2005/02/22 10:37:55 ponchio -Debug, cleaning and optimization. - -Revision 1.8 2005/02/21 20:49:30 ponchio -some culling bug. - -Revision 1.7 2005/02/20 19:49:44 ponchio -cleaning (a bit more). - -Revision 1.6 2005/02/20 18:07:01 ponchio -cleaning. - -Revision 1.5 2005/02/19 16:22:45 ponchio -Minor changes (visited and Cell) - -Revision 1.4 2005/02/08 12:43:03 ponchio -Added copyright - - -****************************************************************************/ - -#ifndef NXS_METRIC_H -#define NXS_METRIC_H - -#include -#include -#include "nexus.h" - -namespace nxs { - - enum MetricKind { FRUSTUM, FLAT, DELTA }; - - class Metric { - public: - vcg::Frustumf frustum; - bool culling; - - Metric(): culling(true) {} - virtual void GetView() { frustum.GetView(); } - virtual float GetError(Entry &entry, bool &visible) = 0; - - }; - - class FlatMetric: public Metric { - public: - float GetError(Entry &entry, bool &visible) { - visible = true; - return entry.error; - } - }; - - class FrustumMetric: public Metric { - public: - float GetError(Entry &entry, bool &visible) { - visible = true; - vcg::Sphere3f &sph = entry.sphere; - float dist = (sph.Center() - frustum.ViewPoint()).Norm() - sph.Radius(); - - if(dist < 0) return 1e20f; - - float error = entry.error/frustum.Resolution(dist); - if(culling) { - float remote = frustum.Remoteness(sph.Center(), sph.Radius()); - if(frustum.IsOutside(sph.Center(), sph.Radius())) { - visible = false; - - - // TODO FIXME remoteness is bugged... (not much only bit - //if we are close to the surface, the projection of - //the bounding sphere in screen space comes out too small - //just using resolution and radius. Im too lazy to fix it. - if(remote > 0) - error /= remote; - } else if(entry.cone.Backface(sph, frustum.ViewPoint())) { - visible = false; - } - } - return error; - } - }; -} - -#endif diff --git a/apps/nexus/mfile.cpp b/apps/nexus/mfile.cpp deleted file mode 100644 index a554a289..00000000 --- a/apps/nexus/mfile.cpp +++ /dev/null @@ -1,192 +0,0 @@ -/**************************************************************************** -* VCGLib o o * -* Visual and Computer Graphics Library o o * -* _ O _ * -* Copyright(C) 2004 \/)\/ * -* Visual Computing Lab /\/| * -* ISTI - Italian National Research Council | * -* \ * -* All rights reserved. * -* * -* This program is free software; you can redistribute it and/or modify * -* it under the terms of the GNU General Public License as published by * -* the Free Software Foundation; either version 2 of the License, or * -* (at your option) any later version. * -* * -* This program is distributed in the hope that it will be useful, * -* but WITHOUT ANY WARRANTY; without even the implied warranty of * -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * -* GNU General Public License (http://www.gnu.org/licenses/gpl.txt) * -* for more details. * -* * -****************************************************************************/ -/**************************************************************************** - History - -$Log: not supported by cvs2svn $ - -****************************************************************************/ - -#include "mfile.h" -#include -#include - -using namespace std; -using namespace nxs; - -bool MFile::Create(const string &fname, unsigned int mxs) { - Close(); - filename = fname; - _size = 0; - readonly = false; - assert(mxs <= MFILE_MAX_SIZE); - max_size = mxs; - return AddFile(); -} - -bool MFile::Load(const string &fname, bool ronly) { - Close(); - filename = fname; - readonly = ronly; - max_size = MFILE_MAX_SIZE; - _size = 0; - - while(1) { - string name = Name(files.size()); - File *file = new File; - files.push_back(file); - if(!file->Load(name, ronly)) { - files.pop_back(); - break; - } - _size += file->Length(); - } - if(files.size() == 0) return false; - if(files.size() == 1) { - assert(_size <= max_size); - } else { - //SANITY TEST - for(unsigned int i = 0; i < files.size() -2; i++) { - if(files[i]->Length() != files[i++]->Length()) { - //"Inconsistent file size for some file.\n"; - return false; - } - max_size = files[0]->Length(); - } - } - return true; -} - -void MFile::Close() { - for(unsigned int i = 0; i < files.size(); i++) - delete files[i]; - files.clear(); -} - -void MFile::Delete() { - while(files.size()) - RemoveFile(); -} - -void MFile::Redim(int64 sz) { - assert(!readonly); - if(sz > _size) { - unsigned int totfile = (unsigned int)(sz/max_size); - //TODO test rhis!!!! - while(files.size() <= totfile) { - RedimLast(max_size); - assert(_size == (int64)max_size * (int64)(files.size())); - AddFile(); - } - assert(_size <= sz); - assert(sz - _size < max_size); - assert(files.back()->Length() + (unsigned int)(sz - _size) < max_size); - RedimLast(files.back()->Length() + (unsigned int)(sz - _size)); - } else { - while(_size - files.back()->Length() > sz) - RemoveFile(); - assert(sz <= _size); - RedimLast(files.back()->Length() - (unsigned int)(_size - sz)); - } - assert(sz == _size); -} - -void MFile::SetPosition(int64 pos) { - assert(pos <= _size); - curr_fp = (unsigned int)(pos/(int64)max_size); - curr_pos = (unsigned int)(pos - (int64)max_size * (int64)curr_fp); - assert(curr_pos < max_size); - assert(curr_fp < files.size()); - files[curr_fp]->SetPosition(curr_pos); -} - -void MFile::ReadBuffer(void *data, unsigned int sz) { - while(sz + curr_pos > max_size) { - unsigned int n = max_size - curr_pos; - files[curr_fp]->ReadBuffer(data, n); - data = ((char *)data) + n; - sz -= n; - curr_fp++; - assert(curr_fp < files.size()); - curr_pos = 0; - files[curr_fp]->SetPosition(curr_pos); - } - files[curr_fp]->ReadBuffer(data, sz); -} - -void MFile::WriteBuffer(void *data, unsigned int sz) { - assert(!readonly); - while(sz + curr_pos > max_size) { - unsigned int n = max_size - curr_pos; - files[curr_fp]->WriteBuffer(data, n); - data = ((char *)data) + n; - sz -= n; - curr_fp++; - assert(curr_fp < files.size()); - curr_pos = 0; - files[curr_fp]->SetPosition(curr_pos); - } - files[curr_fp]->WriteBuffer(data, sz); -} - - bool MFile::AddFile() { - string name = Name(files.size()); - File *file = new File; - files.push_back(file); - return file->Create(name); - } - - void MFile::RemoveFile() { - assert(files.size()); - - string name = Name(files.size()-1); - File *file = files.back(); - unsigned int last_size = file->Length(); - delete file; - files.pop_back(); - _size -= last_size; - cerr << "Removing file: " << name << endl; -#ifdef WIN32 - DeleteFile(name.c_str()); -#else - unlink(name.c_str()); -#endif - } - -void MFile::RedimLast(unsigned int sz) { - assert(sz <= max_size); - File &file = *files.back(); - unsigned int last_size = (int64)file.Length(); - file.Redim(sz); - _size += sz - (int64)last_size; -} - -std::string MFile::Name(unsigned int n) { - char buffer[1024]; - if(n == 0) - sprintf(buffer, "%s", filename.c_str()); - else - sprintf(buffer, "%s%d", filename.c_str(), n); - return string(buffer); -} - diff --git a/apps/nexus/mfile.h b/apps/nexus/mfile.h deleted file mode 100644 index a9d94adb..00000000 --- a/apps/nexus/mfile.h +++ /dev/null @@ -1,91 +0,0 @@ -/**************************************************************************** -* VCGLib o o * -* Visual and Computer Graphics Library o o * -* _ O _ * -* Copyright(C) 2004 \/)\/ * -* Visual Computing Lab /\/| * -* ISTI - Italian National Research Council | * -* \ * -* All rights reserved. * -* * -* This program is free software; you can redistribute it and/or modify * -* it under the terms of the GNU General Public License as published by * -* the Free Software Foundation; either version 2 of the License, or * -* (at your option) any later version. * -* * -* This program is distributed in the hope that it will be useful, * -* but WITHOUT ANY WARRANTY; without even the implied warranty of * -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * -* GNU General Public License (http://www.gnu.org/licenses/gpl.txt) * -* for more details. * -* * -****************************************************************************/ -/**************************************************************************** - History - -$Log: not supported by cvs2svn $ - -****************************************************************************/ - -#ifndef NXS_MFILE_H -#define NXS_MFILE_H - -#include -#include - -#include "file.h" -#include "nxstypes.h" - -namespace nxs { - - /*#ifdef WIN32 -typedef __int64 int64; -#else -typedef unsigned long long int64; -#endif*/ - -#define MFILE_MAX_SIZE (1<<30) - -class MFile { - public: - - MFile() {} - ~MFile() { Close(); } - - //max is so default is 1 G - bool Create(const std::string &filename, - unsigned int max_file_size = MFILE_MAX_SIZE); - bool Load(const std::string &filename, bool readonly = false); - void Close(); - void Delete(); - - int64 Length() { return _size; } - void Redim(int64 size); - - void SetPosition(int64 pos); - void ReadBuffer(void *data, unsigned int size); - void WriteBuffer(void *data, unsigned int size); - - bool Opened() { return files.size() > 0; } - bool IsReadOnly() { return readonly; } - void SetReadOnly(bool rd) { readonly = rd; } //USE WITH CARE!!!! - protected: - std::string filename; - std::vector files; - unsigned int curr_pos; - unsigned int curr_fp; - int64 _size; - unsigned int max_size; - bool readonly; - private: - //all theese refer to the last in the fp. - bool AddFile(); - void RemoveFile(); - void RedimLast(unsigned int sz); - unsigned int GetSize(); - std::string Name(unsigned int n); -}; - -} - -#endif diff --git a/apps/nexus/nexus.cpp b/apps/nexus/nexus.cpp deleted file mode 100644 index a6db5d90..00000000 --- a/apps/nexus/nexus.cpp +++ /dev/null @@ -1,319 +0,0 @@ -/**************************************************************************** -* VCGLib o o * -* Visual and Computer Graphics Library o o * -* _ O _ * -* Copyright(C) 2004 \/)\/ * -* Visual Computing Lab /\/| * -* ISTI - Italian National Research Council | * -* \ * -* All rights reserved. * -* * -* This program is free software; you can redistribute it and/or modify * -* it under the terms of the GNU General Public License as published by * -* the Free Software Foundation; either version 2 of the License, or * -* (at your option) any later version. * -* * -* This program is distributed in the hope that it will be useful, * -* but WITHOUT ANY WARRANTY; without even the implied warranty of * -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * -* GNU General Public License (http://www.gnu.org/licenses/gpl.txt) * -* for more details. * -* * -****************************************************************************/ -/**************************************************************************** - History - -$Log: not supported by cvs2svn $ -Revision 1.29 2005/02/19 10:45:04 ponchio -Patch generalized and small fixes. - -Revision 1.28 2005/02/08 12:43:03 ponchio -Added copyright - - -****************************************************************************/ - -#include - -#include -#include - -#include "nexus.h" - -using namespace std; -using namespace vcg; -using namespace nxs; - -Nexus::~Nexus() { - Close(); -} - -bool Nexus::Create(const string &file, Signature &sig, unsigned int c_size) { - signature = sig; - totvert = 0; - totface = 0; - sphere = Sphere3f(); - chunk_size = c_size; - unsigned int header_size = 256; //a bit more than 64 needed - if(chunk_size > header_size) header_size = chunk_size; - - history.Clear(); - ram_used = 0; - ram_max = 50 * (1<<20) / chunk_size; - - if(!IndexFile::Create(file + ".nxp", header_size)) { - cerr << "Could not create file: " << file << ".nxp" << endl; - return false; - } - - //Important: chunk_size must be 1 so that i can use Region in VFile. - if(!borders.Create(file + ".nxb")) { - cerr << "Could not create file: " << file << ".nxb" << endl; - return false; - } - return true; -} - - -bool Nexus::Load(const string &file, bool rdonly) { - if(!IndexFile::Load(file + ".nxp", rdonly)) return false; - ram_used = 0; - ram_max = 50 * (1<<20) / chunk_size; - - history.Clear(); - SetPosition(history_offset); - unsigned int history_size; - ReadBuffer(&history_size, sizeof(unsigned int)); - - char *buffer = new char[history_size]; - ReadBuffer(buffer, history_size); - - if(!history.Load(history_size, buffer)) { - cerr << "Error loading history\n"; - return false; - } - - borders.Load(file + ".nxb", rdonly); - //TODO on nxsbuilder assure borders are loaded - return true; -} - -void Nexus::Close() { - if(!Opened()) return; - - Flush(); - - if(!IsReadOnly()) { - //set history_offset - history_offset = 0; - if(size()) { - //we need to discover where is the last patch - for(unsigned int i = 0; i < size(); i++) { - Entry &e = operator[](i); - if(e.patch_start + e.disk_size > history_offset) - history_offset = e.patch_start + e.disk_size; - } - // history_offset = (back().patch_start + back().disk_size); - } - history_offset *= chunk_size; - - unsigned int history_size; - char *mem = history.Save(history_size); - Redim(history_offset + history_size + sizeof(unsigned int)); - SetPosition(history_offset); - WriteBuffer(&history_size, sizeof(unsigned int)); - WriteBuffer(mem, history_size); - delete []mem; - } - borders.Close(); - IndexFile::Close(); -} - -void Nexus::SaveHeader() { - unsigned int magic = 0x3053584e; // nxs0 - WriteBuffer(&magic, sizeof(unsigned int)); - unsigned int version = 1; - WriteBuffer(&version, sizeof(unsigned int)); - - WriteBuffer(&signature, sizeof(Signature)); - WriteBuffer(&chunk_size, sizeof(unsigned int)); - WriteBuffer(&offset, sizeof(int64)); - WriteBuffer(&history_offset, sizeof(int64)); - WriteBuffer(&totvert, sizeof(unsigned int)); - WriteBuffer(&totface, sizeof(unsigned int)); - WriteBuffer(&sphere, sizeof(Sphere3f)); -} - -bool Nexus::LoadHeader() { - unsigned int magic; - ReadBuffer(&magic, sizeof(unsigned int)); - if(magic != 0x3053584e) { - cerr << "Invalid magic. Not a nxs file\n"; - return false; - } - //Current version is 1 - unsigned int version; - ReadBuffer(&version, sizeof(unsigned int)); - if(version != NXS_CURRENT_VERSION) { - cerr << "Old version. Sorry.\n"; - return false; - } - ReadBuffer(&signature, sizeof(Signature)); - ReadBuffer(&chunk_size, sizeof(unsigned int)); - ReadBuffer(&offset, sizeof(int64)); - ReadBuffer(&history_offset, sizeof(int64)); - ReadBuffer(&totvert, sizeof(unsigned int)); - ReadBuffer(&totface, sizeof(unsigned int)); - ReadBuffer(&sphere, sizeof(Sphere3f)); - return true; -} - -void Nexus::Flush(bool all) { - if(all) { - std::map::iterator>::iterator i; - for(i = index.begin(); i != index.end(); i++) { - unsigned int patch = (*i).first; - FlushPatch(patch); - } - pqueue.clear(); - index.clear(); - } else { - while(ram_used > ram_max) { - unsigned int to_flush = pqueue.back(); - pqueue.pop_back(); - index.erase(to_flush); - FlushPatch(to_flush); - } - } -} - - - -Patch &Nexus::GetPatch(unsigned int patch, bool flush) { - Entry &entry = operator[](patch); - if(index.count(patch)) { - assert(entry.patch); - list::iterator i = index[patch]; - pqueue.erase(i); - pqueue.push_front(patch); - index[patch] = pqueue.begin(); - } else { - while(flush && ram_used > ram_max) { - unsigned int to_flush = pqueue.back(); - pqueue.pop_back(); - index.erase(to_flush); - FlushPatch(to_flush); - } - assert(!entry.patch); - entry.patch = LoadPatch(patch); - pqueue.push_front(patch); - list::iterator i = pqueue.begin(); - index[patch] = i; - } - return *(entry.patch); -} - -Border &Nexus::GetBorder(unsigned int patch, bool flush) { - return borders.GetBorder(patch); -} - -unsigned int Nexus::AddPatch(unsigned int nvert, unsigned int nface, - unsigned int nbord) { - - Entry entry; - entry.patch_start = 0xffffffff; - entry.ram_size = Patch::ChunkSize(signature, nvert, nface, chunk_size); - entry.disk_size = 0xffff; - entry.nvert = nvert; - entry.nface = nface; - entry.error = 0; - //sphere undefined. - entry.patch = NULL; - entry.vbo_array = 0; - entry.vbo_element = 0; - - push_back(entry); - - borders.AddBorder(nbord); - - totvert += nvert; - totface += nface; - return size() - 1; -} - -Patch *Nexus::LoadPatch(unsigned int idx) { - assert(idx < size()); - Entry &entry = operator[](idx); - if(entry.patch) return entry.patch; - - char *ram = new char[entry.ram_size * chunk_size]; -#ifndef NDEBUG - if(!ram) { - cerr << "COuld not allocate ram!\n"; - exit(0); - } -#endif - - Patch *patch = new Patch(signature, ram, entry.nvert, entry.nface); - - if(entry.patch_start != 0xffffffff) { //was allocated. - assert(entry.disk_size != 0xffff); - - MFile::SetPosition((int64)entry.patch_start * (int64)chunk_size); - - if(signature.compr == 0) { //not compressed - MFile::ReadBuffer(ram, entry.disk_size * chunk_size); - } else { - unsigned char *disk = new unsigned char[entry.disk_size * chunk_size]; - MFile::ReadBuffer(disk, entry.disk_size * chunk_size); - - patch->Decompress(entry.ram_size * chunk_size, - disk, entry.disk_size * chunk_size); - delete []disk; - } - } else { - //zero all bytes... so compressio gets better with padding. - memset(ram, 0, entry.ram_size * chunk_size); - } - ram_used += entry.ram_size; - entry.patch = patch; - return patch; -} - -void Nexus::FlushPatch(unsigned int id) { - Entry &entry = operator[](id); - assert(entry.patch); - - if(!MFile::IsReadOnly()) { //write back patch - if(signature.compr) { - unsigned int compressed_size; - char *compressed = entry.patch->Compress(entry.ram_size * chunk_size, - compressed_size); - if(entry.disk_size == 0xffff) {//allocate space - assert(entry.patch_start == 0xffffffff); - entry.disk_size = (unsigned int)((compressed_size-1)/chunk_size) + 1; - entry.patch_start = (unsigned int)(Length()/chunk_size); - Redim(Length() + entry.disk_size * chunk_size); - } else { - //cerr << "OOOOPSPPPS not supported!" << endl; - exit(-1); - } - MFile::SetPosition((int64)entry.patch_start * (int64)chunk_size); - MFile::WriteBuffer(compressed, entry.disk_size * chunk_size); - delete []compressed; - } else { - if(entry.disk_size == 0xffff) { - entry.disk_size = entry.ram_size; - entry.patch_start = (unsigned int)(Length()/chunk_size); - Redim(Length() + entry.disk_size * chunk_size); - } - MFile::SetPosition((int64)entry.patch_start * (int64)chunk_size); - MFile::WriteBuffer(entry.patch->fstart, entry.disk_size * chunk_size); - } - } - - delete [](entry.patch->fstart); - delete entry.patch; - entry.patch = NULL; - ram_used -= entry.ram_size; -} diff --git a/apps/nexus/nexus.h b/apps/nexus/nexus.h deleted file mode 100644 index 0f57e2c8..00000000 --- a/apps/nexus/nexus.h +++ /dev/null @@ -1,146 +0,0 @@ -/**************************************************************************** -* VCGLib o o * -* Visual and Computer Graphics Library o o * -* _ O _ * -* Copyright(C) 2004 \/)\/ * -* Visual Computing Lab /\/| * -* ISTI - Italian National Research Council | * -* \ * -* All rights reserved. * -* * -* This program is free software; you can redistribute it and/or modify * -* it under the terms of the GNU General Public License as published by * -* the Free Software Foundation; either version 2 of the License, or * -* (at your option) any later version. * -* * -* This program is distributed in the hope that it will be useful, * -* but WITHOUT ANY WARRANTY; without even the implied warranty of * -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * -* GNU General Public License (http://www.gnu.org/licenses/gpl.txt) * -* for more details. * -* * -****************************************************************************/ -/**************************************************************************** - History - -$Log: not supported by cvs2svn $ -Revision 1.21 2005/02/19 10:45:04 ponchio -Patch generalized and small fixes. - -Revision 1.20 2005/02/08 12:43:03 ponchio -Added copyright - - -****************************************************************************/ - -#ifndef NXS_NEXUS_H -#define NXS_NEXUS_H - -#include -#include -#include -#include - -#include - -#include "normalscone.h" -#include "patch.h" -#include "index_file.h" -#include "history.h" -#include "borderserver.h" - -namespace nxs { - - /* Header fo nexus: - 1Kb riservato per dati globali: - Magic: 'n' 'x' 's' 0x00 - Signature: unsigned int (maschera di bit) - Chunk size: unsigned int - Index offset: unsigned int (offset to the index begin, - must be a multiple of chunk size) - History offset: unsigned int: multiple of chunk_size - - Tot vert: unsigned int - Tot face: unsigned int - Bound sphere: Sphere3f (4 float: Point3f center (x, y, z), (radius)) - - 11 * 4 = 44 bytes -> 4k per alignment purpoouses and reserving space. */ - -struct Entry { - unsigned int patch_start; //granularita' Chunk - unsigned short ram_size; //in chunks - unsigned short disk_size; // in chunks (used when compressed) - - unsigned short nvert; - unsigned short nface; - - vcg::Sphere3f sphere; - float error; - NCone3s cone; - - Patch *patch; - unsigned int vbo_array; - unsigned int vbo_element; -}; - -class Nexus: public IndexFile { - public: - enum Version { NXS_CURRENT_VERSION = 1 }; - - //HEader data: - Signature signature; - unsigned int chunk_size; - //unsigned int .IndexFile::offset; - int64 history_offset; - - unsigned int totvert; - unsigned int totface; - vcg::Sphere3f sphere; - - History history; - - BorderServer borders; - - - Nexus() {} - ~Nexus(); - - bool Create(const std::string &filename, Signature &signature, - unsigned int chunk_size = 1024); - bool Load(const std::string &filename, bool readonly = false); - void Close(); - void Flush(bool all = true); - - unsigned int AddPatch(unsigned int nv, unsigned int nf, unsigned int nb); - Patch &GetPatch(unsigned int patch, bool flush = true); - Border &GetBorder(unsigned int patch, bool flush = true); - - unsigned int &MaxRam() { return ram_max; } - // void AddBorder(unsigned int patch, Link &link); - - //move to nxsalgo! - void Unify(float threshold = 0.0f); - - bool IsCompressed() { return signature.compr != 0; } - bool HasStrips() { return signature.face == Signature::STRIPS; } - bool HasColors() { return signature.vcolor != 0; } - bool HasNormals() { return signature.vnorm != 0; } - bool HasTextures() { return signature.vtext != 0; } - - unsigned int ram_max; - unsigned int ram_used; - protected: - - std::list pqueue; - std::map::iterator> index; - - Patch *LoadPatch(unsigned int id); - virtual void FlushPatch(unsigned int id); - - bool LoadHeader(); - void SaveHeader(); -}; - -} - -#endif diff --git a/apps/nexus/nexus.html b/apps/nexus/nexus.html deleted file mode 100644 index 1ec180bd..00000000 --- a/apps/nexus/nexus.html +++ /dev/null @@ -1,174 +0,0 @@ - - - - -

-

-

-

Index:

-

-

- - -

Big picture

-La truttura nexus divide la mesh in tante piccole parti.
-Ciascuna parte ha le facce indicizzate localmente, e sono codificate -esplicitamente le corrispondenze tra vertici di patches diverse.
- -

Structures and interfaces

- -

VFile

-VFile dovrebbe avere piu' o meno la stessa interfaccia di vector -ma usare un file per storare i dati (un mmapping, ma non limitato a 4Gb).
- -

Crude

-
-Crude e' un formato tipo il ply... solo che usa dei VFile per 
-storare i dati.(3 unsigned int per una faccia e 3 float per un vertice).
-Per cui e' composto di 3 files:
- Header (.crd)
-  Magic:     'c' 'r' 'd' 0x00 (4 bytes)
-  N vertici: unsigned int (4 bytes)
-  N facce: unsigned int (4 bytes)
-  Box: Box3f (6 float min(x, y, z) e max(x, y, z))
-  
- File dei vertici:  Point3f in sequenza (3 float, x, y, z)
- File delle facce:  3 unsigned int
-  
- opzionalmente file degli attributi dei vertici e delle facce.
-
- Come interfaccia e' sufficente che dia accesso casuale a facce e vertici...
-
- -

PChain

-Sta per 'partition chain' cioe' una catena di partizioni dello -spazio.
-Una PChain detto in matematichese e' una funzione da -[0..L] X R^3 -> N (cioe' dato un livello e un punto nello spazio -restituisce un numero naturale. (una patch)
-Oltre a questo va aggiunta una funzione che dato un punto e una patch -ne restituisce la distanza (o un valore 'equivalente').
-Si deve poter salvare su disco e recuperare una pchain
- - - -

Nexus

-
-E' una struttura con 2 files:
-
-File delle patches: (.nxs)
-  1Kb riservato per dati globali:
-     Magic:        'n' 'x' 's' 0x00
-     Signature:    unsigned int (maschera di bit)
-     Chunk size:   unsigned int
-     Index offset: int64 (offset to the index begin, 
-                                 must be a multiple of chunk size)
-     History offset: int64: multiple of chunk_size
-
-     Tot vert:     unsigned int
-     Tot face:     unsigned int  
-     Bound sphere: Sphere3f (4 float: Point3f center (x, y, z), (radius))
-
-  Dati (la sequenza di patches)
- 
-  Index
-  History
-
-  'Index' contiene l'indice delle patches, per ogni patch viene storato:
-  offset, size dei dati geometrici nel file delle patches etc.
-  'History' vedi history.h
-
-  Index e History sono tenuti in memoria se il file e' aperto per creare
-  o per modificare, e sono salvati quando si chiude il file.
-
-File dei bordi:
-   Links.
-   Index (offset, size tot size used)
-
-
-  Ogni link fa riferimento ad un vertice di bordo 
-  tra la patch A (V_a) e la B (V_b) e contiene (V_a, V_b, B) (A e' implicito). 
-   L'informazione e' replicata nei bordi relativi a B con (V_b, V_a, A)
-
-
- -

Bmt

-Bmt (batched multi triangulation) e' il formato per la -multirisoluzione:
-E' un vettore di 'Cell' scritti su disco + un 'Index' e una 'History'. -Cell contiene i dati da visualizzare: vertici e strip (e altro?).
-Index contiene per ogni cell 'offset' per trovare la cell -corrispondente, error e bounding sphere (e per il face o vertex -count?).
-History e' la storia della multirisoluzione.
- -

Algorithms

-

Plys to Crude

-Si copiano i vertici un ply dopo l'altro nel crude.
-Per le facce si copiano sommando un offset ai vertici
-Se si montano insieme piu' ply i vertici rimangono duplicati.
-E' piu' semplice fare il join dentro Nexus.
- -

Crude + PChain to Remap

-Come prima cosa si costruisce il pchain passandogli il Crude.
-Asegnamo per ogni faccia la sua patch al livello 0.
-Per ogni patch sappiamo quante ce ne sono.
-Ridistribuiamo le patch troppo piccole (e rimappiamo i numeri delle -patches per rimuovere i buchi (anche dentro il PChain).
-Per risparmiare nella stessa passata ci segnamo dove vanno i vertici
-Poi facciamo un'altra passate per contare i bordi
-Infine si sortano le facce secondo l'ordine delle patches.
- -

Crude + Remap to Nexus

-Per ogni patch raccogliamo le facce, e i vertici (ma non li -unifichiamo) e costruiamo una patch nel Nexus.
-Ci dobbiamo segnare i bordi mano a mano che lo facciamo: -per ogni patch ci salviamo una lista di triplette: il numero assoluto -del vertice di bordo, il numero relativo nella patch che stiamo -salvando, e il numero della patch (o delle patch) con la quale -confina.
-Queste informazioni le tiriamo fuori dal Remap dei vertici
-Una volta salvate tutte le patches ci smazziamo i bordi: -per ogni patch prendiamo quella lista e la incrociamo con quella -delle patches confinanti per costruire i bordi da passare a nexus.
- -

Nexus + PChain to Bmt

-Per costruire il file multirisoluzione aggiungeremo semplicemente -nuove patches al file nexus.
-Ad ogni passo selezioniamo un gruppo di patches (il PChain ci dice i -gruppi), li joiniamo insieme usando i bordi per riunificare i vertici -e per marcare i bordi esterni.
-Poi semplifichiamo e splittiamo (e sempre il PChain ci dice quali -nuove patches creare), ridistribuiamo le patches troppo piccole.
-E aggiungiamo le nuove patches al Nexus, e i nuovi bordi.
-Ci salviamo anche la storia da qualche parte.
- - diff --git a/apps/nexus/nexus_logo.png b/apps/nexus/nexus_logo.png deleted file mode 100644 index 79eab848..00000000 Binary files a/apps/nexus/nexus_logo.png and /dev/null differ diff --git a/apps/nexus/nexus_logo_large.png b/apps/nexus/nexus_logo_large.png deleted file mode 100644 index 829744cd..00000000 Binary files a/apps/nexus/nexus_logo_large.png and /dev/null differ diff --git a/apps/nexus/nexus_logo_midi.png b/apps/nexus/nexus_logo_midi.png deleted file mode 100644 index 47e791f5..00000000 Binary files a/apps/nexus/nexus_logo_midi.png and /dev/null differ diff --git a/apps/nexus/nexusmt.cpp b/apps/nexus/nexusmt.cpp deleted file mode 100644 index ba5ed374..00000000 --- a/apps/nexus/nexusmt.cpp +++ /dev/null @@ -1,464 +0,0 @@ -/**************************************************************************** -* VCGLib o o * -* Visual and Computer Graphics Library o o * -* _ O _ * -* Copyright(C) 2004 \/)\/ * -* Visual Computing Lab /\/| * -* ISTI - Italian National Research Council | * -* \ * -* All rights reserved. * -* * -* This program is free software; you can redistribute it and/or modify * -* it under the terms of the GNU General Public License as published by * -* the Free Software Foundation; either version 2 of the License, or * -* (at your option) any later version. * -* * -* This program is distributed in the hope that it will be useful, * -* but WITHOUT ANY WARRANTY; without even the implied warranty of * -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * -* GNU General Public License (http://www.gnu.org/licenses/gpl.txt) * -* for more details. * -* * -****************************************************************************/ -/**************************************************************************** - History - -$Log: not supported by cvs2svn $ -Revision 1.37 2005/03/02 10:40:17 ponchio -Extraction rewrittten (to fix recusive problems). - -Revision 1.36 2005/02/22 10:38:06 ponchio -Debug, cleaning and optimization. - -Revision 1.35 2005/02/20 19:49:44 ponchio -cleaning (a bit more). - -Revision 1.34 2005/02/20 18:07:01 ponchio -cleaning. - -Revision 1.33 2005/02/20 00:43:23 ponchio -Less memory x extraction. (removed frags) - -Revision 1.32 2005/02/19 12:06:53 ponchio -Debug... - -Revision 1.31 2005/02/19 10:45:04 ponchio -Patch generalized and small fixes. - -Revision 1.30 2005/02/17 15:39:44 ponchio -Reorderes statistics a bit. - -Revision 1.29 2005/02/14 17:11:07 ponchio -aggiunta delle sphere - -Revision 1.28 2005/02/08 12:43:03 ponchio -Added copyright - - -****************************************************************************/ - -#ifndef WIN32 -#include -#endif - -#include -#include - -#include - -#include - -#include "nexusmt.h" - -using namespace nxs; -using namespace vcg; -using namespace std; - -void Stats::Start() { - tri = extr = disk_tri = 0; - watch.Start(); -} - -void Stats::Disk(float _disk) { - disk.push_front(_disk); - if(disk.size() > log_size) disk.pop_back(); -} - -void Stats::Error(float _error) { - error.push_front(_error); - if(error.size() > log_size) error.pop_back(); -} - -void Stats::Stop() { - time.push_front((float)watch.Time()); - if(time.size() > log_size) time.pop_back(); - fps = (7*fps + 1/time[0])/8.0f; -} - -NexusMt::NexusMt() { - preload.mt = this; - preload.start(); -} - -NexusMt::~NexusMt() { - preload.signal(); - preload.waitfor(); -} - -void NexusMt::SetPreload(bool on) { - if(on == (preload.get_running() && !preload.get_finished())) return; - if(on) preload.start(); - else { - preload.signal(); - // preload.waitfor(); - } -} - -bool NexusMt::Load(const string &filename) { - if(!Nexus::Load(filename, true)) return false; - if(!history.IsQuick() && !history.UpdatesToQuick(*this)) - return false; - -#ifndef WIN32 - //i will read data only once usually. - // for(unsigned int i = 0; i < files.size(); i++) { - // int fd = fileno(files[i]->fp); - // posix_fadvise(fd, 0, 0, POSIX_FADV_NOREUSE); - // } - -#endif - return true; -} - -bool NexusMt::InitGL(bool vbo) { - use_vbo = vbo; - - GLenum ret = glewInit(); - if(ret != GLEW_OK) return false; - if(vbo && !GLEW_ARB_vertex_buffer_object) { - cerr << "No vbo available!" << endl; - use_vbo = false; - } - return true; -} - -void NexusMt::Render(DrawContest contest) { - Extraction extraction; - extraction.metric->GetView(); - extraction.Extract(this); - Render(extraction, contest); -} - - -void NexusMt::Render(Extraction &extraction, DrawContest &contest, - Stats *stats) { - static ::GLUquadricObj * spr = gluNewQuadric(); - - - //Updating heap errors - map errors; - for(unsigned int i = 0; i < extraction.selected.size(); i++) { - Item &item = extraction.selected[i]; - errors[item.id] = item.error; - } - for(unsigned int i = 0; i < heap.size(); i++) { - Item &item = heap[i]; - if(!errors.count(item.id)) { - item.error = 1e20; - } else - item.error = errors[item.id]; - } - make_heap(heap.begin(), heap.end()); - - - - preload.post(extraction.selected); - - glEnableClientState(GL_VERTEX_ARRAY); - if(signature.vcolor && (contest.attrs & DrawContest::COLOR)) - glEnableClientState(GL_COLOR_ARRAY); - if(signature.vnorm && (contest.attrs & DrawContest::NORMAL)) - glEnableClientState(GL_NORMAL_ARRAY); - - vector skipped; - - for(unsigned int i = 0; i < extraction.draw_size; i++) { - unsigned int patch = extraction.selected[i].id; - Entry &entry = operator[](patch); - if(stats) stats->extr += 2*entry.nvert; - - if(!extraction.Visible(patch)) - continue; - - if(stats) stats->tri += 2*entry.nvert; - - if(!entry.patch) { - skipped.push_back(extraction.selected[i]); - continue; - } - Draw(patch, contest); - } - - - preload.trigger.reset(); - preload.lock.enter(); - - // if(skipped.size()) cerr << "Skipped: " << skipped.size() << endl; - - for(vector::iterator i = skipped.begin(); i != skipped.end(); i++) { - GetPatch((*i).id, (*i).error); - Draw((*i).id, contest); - } - Flush(false); //in case there are no skipped... :P - - if(stats) { - stats->Error(extraction.max_error); - stats->Disk(preload.disk); - stats->disk_tri += preload.disk_tri; - preload.disk = 0; - } - - - preload.trigger.post(); - preload.lock.leave(); - - - - glDisableClientState(GL_VERTEX_ARRAY); - glDisableClientState(GL_COLOR_ARRAY); - glDisableClientState(GL_NORMAL_ARRAY); -} - -void NexusMt::Draw(unsigned int cell, DrawContest &contest) { - static ::GLUquadricObj * spr = gluNewQuadric(); - - Entry &entry = operator[](cell); - Patch &patch = *(entry.patch); - char *fstart; - char *vstart; - char *cstart; - char *nstart; - - if(contest.attrs & DrawContest::SPHERES){ - vcg::Sphere3f &sphere = entry.sphere; - glPushAttrib(GL_POLYGON_BIT); - glPolygonMode(GL_FRONT_AND_BACK,GL_LINE); - glPushMatrix(); - glTranslatef(sphere.Center().X(),sphere.Center().Y(),sphere.Center().Z()); - gluSphere(spr,sphere.Radius(),15,15); - glPopMatrix(); - glPopAttrib(); - } - - - if(use_vbo) { - if(!entry.vbo_element) - LoadVbo(entry); - - glBindBufferARB(GL_ARRAY_BUFFER_ARB, entry.vbo_array); - glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, entry.vbo_element); - - fstart = NULL; - vstart = NULL; - cstart = (char *)(patch.vstartc - patch.vstart); - nstart = (char *)(patch.vstartn - patch.vstart); - } else { - fstart = (char *)patch.FaceBegin(); - vstart = (char *)patch.Vert3fBegin(); - cstart = (char *)patch.VColorBegin(); - nstart = (char *)patch.VNormBegin(); - } - assert(signature.vert == Signature::POINT3F); - glVertexPointer(3, GL_FLOAT, 0, vstart); - - - if(signature.vcolor && contest.attrs & DrawContest::COLOR) { - assert(signature.vcolor == Encodings::BYTE4); - glColorPointer(4, GL_UNSIGNED_BYTE, 0, cstart); - } - - - if(signature.vnorm && contest.attrs & DrawContest::NORMAL) { - // assert(signature.vnorm == Encodings::SHORT4); - if(signature.vnorm == Encodings::SHORT4) - glNormalPointer(GL_SHORT, 8, nstart); - else - glNormalPointer(GL_FLOAT, 0, nstart); - } - - - - switch(contest.mode) { - case DrawContest::POINTS: - glDrawArrays(GL_POINTS, 0, patch.nv); break; - case DrawContest::PATCHES: - glColor3ub((cell * 27)%225 + 30, (cell * 37)%225 + 30, (cell * 87)%225 + 30); - case DrawContest::SMOOTH: - if(signature.face == Signature::TRIANGLES) - glDrawElements(GL_TRIANGLES, patch.nf * 3, - GL_UNSIGNED_SHORT, fstart); - else if(signature.face == Signature::STRIPS) - glDrawElements(GL_TRIANGLE_STRIP, patch.nf, - GL_UNSIGNED_SHORT, fstart); - break; - case DrawContest::FLAT: - if(use_vbo) { - cerr << "Unsupported rendering mode sorry\n"; - } else { - if(signature.face == Signature::TRIANGLES) { - glBegin(GL_TRIANGLES); - unsigned short *f = patch.Face(0); - for(int i = 0; i < patch.nf; i++) { - - Point3f &p0 = patch.Vert3f(f[0]); - Point3f &p1 = patch.Vert3f(f[1]); - Point3f &p2 = patch.Vert3f(f[2]); - Point3f n = ((p1 - p0) ^ (p2 - p0)); - glNormal3f(n[0], n[1], n[2]); - glVertex3f(p0[0], p0[1], p0[2]); - glVertex3f(p1[0], p1[1], p1[2]); - glVertex3f(p2[0], p2[1], p2[2]); - f += 3; - } - glEnd(); - } else if(signature.face = Signature::STRIPS) { - cerr << "Unsupported rendering mode sorry\n"; - } - } - break; - default: - cerr << "Unsupported rendering mode sorry\n"; - exit(0); - break; - } -} - -Patch &NexusMt::GetPatch(unsigned int patch, float error, bool flush) { - Entry &entry = operator[](patch); - if(entry.patch) return *(entry.patch); - - while(flush && ram_used > ram_max) { - if(heap[0].error == 0) break; - unsigned int to_flush = heap[0].id; - pop_heap(heap.begin(), heap.end()); - heap.pop_back(); - FlushPatch(to_flush); - } - entry.patch = LoadPatch(patch); - heap.push_back(Item(patch, error)); - push_heap(heap.begin(), heap.end()); - return *(entry.patch); -} - -void NexusMt::Flush(bool all) { - if(all) { - for(unsigned int i = 0; i < heap.size(); i++) { - unsigned int patch = heap[i].id; - FlushPatch(patch); - } - heap.clear(); - } else { - while(heap.size() && ram_used > ram_max) { - if(heap[0].error == 0) break; - unsigned int to_flush = heap[0].id; - pop_heap(heap.begin(), heap.end()); - heap.pop_back(); - FlushPatch(to_flush); - } - } -} - -bool NexusMt::CanAdd(Item &item) { - if(!heap.size()) return true; - Entry &entry = operator[](item.id); - if(ram_used + entry.ram_size < ram_max) - return true; - return heap[0].error > item.error; -} - -void NexusMt::FlushPatch(unsigned int id) { - Entry &entry = operator[](id); - if(entry.vbo_element) - FlushVbo(entry); - - if(entry.patch->fstart) - delete [](entry.patch->fstart); - delete entry.patch; - entry.patch = NULL; - ram_used -= entry.ram_size; -} - -void NexusMt::LoadVbo(Entry &entry) { - assert(entry.vbo_element == 0); - // if(entry.vbo_element) return; - - Patch &patch = *entry.patch; - unsigned int size = patch.nf * sizeof(unsigned short); - if(signature.face == Signature::TRIANGLES) - size *= 3; - else if(signature.face != Signature::STRIPS) - assert(0); - - glGenBuffersARB(1, &entry.vbo_element); - assert(entry.vbo_element); - glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, entry.vbo_element); - glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, size, patch.FaceBegin(), - GL_STATIC_DRAW_ARB); - vbo_used += size; - - //TODO fix this when we allow data :p - size = patch.vstartd - patch.vstart; - - glGenBuffersARB(1, &entry.vbo_array); - assert(entry.vbo_array); - glBindBufferARB(GL_ARRAY_BUFFER_ARB, entry.vbo_array); - glBufferDataARB(GL_ARRAY_BUFFER_ARB, size, patch.Vert3fBegin(), - GL_STATIC_DRAW_ARB); - - vbo_used += size; - delete [](entry.patch->fstart); - entry.patch->fstart = NULL; -} - -void NexusMt::FlushVbo(Entry &entry) { - if(!entry.vbo_element) return; - glDeleteBuffersARB(1, &entry.vbo_element); - glDeleteBuffersARB(1, &entry.vbo_array); - entry.vbo_element = 0; - entry.vbo_array = 0; - - Patch &patch = *entry.patch; - vbo_used -= patch.nf * sizeof(unsigned short); - vbo_used -= sizeof(float) * (patch.vstart - patch.vstartd); -} - -//Kept for historical reasons. -/*void NexusMt::ExtractFixed(vector &selected, float error) { - std::vector::iterator n; - for(n = nodes.begin(); n != nodes.end(); n++) - (*n).visited = false; - - std::queue qnodo; - qnodo.push(&nodes[0]); - nodes[0].visited = true; - - for( ; !qnodo.empty(); qnodo.pop()) { - Node &node = *qnodo.front(); - - std::vector::iterator fragment; - std::vector::iterator on; - for(on = node.out.begin(), fragment = node.frags.begin(); - on != node.out.end(); ++on, ++fragment) { - - if((*on)->visited) continue; - - if(error < (*on)->error) { //need to expand this node. - qnodo.push(*on); - (*on)->visited = 1; - } else { - vector::iterator cell; - for(cell=(*fragment).begin(); cell != (*fragment).end(); ++cell) selected.push_back(*cell); - } - } - } -} */ diff --git a/apps/nexus/nexusmt.h b/apps/nexus/nexusmt.h deleted file mode 100644 index d01c6b14..00000000 --- a/apps/nexus/nexusmt.h +++ /dev/null @@ -1,162 +0,0 @@ -/**************************************************************************** -* VCGLib o o * -* Visual and Computer Graphics Library o o * -* _ O _ * -* Copyright(C) 2004 \/)\/ * -* Visual Computing Lab /\/| * -* ISTI - Italian National Research Council | * -* \ * -* All rights reserved. * -* * -* This program is free software; you can redistribute it and/or modify * -* it under the terms of the GNU General Public License as published by * -* the Free Software Foundation; either version 2 of the License, or * -* (at your option) any later version. * -* * -* This program is distributed in the hope that it will be useful, * -* but WITHOUT ANY WARRANTY; without even the implied warranty of * -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * -* GNU General Public License (http://www.gnu.org/licenses/gpl.txt) * -* for more details. * -* * -****************************************************************************/ -/**************************************************************************** - History - -$Log: not supported by cvs2svn $ -Revision 1.24 2005/02/17 15:39:44 ponchio -Reorderes statistics a bit. - -Revision 1.23 2005/02/14 17:11:07 ponchio -aggiunta delle sphere - -Revision 1.22 2005/02/10 09:18:20 ponchio -Statistics. - -Revision 1.21 2005/02/08 12:43:03 ponchio -Added copyright - - -****************************************************************************/ - -#ifndef NXS_MT_H -#define NXS_MT_H - -#include -#include -#include - -#include "nexus.h" -#include "history.h" -#include "extraction.h" -#include "metric.h" -#include "preload.h" -#include "watch.h" - -namespace nxs { - - struct DrawContest { - - enum Mode { POINTS, SMOOTH, XRAY, HIDDEN_LINE, FLAT_WIRE, FLAT, PATCHES }; - enum Attr { COLOR = 0x1, NORMAL = 0x2, TEXTURE = 0x4, DATA = 0x8, SPHERES = 0x10 }; - - Mode mode; - unsigned int attrs; - - DrawContest(Mode m = SMOOTH, unsigned int a = 0xf): mode(m), attrs(a) {} - void SetAttr(Attr attr, bool value); - bool HasComponent(Attr attr); - }; - - struct Stats { - //per frame data... - float tri; //k triangles rendered. - float extr; //k triangles extracted - float disk_tri; //k triangles readed from disk - - int log_size; - - deque error; //max error in extraction (push_front pop_back) - deque time; - deque disk; //kdisk readed per frame - - float fps; //averaged over 8 frames - - Watch watch; - - Stats(): log_size(48), fps(0.0f) {} - void Start(); - void Disk(float disk); - void Error(float error); - void Stop(); - }; - - class NexusMt: public Nexus { - public: - bool use_vbo; - bool prefetch; - - unsigned int vbo_used; //TODO remember to zero it! - - Preload preload; - - NexusMt(); - ~NexusMt(); - - bool Load(const std::string &filename); - // void Close(); - - bool InitGL(bool use_vbo = true); - - void Render(DrawContest contest = DrawContest()); - void Render(Extraction &extraction, - DrawContest &contest, - Stats *stats = NULL); - - void SetPreload(bool on); - - void Flush(bool all = true); - Patch &GetPatch(unsigned int patch, float error, bool flush = true); - bool CanAdd(Item &item); - protected: - std::vector heap; - - void FlushPatch(unsigned int id); - void LoadVbo(Entry &entry); - void FlushVbo(Entry &entry); - void Draw(unsigned int cell, DrawContest &contest); - - }; - - /* class NexusViewer { - public: - NexusMt &mt; - - DrawContest contest; - Extraction extraction; - Statistics stats; - - NexusViewer(NexyusMt &_mt): mt(&mt) {} - void Render(); - - - bool SetMode(DrawContest::Mode mode); - bool SetComponent(DrawContest::Component c, bool on); - bool SetComponents(unsigned int mask); - - void SetMetric(MetricKind kind); - void SetError(float error); - - //Uinits expressed in Kb - void SetExtractionSize(unsigned int ksize); - void SetDrawSize(unsigned int ksize); - void SetDiskDelta(unsigned int kdelta); - //void SetPrefetchSize(unsigned int size); - };*/ - - - - -} - -#endif diff --git a/apps/nexus/nexusview.cpp b/apps/nexus/nexusview.cpp deleted file mode 100644 index ddf24cca..00000000 --- a/apps/nexus/nexusview.cpp +++ /dev/null @@ -1,749 +0,0 @@ -/**************************************************************************** - * VCGLib o o * - * Visual and Computer Graphics Library o o * - * _ O _ * - * Copyright(C) 2004 \/)\/ * - * Visual Computing Lab /\/| * - * ISTI - Italian National Research Council | * - * \ * - * All rights reserved. * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License (http://www.gnu.org/licenses/gpl.txt) * - * for more details. * - * * - ****************************************************************************/ -/**************************************************************************** - History - -$Log: not supported by cvs2svn $ -Revision 1.46 2005/04/04 14:27:53 ponchio -*** empty log message *** - -Revision 1.45 2005/03/02 10:40:17 ponchio -Extraction rewrittten (to fix recusive problems). - -Revision 1.44 2005/03/01 11:20:22 ponchio -nothing really - -Revision 1.43 2005/02/20 18:07:01 ponchio -cleaning. - -Revision 1.42 2005/02/20 00:43:24 ponchio -Less memory x extraction. (removed frags) - -Revision 1.41 2005/02/19 12:06:55 ponchio -Debug... - -Revision 1.40 2005/02/17 15:39:44 ponchio -Reorderes statistics a bit. - -Revision 1.39 2005/02/17 14:02:03 ponchio -Full screen options... - -Revision 1.38 2005/02/16 15:52:09 ponchio -qualche opzione in piu' , tolti i grafici - -Revision 1.37 2005/02/15 15:55:36 ponchio -aggiunta delle sphere - -Revision 1.36 2005/02/14 17:11:08 ponchio -aggiunta delle sphere - -Revision 1.35 2005/02/14 14:49:09 ponchio -*** empty log message *** - -Revision 1.34 2005/02/14 14:21:24 ponchio -Preload disabled at startap (-p) - -Revision 1.33 2005/02/10 09:18:20 ponchio -Statistics. - -Revision 1.32 2005/02/03 12:35:01 ponchio -Patch cache -> heap - -Revision 1.31 2005/02/01 16:42:30 ponchio -Trigger - -Revision 1.30 2005/01/21 17:09:13 ponchio -Porting and debug. - -Revision 1.29 2005/01/17 17:35:47 ponchio -Small changes and adding realtime extr. - -Revision 1.28 2005/01/14 15:25:29 ponchio -Revolution. - -Revision 1.27 2004/12/15 16:37:55 ponchio -Optimizing realtime vis. - -Revision 1.26 2004/12/15 13:50:32 ponchio -Optimizing realtime vis. - -Revision 1.25 2004/12/15 08:46:16 ponchio -Optimizing realtime vis. - -Revision 1.24 2004/12/13 00:44:48 ponchio -Lotsa changes... - -Revision 1.23 2004/12/01 18:46:21 ponchio -Microchanges. - -Revision 1.22 2004/11/28 04:16:19 ponchio -*** empty log message *** - -Revision 1.21 2004/11/28 01:23:26 ponchio -Fixing borders... let's hope. - -Revision 1.20 2004/11/18 18:30:14 ponchio -Using baricenters... lotsa changes. - -Revision 1.19 2004/10/30 20:17:03 ponchio -Fixed big patches problem. - -Revision 1.18 2004/10/21 13:40:16 ponchio -Debugging. - -Revision 1.17 2004/10/21 12:22:21 ponchio -Small changes. - -Revision 1.16 2004/10/19 01:23:02 ponchio -Daily backup (fragment...) - -Revision 1.15 2004/10/15 16:45:27 ponchio -Vbo added. - -Revision 1.14 2004/10/14 13:52:02 ponchio -Small changes. - -Revision 1.13 2004/10/14 13:41:34 ponchio -Added statistics. - -Revision 1.12 2004/10/09 14:46:47 ponchio -Windows porting small changes. - -Revision 1.11 2004/10/04 16:49:54 ponchio -Daily backup. Preparing for compression. - -Revision 1.10 2004/10/01 16:54:57 ponchio -Daily backup. - -Revision 1.9 2004/09/30 23:56:33 ponchio -Backup (added strips and normals) - -Revision 1.8 2004/09/30 00:27:42 ponchio -Lot of changes. Backup. - -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. -Revision 1.5 2004/09/16 14:25:16 ponchio -Backup. (lot of changes). - -Revision 1.4 2004/08/27 00:38:34 ponchio -Minor changes. - -Revision 1.3 2004/07/15 14:32:49 ponchio -Debug. - -Revision 1.2 2004/07/05 15:49:39 ponchio -Windows (DevCpp, mingw) port. - -Revision 1.1 2004/07/04 15:30:00 ponchio -Changed directory structure. - -Revision 1.2 2004/07/04 15:16:01 ponchio -*** empty log message *** - -Revision 1.1 2004/07/02 17:41:57 ponchio -Created. - -Revision 1.3 2004/07/02 13:03:34 ponchio -*** empty log message *** - -Revision 1.2 2004/07/01 21:33:46 ponchio -Added remap reading. - -Revision 1.1 2004/06/23 00:10:38 ponchio -Created - - -****************************************************************************/ -#ifdef WIN32 -#include -#else -#include -#endif - -#include -#include -#include - -using namespace std; - -#include - -//this include MUST precede GL includes. -#include - -#ifdef WIN32 -#include -#endif - -#include -#include -#include - -#include -#include "watch.h" - - -using namespace vcg; -using namespace nxs; - -bool fullscreen = false; -int width = 1024; -int height = 768; - -Point3f view(0, 0, 5); -Point3f target(0, 0, 0); - -void gl_print(float x, float y, char *str); - -SDL_Surface *screen = NULL; - -bool init(const string &str) { - - if(SDL_Init(SDL_INIT_VIDEO) != 0) { - return false; - } - - const SDL_VideoInfo *info = SDL_GetVideoInfo(); - int bpp = info->vfmt->BitsPerPixel; - - SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5); - SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); - - int flags = SDL_OPENGL; - if(fullscreen) - flags |= SDL_FULLSCREEN; - - screen = SDL_SetVideoMode(width, height, bpp, flags); - if(!screen) { - return false; - } - - // SDL_WM_SetIcon(SDL_LoadBMP("icon.bmp"), NULL); - SDL_WM_SetCaption(str.c_str(), str.c_str()); - - - glDisable(GL_DITHER); - glShadeModel(GL_SMOOTH); - glHint( GL_FOG_HINT, GL_NICEST ); - glEnable(GL_DEPTH_TEST); - glDepthFunc( GL_LEQUAL ); - glDisable(GL_LIGHTING); - - glEnableClientState(GL_VERTEX_ARRAY); - return true; -} - - - - -int main(int argc, char *argv[]) { - int level = 0; - int apatch = -1; - float error = 4; - string file; - - Trackball track; - - if(argc < 2) { - cerr << "Usage: " << argv[0] << " [options]\n"; - cerr << "-e : set initial target error\n" - << "-m : max ram used\n" - << "-x : max extraction size\n" - << "-r : max draw size\n" - << "-d : max disk read per frame\n" - << "-p : no preload\n" - << "-w : window width\n" - << "-h : window height\n" - << "-f : fullscreen mode\n" - << "-l : log timing on file\n" - << "-o namefile: ouput stats"; - return -1; - } - - NexusMt nexus; - if(!nexus.Load(argv[1])) { - cerr << "Could not load nexus file: " << argv[1] << endl; - return -1; - } - - Sphere3f sphere = nexus.sphere; - Extraction extraction; - DrawContest contest; - Stats stats; - stats.Start(); - - - bool rotate = false; - bool show_borders = false; - bool do_render = true; - bool show_statistics = true; - bool extract = true; - bool realtime = true; - bool preload = true; - Point4f light(1, -1, 1, 0); - - bool output_stats = false; - char output_filename[100]; - - char window_name [100]; - sprintf(window_name,"%s", argv[1]); - - int option; - while((option = getopt(argc, argv, "e:m:x:r:d:l:o:w:h:p:f")) != EOF) { - switch(option) { - case 'e': extraction.target_error = atof(optarg); break; - case 'm': nexus.MaxRam() = atoi(optarg); break; - case 'x': extraction.extr_max = atoi(optarg); break; - case 'r': extraction.draw_max = atoi(optarg); break; - case 'd': extraction.disk_max = atoi(optarg); break; - case 'l': file = optarg; break; - case 'o': output_stats = true; sprintf(output_filename,"%s",optarg); break; - case 'w': width = atoi(optarg); break; - case 'h': height = atoi(optarg); break; - case 'p': preload = false; nexus.SetPreload(preload); break; - case 'f': fullscreen = true; break; - default: - cerr << "Unknow option.\n"; break; - } - } - - FILE *fp = NULL; - if(file != "") { - fp = fopen(file.c_str(), "rwb+"); - if(!fp) { - cerr << "Could not open log file: " << file << endl; - return -1; - } - fprintf(fp, "timeMs, error, extrTri, drawTri, diskTri, diskKb\n"); - } - - if(!init(window_name)) { - cerr << "Could not init SDL window\n"; - return -1; - } - - cerr << "Commands: \n" - " q : quit\n" - " t : toggle statistics\n" - " right arrow: increase memory buffer\n" - " left arrow : decrease memory buffer\n" - " page up : increase disk space\n" - " page down : increase disk space\n" - " 0 : decrease extraction size\n" - " 1 : increase extraction size\n" - " s : toggle preload\n" - " l : change light\n" - - - " d: debug mode (show patches colored)\n" - " f: flat shading mode\n" - " m: smooth mode\n" - " p: draw points\n" - " h: draw bounding spheres\n" - " w: disable glcalls\n" - - " c: show colors\n" - " n: show normals\n" - " r: rotate model\n" - " -: decrease error\n" - " +: increase error (= too)\n"; - - Watch watch; - - if(!nexus.InitGL()) { - cerr << "Could not init glew.\n"; - return -1; - } - - glClearColor(0, 0, 0, 0); - glEnable(GL_LIGHTING); - glEnable(GL_LIGHT0); - glEnable(GL_NORMALIZE); - glEnable(GL_COLOR_MATERIAL); - glEnable(GL_CULL_FACE); - int quit = 0; - SDL_Event event; - int x, y; - float alpha = 0; - float fps = 0; - unsigned int nave = 5; - unsigned int offset = 0; - deque tframe; - deque terror; - unsigned int tlen = 256; - - bool keepdrawing = true; - - watch.Start(); - while( !quit ) { - unsigned int anything = SDL_PollEvent(&event); - if(!anything && !keepdrawing) { - SDL_WaitEvent(&event); - anything = true; - } - while(anything) { - switch( event.type ) { - case SDL_QUIT: quit = 1; break; - case SDL_KEYDOWN: - switch(event.key.keysym.sym) { - case SDLK_RCTRL: - case SDLK_LCTRL: track.ButtonDown(Trackball::KEY_CTRL); break; - case SDLK_q: exit(0); break; - case SDLK_k: keepdrawing = !keepdrawing; break; - case SDLK_e: extract = !extract; break; - case SDLK_c: - if(contest.attrs & DrawContest::COLOR) - contest.attrs &= ~DrawContest::COLOR; - else - contest.attrs |= DrawContest::COLOR; break; - - case SDLK_n: - if(contest.attrs & DrawContest::NORMAL) - contest.attrs &= ~DrawContest::NORMAL; - else - contest.attrs |= DrawContest::NORMAL; break; - - case SDLK_w: do_render = !do_render; break; - - case SDLK_LEFT: nexus.MaxRam() *= 0.8; break; - case SDLK_RIGHT: nexus.MaxRam() *= 1.3; break; - case SDLK_UP: extraction.draw_max *= 1.3; break; - case SDLK_DOWN: extraction.draw_max *= 0.8; break; - case SDLK_PAGEUP: extraction.disk_max *= 1.3; break; - case SDLK_PAGEDOWN: extraction.disk_max *= 0.8; break; - case SDLK_0: extraction.extr_max *= 1.3; break; - case SDLK_9: extraction.extr_max *= 0.8; break; - - case SDLK_p: contest.mode = DrawContest::POINTS; break; - case SDLK_d: contest.mode = DrawContest::PATCHES; break; - case SDLK_f: contest.mode = DrawContest::FLAT; break; - case SDLK_m: contest.mode = DrawContest::SMOOTH; break; - case SDLK_h: if(contest.attrs&DrawContest::SPHERES) - contest.attrs &=~DrawContest::SPHERES; - else - contest.attrs |=DrawContest::SPHERES; - break; - - case SDLK_l: - light[0] = rand(); - light[1] = rand(); - light[2] = rand(); - light.Normalize(); - break; - case SDLK_o: realtime = !realtime; break; - case SDLK_s: preload = !preload; nexus.SetPreload(preload); break; - case SDLK_t: show_statistics = !show_statistics; break; - case SDLK_r: - case SDLK_SPACE: rotate = !rotate; break; - - case SDLK_MINUS: - extraction.target_error *= 0.9f; - cerr << "Error: " << extraction.target_error << endl; - break; - - case SDLK_EQUALS: - case SDLK_PLUS: - extraction.target_error *= 1.1f; - cerr << "Error: " << extraction.target_error << endl; - break; - } - break; - case SDL_KEYUP: - switch(event.key.keysym.sym) { - case SDLK_RCTRL: - case SDLK_LCTRL: - track.ButtonUp(Trackball::KEY_CTRL); break; - } - break; - case SDL_MOUSEBUTTONDOWN: - x = event.button.x; - y = height - event.button.y; -#ifdef SDL_BUTTON_WHEELUP - if(event.button.button == SDL_BUTTON_WHEELUP) - track.MouseWheel(1); - else if(event.button.button == SDL_BUTTON_WHEELDOWN) - track.MouseWheel(-1); - else -#endif - if(event.button.button == SDL_BUTTON_LEFT) - track.MouseDown(x, y, Trackball::BUTTON_LEFT); - else if(event.button.button == SDL_BUTTON_RIGHT) - track.MouseDown(x, y, Trackball::BUTTON_RIGHT); - break; - case SDL_MOUSEBUTTONUP: - x = event.button.x; - y = height - event.button.y; - if(event.button.button == SDL_BUTTON_LEFT) - track.MouseUp(x, y, Trackball::BUTTON_LEFT); - else if(event.button.button == SDL_BUTTON_RIGHT) - track.MouseUp(x, y, Trackball::BUTTON_RIGHT); - break; - case SDL_MOUSEMOTION: - while(SDL_PeepEvents(&event, 1, SDL_GETEVENT, SDL_MOUSEMOTIONMASK)); - x = event.motion.x; - y = height - event.motion.y; - track.MouseMove(x, y); - break; - case SDL_VIDEOEXPOSE: - default: break; - } - anything = SDL_PeepEvents(&event, 1, SDL_GETEVENT, - SDL_ALLEVENTS); - } - - - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - gluPerspective(40, width/(float)height, 0.1, 100); - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - - // gluLookAt(0,0,5, 0,0,0, 0,1,0); - gluLookAt(view[0],view[1], view[2], - target[0],target[1],target[2], 0,1,0); - - - track.GetView(); - track.Apply(); - - - glLightfv(GL_LIGHT0, GL_POSITION, &light[0]); - - - glViewport(0,0,width,height); - glRotatef(alpha, 0, 1, 0); - if(rotate) { - alpha++; - if(alpha > 360) alpha = 0; - if(!keepdrawing) { - SDL_Event redraw; - redraw.type = SDL_VIDEOEXPOSE; - SDL_PushEvent(&redraw); - } - } - - float scale = 2/sphere.Radius(); - - glScalef(scale, scale, scale); - Point3f center = sphere.Center(); - glTranslatef(-center[0], -center[1], -center[2]); - - // Point3f &p = nexus.sphere.Center(); - // float r = nexus.sphere.Radius(); - - - glColor3f(0.8f, 0.8f, 0.8f); - - if(extract) { - // Sould we want a different view from metric and extraction - // extraction.frustum->GetView(); - extraction.metric->GetView(); - if(!realtime) { - extraction.visited.clear(); - extraction.Extract(&nexus); - extraction.Update(&nexus); - } else { - extraction.Update(&nexus); - } - } - stats.Stop(); - stats.Start(); - if(do_render) - nexus.Render(extraction, contest, &stats); - - - - /* if(show_borders) { - for(unsigned int i = 0; i < cells.size(); i++) { - Border &border = nexus.GetBorder(cells[i]); - Patch &patch = nexus.GetPatch(cells[i]); - glPointSize(4); - glColor3f(1.0f, 1.0f, 1.0f); - glBegin(GL_POINTS); - for(unsigned int b = 0; b < border.Size(); b++) { - Link &link = border[b]; - Point3f &p = patch.Vert(link.start_vert); - glVertex3f(p[0], p[1], p[2]); - } - glEnd(); - glPointSize(1); - } - }*/ - - tframe.push_front(watch.Time()); - if(tframe.size() > tlen) tframe.pop_back(); - - terror.push_front(extraction.max_error); - if(terror.size() > tlen) terror.pop_back(); - - if(show_statistics) { - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); - glLoadIdentity(); - glMatrixMode(GL_PROJECTION); - glPushMatrix(); - glLoadIdentity(); - gluOrtho2D(0, 1, 0, 1); - - - glDisable(GL_DEPTH_TEST); - glDisable(GL_LIGHTING); - - //show frame and error graphics - if(false){ - glColor4f(0.6f, 0.6f, 0.6f, 0.5f); - - glBegin(GL_LINE_STRIP); - for(unsigned int i = 0; i < tframe.size() -1; i++) { - double diff = (tframe[i] - tframe[i+1]); - //glVertex2f(i/1024.0f,0); - glVertex2f(i/1024.0f,2*diff); - } - glEnd(); - - glColor4f(0.0f, 0.6f, 0.2f, 0.5f); - - glBegin(GL_LINE_STRIP); - for(unsigned int i = 0; i < terror.size() -1; i++) { - // glVertex2f(i/1024.0f,0); - glVertex2f(i/1024.0f,terror[i]/300); - } - glEnd(); - } - - glColor3f(1.0f, 1.0f, 1.0f); - - char buffer[1024]; - sprintf(buffer, "Ram size : %.2f / %.2f Mb", - nexus.ram_used * nexus.chunk_size/(float)(1<<20), - nexus.ram_max * nexus.chunk_size/(float)(1<<20)); - gl_print(0.03, 0.15, buffer); - - sprintf(buffer, "Extr size: %.2f / %.2f Mb", - extraction.extr_used * nexus.chunk_size/(float)(1<<20), - extraction.extr_max * nexus.chunk_size/(float)(1<<20)); - gl_print(0.03, 0.12, buffer); - - sprintf(buffer, "Draw size: %.2f / %.2f Mb", - extraction.draw_used * nexus.chunk_size/(float)(1<<20), - extraction.draw_max * nexus.chunk_size/(float)(1<<20)); - gl_print(0.03, 0.09, buffer); - - sprintf(buffer, "Disk size: %.2f / %.2f Mb", - extraction.disk_max * nexus.chunk_size/(float)(1<<20), - extraction.disk_used * nexus.chunk_size/(float)(1<<20)); - gl_print(0.03, 0.06, buffer); - - sprintf(buffer, "%.2f KTri %.2f FPS %.0f M/s", - stats.tri/(float)(1<<10), - stats.fps, stats.fps * stats.tri/(float)(1<<20)); - gl_print(0.03, 0.03, buffer); - - - glEnable(GL_DEPTH_TEST); - glEnable(GL_LIGHTING); - glPopMatrix(); - glMatrixMode(GL_MODELVIEW); - glPopMatrix(); - - /* statistics: output on file - if(output_stats){ - - static Stats statsAcc; - static float ram_used; - static float extr_used; - static float draw_used; - static float disk_used; - static std::ofstream outf(output_filename); - static bool first=true; - if(first) { - outf<< "ktri\t fps\t ram \t extr \t draw \t disk \n" - << " \t \t" - << nexus.ram_max * nexus.chunk_size/(float)(1<<20) << "\t" - << extraction.extr_max * nexus.chunk_size/(float)(1<<20) << "\t" - << extraction.draw_max * nexus.chunk_size/(float)(1<<20)<<"\t" - << extraction.disk_max * nexus.chunk_size/(float)(1<<20)<< "\n"; - first = false; - } - - statsAcc.count++ ; - if((statsAcc.count%30)==0) { - outf - << (statsAcc.tri/(float)statsAcc.count)/(float)(1<<10) << "\t" - << (statsAcc.fps/(float)statsAcc.count) << "\t" - // << (statsAcc.kdisk/(float)statsAcc.count) << "\t" - << ram_used/(float)statsAcc.count*nexus.chunk_size/(float)(1<<20) << "\t" - << extr_used/(float)statsAcc.count*nexus.chunk_size/(float)(1<<20) << "\t" - << draw_used/(float)statsAcc.count*nexus.chunk_size/(float)(1<<20) << "\t" - << disk_used/(float)statsAcc.count*nexus.chunk_size/(float)(1<<20) << "\t" - << "\n"; - statsAcc.Init(); - statsAcc.count = 0; - statsAcc.fps = 0; - ram_used = extr_used = draw_used = disk_used = 0.0; - } else { - statsAcc.fps += stats.fps; - statsAcc.kdisk += stats.kdisk; - statsAcc.ktri += stats.ktri; - - ram_used += nexus.ram_used; - extr_used += extraction.extr_used; - draw_used += extraction.draw_used; - disk_used += extraction.disk_used; - } - }*/ - } - - SDL_GL_SwapBuffers(); - if(fp && stats.time.size()) { - //fprintf(fp, "timeMs, error, extrTri, drawTri, diskTri, diskKb\n"); - assert(stats.time.size() && stats.error.size() && stats.disk.size()); - fprintf(fp, "%d, %f, %d, %d, %d, %d\n", - (*stats.time.begin())*1000, - stats.error.begin(), - (int)stats.extr, - (int)stats.tri, - (int)stats.disk_tri, - (int)((*stats.disk.begin())/1024)*nexus.chunk_size); - } - } - if(fp) - fclose(fp); - - SDL_Quit(); - return -1; -} - -void gl_print(float x, float y, char *str) { - glRasterPos2f(x, y); - int len = (int)strlen(str); - for(int i = 0; i < len; i++) - glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, str[i]); -} - - diff --git a/apps/nexus/normalscone.cpp b/apps/nexus/normalscone.cpp deleted file mode 100644 index 20f80a2d..00000000 --- a/apps/nexus/normalscone.cpp +++ /dev/null @@ -1,180 +0,0 @@ -#include "normalscone.h" -#include - -using namespace std; -using namespace vcg; -using namespace nxs; - - -ANCone3f::ANCone3f() { - scaledNormal = Point3f(0,0,0); - frontAnchor = Point3f(0,0,0); - backAnchor = Point3f(0,0,0); -} - -bool ANCone3f::Frontface(const Point3f &viewPoint) { - Point3f d = frontAnchor - viewPoint; //Vector from viewPoint to frontAnchor. - float f = - d * scaledNormal; - if (f < 0.001 || f * f < d * d) - return false; - return true; -} - -bool ANCone3f::Backface(const Point3f &viewPoint) { - Point3f d = backAnchor - viewPoint; //Vector from viewPoint to frontAnchor. - float f = d * scaledNormal; - if (f < 0.001 || f * f < d * d) - return false; - return true; -} - -void ANCone3f::AddNormals(vector &normal, vector &area, float threshold) { - assert(normal.size() == area.size()); - scaledNormal = Point3f(0,0,0); - int count = 0; - vector::iterator i; - for(i = normal.begin(); i != normal.end(); i++) { - scaledNormal += *i; - count++; - } - scaledNormal /= count; - scaledNormal.Normalize(); - - double distr[50]; - for(int k = 0; k < 50; k++) - distr[k] = 0; - double tot_area = 0; - - vector::iterator j; - for(i = normal.begin(), j = area.begin(); i != normal.end(); i++, j++) { - int pos = (int)(49.0 * Angle(scaledNormal, *i)/M_PI); - if(pos < 0) continue; - assert(pos >=0 && pos < 50); - distr[pos] += *j; - tot_area += *j; - } - - float tot = 0; - int best; - for(best = 0; best < 50; best++) { - tot += distr[best]; - if(tot > threshold * tot_area) - break; - } - double alpha = M_PI * (best + 1) / 50; - if(alpha >= M_PI/ 2 - 0.1) - scaledNormal = Point3f(0,0,0); - else - scaledNormal /= cos(M_PI/2 - alpha); -} - -void ANCone3f::AddNormals(vector &normal, float threshold) { - assert(normal.size() > 0); - scaledNormal = Point3f(0,0,0); - int count = 0; - vector::iterator i; - for(i = normal.begin(); i != normal.end(); i++) { - Point3f norm = *i; - if(norm.Norm() < 0.00001) continue; - norm.Normalize(); - scaledNormal += norm; - count++; - } - scaledNormal /= count; - float len = scaledNormal.Norm(); - if(len == 0) return; - scaledNormal /= len; - - int distr[50]; - for(int k = 0; k < 50; k++) - distr[k] =0; - - for(i = normal.begin(); i != normal.end(); i++) { - int pos = (int)(50.0 * Angle(scaledNormal, *i)/M_PI); - distr[pos]++; - } - int tot = 0; - int best; - for(best = 0; best < 50; best++) { - tot += distr[best]; - if(tot >= threshold * normal.size()) - break; - } - double alpha = M_PI * (best +1) / 50; - if(alpha >= M_PI/ 2 - 0.1) { - scaledNormal = Point3f(0,0,0); - } else { - scaledNormal /= cos(M_PI/2 - alpha); - } -} - -void ANCone3f::AddAnchors(vector &anchors) { - assert(anchors.size() > 0); - frontAnchor = anchors[0]; - backAnchor = anchors[0]; - - float fa = frontAnchor * scaledNormal; - float fb = -backAnchor * scaledNormal; - - vector::iterator i; - for(i = anchors.begin(); i != anchors.end(); i++) { - Point3f &anchor = *i; - float na = anchor * scaledNormal; - if(na < fa) { - frontAnchor = anchor; - fa = na; - } - if(-na < fb) { - backAnchor = anchor; - fb = -na; - } - } -} - -void NCone3s::Import(const ANCone3f &c) { - Point3f normal = c.scaledNormal; - float len = normal.Norm(); - if(len != 0) - normal /= len; - - for(int i = 0; i < 3; i++) { - assert(normal[i] < 1.01 && normal[i] > -1.01); - - if(normal[i] > 1.0f) normal[i] = 1; - if(normal[i] < -1.0f) normal[i] = -1; - } - n[0] = (short)(normal[0] * 32766); - n[1] = (short)(normal[1] * 32766); - n[2] = (short)(normal[2] * 32766); - //i want to rapresent number from 1 to 10 - if(len > 10.0f) len = 10.0f; - if(len < -10.0f) len = -10.0f; - n[3] = (short)(len * 3276); -} - - - - -bool NCone3s::Backface(const vcg::Sphere3f &sphere, - const vcg::Point3f &view) const { - vcg::Point3f norm(n[0]/32766.0f, n[1]/32766.0f, n[2]/32766.0f); - vcg::Point3f d = (sphere.Center() - norm * sphere.Radius()) - view; - norm *= n[3]/3276.0f; - - float f = d * norm; - if (f < 0.001 || f * f < d * d) - return false; - return true; -} - -bool NCone3s::Frontface(const vcg::Sphere3f &sphere, - const vcg::Point3f &view) const { - vcg::Point3f norm(n[0]/32766.0f, n[1]/32766.0f, n[2]/32766.0f); - vcg::Point3f d = (sphere.Center() + norm * sphere.Radius()) - view; - norm *= n[3]/3276.0f; - - float f = -d * norm; - if (f < 0.001 || f * f < d * d) - return false; - return true; -} diff --git a/apps/nexus/normalscone.h b/apps/nexus/normalscone.h deleted file mode 100644 index af017531..00000000 --- a/apps/nexus/normalscone.h +++ /dev/null @@ -1,53 +0,0 @@ -#ifndef NXS_NORMALS_CONE_H -#define NXS_NORMALS_CONE_H - -#include - -#include -#include - -namespace nxs { - - - //anchored normal cone. - class ANCone3f { - public: - ANCone3f(); - - bool Frontface(const vcg::Point3f &viewPoint); - bool Backface(const vcg::Point3f &viewPoint); - - //threshold [0, 1]: percentage of normals to left out - void AddNormals(std::vector &normals, - float threshold = 1.0f); - void AddNormals(std::vector &normals, - std::vector &areas, - float threshold = 1.0f); - void AddAnchors(std::vector &anchors); - protected: - vcg::Point3f scaledNormal; - vcg::Point3f frontAnchor; - vcg::Point3f backAnchor; - - friend class NCone3s; - }; - - - - //this is not anchored... need a bounding sphere to report something - class NCone3s { - public: - void Import(const ANCone3f &c); - - bool Backface(const vcg::Sphere3f &sphere, - const vcg::Point3f &view) const; - bool Frontface(const vcg::Sphere3f &sphere, - const vcg::Point3f &view) const; - - //encode normal and sin(alpha) in n[3] - short n[4]; - }; - -} - -#endif diff --git a/apps/nexus/nxs2ply.cpp b/apps/nexus/nxs2ply.cpp deleted file mode 100644 index 86c49edc..00000000 --- a/apps/nexus/nxs2ply.cpp +++ /dev/null @@ -1,72 +0,0 @@ -// mesh definition -#include -#include -#include - -#include - -// input output -#include -#include - -#include "nxsexport.h" -#include "extraction.h" -#include "metric.h" - -using namespace vcg; -using namespace nxs; - -struct MyFace; -struct MyTetra; -struct MyEdge; -struct MyVertex: public VertexAFVNf{}; -struct MyFace: public FaceAF{}; -struct MyMesh: public tri::TriMesh< vector, vector >{}; - -int main(int argc, char *argv[]) { - - string input; - string output; - float target_error = 0; - - int option; - while((option = getopt(argc, argv, "e:")) != EOF) { - switch(option) { - case 'e': target_error = atof(optarg); break; - case 'o': output = optarg; break; - } - } - - if(optind != argc -1) { - cerr << "Usage: " << argv[0] << " [options]\n" - << " -e : extraction target error\n" - << " -o : output name\n\n"; - return -1; - } - input = argv[optind]; - if(!output.size()) output = input + ".ply"; - - Nexus nexus; - if(!nexus.Load(input.c_str())) { - cerr << "Could not open file: " << input.c_str() << ".nxs\n"; - return -1; - } - - Extraction extr; - extr.SetMetric(new FlatMetric); - extr.target_error = target_error; - extr.Extract(&nexus); - - vector selected; - for(unsigned int i = 0; i < extr.selected.size(); i++) - selected.push_back(extr.selected[i].id); - - - MyMesh m; - ExportTriMesh(nexus, selected, m); - - //write to ply: - vcg::tri::io::PlyInfo pi; - vcg::tri::io::ExporterPLY::Save(m, output.c_str(), pi.mask); - return 0; -} diff --git a/apps/nexus/nxsalgo.cpp b/apps/nexus/nxsalgo.cpp deleted file mode 100644 index f14e88a7..00000000 --- a/apps/nexus/nxsalgo.cpp +++ /dev/null @@ -1,796 +0,0 @@ -/**************************************************************************** -* VCGLib o o * -* Visual and Computer Graphics Library o o * -* _ O _ * -* Copyright(C) 2004 \/)\/ * -* Visual Computing Lab /\/| * -* ISTI - Italian National Research Council | * -* \ * -* All rights reserved. * -* * -* This program is free software; you can redistribute it and/or modify * -* it under the terms of the GNU General Public License as published by * -* the Free Software Foundation; either version 2 of the License, or * -* (at your option) any later version. * -* * -* This program is distributed in the hope that it will be useful, * -* but WITHOUT ANY WARRANTY; without even the implied warranty of * -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * -* GNU General Public License (http://www.gnu.org/licenses/gpl.txt) * -* for more details. * -* * -****************************************************************************/ -/**************************************************************************** - History - -$Log: not supported by cvs2svn $ -Revision 1.26 2005/03/02 10:40:18 ponchio -Extraction rewrittten (to fix recusive problems). - -Revision 1.25 2005/03/01 11:21:20 ponchio -Added line intersection - -Revision 1.24 2005/02/22 14:20:44 ponchio -debug and mostly vertex unifying across borders -(still not perfect... :P) - -Revision 1.23 2005/02/22 10:38:10 ponchio -Debug, cleaning and optimization. - -Revision 1.22 2005/02/21 17:55:36 ponchio -debug debug debug - -Revision 1.21 2005/02/20 18:07:01 ponchio -cleaning. - -Revision 1.20 2005/02/19 10:45:04 ponchio -Patch generalized and small fixes. - -Revision 1.19 2005/02/18 13:04:12 ponchio -Added patch reordering. - -Revision 1.18 2005/02/17 16:40:35 ponchio -Optimized BuildLevels. - -Revision 1.17 2005/02/08 12:43:03 ponchio -Added copyright - - -****************************************************************************/ - -#include -#include -#include -#include -#include - -//#include - -#include "nxsalgo.h" -#include "extraction.h" -#include "vpartition.h" -#include "vfile.h" -#include "nexus.h" -#include "zcurve.h" -#include "watch.h" - -#include -#include - -using namespace std; -using namespace nxs; -using namespace vcg; - - -void nxs::Connect(Nexus &nexus, std::vector< set > &close, - float threshold) { - - VPartition grid; - float max_radius = 0; - - for(unsigned int patch = 0; patch < nexus.size(); patch++) { - Sphere3f &sphere = nexus[patch].sphere; - grid.push_back(sphere.Center()); - float r = sphere.Radius(); - if(r > max_radius) max_radius = r; - } - grid.Init(); - close.clear(); - close.resize(nexus.size()); - - vector targets; - vector dists; - for(unsigned int patch = 0; patch < nexus.size(); patch++) { - float radius = nexus[patch].sphere.Radius(); - float max_distance = radius + max_radius + threshold; - max_distance *= max_distance; - grid.Closest(grid[patch], targets, dists, max_distance); - - for(unsigned int i = 0; i < targets.size(); i++) { - unsigned int target = targets[i]; - if(target == patch) continue; - float dist = radius + nexus[target].sphere.Radius() + threshold; - dist *= dist; - if(dist >= dists[i]) { - close[patch].insert(target); - } - } - } - - //DOUBLECROSS CHECK - for(unsigned int patch = 0; patch < nexus.size(); patch++) { - set::iterator i; - for(i = close[patch].begin(); i != close[patch].end(); i++) { - if(!close[*i].count(patch)) { - cerr << "Some problem width sphere intersection. Have alook.\n"; - cerr << "Meanwhile i fix it.\n"; - close[*i].insert(patch); - } - } - } -} - -void nxs::ComputeNormals(Nexus &nexus) { - assert(nexus.signature.vnorm); - assert(!nexus.borders.IsReadOnly()); - - //first calculate level 0 normals - //I load all patches in a fragment - //calculate normals - //fix external borders getting from level below - - //first try naive approach just load neighborough get normals and - //fix border with lower level - - vector levels; - nexus.history.BuildLevels(levels); - Report report(nexus.size(), 15); - - //TODO check level 0 is the finer one - - int current_level = 0; - while(1) { - int count = 0; - for(unsigned int p = 0; p < nexus.size(); p++) { - if(levels[p] != current_level) continue; - count++; - report.Step(p); - - Border &border = nexus.GetBorder(p); - - map > normals; - normals[p] = vector(); - - for(unsigned int i = 0; i < border.Size(); i++) { - Link &link = border[i]; - if(levels[link.end_patch] == current_level) - normals[link.end_patch] = vector(); - } - map >::iterator k; - for(k = normals.begin(); k != normals.end(); k++) { - Patch &patch = nexus.GetPatch((*k).first); - - vector &normal = (*k).second; - normal.resize(patch.nv, Point3f(0, 0, 0)); - - if(nexus.signature.face == Signature::TRIANGLES) { - for(unsigned int i = 0; i < patch.nf; i++) { - unsigned short *f = patch.Face(i); - Point3f &v0 = patch.Vert3f(f[0]); - Point3f &v1 = patch.Vert3f(f[1]); - Point3f &v2 = patch.Vert3f(f[2]); - - Point3f a = (v1 - v0); - Point3f b = (v2 - v0); - float n = a.Norm() * b.Norm(); - if(n == 0) continue; - Point3f norm = a^b; - float rn = norm.Norm(); - norm *= asin(rn/n)/n; - - normal[f[0]] += norm; - normal[f[1]] += norm; - normal[f[2]] += norm; - } - } else if(nexus.signature.face == Signature::STRIPS) { - for(int i = 0; i < patch.nf - 2; i++) { - unsigned short *f = patch.FaceBegin() + i; - Point3f &v0 = patch.Vert3f(f[0]); - Point3f &v1 = patch.Vert3f(f[1]); - Point3f &v2 = patch.Vert3f(f[2]); - - Point3f a = (v1 - v0); - Point3f b = (v2 - v0); - float n = a.Norm() * b.Norm(); - if(n == 0) continue; - Point3f norm = a^b; - float rn = norm.Norm(); - norm *= asin(rn/n)/n; - - - if(i%2) norm = -norm; - normal[f[0]] += norm; - normal[f[1]] += norm; - normal[f[2]] += norm; - } - } else - assert(0); - } - - //now fix borders - map > lowers; - for(unsigned int i = 0; i < border.Size(); i++) { - Link &link = border[i]; - if(levels[link.end_patch] == current_level) { - //TODO remove these asserts - assert(normals[p].size() > link.start_vert); - assert(normals.count(link.end_patch)); - assert(normals[link.end_patch].size() > link.end_vert); - normals[p][link.start_vert] += normals[link.end_patch][link.end_vert]; - } else if (levels[link.end_patch] < current_level) { - lowers[link.end_patch].push_back(link); - } - } - - map >::iterator s; - for(s = lowers.begin(); s != lowers.end(); s++) { - Patch &patch = nexus.GetPatch((*s).first); - for(unsigned int i = 0; i < (*s).second.size(); i++) { - Link &link = (*s).second[i]; - if(nexus.signature.vnorm == Encodings::FLOAT3) - normals[p][link.start_vert] = - ((Point3f *)patch.VNormBegin())[link.end_vert]; - else if(nexus.signature.vnorm == Encodings::SHORT4) { - Point3f &nor = normals[p][link.start_vert]; - short *n = ((short *)patch.VNormBegin()) + 4*link.end_vert; - nor[0] = n[0]; - nor[1] = n[1]; - nor[2] = n[2]; - } - } - } - //copy and normalize - Patch &patch = nexus.GetPatch(p); - Entry &entry = nexus[p]; - Point3f *norm = (Point3f *)patch.VNormBegin(); - vector &newnormals = normals[p]; - assert(newnormals.size() == patch.nv); - for(unsigned int i = 0; i < patch.nv; i++) { - newnormals[i].Normalize(); - if(nexus.signature.vnorm == Encodings::SHORT4) { - newnormals[i] *= 32766; - short *np = ((short *)norm) + 4 * i; - np[0] = (short)newnormals[i][0]; - np[1] = (short)newnormals[i][1]; - np[2] = (short)newnormals[i][2]; - np[3] = 0; - } else if(nexus.signature.vnorm == Encodings::FLOAT3) - norm[i] = newnormals[i]; - } - } - if(count == 0) break; - current_level++; - } -} - - - -/*void nxs::ComputeNormals(Nexus &nexus) { - assert(nexus.signature.vnorm); - - //setting borders readonly: - - assert(!nexus.borders.IsReadOnly()); - nexus.borders.SetReadOnly(true); - - //TODO use a temporary file to store border normals - unsigned int tmpb_offset = 0; - vector tmpb_start; - VFile tmpb; - if(!tmpb.Create("tmpb.tmp")) { - cerr << "Could not create temporary border file\n"; - exit(0); - } - - for(unsigned int p = 0; p < nexus.size(); p++) { - Border &border = nexus.borders[p]; - tmpb_start.push_back(tmpb_offset); - tmpb_offset += border.Size(); - } - - Point3f zero(0.0f, 0.0f, 0.0f); - - tmpb.Resize(tmpb_offset); - for(unsigned int i = 0; i < tmpb.Size(); i++) - tmpb[i] = zero; - tmpb.Flush(); - - - vector levels; - nexus.history.BuildLevels(levels); - - //first step normals in the same patch. - cerr << "First Step\n"; - Report report(nexus.size(), 5); - vector normals; - - for(unsigned int p = 0; p < nexus.size(); p++) { - int current_level = levels[p]; - report.Step(p); - Patch &patch = nexus.GetPatch(p); - - normals.clear(); - normals.resize(patch.nv, Point3f(0, 0, 0)); - - if(nexus.signature.face == Signature::TRIANGLES) - for(unsigned int i = 0; i < patch.nf; i++) { - unsigned short *f = patch.Face(i); - Point3f &v0 = patch.Vert3f(f[0]); - Point3f &v1 = patch.Vert3f(f[1]); - Point3f &v2 = patch.Vert3f(f[2]); - - Point3f norm = (v1 - v0) ^ (v2 - v0); - normals[f[0]] += norm; - normals[f[1]] += norm; - normals[f[2]] += norm; - } - if(nexus.signature.face == Signature::STRIPS) - for(int i = 0; i < patch.nf - 2; i++) { - unsigned short *f = patch.FaceBegin() + i; - Point3f &v0 = patch.Vert3f(f[0]); - Point3f &v1 = patch.Vert3f(f[1]); - Point3f &v2 = patch.Vert3f(f[2]); - - Point3f norm = (v1 - v0) ^ (v2 - v0); - if(i%2) norm = -norm; - normals[f[0]] += norm; - normals[f[1]] += norm; - normals[f[2]] += norm; - } - - if(nexus.signature.vnorm == Encodings::SHORT4) { - short *n = (short *)patch.VNormBegin(); - for(unsigned int i = 0; i < patch.nv; i++, n += 4) { - Point3f &norm = normals[i]; - norm.Normalize(); - for(int k = 0; k < 3; k++) - n[k] = (short)(norm[k] * 32766); - n[3] = 0; - } - } else if(nexus.signature.vnorm == Encodings::FLOAT3) { - Point3f *n = (Point3f *)patch.VNormBegin(); - for(unsigned int i = 0; i < patch.nv; i++) { - n[i] = normals[i]; - n[i].Normalize(); - } - } - - - Border &border = nexus.GetBorder(p); - - map > bnorm; - map bcopy; - - unsigned int poff = tmpb_start[p]; - for(unsigned int i = 0; i < border.Size(); i++) { - Link &link = border[i]; - if(link.IsNull()) continue; //this should never happen now. - Point3f pt = normals[link.start_vert]; - if(levels[link.end_patch] == current_level) { - bnorm[link.end_patch][link.end_vert] = pt; - tmpb[poff + i] += pt; - } else if(levels[link.end_patch] > current_level) { - bcopy[i] = link; - } - } - - map >::iterator k; - for(k = bnorm.begin(); k != bnorm.end(); k++) { - unsigned int patch = (*k).first; - Border &rborder = nexus.GetBorder(patch); - unsigned int offset = tmpb_start[patch]; - for(unsigned int i = 0; i < rborder.Size(); i++) { - Link &link = rborder[i]; - //assert(!link.IsNull()); - //TODO not accurate - if(link.end_patch != p) continue; - if((*k).second.count(link.start_vert)) - tmpb[offset + i] += (*k).second[link.start_vert]; - } - } - - //Uncomment this only when links are ok! - map::iterator j; - for(j = bcopy.begin(); j != bcopy.end(); j++) { - unsigned int b = (*j).first; - Link link = (*j).second; - Border &rborder = nexus.GetBorder(link.end_patch, false); - unsigned int offset = tmpb_start[link.end_patch]; - for(unsigned int i = 0; i < rborder.Size(); i++) { - Link &rlink = rborder[i]; - if(rlink.end_patch == p && rlink.start_vert == link.end_vert) { - assert(rlink.end_vert == link.start_vert); - tmpb[poff + b] = tmpb[offset + i]; - } - } - } - } - - //Second step unify normals across borders - cerr << "Second step\n"; - report.Init(nexus.size()); - for(unsigned int p = 0; p < nexus.size(); p++) { - report.Step(p); - Patch &patch = nexus.GetPatch(p); - Border &border = nexus.GetBorder(p); - - Point3f *normf = (Point3f *)patch.VNormBegin(); - short *norms = (short *)patch.VNormBegin(); - - for(unsigned int i = 0; i < border.Size(); i++) { - Link &link = border[i]; - if(link.IsNull()) continue; - unsigned int off = tmpb_start[p]; - // Point3f &n = tmpb[off + i]; - Point3f n = tmpb[off + i]; - if(n == Point3f(0.0f,0.0f,0.0f)) continue; - n.Normalize(); - if(nexus.signature.vnorm == Encodings::SHORT4) { - n *= 32766; - short *np = norms + 4 * link.start_vert; - np[0] = (short)n[0]; - np[1] = (short)n[1]; - np[2] = (short)n[2]; - np[3] = 0; - } else if(nexus.signature.vnorm == Encodings::FLOAT3) { - normf[link.start_vert] = n; - } - } - } - tmpb.Close(); - tmpb.Delete(); - //TODO remove temporary file. - nexus.borders.SetReadOnly(false); - }*/ - - - -/* - //TODO why i created this function? wonder...void nxs::Reorder(Signature &signature, Patch &patch) { - vector remap; - remap.resize(patch.nv, 0xffff); - - int nf = patch.nf; - if(signature.face == Signature::TRIANGLES) - nf *= 3; - else if(signature.face != Signature::STRIPS) { - assert(0); //mah... - } - - //building remap - unsigned short *f = patch.FaceBegin(); - unsigned int count = 0; - for(int i = 0; i < nf; i++) { - assert(f[i] < remap.size()); - if(remap[f[i]] == 0xffff) { - remap[f[i]] = count++; - } - } - //test no unreferenced vertices - for(int i = 0; i < patch.nv; i++) - if(remap[i] == 0xffff) - remap[i] = i; - - //converting faces - for(int i = 0; i < nf; i++) - f[i] = remap[f[i]]; - - vector vert; - vert.resize(patch.nv); - memcpy(&*vert.begin(), patch.Vert3fBegin(), patch.nv * sizeof(Point3f)); - for(int i = 0; i < patch.nv; i++) - patch.Vert3f(remap[i]) = vert[i]; - }*/ - -//TODO actually use threshold - -void nxs::Unify(vector &points, vector &faces, - vector &remap, float threshold) { - vector newfaces = faces; - - VPartition grid; - for(unsigned int i = 0; i < points.size(); i++) - grid.push_back(points[i]); - grid.Init(); - - remap.resize(points.size()); - vector targets; - vector dists; - - points.clear(); - unsigned int count = 0; - for(unsigned int i = 0; i < grid.size(); i++) { - - grid.Closest(grid[i], targets, dists, threshold); - - if(targets.size() > 1) { - unsigned int p; - for(p = 0; p < targets.size(); p++) { - if(targets[p] < i) { - remap[i] = remap[targets[p]]; - break; - } - } - if(p < targets.size()) continue; - } - remap[i] = count++; - points.push_back(grid[i]); - } - - //fixing faces now - faces.clear(); - for(unsigned int i = 0; i < newfaces.size(); i += 3) { - unsigned short f[3]; - f[0] = remap[newfaces[i]]; - f[1] = remap[newfaces[i+1]]; - f[2] = remap[newfaces[i+2]]; - if(f[0] == f[1] || f[0] == f[2] || f[1] == f[2]) - continue; - - for(int k = 0; k < 3; k++) - faces.push_back(f[k]); - } -} - -/*void nxs::Unify(Nexus &nexus, float threshold) { - threshold = 0.00001; - unsigned int duplicated = 0; - unsigned int degenerate = 0; - - for(unsigned int p = 0; p < nexus.size(); p++) { - if(levels[p] != current_level) continue; - count++; - report.Step(p); - - Border &border = nexus.GetBorder(p); - - map > normals; - normals[p] = vector(); - - for(unsigned int i = 0; i < border.Size(); i++) { - Link &link = border[i]; - if(levels[link.end_patch] == current_level) - normals[link.end_patch] = vector(); - } - map >::iterator k; - for(k = normals.begin(); k != normals.end(); k++) { - Patch &patch = nexus.GetPatch((*k).first); - } - } - }*/ - -/* -void nxs::Unify(Nexus &nexus, float threshold) { - threshold = 0.001; - //TODO what if colors or normals or strips? - unsigned int duplicated = 0; - unsigned int degenerate = 0; - - for(unsigned int p = 0; p < nexus.size(); p++) { - Entry &entry = nexus[p]; - Patch &patch = nexus.GetPatch(p); - - - - VPartition part; - for(unsigned int i = 0; i < patch.nv; i++) { - Point3f &point = patch.Vert3f(i); - part.push_back(point); - } - part.Init(); - - unsigned int vcount = 0; - vector remap; - remap.resize(patch.nv); - - int targets[8]; - double dists[8]; - - //TODO CRITICAL FIX this unifying routine. - for(unsigned int i = 0; i < patch.nv; i++) { - Point3f &point = patch.Vert3f(i); - part.Closest(point, 8, targets, dists); - int k = 0; - for(k = 0; k < 8; k++) { - if(dists[k] > threshold) { - remap[i] = vcount++; - break; - } - if(targets[k] < i) { - remap[i] = remap[targets[k]]; - duplicated++; - break; - } - } - if(k == 8) - remap[i] = vcount++; - - } - - if(vcount == patch.nv) //no need to unify - continue; - - vector newvert; - newvert.resize(vcount); - for(unsigned int i = 0; i < patch.nv; i++) - newvert[remap[i]] = patch.Vert3f(i); - - vector newface; - //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(nexus.signature, entry.nvert, entry.nface); - - memcpy(patch.Vert3fBegin(), &(newvert[0]), entry.nvert*sizeof(Point3f)); - memcpy(patch.FaceBegin(), &(newface[0]), entry.nface*3*sizeof(short)); - - //testiamo il tutto... TODO remove this of course -#ifdef NDEBUG - for(unsigned int i =0; i < patch.nf; i++) { - for(int k =0 ; k < 3; k++) - if(patch.Face(i)[k] >= patch.nv) { - cerr <<" Unify has problems\n"; - exit(0); - } - } -#endif - //TODO CRITICAL FIX unify vertices across borders..... HOW?????? - - //fix patch borders now - set close; //bordering pathes - Border &border = nexus.GetBorder(p); - for(unsigned int b = 0; b < border.Size(); b++) { - if(border[b].IsNull()) continue; - close.insert(border[b].end_patch); - border[b].start_vert = remap[border[b].start_vert]; - } - - set::iterator c; - for(c = close.begin(); c != close.end(); c++) { - Border &bord = nexus.GetBorder(*c); - for(unsigned int b = 0; b < bord.Size(); b++) { - if(bord[b].IsNull()) continue; - if(bord[b].end_patch == p) { - bord[b].end_vert = remap[bord[b].end_vert]; - } - } - } - } - //better to compact directly borders than setting them null. - - //finally: there may be duplicated borders - for(unsigned int p = 0; p < nexus.size(); p++) { - Border &border = nexus.GetBorder(p); - set links; - for(unsigned int b = 0; b < border.Size(); b++) { - Link &link = border[b]; - assert(!link.IsNull()); - //if(border[b].IsNull()) continue; - links.insert(link); - } - int count = 0; - for(set::iterator k = links.begin(); k != links.end(); k++) - border[count++] = *k; - - nexus.borders[p].used = links.size(); - } - - nexus.totvert -= duplicated; - if(duplicated) - cerr << "Found " << duplicated << " duplicated vertices" << endl; - if(degenerate) - cerr << "Found " << degenerate << " degenerate face while unmifying\n"; -} -*/ -void nxs::ZSort(Nexus &nexus, vector &forward, - vector &backward) { - //lets get a bounding box from the sphere: - ZCurve zcurve; - float r = nexus.sphere.Radius(); - Point3f radius(r, r, r); - zcurve.Set(nexus.sphere.Center()); - zcurve.Add(nexus.sphere.Center() - radius); - zcurve.Add(nexus.sphere.Center() + radius); - - vector levels; - nexus.history.BuildLevels(levels); - - forward.clear(); - - vector< vector > entries; - - for(unsigned int i = 0; i < nexus.size(); i++) { - int level = levels[i]; - while(level >= entries.size()) entries.push_back(vector()); - - ZEntry e; - e.id = i; - e.pos = zcurve.Pos(nexus[i].sphere.Center()); - entries[level].push_back(e); - } - - for(unsigned int i = 0; i < entries.size(); i++) { - vector &lev = entries[i]; - std::sort(lev.begin(), lev.end()); - for(unsigned int k = 0; k < lev.size(); k++) - forward.push_back(lev[k].id); - } - - backward.resize(forward.size()); - for(unsigned int i = 0; i < backward.size(); i++) - backward[forward[i]] = i; -} - -bool nxs::LineIntersect(Nexus &nexus, Extraction &extraction, - Line3f line, Point3f &hit) { - //seguiamo la history; - Point3f tmp; - if(!Intersection(nexus.sphere, line, hit, tmp)) - return false; - - bool found = false; - float min_dist = -1; - float bar1, bar2, dist; - for(unsigned int i = 0; i < extraction.draw_size; i++) { - unsigned int p = extraction.selected[i].id; - if(!Intersection(nexus[p].sphere, line, hit, tmp)) - continue; - Patch &patch = nexus.GetPatch(p); - if(nexus.signature.face == Signature::TRIANGLES) { - for(unsigned int i = 0; i < patch.nf; i++) { - unsigned short *f = patch.Face(i); - Point3f &v0 = patch.Vert3f(f[0]); - Point3f &v1 = patch.Vert3f(f[1]); - Point3f &v2 = patch.Vert3f(f[2]); - if(Intersection(line, v0, v1, v2, bar1, bar2, dist) && - dist > 0 && - (min_dist == -1 || min_dist > dist)) { - hit = v0*(1-bar1-bar2) + v1*bar1 + v2*bar2; - min_dist = dist; - found = true; - } - } - } else if(nexus.signature.face == Signature::STRIPS) { - for(int i = 0; i < patch.nf - 2; i++) { - unsigned short *f = patch.FaceBegin() + i; - Point3f &v0 = patch.Vert3f(f[0]); - Point3f &v1 = patch.Vert3f(f[1]); - Point3f &v2 = patch.Vert3f(f[2]); - if(Intersection(line, v0, v1, v2, bar1, bar2, dist) && - dist > 0 && - (min_dist == -1 || min_dist > dist)) { - hit = v0*(1-bar1-bar2) + v1*bar1 + v2*bar2; - min_dist = dist; - found = true; - } - } - } else - assert(0); - } - return found; -} diff --git a/apps/nexus/nxsalgo.h b/apps/nexus/nxsalgo.h deleted file mode 100644 index b2baacf5..00000000 --- a/apps/nexus/nxsalgo.h +++ /dev/null @@ -1,93 +0,0 @@ -/**************************************************************************** -* VCGLib o o * -* Visual and Computer Graphics Library o o * -* _ O _ * -* Copyright(C) 2004 \/)\/ * -* Visual Computing Lab /\/| * -* ISTI - Italian National Research Council | * -* \ * -* All rights reserved. * -* * -* This program is free software; you can redistribute it and/or modify * -* it under the terms of the GNU General Public License as published by * -* the Free Software Foundation; either version 2 of the License, or * -* (at your option) any later version. * -* * -* This program is distributed in the hope that it will be useful, * -* but WITHOUT ANY WARRANTY; without even the implied warranty of * -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * -* GNU General Public License (http://www.gnu.org/licenses/gpl.txt) * -* for more details. * -* * -****************************************************************************/ -/**************************************************************************** - History - -$Log: not supported by cvs2svn $ -Revision 1.11 2005/03/01 11:21:20 ponchio -Added line intersection - -Revision 1.10 2005/02/22 14:20:44 ponchio -debug and mostly vertex unifying across borders -(still not perfect... :P) - -Revision 1.9 2005/02/22 10:38:11 ponchio -Debug, cleaning and optimization. - -Revision 1.8 2005/02/21 17:55:36 ponchio -debug debug debug - -Revision 1.7 2005/02/20 18:07:01 ponchio -cleaning. - -Revision 1.6 2005/02/19 10:45:04 ponchio -Patch generalized and small fixes. - -Revision 1.5 2005/02/18 13:04:13 ponchio -Added patch reordering. - -Revision 1.4 2005/02/08 12:43:03 ponchio -Added copyright - - -****************************************************************************/ - -#ifndef NXS_ALGO_H -#define NXS_ALGO_H - -#include -#include -#include "patch.h" -#include -#include - -namespace nxs { - - - class Nexus; - class Patch; - class Extraction; - - - struct ZEntry { - unsigned int id; - unsigned int pos; - bool operator<(const ZEntry &e) const { return pos < e.pos; } - }; - - //for every patch return close by (sphere intersecting) //threshold is added to the distance to make sure we do not miss anything - void Connect(Nexus &nexus, std::vector< std::set > &close, - float threshold); - - void ComputeNormals(Nexus &nexus); - - void Unify(std::vector &points, - std::vector &faces, - std::vector &vremap, float threshold); - void ZSort(Nexus &nexus, std::vector &forward, - std::vector &backward); - bool LineIntersect(Nexus &nexus, Extraction &extraction, - vcg::Line3f line, vcg::Point3f &hit); -} - -#endif diff --git a/apps/nexus/nxsbuilder.cpp b/apps/nexus/nxsbuilder.cpp deleted file mode 100644 index 89dc1694..00000000 --- a/apps/nexus/nxsbuilder.cpp +++ /dev/null @@ -1,972 +0,0 @@ -/**************************************************************************** -* VCGLib o o * -* Visual and Computer Graphics Library o o * -* _ O _ * -* Copyright(C) 2004 \/)\/ * -* Visual Computing Lab /\/| * -* ISTI - Italian National Research Council | * -* \ * -* All rights reserved. * -* * -* This program is free software; you can redistribute it and/or modify * -* it under the terms of the GNU General Public License as published by * -* the Free Software Foundation; either version 2 of the License, or * -* (at your option) any later version. * -* * -* This program is distributed in the hope that it will be useful, * -* but WITHOUT ANY WARRANTY; without even the implied warranty of * -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * -* GNU General Public License (http://www.gnu.org/licenses/gpl.txt) * -* for more details. * -* * -****************************************************************************/ -/**************************************************************************** - History - -$Log: not supported by cvs2svn $ -Revision 1.22 2005/02/22 14:20:44 ponchio -debug and mostly vertex unifying across borders -(still not perfect... :P) - -Revision 1.21 2005/02/22 10:38:11 ponchio -Debug, cleaning and optimization. - -Revision 1.20 2005/02/21 17:55:47 ponchio -debug debug debug - -Revision 1.19 2005/02/20 18:07:01 ponchio -cleaning. - -Revision 1.18 2005/02/20 00:43:24 ponchio -Less memory x extraction. (removed frags) - -Revision 1.17 2005/02/19 17:14:02 ponchio -History quick by default. - -Revision 1.16 2005/02/19 10:45:04 ponchio -Patch generalized and small fixes. - -Revision 1.15 2005/02/14 15:17:36 ponchio -Cleaning up. - -Revision 1.14 2005/01/21 17:09:13 ponchio -Porting and debug. - -Revision 1.13 2005/01/17 17:35:48 ponchio -Small changes and adding realtime extr. - -Revision 1.12 2005/01/14 15:25:29 ponchio -Revolution. - -Revision 1.11 2004/12/13 00:44:48 ponchio -Lotsa changes... - -Revision 1.10 2004/12/09 22:33:28 ponchio -Different splitting optimization. - -Revision 1.9 2004/12/04 13:22:55 ponchio -*** empty log message *** - -Revision 1.8 2004/12/03 21:19:00 ponchio -Fixed a couple of memory leak... - -Revision 1.7 2004/12/03 01:20:56 ponchio -Debug - -Revision 1.6 2004/12/02 20:22:42 ponchio -Level 5; - -Revision 1.5 2004/12/02 19:10:18 ponchio -Bounding sphere fix. - -Revision 1.4 2004/12/01 16:00:35 ponchio -Level 3 - -Revision 1.3 2004/12/01 03:32:46 ponchio -Level 2 (debug). - -Revision 1.2 2004/12/01 03:24:32 ponchio -Level 2. - -Revision 1.1 2004/12/01 01:15:03 ponchio -Level 0. - -Revision 1.26 2004/11/30 22:49:39 ponchio -Level 0. - - -****************************************************************************/ - -#ifdef WIN32 -#include -#else -#include -#endif - -#ifdef WIN32 -#include -#endif - -#include - - -#include "nxstypes.h" -#include "crude.h" -#include "remapping.h" -#include "decimate.h" -#include "fragment.h" -#include "nxsalgo.h" -#include "nxsdispatcher.h" -#include "watch.h" -#include "nexus.h" - - -using namespace std; -using namespace vcg; -using namespace nxs; - -void BuildFragment(Nexus &nexus, VPartition &part, - set &patches, - Fragment &fragment); - -void SaveFragment(Nexus &nexus, VChain &chain, - Fragment &fragin, - Fragment &fragout); - -void ReverseHistory(vector &history); - - -unsigned int current_level; -vector patch_levels; - -void usage() { - cerr << "Usage: voronoinxs [options]\n" - " Options:\n" - " -f N: use N faces per patch (default 1000, max 32000)\n" - " -t N: mini faces per patch (default 200)\n" - " -l N: number of levels\n" - " -s F: scaling factor (0 < F < 1, default 0.5)\n" - " -o N: number of optimization steps\n" - " -d : decimation method: quadric, cluster. (default quadric)\n" - " -b N: ram buffer size (in bytes)\n" - " -p N: which fase perform:\n" - " 0) Remap faces\n" - " 1) Sort faces\n" - " 2) Build patches\n" - " 3) Build borders\n" - " 4) Build levels\n\n" - " If you use the step option, all other parameters MUST stay the same\n\n"; - -} - - -void FirstStep(const string &crudefile, const string &output, - unsigned int patch_size, unsigned int patch_threshold, - float scaling, unsigned int optimization_steps) { - Crude crude; - - if(!crude.Load(crudefile, true)) { - cerr << "Could not open crude input: " << crudefile << endl; - exit(0); - } - - if(patch_size > crude.vert.Size()/2) { - cerr << "Patch size too big: " << patch_size << " * 2 > " - << crude.vert.Size() << endl; - exit(0); - } - - if(patch_threshold == 0xffffffff) - patch_threshold = patch_size/4; - - - VChain vchain; - - VFile face_remap; - if(!face_remap.Create(output + ".rfm")) { - cerr << "Could not create remap files: " << output << ".rmf\n"; - exit(0); - } - face_remap.Resize(crude.Faces()); - - VFile baricenters; - if(!baricenters.Create(output + ".bvr")) { - cerr << "Could not create temporary baricenters file\n"; - exit(0); - } - baricenters.Resize(crude.Faces()); - for(unsigned int i = 0; i < crude.Faces(); i++) { - baricenters[i] = crude.GetBari(i); - } - - BlockIndex face_index; - - Remap(vchain, baricenters, face_remap, face_index, - patch_size, patch_threshold, 65000, scaling, - optimization_steps); - - if(!vchain.Save(output + ".vchain")) { - cerr << "Could not save file: " << output << ".vchain\n"; - exit(0); - } - if(!face_index.Save(output + ".rfi")) { - cerr << "Could not save file: " << output << ".rmi\n"; - exit(0); - } - - baricenters.Delete(); -} - - -void SecondStep(const string &crudefile, const string &output) { - Crude crude; - - if(!crude.Load(crudefile, true)) { - cerr << "Could not open crude input: " << crudefile << endl; - exit(0); - } - VFile face_remap; - if(!face_remap.Load(output + ".rfm", true)) { - cerr << "Could not load: " << output << ".rmf\n;"; - exit(0); - } - assert(face_remap.Size() == crude.Faces()); - - VFile sorted; - if(!sorted.Create(output + ".faces")) { - cerr << "Could not create sorted faces\n"; - exit(0); - } - sorted.Resize(face_remap.Size()); - - BlockIndex face_index; - if(!face_index.Load(output + ".rfi")) { - cerr << "Could not load index\n"; - exit(0); - } - - //Sorting now. - vector done; - done.resize(face_index.size(), 0); - - for(unsigned int i = 0; i < face_remap.Size(); i++) { - unsigned int patch = face_remap[i]; - assert(patch < face_index.size()); - int64 offset = face_index[patch].offset + done[patch]++; - sorted[offset] = crude.GetFace(i); - } - - //once sorted - crude.Close(); - sorted.Close(); - - /* TODO fix this (after debug!) - WARNING what if multiple files? - - if(0 != unlink((crudefile + ".crf").c_str())) { - cerr << "Could not remove " << crudefile << ".crf\n"; - exit(0); - } - if(0 != rename((output + ".faces").c_str(), (crudefile + ".crf").c_str())) { - cerr << "Could not rename to: " << crudefile + ".crf\n"; - exit(0); - } - face_remap.Close(); */ - //TODO remove the file... (after finishing debug!) - // face_remap.Delete(); -} - -void ThirdStep(const string &crudefile, const string &output, - unsigned int chunk_size) { - - cerr << "Third step!\n"; - Crude crude; - - if(!crude.Load(crudefile, true)) { - cerr << "Could not open crude input: " << crudefile << endl; - exit(0); - } - - VFile sorted; - if(!sorted.Load(crudefile + ".faces", true)) { - cerr << "Could not load sorted faces\n"; - exit(0); - } - BlockIndex face_index; - if(!face_index.Load(output + ".rfi")) { - cerr << "Could not load index\n"; - exit(0); - } - - VFile vert_remap; - if(!vert_remap.Create(output + ".rvm")) { - cerr << "Could not create: " << output << ".rvm\n"; - exit(0); - } - - BlockIndex vert_index; - - Nexus nexus; - //TODO here i really need no ram_buffer..... - nexus.MaxRam() = 0; - Signature signature; //default triangles and vertices3f - if(!nexus.Create(output, signature, chunk_size)) { - cerr << "Could not create nexus output: " << output << endl; - getchar(); - exit(0); - } - - Report report(face_index.size()); - for(unsigned int patch = 0; patch < face_index.size(); patch++) { - report.Step(patch); - - unsigned int vcount = 0; - unsigned int fcount = 0; - map vremap; - - vector vertices; - vector faces; - - int64 &offset = face_index[patch].offset; - unsigned int size = face_index[patch].size; - for(unsigned int i = offset; i < offset + size; i++) { - //TODO fix this after debug - Crude::Face face = sorted[i]; - if(face[0] == face[1] || face[1] == face[2] || face[0] == face[2]) - continue; //degenerate - for(int j = 0; j < 3; j++) { - assert(face[j] < crude.Vertices()); - if(!vremap.count(face[j])) { - Point3f &v = crude.vert[face[j]]; - vertices.push_back(v); - vremap[face[j]] = vcount++; - } - faces.push_back(vremap[face[j]]); - fcount++; - } - } - vector remap; - nxs::Unify(vertices, faces, remap, 0.0001); - //fixing vremap - map::iterator q; - for(q = vremap.begin(); q != vremap.end(); q++) - (*q).second = remap[(*q).second]; - - vcount = vertices.size(); - fcount = faces.size(); - - //TODO deal with this case adding another patch at the end... - //its not that difficult! - - //This can happen on degenerate cases when we have a lot of detached faces. - if(vcount > 65000 && fcount > 65000) { - cerr << "Too many vertices or faces in patch: " << patch - << " v: " << vcount << " f: " << fcount << endl; - exit(0); - } - - unsigned int patch_idx = nexus.AddPatch(vertices.size(), - faces.size()/3, - 0); //no borders! - Patch &patch = nexus.GetPatch(patch_idx); - memcpy(patch.FaceBegin(), &*faces.begin(), fcount * sizeof(short)); - memcpy(patch.Vert3fBegin(), &*vertices.begin(), vcount * sizeof(Point3f)); - - - //Fixing sphere - Sphere3f &sphere = nexus[patch_idx].sphere; - sphere.CreateTight(vertices.size(), &*vertices.begin()); - - - //Fixing normalscone - vector normals; - normals.reserve(patch.nf); - for(unsigned int i = 0; i < patch.nf; i++) { - unsigned short *f = patch.Face(i); - Point3f &v0 = patch.Vert3f(f[0]); - Point3f &v1 = patch.Vert3f(f[1]); - Point3f &v2 = patch.Vert3f(f[2]); - - Point3f norm = (v1 - v0) ^ (v2 - v0); - float len = norm.Norm(); - if(len == 0) { - cerr << "Degenerate face... should not be here.\n"; - continue; - } - norm /= len; -#ifndef WIN32 - if(isnan(norm[0]) || isnan(norm[1]) || isnan(norm[2])) { - cerr << "Invalid normal computation. Strange.\n"; - continue; - } -#endif - normals.push_back(norm); - } - ANCone3f cone; - cone.AddNormals(normals, 0.99f); - nexus[patch_idx].cone.Import(cone); - - - //saving vert_remap - int64 vroffset = vert_remap.Size(); - vert_index.push_back(BlockEntry(vroffset, vcount)); - vert_remap.Resize(vroffset + vcount); - - map::iterator r; - for(r = vremap.begin(); r != vremap.end(); r++) { - assert((*r).second < vcount); - assert(vroffset + (*r).second < vert_remap.Size()); - vert_remap[vroffset + (*r).second] = (*r).first; - } - if(vcount < 100) { - cerr << "Small patch: " << vcount << "\n"; - } - } - - //we can now update bounding sphere. - for(unsigned int i = 0; i < nexus.size(); i++) - nexus.sphere.Add(nexus[i].sphere); - - History::Update update; - for(unsigned int i = 1; i < nexus.size(); i++) - update.created.push_back(i); - nexus.history.updates.push_back(update); - - update.created.clear(); - update.created.push_back(0); - for(unsigned int i = 1; i < nexus.size(); i++) - update.erased.push_back(i); - nexus.history.updates.push_back(update); - - if(!vert_index.Save(output + ".rvi")) { - cerr << "Could not save: " << output << ".rvi\n"; - exit(0); - } - nexus.Close(); -} - -void FourthStep(const string &crudefile, const string &output, - unsigned int ram_buffer) { - float threshold = 0.0001; - cerr << "Creating borders\n"; - Nexus nexus; - if(!nexus.Load(output)) { - cerr << "Could not load nexus " << output << endl; - exit(0); - } - nexus.MaxRam() = ram_buffer / nexus.chunk_size; - - VFile vert_remap; - if(!vert_remap.Load(output + ".rvm", true)) { - cerr << "Could not load: " << crudefile << ".rvm\n"; - exit(0); - } - - BlockIndex vert_index; - if(!vert_index.Load(output + ".rvi")) { - cerr << "Could not load index\n"; - exit(0); - } - - vector > close; - Connect(nexus, close, 0.0001); - - Report report(nexus.size()); - - //WARNING this is not robust at all!!!! - //TO make all this work we should neeed to quantize - //vertex position with 2 * threshold step (at least) - for(int start = 0; start < nexus.size(); start++) { - report.Step(start); - - vector links; - set::iterator t; - for(t = close[start].begin(); t != close[start].end(); t++) { - unsigned int end = (*t); - Patch &pend = nexus.GetPatch(end); - VPartition grid; - for(int i = 0; i < pend.nv; i++) { - grid.push_back(pend.Vert3f(i)); - } - grid.Init(); - - vector targets; - vector dists; - Patch &patch = nexus.GetPatch(start); - for(int i = 0; i < patch.nv; i++) { - grid.Closest(patch.Vert3f(i), targets, dists, threshold); - for(unsigned int k = 0; k < targets.size(); k++) { - Link link; - link.start_vert = i; - link.end_vert = targets[k]; - link.end_patch = end; - links.push_back(link); - patch.Vert3f(i) = grid[targets[k]]; - } - } - - } - - Border &border = nexus.GetBorder(start); - nexus.borders.ResizeBorder(start, 3 * links.size()); - border.used = links.size(); - memcpy(&(border[0]), &*links.begin(), links.size() * sizeof(Link)); - } - - /*old way.. - for(int start = 0; start < nexus.size(); start++) { - report.Step(start); - - vector links; - map vremap; - for(unsigned int i = 0; i < vert_index[start].size; i++) { - unsigned int global = vert_remap[vert_index[start].offset + i]; - vremap[global] = i; - } - - set::iterator t; - for(t = close[start].begin(); t != close[start].end(); t++) { - unsigned int end = (*t); - - for(unsigned int i = 0; i < vert_index[end].size; i++) { - unsigned int global = vert_remap[vert_index[end].offset + i]; - if(vremap.count(global)) { - Link link; - link.start_vert = vremap[global]; - link.end_vert = i; - link.end_patch = end; - links.push_back(link); - } - } - } - - - Border &border = nexus.GetBorder(start); - nexus.borders.ResizeBorder(start, 3 * links.size()); - border.used = links.size(); - memcpy(&(border[0]), &*links.begin(), links.size() * sizeof(Link)); - }*/ -} - -void FifthStep(const string &crudefile, const string &output, - unsigned int ram_buffer, - unsigned int optimization_steps, - unsigned int patch_size, - unsigned int patch_threshold, - Decimation decimation, - float scaling, - unsigned int max_level) { - - Nexus nexus; - if(!nexus.Load(output)) { - cerr << "Could not load nexus " << output << endl; - exit(0); - } - nexus.MaxRam() = ram_buffer / nexus.chunk_size; - - VChain vchain; - if(!vchain.Load(output + ".vchain")) { - cerr << "Could not load : " << output << ".vchain\n"; - exit(0); - } - nexus.history.Clear(); - History::Update update; - for(unsigned int i = 0; i < nexus.size(); i++) { - update.created.push_back(i); - patch_levels.push_back(0); - } - nexus.history.updates.push_back(update); - // Unify(nexus, 0.0f); - // nexus.Unify(); - nexus.Flush(); - - - Dispatcher dispatcher(&nexus, &vchain); - dispatcher.mode = decimation; - dispatcher.scaling = scaling; - if(!dispatcher.Init("servers.txt")) { - cerr << "Could not parse server file: " << "servers.txt" - << " proceding locally\n"; - } - - unsigned int oldoffset = 0; - for(unsigned int level = 1; level < max_level; level++) { - current_level = level; - cerr << "Level: " << level << endl; - - unsigned int newoffset = nexus.size(); - BuildLevel(vchain, nexus, oldoffset, scaling, - patch_size, patch_threshold, 65000, - optimization_steps); - - Report report(vchain.oldfragments.size()); - - unsigned int fcount = 0; - map >::iterator fragment; - for(fragment = vchain.oldfragments.begin(); - fragment != vchain.oldfragments.end(); fragment++) { - report.Step(fcount++); - - Fragment *fragin = new Fragment; - BuildFragment(nexus, *vchain[level+1], - (*fragment).second, *fragin); - - dispatcher.SendFragment(fragin); - - - /* - //this can be executed on a remote host - - //TODO move this part to remote.... - vector newvert; - vector newface; - vector newbord; - Join(fragin, newvert, newface, newbord); - - float error = Decimate(decimation, - (unsigned int)((newface.size()/3) * scaling), - newvert, newface, newbord); - Fragment fragout; - fragout.error = error; - fragout.id = fragin.id; - fragout.seeds = fragin.seeds; - fragout.seeds_id = fragin.seeds_id; - Split(fragout, newvert, newface, newbord);//, vchain.levels[level+1]); - - - SaveFragment(nexus, vchain, fragin, fragout); - */ - dispatcher.processmsgs(); - } - //TODO porcata!!!! - while(dispatcher.frags.size()) { - // cerr << "frags: " << dispatcher.frags.size() << endl; - dispatcher.processmsgs(); - } - - report.Finish(); - - if(vchain.oldfragments.size() == 1) break; - - vchain.oldfragments = vchain.newfragments; - oldoffset = newoffset; - } - - //last level clean history: - update.created.clear(); - update.erased.clear(); - map >::iterator fragment; - for(fragment = vchain.newfragments.begin(); - fragment != vchain.newfragments.end(); fragment++) { - set &fcells = (*fragment).second; - set::iterator s; - for(s = fcells.begin(); s != fcells.end(); s++) - update.erased.push_back(*s); - } - nexus.history.updates.push_back(update); - ReverseHistory(nexus.history.updates); - - nexus.borders.Flush(); - if(!nexus.history.IsQuick()) - nexus.history.UpdatesToQuick(nexus); - // TestBorders(nexus); - nexus.Close(); - -} - -int main(int argc, char *argv[]) { - - /* Parameters: */ - unsigned int patch_size = 1000; //step 0 - unsigned int patch_threshold = 0xffffffff; //Step 0 - float scaling = 0.5; //step 0, 4 - unsigned int optimization_steps = 5; //step 0, 4 - - Decimation decimation = CLUSTER; //step 4 - unsigned int max_level = 0xffffffff; //step 4 - - unsigned int ram_buffer = 128000000; //step 2, 3, 4 - unsigned int chunk_size = 1024; //step 2, 3, 4 - int step = -1; //means all of them. - - int option; - while((option = getopt(argc, argv, "f:t:l:s:d:o:b:c:p:")) != EOF) { - switch(option) { - case 'f': patch_size = atoi(optarg); - if(patch_size == 0 || patch_size > 32000) { - cerr << "Invalid number of faces per patch: " << optarg << endl; - return -1; - } - break; - case 't': patch_threshold = atoi(optarg); - if(patch_threshold == 0 || patch_threshold > patch_size) { - cerr << "Invalid patch threshold: " << optarg << endl; - return -1; - } - break; - case 'l': max_level = atoi(optarg); - if(max_level == 0) { - cerr << "Invalid number of levels: " << optarg << endl; - return -1; - } - break; - case 's': scaling = (float)atof(optarg); - if(scaling <= 0 || scaling >= 1) { - cerr << "Invalid scaling: " << optarg << endl; - cerr << "Must be 0 < scaling < 1" << endl; - } - break; - case 'd': - if(!strcmp("quadric", optarg)) - decimation = QUADRIC; - else if(!strcmp("cluster", optarg)) - decimation = CLUSTER; - else { - cerr << "Unknown decimation method: " << optarg << endl; - return -1; - } - break; - case 'o': optimization_steps = atoi(optarg); break; - case 'p': step = atoi(optarg); break; - case 'b': ram_buffer = atoi(optarg); - if(ram_buffer == 0) { - cerr << "Invalid ram buffer: " << optarg << endl; - return -1; - } - break; - case 'c': chunk_size = atoi(optarg); - if(chunk_size == 0) { - cerr << "Invalid chunk size: " << optarg << endl; - return -1; - } - break; - default: cerr << "Unknown option: " << (char)option << endl; - return -1; - } - } - - if(optind != argc -2) { - usage(); - return -1; - } - string crudefile = argv[optind]; - string output = argv[optind+1]; - - if(step < 0 || step == 0) - FirstStep(crudefile, output, patch_size, patch_threshold, - scaling, optimization_steps); - if(step < 0 || step == 1) - SecondStep(crudefile, output); - - if(step < 0 || step == 2) - ThirdStep(crudefile, output, chunk_size); - - if(step < 0 || step == 3) - FourthStep(crudefile, output, ram_buffer); - - if(step < 0 || step == 4) - FifthStep(crudefile, output, - ram_buffer, - optimization_steps, - patch_size, patch_threshold, - decimation, - scaling, max_level); - return 0; -} - -void BuildFragment(Nexus &nexus, VPartition &part, - set &patches, - Fragment &fragment) { - - set::iterator f; - for(f = patches.begin(); f != patches.end(); f++) { - fragment.pieces.push_back(NxsPatch()); - NxsPatch &nxs = fragment.pieces.back(); - nxs.patch = *f; - - Patch &patch = nexus.GetPatch(*f); - Border &border = nexus.GetBorder(*f); - - for(unsigned int k = 0; k < patch.nf; k++) { - assert(patch.FaceBegin()[3*k + 0] != patch.FaceBegin()[3*k + 1]); - assert(patch.FaceBegin()[3*k + 0] != patch.FaceBegin()[3*k + 2]); - assert(patch.FaceBegin()[3*k + 1] != patch.FaceBegin()[3*k + 2]); - } - - - nxs.vert.resize(patch.nv); - nxs.face.resize(patch.nf * 3); - memcpy(&*nxs.vert.begin(), patch.Vert3fBegin(), patch.nv * sizeof(Point3f)); - memcpy(&*nxs.face.begin(), patch.FaceBegin(), patch.nf * 3*sizeof(short)); - for(unsigned int i = 0; i < border.Size(); i++) { - Link &link = border[i]; - if(!link.IsNull() && - patch_levels[link.end_patch] == current_level-1) { - assert(link.end_patch != *f); - nxs.bord.push_back(link); - } - } - } - - //TODO Use the closest with threshold here instead of a cracnut number?? - set seeds; - vector nears; - vector dists; - int nnears = 10; - if(part.size() < 10) nnears = part.size(); - for(f = patches.begin(); f != patches.end(); f++) { - Point3f ¢er = nexus[*f].sphere.Center(); - part.Closest(center, nnears, nears, dists); - for(int i = 0; i < nnears; i++) - seeds.insert(nears[i]); - } - for(f = seeds.begin(); f != seeds.end(); f++) { - Point3f &p = part[*f]; - fragment.seeds.push_back(p); - fragment.seeds_id.push_back(*f); - } -} - -void SaveFragment(Nexus &nexus, VChain &chain, - Fragment &fragin, - Fragment &fragout) { - - set orig_patches; - - History::Update update; - for(unsigned int i = 0; i < fragin.pieces.size(); i++) { - NxsPatch &patch = fragin.pieces[i]; - update.erased.push_back(patch.patch); - orig_patches.insert(patch.patch); - } - - vector patch_remap; - patch_remap.resize(fragout.pieces.size()); - - for(unsigned int i = 0; i < fragout.pieces.size(); i++) { - NxsPatch &patch = fragout.pieces[i]; - //TODO detect best parameter below for bordersize... - unsigned int bordsize = 6 * patch.bord.size(); - if(bordsize > 65500) bordsize = 65499; - unsigned int patch_idx = nexus.AddPatch(patch.vert.size(), - patch.face.size()/3, - bordsize); - patch_levels.push_back(current_level); - Entry &entry = nexus[patch_idx]; - entry.error = fragout.error; - entry.sphere = patch.sphere; - entry.cone.Import(patch.cone); - - patch_remap[i] = patch_idx; - chain.newfragments[patch.patch].insert(patch_idx); - update.created.push_back(patch_idx); - } - - //here i put for every patch all its new links. - map > newlinks; - - for(unsigned int i = 0; i < fragout.pieces.size(); i++) { - NxsPatch &outpatch = fragout.pieces[i]; - unsigned int patch_idx = patch_remap[i]; - - for(unsigned int k = 0; k < outpatch.face.size(); k += 3) { - assert(k+2 < outpatch.face.size()); - assert(outpatch.face[k] != outpatch.face[k+1]); - assert(outpatch.face[k] != outpatch.face[k+2]); - assert(outpatch.face[k+1] != outpatch.face[k+2]); - } - - Patch &patch = nexus.GetPatch(patch_idx); - memcpy(patch.FaceBegin(), &outpatch.face[0], - outpatch.face.size() * sizeof(unsigned short)); - memcpy(patch.Vert3fBegin(), &outpatch.vert[0], - outpatch.vert.size() * sizeof(Point3f)); - - Entry &entry = nexus[patch_idx]; - - //remap internal borders - for(unsigned int k = 0; k < outpatch.bord.size(); k++) { - Link &link = outpatch.bord[k]; - if(link.end_patch >= (1<<31)) { //internal - link.end_patch = patch_remap[link.end_patch - (1<<31)]; - assert(link.end_patch != patch_remap[i]); - newlinks[patch_idx].insert(link); - } - } - //TODO not efficient! - //processing external borders - for(unsigned int l = 0; l < outpatch.bord.size(); l++) { - Link &link = outpatch.bord[l]; - if(link.end_patch >= (1<<31)) continue; - - unsigned short &start_vert = link.start_vert; - unsigned int &start_patch = patch_idx; - - //Adding vertical connection - newlinks[patch_idx].insert(link); - - Link up(link.end_vert, link.start_vert, patch_idx); - newlinks[link.end_patch].insert(up); - - assert(link.end_patch != patch_idx); - Border &cborder = nexus.GetBorder(link.end_patch); - for(unsigned int k = 0; k < cborder.Size(); k++) { - //cerr << "Cborder.size: " << cborder.Size() << endl; - //cerr << "K: " << k << endl; - Link &clink = cborder[k]; - assert(!clink.IsNull()); - - if(clink.start_vert != link.end_vert) continue; - if(patch_levels[clink.end_patch] < current_level-1) continue; - //boy i want only the external links! - if(orig_patches.count(clink.end_patch)) continue; - - unsigned short &end_vert = clink.end_vert; - unsigned int &end_patch = clink.end_patch; - - //TODO FIX THIS!!!! - assert(clink.end_patch != start_patch); - assert(clink.end_patch != link.end_patch); - - Link newlink; - - newlink.start_vert = start_vert; - newlink.end_vert = end_vert; - newlink.end_patch = end_patch; - - newlinks[patch_idx].insert(newlink); - - newlink.start_vert = end_vert; - newlink.end_vert = start_vert; - newlink.end_patch = start_patch; - - newlinks[end_patch].insert(newlink); - } - } - } - map >::iterator n; - for(n = newlinks.begin(); n != newlinks.end(); n++) { - set::iterator l; - unsigned int patch = (*n).first; - set &links = (*n).second; - Border &border = nexus.GetBorder(patch); - unsigned int bstart = border.Size(); - nexus.borders.ResizeBorder(patch, border.Size() + links.size()); - for(l = links.begin(); l != links.end(); l++) { - Link link = *l; - border[bstart++] = link; - } - } - nexus.history.updates.push_back(update); -} - -void ReverseHistory(vector &history) { - vector revert = history; - history.clear(); - for(int i = revert.size()-1; i >= 0; i--) - history.push_back(revert[i]); - //std::reverse(history.begin(), history.end()); - vector::iterator i; - for(i = history.begin(); i != history.end(); i++) - swap((*i).erased, (*i).created); -} diff --git a/apps/nexus/nxsclient.cpp b/apps/nexus/nxsclient.cpp deleted file mode 100644 index 0428c8bc..00000000 --- a/apps/nexus/nxsclient.cpp +++ /dev/null @@ -1,71 +0,0 @@ -/**************************************************************************** -* VCGLib o o * -* Visual and Computer Graphics Library o o * -* _ O _ * -* Copyright(C) 2004 \/)\/ * -* Visual Computing Lab /\/| * -* ISTI - Italian National Research Council | * -* \ * -* All rights reserved. * -* * -* This program is free software; you can redistribute it and/or modify * -* it under the terms of the GNU General Public License as published by * -* the Free Software Foundation; either version 2 of the License, or * -* (at your option) any later version. * -* * -* This program is distributed in the hope that it will be useful, * -* but WITHOUT ANY WARRANTY; without even the implied warranty of * -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * -* GNU General Public License (http://www.gnu.org/licenses/gpl.txt) * -* for more details. * -* * -****************************************************************************/ -/**************************************************************************** - History - -$Log: not supported by cvs2svn $ - -****************************************************************************/ - -#include - -class NxsClientPool { - vector clients; - void Push(NxsRequest *request); -}; - -class NxsClient: public pt::ipstream { -public: - queue requests; - - void Push(NxsRequest *request); -}; - - -ipaddress addr = phostbyname("nb-ponchio.isti.cnr.it"); - ipstream client; - client.set_ip(addr); - client.set_port(testport); - try - { - client.open(); - - pout.put("Sending a request to the server...\n"); - client.write("Hello", 6); - client.flush(); - - // receive the response - string rsp = client.line(maxtoken); - pout.putf("Received: %s\n", pconst(rsp)); - - // need to close the socket explicitly to gracefully shutdown - // the peer host too. otherwise, ~ipstream() will call cancel() - // and leave the peer in a waiting state (not forever though). - client.close(); - } - catch(estream* e) - { - perr.putf("Error: %s\n", pconst(e->get_message())); - delete e; - } - diff --git a/apps/nexus/nxsdispatcher.cpp b/apps/nexus/nxsdispatcher.cpp deleted file mode 100644 index 76f8d451..00000000 --- a/apps/nexus/nxsdispatcher.cpp +++ /dev/null @@ -1,221 +0,0 @@ -/**************************************************************************** -* VCGLib o o * -* Visual and Computer Graphics Library o o * -* _ O _ * -* Copyright(C) 2004 \/)\/ * -* Visual Computing Lab /\/| * -* ISTI - Italian National Research Council | * -* \ * -* All rights reserved. * -* * -* This program is free software; you can redistribute it and/or modify * -* it under the terms of the GNU General Public License as published by * -* the Free Software Foundation; either version 2 of the License, or * -* (at your option) any later version. * -* * -* This program is distributed in the hope that it will be useful, * -* but WITHOUT ANY WARRANTY; without even the implied warranty of * -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * -* GNU General Public License (http://www.gnu.org/licenses/gpl.txt) * -* for more details. * -* * -****************************************************************************/ -/**************************************************************************** - History - -$Log: not supported by cvs2svn $ - -****************************************************************************/ - -#include "nxsdispatcher.h" -#include "fragment.h" -#include "decimate.h" -#include -#include - -using namespace std; -using namespace vcg; -using namespace nxs; -using namespace pt; - -void SaveFragment(Nexus &nexus, VChain &chain, - Fragment &fragin, - Fragment &fragout); - - -void Opener::execute() { - // cerr << "Trying to connect to: " << server->get_host() << endl; - server->reading.lock(); - server->writing.lock(); - while(1) { - if(get_signaled()) - return; - // cerr << "Trying to connect to: " << server->get_host() << endl; - try { - server->open(); - server->connected = true; - server->queue = 0; - // cerr << "Connected to: " << server->get_host() << endl; - break; - } catch(...) { - } - psleep(4000); - } - server->reading.unlock(); - server->writing.unlock(); -} - -void FragIO::execute() { - pincrement(&(server->queue)); - server->writing.lock(); - // cerr << "Writing frag...: " << fragin->id << "\n"; - - outmemory outm; - outm.open(); - fragin->Write(&outm); - pt::string a = outm.get_strdata(); - try { - server->write((const char *)a, length(a)); - server->flush(); - } catch (estream *e) { - perr.putf("Error reading: %s\n", pconst(e->get_message())); - delete e; - server->close(); - server->connected = false; - server->writing.unlock(); - message *msg = new message(MSG_FAIL, (int)fragin); - dispatcher->post(msg); - server->opener.start(); - return; - } - - server->reading.lock(); - server->writing.unlock(); - - Fragment *out = new Fragment; - if(!server->waitfor(10000) || (!out->Read(server))) { - perr.putf("Error reading!!\n"); - server->close(); - server->connected = false; - server->reading.unlock(); - message *msg = new message(MSG_FAIL, (int)fragin); - dispatcher->post(msg); - server->opener.start(); - return; - } - server->reading.unlock(); - pdecrement(&(server->queue)); - // cerr << "Received frag: " << out->id << endl; - - message *msg = new message(MSG_RECEIVE, (int)fragin); - msg->result = (int)out; - dispatcher->post(msg); -} - -bool Dispatcher::Init(const std::string &file) { - FILE *fp = fopen(file.c_str(), "rb"); - if(!fp) return false; - char host[256]; - int port; - while(fscanf(fp, "%s %d\n", host, &port) == 2) { - cerr << "Host: " << host << " port: " << port << endl; - Server *server = new Server(host, port); - server->opener.start(); - servers.push_back(server); - } - fclose(fp); - if(servers.size() == 0) { - cerr << "Empty server file!\n"; - return false; - } - return true; -} - -Dispatcher::~Dispatcher() { - for(unsigned int i = 0; i < servers.size(); i++) { - Server *server = servers[i]; - server->opener.signal(); - server->close(); - delete server; - } -} - -void Dispatcher::SendFragment(Fragment *frag) { - //WARNING this handles no more than 1<<31 fragments! - frag->id = count++; - message *msg = new message(MSG_SEND, (int)frag); - post(msg); -} - -Server *Dispatcher::BestServer() { - Server *best = NULL; - for(unsigned int i = 0; i < servers.size(); i++){ - if(servers[i]->connected) { - if((servers[i]->queue <= maxqueue) && - (!best || servers[i]->queue < best->queue)) { - - best = servers[i]; - // cerr << "best: " << i << " queue: " << best->queue << endl; - } - } - } - return best; -} - -void Dispatcher::ReceiveFragment(Fragment *in, Fragment *out) { - //lock nexus if run in thread. - // cerr << "Saving: " << in->id << endl; - SaveFragment(*nexus, *chain, *in, *out); - - if(frags.count(in->id)) { - FragIO *frag = frags[in->id]; - delete frag; - frags.erase(frags.find(in->id)); - } - delete in; - delete out; -} - -void Dispatcher::msghandler(message &msg) { - switch(msg.id) { - case MSG_FAIL: - case MSG_SEND: { - //get server! - Server *best = BestServer(); - Fragment *fragin = (Fragment *)(msg.param); - - if(!best || mode == CLUSTER) { //no server process locally.... - // cerr << "Local: " << fragin->id << endl; - vector newvert; - vector newface; - vector newbord; - Join(*fragin, newvert, newface, newbord); - - float error = Decimate(mode, - (unsigned int)((newface.size()/3) * scaling), - newvert, newface, newbord); - - Fragment *fragout = new Fragment; - - fragout->error = error; - fragout->id = fragin->id; - fragout->seeds = fragin->seeds; - fragout->seeds_id = fragin->seeds_id; - Split(*fragout, newvert, newface, newbord); - ReceiveFragment(fragin, fragout); - } else { - // cerr << "Server: " << fragin->id << endl; - FragIO *frag = new FragIO(best, this, fragin); - if(msg.id == MSG_SEND) - assert(!frags.count(fragin->id)); - frags[fragin->id] = frag; - frag->start(); - } - } break; - case MSG_RECEIVE: - ReceiveFragment((Fragment *)(msg.param), (Fragment *)(msg.result)); - break; - default: - defhandler(msg); - } -} diff --git a/apps/nexus/nxsdispatcher.h b/apps/nexus/nxsdispatcher.h deleted file mode 100644 index c44446aa..00000000 --- a/apps/nexus/nxsdispatcher.h +++ /dev/null @@ -1,120 +0,0 @@ -/**************************************************************************** -* VCGLib o o * -* Visual and Computer Graphics Library o o * -* _ O _ * -* Copyright(C) 2004 \/)\/ * -* Visual Computing Lab /\/| * -* ISTI - Italian National Research Council | * -* \ * -* All rights reserved. * -* * -* This program is free software; you can redistribute it and/or modify * -* it under the terms of the GNU General Public License as published by * -* the Free Software Foundation; either version 2 of the License, or * -* (at your option) any later version. * -* * -* This program is distributed in the hope that it will be useful, * -* but WITHOUT ANY WARRANTY; without even the implied warranty of * -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * -* GNU General Public License (http://www.gnu.org/licenses/gpl.txt) * -* for more details. * -* * -****************************************************************************/ -/**************************************************************************** - History - -$Log: not supported by cvs2svn $ - -****************************************************************************/ - -#ifndef NXS_DISPATCHER_H -#define NXS_DISPATCHER_H - -#include -#include -#include -#include -#include - -#include "decimate.h" - -namespace nxs { - -#define MSG_SEND MSG_USER + 1 -#define MSG_RECEIVE MSG_USER + 2 -#define MSG_FAIL MSG_USER + 3 - - class Fragment; - class Nexus; - class VChain; - - class Server; - class FragIO; - class Dispatcher; - - - class Opener: public pt::thread { - public: - Opener(Server *s): thread(false), server(s) {} - ~Opener() { waitfor(); } - void execute(); - void cleanup() {} - - Server *server; - }; - - - class Server: public pt::ipstream { - public: - Server(pt::string host, int port): ipstream(host, port), queue(0), - connected(false), opener(this) {} - - int queue; - pt::mutex reading; - pt::mutex writing; - bool connected; - Opener opener; - }; - - - class Dispatcher: public pt::msgqueue { - public: - Dispatcher(Nexus *nx, VChain *ch): - count(0), maxqueue(3), nexus(nx), chain(ch) {} - ~Dispatcher(); - - bool Init(const std::string &file); - void SendFragment(Fragment *frag); - void ReceiveFragment(Fragment *in, Fragment *out); - Server *BestServer(); - - void msghandler(pt::message &msg); - - int count; - int maxqueue; - Nexus *nexus; - VChain *chain; - Decimation mode; - float scaling; - std::vector servers; - std::map frags; - }; - - class FragIO: public pt::thread { - public: - FragIO(Server *se, Dispatcher *di, Fragment *frag): - thread(false), server(se), dispatcher(di), fragin(frag) {} - ~FragIO() { waitfor(); } - void execute(); - void cleanup() {} - - Server *server; - Dispatcher *dispatcher; - Fragment *fragin; - }; - - - -} - -#endif diff --git a/apps/nexus/nxsedit.cpp b/apps/nexus/nxsedit.cpp deleted file mode 100644 index 48a4cc0b..00000000 --- a/apps/nexus/nxsedit.cpp +++ /dev/null @@ -1,670 +0,0 @@ -/**************************************************************************** -* VCGLib o o * -* Visual and Computer Graphics Library o o * -* _ O _ * -* Copyright(C) 2004 \/)\/ * -* Visual Computing Lab /\/| * -* ISTI - Italian National Research Council | * -* \ * -* All rights reserved. * -* * -* This program is free software; you can redistribute it and/or modify * -* it under the terms of the GNU General Public License as published by * -* the Free Software Foundation; either version 2 of the License, or * -* (at your option) any later version. * -* * -* This program is distributed in the hope that it will be useful, * -* but WITHOUT ANY WARRANTY; without even the implied warranty of * -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * -* GNU General Public License (http://www.gnu.org/licenses/gpl.txt) * -* for more details. * -* * -****************************************************************************/ -/**************************************************************************** - History - -$Log: not supported by cvs2svn $ -Revision 1.26 2005/02/22 10:38:14 ponchio -Debug, cleaning and optimization. - -Revision 1.25 2005/02/21 17:55:47 ponchio -debug debug debug - -Revision 1.24 2005/02/20 19:49:44 ponchio -cleaning (a bit more). - -Revision 1.23 2005/02/20 18:07:01 ponchio -cleaning. - -Revision 1.22 2005/02/20 00:43:24 ponchio -Less memory x extraction. (removed frags) - -Revision 1.21 2005/02/19 17:14:02 ponchio -History quick by default. - -Revision 1.20 2005/02/19 10:45:04 ponchio -Patch generalized and small fixes. - -Revision 1.19 2005/02/18 13:04:13 ponchio -Added patch reordering. - -Revision 1.18 2005/02/08 12:43:03 ponchio -Added copyright - - -****************************************************************************/ - -#ifdef WIN32 -#include -#else -#include -#endif - -#include - - -#include - - -#include -#include -#include -//WARNING WARNING this must be included AFTER mesh includes.... -#include -#include - -#include "nxsalgo.h" -#include "strip.h" -#include "nexus.h" -#include "watch.h" - -using namespace nxs; -using namespace vcg; -using namespace std; -using namespace tri; - -class CFace; - -class CVertex: public VertexVCf {}; - -class CFace: public Face{}; - -class CMesh: public tri::TriMesh, vector > {}; - -string getSuffix(Signature &signature) { - string suff; - if(signature.compr) suff += "Z"; - if(signature.face == Signature::STRIPS) suff += "S"; - if(signature.vcolor) suff += "C"; - if(signature.vnorm) suff += "N"; - if(signature.vtext) suff += "T"; - if(signature.vdata) suff += "D"; - return suff; -} - -void printInfo(Nexus &nexus, bool verbose, bool dump_history); - -int main(int argc, char *argv[]) { - - string input; - string output; - string plysource; - - bool info = false; - bool verbose = false; - bool dump_history = false; - - unsigned int ram_size = 128000000; - unsigned int chunk_size = 0; - - bool add = false; - bool add_strips = false; - bool add_colors = false; - unsigned char add_normals = 0; - bool add_textures = false; - bool add_data = false; - - bool remove = false; - bool remove_strips = false; - bool remove_colors = false; - bool remove_normals = false; - bool remove_textures = false; - bool remove_data = false; - - bool compress = false; - bool uncompress = false; - bool zsort = false; - - float qvertex = 0; - float qnormal = 0; - float qcolor = 0; - float qtexture = 0; - float cone_threshold = 0; - - int option; - while((option = getopt(argc, argv, "ilho:a:r:zxsv:n:k:t:b:c:V:")) != EOF) { - switch(option) { - case 'i': info = true; break; - case 'l': verbose = true; break; - case 'h': dump_history = true; break; - case 'o': output = optarg; break; - case 'p': plysource = optarg; break; - - case 'a': { - if(strstr(optarg, "strips")) { add_strips = true; add = true; } - if(strstr(optarg, "colors")) { add_colors = true; add = true; } - if(strstr(optarg, "normals")) { - add_normals = Encodings::SHORT4; add = true; } - if(strstr(optarg, "normalf")) { - add_normals = Encodings::FLOAT3; add = true; } - if(strstr(optarg, "textures")) { add_textures = true; add = true; } - if(strstr(optarg, "data")) { add_data = true; add = true; } - if(add == false) { - cerr << "Invalid -a argument: " << optarg << "\n" - << "Valid options are: strips, colors, normals, textures, data\n"; - return -1; - } - break; - } - case 'r': { - if(strstr(optarg, "strips")) { - cerr << "Strips removing not supported!\n"; - return -1; - } - if(strstr(optarg, "colors")) { remove_colors = true; remove = true; } - if(strstr(optarg, "normals")) { remove_normals = true; remove = true; } - if(strstr(optarg, "textures")) { remove_textures = true; remove = true; } - if(strstr(optarg, "data")) { remove_data = true; remove = true; } - if(remove == false) { - cerr << "Invalid -a argument: " << optarg << "\n" - << "Valid options are: strip, colors, normals, normalf, " - << "textures, data\n"; - return -1; - } - break; - } - - - - case 'z': compress = true; break; - case 'x': uncompress = true; break; - case 's': zsort = true; break; - - case 'V': cone_threshold = atof(optarg); break; - case 'v': qvertex = (float)atof(optarg); - if(qvertex == 0) { - cerr << "Invalid value for quantization: " << optarg << endl; - return -1; - } - break; - case 'n': qnormal = (float)atof(optarg); - if(qnormal == 0) { - cerr << "Invalid value for quantization: " << optarg << endl; - return -1; - } - break; - case 'k': qcolor = (float)atof(optarg); - if(qcolor == 0) { - cerr << "Invalid value for quantization: " << optarg << endl; - return -1; - } - break; - case 't': qtexture = (float)atof(optarg); - if(qtexture == 0) { - cerr << "Invalid value for quantization: " << optarg << endl; - return -1; - } - break; - - case 'b': ram_size = atoi(optarg); - if(ram_size == 0) { - cerr << "Invalid ram_size: " << optarg << endl; - return -1; - } - break; - case 'c': chunk_size = atoi(optarg); - if(chunk_size == 0) { - cerr << "Invalid chunk_size: " << optarg << endl; - return -1; - } - break; - default: cerr << "Unknown option: " << (char)option << endl; - return -1; - } - } - - if(optind != argc - 1) { - cerr << "Usage: " << argv[0] << " [options]\n" - << " -i : display some info about nexus file\n" - << " -l : list nodes\n" - << " -h : list history\n" - << " -o : output filename (default is adding 00 to nexus)\n" - << " -a : Add [colors|normals|normalf|strips|textures|data|borders]\n" - << " -r : As add...\n" - << " -p : Ply source for colors or textures or data\n" - << " -z : compress\n" - << " -x : uncompress\n" - << " -s : sort using zcurve\n" - << " -v: Vertex quantization (float is the 0 level amount)\n" - << " -n: Normal quantization\n" - << " -c: Color quantization\n" - << " -t: Texture quantization\n" - << " -V: Normal cone threshold [0, 1] (0.95 default)\n\n" - << " This option will not create a new nexus file\n"; - return -1; - } - input = argv[optind]; - - //Sanity test of options... - - if(compress && uncompress) { - cerr << "x and z are obviously exclusive :P\n"; - return -1; - } - - if(add_normals && compress) { - cerr << "Its not possible to add normals and compress in the same step\n" - << "Because normals requires 2 passes to be calculated\n\n"; - return -1; - } - - - - bool compute_cones = false; - if(!add && !remove && !compress && !uncompress && !zsort && - !qvertex && !qcolor && !qnormal && !qtexture && cone_threshold != 0) - compute_cones = true; - - - Nexus nexus; - - if(!nexus.Load(input, true)) { - cerr << "Could not open nexus file: " << input << "\n"; - return -1; - } - nexus.MaxRam() = ram_size / nexus.chunk_size; - - - //Sanity tests - if(remove_strips && !(nexus.signature.face != Signature::STRIPS)) { - cerr << "Nexus file does not have strips\n"; - return -1; - } - if(remove_colors && !nexus.signature.vcolor) { - cerr << "Nexus file does not have colors\n"; - return -1; - } - if(remove_normals && !nexus.signature.vnorm) { - cerr << "Nexus file does not have normals\n"; - return -1; - } - if(remove_textures && !nexus.signature.vtext) { - cerr << "Nexus file does not have textures\n"; - return -1; - } - if(remove_data && !nexus.signature.vdata) { - cerr << "Nexus file does not have data\n"; - return -1; - } - - if(add_strips && (nexus.signature.face == Signature::STRIPS)) { - cerr << "Nexus file already has strips\n"; - return -1; - } - if(add_colors && nexus.signature.vcolor) { - cerr << "Nexus file already has colors\n"; - return -1; - } - if(add_normals && nexus.signature.vnorm) { - cerr << "Nexus file already has normals\n"; - return -1; - } - if(add_textures && nexus.signature.vtext) { - cerr << "Nexus file already has textures\n"; - return -1; - } - if(add_data && nexus.signature.vdata) { - cerr << "Nexus file already has data\n"; - return -1; - } - - if(nexus.IsCompressed() && compress) { - cerr << "File already compressed.\n"; - return -1; - } - - if(!nexus.IsCompressed() && uncompress) { - cerr << "File not compressed.\n"; - return -1; - } - - - if(info) { - cout << "Nexus file: " << input << "\n"; - printInfo(nexus, verbose, dump_history); - } - - - //determine if we must proceed: - if(!add && !remove && !compress && !uncompress && !zsort && - qvertex == 0 && qnormal == 0 && qcolor == 0 && qtexture == 0 && - cone_threshold == 0) { - nexus.Close(); - return 0; - } - - if(compute_cones) {//just recalculate normal cones - cerr << "Unimplemented at the moment...\n"; - - /*vector cones; - // ComputeCones(Nexus &nexus, float cone_threshold); - nexus.Close(); - nexus.Load(intput, false); - for(unsigned int i = 0; i < nexus.size(); i++) { - nexus[i].cone = cones[i]; - }*/ - nexus.Close(); - return 0; - } - - CMesh mesh; - GridStaticPtr grid; - if(add_colors) { - if(!plysource.size()) { - cerr << "No plysource specified when adding color (-p option)\n"; - } else { - if(!tri::io::ImporterPLY::Open(mesh, plysource.c_str())) { - cerr << "Could not load ply: " << plysource << endl; - return -1; - } - //calcoliamo il box: - Box3f box; - for(unsigned int i = 0; i < mesh.vert.size(); i++) - box.Add(mesh.vert[i].P()); - grid.SetBBox(box); - grid.Set(mesh.face); - } - } - - Signature signature = nexus.signature; - if(add_strips) signature.face = Signature::STRIPS; - if(add_normals) signature.vnorm = add_normals; - if(add_colors) signature.vcolor = Encodings::BYTE4; - - if(remove_normals) signature.vnorm = 0; - if(remove_colors) signature.vcolor = 0; - - if(compress) signature.compr = Signature::LZO; - if(uncompress) signature.compr = 0; - - if(!output.size()) output = input + getSuffix(signature); - if(output == input) { - cerr << "Output and input files are the same.\n" - << "Use option -o \n" - << "You do not want to overwrite your data. Trust me.\n"; - return -1; - } - - cout << "Writing to nexus: " << output << endl; - - Nexus out; - - if(!chunk_size) - chunk_size = nexus.chunk_size; - - if(!out.Create(output, signature, chunk_size)) { - cerr << "Could not open output: " << output << endl; - return -1; - } - - //TODO fix this broken interface (you should not care abou chunk_size - out.MaxRam() = ram_size / out.chunk_size; - //TODO set rambuffer low (or even direct access!) - - vector forward; - vector backward; - if(zsort) - ZSort(nexus, forward, backward); - - //Fixing history - assert(nexus.history.IsQuick()); - - unsigned int hsize; - char *buffer = nexus.history.Save(hsize); - out.history.Load(hsize, buffer); - - - - if(zsort) { - assert(0); - //TODO FIX THIS... - /* if(out.history.IsQuick()) { - for(unsigned int i = 0; i < out.history.n_frags(); i++) - out.history.frags[i] = backward[out.history.frags[i]]; - } else { - for(unsigned int i = 0; i < out.history.updates.size(); i++) { - History::Update &update = out.history.updates[i]; - for(unsigned int k = 0; k < update.created.size(); k++) - update.created[k] = backward[update.created[k]]; - - for(unsigned int k = 0; k < update.erased.size(); k++) - update.erased[k] = backward[update.erased[k]]; - } - }*/ - } - - Report report(nexus.size()); - cout << "Copying and allocating...\n"; - for(unsigned int p = 0; p < nexus.size(); p++) { - unsigned int patch = p; - report.Step(patch); - - if(zsort) patch = forward[patch]; - - Entry &src_entry = nexus[patch]; - Patch &src_patch = nexus.GetPatch(patch); - Border &src_border = nexus.GetBorder(patch); - - - vector strip; - if(add_strips) { - ComputeTriStrip(src_patch.nf, src_patch.FaceBegin(), strip); - assert(strip.size() < 65000); - out.AddPatch(src_entry.nvert, strip.size(), src_border.Capacity()); - if(verbose) { - cerr << "tri: " << src_patch.nf << " strip: " << strip.size() - << " ratio: " << (float)strip.size()/(float)src_patch.nf - << endl; - } - } else - out.AddPatch(src_entry.nvert, src_entry.nface, src_border.Capacity()); - - - Entry &dst_entry = out[p]; - Patch &dst_patch = out.GetPatch(p); - - //copy vertices: - assert(out.signature.vert == Signature::POINT3F); - assert(out.signature.vert = nexus.signature.vert); - memcpy(dst_patch.Vert3fBegin(), src_patch.Vert3fBegin(), - src_patch.nv * sizeof(Point3f)); - - if(qvertex && !add_normals) { - float *ptr = (float *)dst_patch.Vert3fBegin(); - for(int i = 0; i < dst_patch.nv*3; i++) - ptr[i] = qvertex * (int)(ptr[i]/qvertex); - } - - - //now faces. - if(add_strips) { - assert(out.signature.face == Signature::STRIPS); - memcpy(dst_patch.FaceBegin(), &*strip.begin(), - strip.size() * sizeof(short)); - } else { - assert(nexus.signature.face == out.signature.face); - if(nexus.signature.face == Signature::STRIPS) { - memcpy(dst_patch.FaceBegin(), src_patch.FaceBegin(), - src_patch.nf * sizeof(unsigned short)); - } else if(nexus.signature.face == Signature::TRIANGLES) { - memcpy(dst_patch.FaceBegin(), src_patch.FaceBegin(), - src_patch.nf * sizeof(unsigned short) * 3); - } else { - assert(0); - } - } - - if(nexus.signature.vcolor) { - if(nexus.signature.vcolor == out.signature.vcolor) { - memcpy(dst_patch.VColorBegin(), src_patch.VColorBegin(), - Patch::encodings[out.signature.vcolor].size(dst_patch.nv)); - } else { - assert(0); - } - } - - if(nexus.signature.vnorm) { - if(nexus.signature.vnorm == out.signature.vnorm) { - memcpy(dst_patch.VNormBegin(), src_patch.VNormBegin(), - Patch::encodings[out.signature.vnorm].size(dst_patch.nv)); - } else { - assert(0); - } - } - - //copying entry information; - dst_entry.sphere = src_entry.sphere; - dst_entry.error = src_entry.error; - dst_entry.cone = src_entry.cone; - - out.borders.ResizeBorder(p, src_border.Size()); - Border &dst_border = out.GetBorder(p); - memcpy(dst_border.Start(), src_border.Start(), - src_border.Size() * sizeof(Link)); - //TODO test this - if(zsort) - for(unsigned i = 0; i < dst_border.Size(); i++) - dst_border[i].end_patch = backward[dst_border[i].end_patch]; - - } - report.Finish(); - - //TODO this is ok only if we have faces still! - if(add_normals) { - cout << "Computing normals" << endl; - ComputeNormals(out); - } - - if(add_colors) { - // if(!plysource.size()) - //source of color: - // cerr << "Unsupported color\n"; - // return -1; - } - - if(qvertex && add_normals) { - report.Init(nexus.size()); - cout << "Quantizing vertices\n"; - for(unsigned int patch = 0; patch < nexus.size(); patch++) { - report.Step(patch); - Patch src_patch = nexus.GetPatch(patch); - - float *ptr = (float *)src_patch.Vert3fBegin(); - for(int i = 0; i < src_patch.nv*3; i++) - ptr[i] = qvertex * (int)(ptr[i]/qvertex); - } - report.Finish(); - } - - out.sphere = nexus.sphere; - - out.Close(); - nexus.Close(); - return 0; -} - - -void printInfo(Nexus &nexus, bool verbose, bool dump_history) { - //perform locality statistics - double meandist = 0; - vcg::Sphere3f last = nexus[0].sphere; - for(unsigned int i = 1; i < nexus.size(); i++) { - vcg::Sphere3f &sphere = nexus[i].sphere; - double dist = vcg::Distance(last.Center(), sphere.Center()); - meandist += dist; - last = sphere; - } - meandist /= nexus.size() -1; - cout << "\n\tCompressed: " << nexus.IsCompressed() - << "\n\tStripped : " - << (int)(nexus.signature.face == Signature::STRIPS) - << "\n\tColor : " << (int)(nexus.signature.vcolor) - << "\n\tNormal : " << (int)(nexus.signature.vnorm) - << "\n\tTexture : " << (int)(nexus.signature.vtext) - << "\n\tData : " << (int)(nexus.signature.vdata) - << "\n\n\tVertices: " << nexus.totvert - << "\tFaces : " << nexus.totface - << "\tPatches : " << nexus.size() - << "\n\tSphere : " - << nexus.sphere.Center()[0] << " " - << nexus.sphere.Center()[1] << " " - << nexus.sphere.Center()[2] << " R: " - << nexus.sphere.Radius() - << "\n\tAverage distance: " << meandist - << "\n\tChunk size " << nexus.chunk_size << endl; - - if(dump_history) { - if(nexus.history.IsQuick()) { - cout << "Quick format\n"; - for(unsigned int i = 0; i < nexus.history.n_nodes(); i++) { - cout << "Node: " << i << " out: "; - History::Node node = nexus.history.nodes[i]; - for(History::Link *l = node.out_begin; l != node.out_end; l++) { - cout << "."; - for(unsigned int p = l->begin; p != l->end; p++) { - cout << p << " "; - } - } - cout << " in: "; - for(History::Link *j = node.in_begin; j != node.in_end; j++) { - cout << "."; - for(unsigned int p = j->begin; p != j->end; p++) { - cout << p << " "; - } - } - cout << endl; - } - - } else { - cout << "Update format\n"; - for(unsigned int i = 0; i < nexus.history.updates.size(); i++) { - History::Update &update = nexus.history.updates[i]; - cout << "Created: "; - for(unsigned int k = 0; k < update.created.size(); k++) { - cout << update.created[k] << " "; - } - cout << "\nErased: "; - for(unsigned int k = 0; k < update.erased.size(); k++) { - cout << update.erased[k] << " "; - } - cout << "\n\n"; - } - } - } - - if(verbose) { - for(unsigned int i = 0; i < nexus.size(); i++) { - Entry &entry = nexus[i]; - cout << i << " -> nv: " << entry.nvert << " nf: " << entry.nface - << " error: " << entry.error - << " disk_size: " << entry.disk_size - << " start: " << entry.patch_start << endl; - cout << " Cone: " << entry.cone.n[0] << " " - << entry.cone.n[1] << " " - << entry.cone.n[2] << " " - << entry.cone.n[3] << "\n"; - - } - cout << endl; - } -} diff --git a/apps/nexus/nxsexport.h b/apps/nexus/nxsexport.h deleted file mode 100644 index a38bacc8..00000000 --- a/apps/nexus/nxsexport.h +++ /dev/null @@ -1,119 +0,0 @@ -#ifndef NXS_EXPORT_H -#define NXS_EXPORT_H - -#include -#include -#include "nexus.h" -#include "extraction.h" - -namespace nxs { - -template void ExportTriMesh(Nexus &nexus, - vector &patches, - MESH &mesh) { - - - typedef typename MESH::VertexType VertexType; - typedef typename MESH::FaceType FaceType; - typedef typename MESH::ScalarType ScalarType; - //for every patch record the global position of the vertices - std::map > remap; - - //Resize all remapping vectors - for(unsigned int p = 0; p < patches.size(); p++) { - unsigned int npatch = patches[p]; - remap[npatch].resize(nexus[npatch].nvert, 0xffffffff); - } - - //Filling remapping vectors - unsigned int vcount = 0; - for(unsigned int p = 0; p < patches.size(); p++) { - unsigned int npatch = patches[p]; - Patch &patch = nexus.GetPatch(npatch); - - std::vector &rmp = remap[npatch]; - - for(unsigned int v = 0; v < patch.nv; v++) - if(rmp[v] == 0xffffffff) - rmp[v] = vcount++; - - Border &border = nexus.GetBorder(npatch); - for(unsigned int k = 0; k < border.Size(); k++) { - Link link = border[k]; - if(link.IsNull()) continue; - - if(remap.count(link.end_patch)) //internal - if(remap[link.end_patch][link.end_vert] == 0xffffffff) - remap[link.end_patch][link.end_vert] = rmp[link.start_vert]; - } - } - - mesh.vert.resize(vcount); - mesh.VertexNumber() = vcount; - //copying vectors and faces - for(unsigned int p = 0; p < patches.size(); p++) { - unsigned int npatch = patches[p]; - Patch &patch = nexus.GetPatch(npatch); - - std::vector &rmp = remap[npatch]; - - //coping vertices - VertexType vertex; - vertex.ClearFlags(); - for(unsigned int v = 0; v < patch.nv; v++) { - vertex.P()[0] = (ScalarType)patch.Vert3f(v)[0]; - vertex.P()[1] = (ScalarType)patch.Vert3f(v)[1]; - vertex.P()[2] = (ScalarType)patch.Vert3f(v)[2]; - if(mesh.HasPerVertexNormal()) { - if(nexus.signature.vnorm == Encodings::SHORT4) { - vertex.N()[0] = (ScalarType)((short *)patch.VNormBegin())[v*4]; - vertex.N()[1] = (ScalarType)((short *)patch.VNormBegin())[v*4 +1]; - vertex.N()[2] = (ScalarType)((short *)patch.VNormBegin())[v*4 +2]; - } else if(nexus.signature.vnorm == Encodings::FLOAT3) { - vertex.N()[0] = (ScalarType)((float *)patch.VNormBegin())[v*3]; - vertex.N()[0] = (ScalarType)((float *)patch.VNormBegin())[v*3 +1]; - vertex.N()[0] = (ScalarType)((float *)patch.VNormBegin())[v*3 +2]; - } else if(nexus.signature.vnorm) { - //i should write other exporters - assert(0); - } - } - if(mesh.HasPerVertexColor() && nexus.signature.vcolor) { - if(nexus.signature.vcolor == Encodings::BYTE4) { - vertex.C()[0] = ((unsigned char *)patch.VColorBegin())[v*4]; - vertex.C()[1] = ((unsigned char *)patch.VColorBegin())[v*4+1]; - vertex.C()[2] = ((unsigned char *)patch.VColorBegin())[v*4+2]; - vertex.C()[3] = ((unsigned char *)patch.VColorBegin())[v*4+3]; - } else if(nexus.signature.vcolor) { - //i should write other exporters - assert(0); - } - } - if(mesh.HasPerVertexTexture() && nexus.signature.vtext) { - //i should write other exporters - assert(0); - } - assert(rmp[v] < mesh.vert.size()); - mesh.vert[rmp[v]] = vertex; - } - //remap faces now - FaceType face; - if(nexus.signature.face == Signature::TRIANGLES) { - for(unsigned int f = 0; f < patch.nf; f++) { - face.V(0) = &mesh.vert[rmp[patch.Face(f)[0]]]; - face.V(1) = &mesh.vert[rmp[patch.Face(f)[1]]]; - face.V(2) = &mesh.vert[rmp[patch.Face(f)[2]]]; - mesh.face.push_back(face); - mesh.SimplexNumber()++; - /*static bool HasPerFaceColor() {return FaceType::HasFaceColor() ;} - static bool HasPerFaceNormal() {return FaceType::HasFaceNormal();} - static bool HasPerFaceMark() {return FaceType::HasFaceMark() ;} - static bool HasPerFaceQuality(){return FaceType::HasFaceQuality();}*/ - } - } - } -} - -}//namespace - -#endif diff --git a/apps/nexus/nxspatcher.cpp b/apps/nexus/nxspatcher.cpp deleted file mode 100644 index 43f543c3..00000000 --- a/apps/nexus/nxspatcher.cpp +++ /dev/null @@ -1,48 +0,0 @@ -#include -#include "crude.h" -using namespace nxs; -using namespace vcg; -using namespace std; - -int main(int argc, char *argv[]) { - if(argc != 2) { - cerr << "Uso: " << argv[0] << " \n"; - return -1; - } - - unsigned int side = atoi(argv[1]); - if(side > 1000 || side == 0) { - cerr << "Invalid side: " << argv[1] << endl; - return -1; - } - - Crude crude; - if(!crude.Create("square")) { - cerr << "Could not create square" << endl; - return -1; - } - - int half = side/2; - crude.Resize(side * side, (side-1) * (side-1) * 2); - for(unsigned int x = 0; x < side; x++) - for(unsigned int y = 0; y < side; y++) { - // Point3f p(x*x*x/((float)side), - // y*y*y/((float)side), x*y/((float)side)); - Point3f p(x, y, sqrt((float)x*x + y*y)); - crude.SetVertex(x + side * y, p); - crude.GetBox().Add(p); - } - - for(unsigned int x = 0; x < side-1; x++) - for(unsigned int y = 0; y < side-1; y++) { - unsigned int pos = x + side*y; - Crude::Face face(pos, pos + 1, pos + side); - crude.SetFace(0 + 2*x + (side-1)*y*2, face); - - face = Crude::Face(pos + 1, pos + 1 + side, pos +side); - crude.SetFace(1 + 2*x + (side-1)*y*2, face); - } - - crude.Close(); - return 0; -} diff --git a/apps/nexus/nxsserver.cpp b/apps/nexus/nxsserver.cpp deleted file mode 100644 index a474f9d4..00000000 --- a/apps/nexus/nxsserver.cpp +++ /dev/null @@ -1,223 +0,0 @@ -/**************************************************************************** -* VCGLib o o * -* Visual and Computer Graphics Library o o * -* _ O _ * -* Copyright(C) 2004 \/)\/ * -* Visual Computing Lab /\/| * -* ISTI - Italian National Research Council | * -* \ * -* All rights reserved. * -* * -* This program is free software; you can redistribute it and/or modify * -* it under the terms of the GNU General Public License as published by * -* the Free Software Foundation; either version 2 of the License, or * -* (at your option) any later version. * -* * -* This program is distributed in the hope that it will be useful, * -* but WITHOUT ANY WARRANTY; without even the implied warranty of * -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * -* GNU General Public License (http://www.gnu.org/licenses/gpl.txt) * -* for more details. * -* * -****************************************************************************/ -/**************************************************************************** - History - -$Log: not supported by cvs2svn $ - -****************************************************************************/ -#include -#include -#include - - -#include "fragment.h" -#include "decimate.h" - -using namespace pt; -using namespace nxs; -using namespace vcg; -using namespace std; - - -class FragOutQueue: public msgqueue { -public: - FragOutQueue(ipstream &cli): client(cli) {} - void msghandler(message &msg) { - if(msg.id != MSG_USER) { - defhandler(msg); - return; - } - Fragment &fragment = *(Fragment *)(msg.param); - - // pout.putf("Sending: %d\n", fragment.id); - outmemory outm; - outm.open(); - fragment.Write(&outm); - pt::string a = outm.get_strdata(); - try { - client.write((const char *)a, length(a)); - client.flush(); - pout.putf("Sent fragment id: %d\n", fragment.id); - } catch (estream *e) { - perr.putf("Error: %s\n", pconst(e->get_message())); - delete e; - posturgent(MSG_QUIT); - } - delete (Fragment *)(msg.param); - } - ipstream &client; -}; - -class FragInQueue: public msgqueue { -public: - FragInQueue(FragOutQueue &o): out(o) {} - void msghandler(message &msg) { - if(msg.id != MSG_USER) { - if(msg.id == MSG_QUIT) - out.posturgent(MSG_QUIT); - defhandler(msg); - return; - } - Fragment &fragin = *(Fragment *)(msg.param); - // pout.putf("Processing: %d\n", fragin.id); - vector newvert; - vector newface; - vector newbord; - Join(fragin, newvert, newface, newbord); - - float error = Decimate(QUADRIC, - (unsigned int)((newface.size()/3) * 0.5), - newvert, newface, newbord); - - message *outmsg = new message(MSG_USER); - outmsg->param = (int)(new Fragment); - Fragment &fragout = *(Fragment *)(outmsg->param); - - fragout.error = error; - fragout.id = fragin.id; - fragout.seeds = fragin.seeds; - fragout.seeds_id = fragin.seeds_id; - Split(fragout, newvert, newface, newbord); - out.post(outmsg); - delete (Fragment *)(msg.param); - } - - FragOutQueue &out; -}; - - -class Reader: public thread { -public: - Reader(ipstream &cli, FragInQueue &que): - thread(false), client(cli), queue(que) {} - - ~Reader() {waitfor(); } - - void execute() { - while(1) { - if(get_signaled()) return; - message *msg = new message(MSG_USER); - msg->param = (int)(new Fragment); - Fragment &fragment = *(Fragment *)(msg->param); - if(!fragment.Read(&client)) { - pout.putf("Could not read!\n"); - queue.posturgent(MSG_QUIT); - return; - } - queue.post(msg); - // pout.putf("Incoming: %d\n", fragment.id); - } - } - void cleanup() {} - - ipstream &client; - FragInQueue &queue; -}; - -class Worker: public thread { -public: - Worker(FragInQueue &que): thread(false), queue(que) {} - ~Worker() { waitfor(); } - - void execute() { - queue.run(); - } - void cleanup() {} - FragInQueue &queue; -}; - -class Writer: public thread { -public: - Writer(FragOutQueue &que): thread(false), queue(que) {} - ~Writer() {waitfor(); } - void execute() { - queue.run(); - } - void cleanup() {} - FragOutQueue &queue; -}; - - -void servermain(ipstmserver& svr) { - ipstream client; - - while(true) { - // serve() will wait for a connection request and will prepare - // the supplied ipstream object for talking to the peer. - svr.serve(client); - perr.putf("Serving clients!\n"); - if (client.get_active()) { - try { - pout.putf("Incoming connection\n"); - FragOutQueue out(client); - FragInQueue in(out); - Reader reader(client, in); - Worker worker(in); - Writer writer(out); - - reader.start(); - worker.start(); - writer.start(); - - reader.waitfor(); - worker.waitfor(); - writer.waitfor(); - - client.flush(); - client.close(); - } catch(estream* e) { - perr.putf("Error: %s\n", pconst(e->get_message())); - delete e; - } - } - perr.putf("Restarting\n"); - } -} - -int main(int argc, char *argv[]) { - ipstmserver svr; - - int port = 10102; - if(argc == 2) { - port = atoi(argv[1]); - if(port < 1024) { - perr.putf("Error: invalid port: %s\n", argv[1]); - return -1; - } - } - - try { - // bind to all local addresses on port 8085 - svr.bindall(port); - - pout.putf("Ready to answer queries on port %d\n", port); - - // enter an infinite loop of serving requests - servermain(svr); - } catch(estream* e) { - perr.putf("FATAL: %s\n", pconst(e->get_message())); - delete e; - } - return 0; -} diff --git a/apps/nexus/nxstest.cpp b/apps/nexus/nxstest.cpp deleted file mode 100644 index 0461e185..00000000 --- a/apps/nexus/nxstest.cpp +++ /dev/null @@ -1,163 +0,0 @@ -/**************************************************************************** -* VCGLib o o * -* Visual and Computer Graphics Library o o * -* _ O _ * -* Copyright(C) 2004 \/)\/ * -* Visual Computing Lab /\/| * -* ISTI - Italian National Research Council | * -* \ * -* All rights reserved. * -* * -* This program is free software; you can redistribute it and/or modify * -* it under the terms of the GNU General Public License as published by * -* the Free Software Foundation; either version 2 of the License, or * -* (at your option) any later version. * -* * -* This program is distributed in the hope that it will be useful, * -* but WITHOUT ANY WARRANTY; without even the implied warranty of * -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * -* GNU General Public License (http://www.gnu.org/licenses/gpl.txt) * -* for more details. * -* * -****************************************************************************/ -/**************************************************************************** - History - -$Log: not supported by cvs2svn $ -Revision 1.5 2005/02/08 12:43:03 ponchio -Added copyright - - -****************************************************************************/ - -#include - -#include "nexus.h" -#include "watch.h" - -using namespace vcg; -using namespace std; -using namespace nxs; - -int main(int argc, char *argv[]) { - if(argc != 2) { - cerr << "Usage: " << argv[0] << " \n"; - return -1; - } - Nexus nexus; - if(!nexus.Load(argv[1], true)) { - cerr << "Could not open file: " << argv[1] << endl; - return -1; - } - Report report(nexus.size()); - for(unsigned int patchid = 0; patchid < nexus.size(); patchid++) { - report.Step(patchid); - Entry &info = nexus[patchid]; - Patch &patch = nexus.GetPatch(patchid); - for(int f = 0; f < patch.nf; f++) { - unsigned short *face = patch.Face(f); - for(int k = 0; k < 3; k++) { - if(face[k] > patch.nv) { - cerr << "Invalid face number: " << face[k] << " > " - << patch.nv << endl; - cerr << "At patch: " << patchid << endl; - cerr << "start: " << info.patch_start << endl; - cerr << "nf: " << info.nface << " nv: " << info.nvert << endl; - //exit(0); - } - } - } - Sphere3f &sphere = info.sphere; - for(int v = 0; v < patch.nv; v++) { - Point3f &p = patch.Vert3f(v); - float dist = Distance(sphere, p); - if(dist > 0.001) { - //if(!info.sphere.IsIn(p)) { - cerr << "Vertex outside bound: (" << p[0] << " " << p[1] << " " << p[2] << ")\n"; - Point3f &c = sphere.Center(); - cerr << "Sphere: (" << c[0] << " " << c[1] << " " << c[2] << ") R: " << sphere.Radius() << endl;; - cerr << "Distance: " << dist << endl; - cerr << "At patch: " << patchid << endl; - - } - } - } - report.Finish(); - - cerr << "Testing borders\n"; - - for(unsigned int patchid = 0; patchid < nexus.size(); patchid++) { - Entry &info = nexus[patchid]; - Border &border = nexus.GetBorder(patchid); - for(unsigned int i = 0; i < border.Size(); i++) { - Link &link = border[i]; - if(link.start_vert == 0 && link.end_vert == 0 && link.end_patch == 0) { - cerr << "patch: " << patchid << " corrupted memory?" << endl; - } - if(link.IsNull()) { - cerr << "Null link: " << i << " at patch: " << patchid << endl; - exit(0); - } - if(link.end_patch < 0 || link.end_patch >= nexus.size()) { - cerr << "Invalid link end patch: " << link.end_patch << " at patch: " << patchid << endl; - exit(0); - } - if(link.start_vert > info.nvert) { - cerr << "Invalid link start_vert: " << link.start_vert << " at patch: " << patchid << endl; - exit(0); - } - if(link.end_vert > nexus[link.end_patch].nvert) { - cerr << "Invalid link end vert: " << link.end_vert << " at patch: " << patchid << endl; - exit(0); - } - } - } - - cerr << "Reciprocity borders test\n"; - for(unsigned int patchid = 0; patchid < nexus.size(); patchid++) { - Entry &info = nexus[patchid]; - Border &border = nexus.GetBorder(patchid); - vector links; - links.resize(border.Size()); - memcpy(&*links.begin(),&(border[0]),links.size() * sizeof(Link)); - for(unsigned int i = 0; i < links.size(); i++) { - Link &link = links[i]; - Border &rborder = nexus.GetBorder(link.end_patch, false); - - bool found = false; - for(unsigned int k = 0; k < rborder.Size(); k++) { - Link rlink = rborder[k]; - if(rlink.end_patch == patchid) { - - if(rlink.end_vert == link.start_vert) { - if(rlink.start_vert != link.end_vert) { - cerr << "Something wrong with links!\n"; - exit(0); - } - found = true; - break; - } - if(rlink.start_vert == link.end_vert) { - if(rlink.end_vert != link.start_vert) { - cerr << "Something wrong with links!\n"; - exit(0); - } - found = true; - break; - } - } - } - if(!found) { - cerr << "A link is one way from patch: " << patchid << " vert: " << link.start_vert - << " to patch: " << link.end_patch << " vert: " << link.end_vert << endl; - for(unsigned int t = 0; t < rborder.Size(); t++) { - Link &rlink = rborder[t]; - cerr << rlink.start_vert << " -> p: " << rlink.end_patch << " v: " << rlink.end_vert << endl; - } - exit(0); - } - } - } - - return 0; -} diff --git a/apps/nexus/nxstypes.h b/apps/nexus/nxstypes.h deleted file mode 100644 index 66032183..00000000 --- a/apps/nexus/nxstypes.h +++ /dev/null @@ -1,43 +0,0 @@ -/**************************************************************************** -* VCGLib o o * -* Visual and Computer Graphics Library o o * -* _ O _ * -* Copyright(C) 2004 \/)\/ * -* Visual Computing Lab /\/| * -* ISTI - Italian National Research Council | * -* \ * -* All rights reserved. * -* * -* This program is free software; you can redistribute it and/or modify * -* it under the terms of the GNU General Public License as published by * -* the Free Software Foundation; either version 2 of the License, or * -* (at your option) any later version. * -* * -* This program is distributed in the hope that it will be useful, * -* but WITHOUT ANY WARRANTY; without even the implied warranty of * -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * -* GNU General Public License (http://www.gnu.org/licenses/gpl.txt) * -* for more details. * -* * -****************************************************************************/ -/**************************************************************************** - History - -$Log: not supported by cvs2svn $ - -****************************************************************************/ - -#ifndef NXS_TYPES_H -#define NXS_TYPES_H - -#ifdef WIN32 -typedef __int64 int64; -#else -typedef unsigned long long int64; -//typedef unsigned long long uint64; -#endif - -typedef int int32; -typedef unsigned int uint32; - -#endif diff --git a/apps/nexus/patch.cpp b/apps/nexus/patch.cpp deleted file mode 100644 index 5320b688..00000000 --- a/apps/nexus/patch.cpp +++ /dev/null @@ -1,386 +0,0 @@ -/**************************************************************************** -* VCGLib o o * -* Visual and Computer Graphics Library o o * -* _ O _ * -* Copyright(C) 2004 \/)\/ * -* Visual Computing Lab /\/| * -* ISTI - Italian National Research Council | * -* \ * -* All rights reserved. * -* * -* This program is free software; you can redistribute it and/or modify * -* it under the terms of the GNU General Public License as published by * -* the Free Software Foundation; either version 2 of the License, or * -* (at your option) any later version. * -* * -* This program is distributed in the hope that it will be useful, * -* but WITHOUT ANY WARRANTY; without even the implied warranty of * -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * -* GNU General Public License (http://www.gnu.org/licenses/gpl.txt) * -* for more details. * -* * -****************************************************************************/ -/**************************************************************************** - History - -$Log: not supported by cvs2svn $ -Revision 1.13 2005/02/22 10:38:15 ponchio -Debug, cleaning and optimization. - -Revision 1.12 2005/02/21 19:05:58 ponchio -i already fixed this bug. I hate you cvs. - -Revision 1.11 2005/02/19 12:06:55 ponchio -Debug... - -Revision 1.10 2005/02/19 10:45:05 ponchio -Patch generalized and small fixes. - -Revision 1.9 2005/02/08 12:43:03 ponchio -Added copyright - - -****************************************************************************/ - -#include "patch.h" -#ifdef WIN32 -#include "minilzo.108/minilzo.h" -#else -#include -#endif -#include -using namespace std; -using namespace nxs; - -#ifdef WIN32 -static double wrkmem[LZO1X_1_MEM_COMPRESS/sizeof(double) +1]; -#else -static double wrkmem[LZO1X_999_MEM_COMPRESS/sizeof(double) +1]; -#endif - - -Encodings Patch::encodings; - -Encodings::Encodings() { - for(unsigned int i = 0; i < 17; i++) { - e[i].bytes = 0; - e[i].comps = 0; - e[i].pack = NULL; - e[i].unpack = NULL; - } - e[1].bytes = 1; - e[2].bytes = 2; - e[3].bytes = 4; - e[4].bytes = 8; - e[1].comps = e[2].comps = e[3].comps = e[4].comps = 1; - e[5].bytes = 1; - e[6].bytes = 2; - e[7].bytes = 4; - e[8].bytes = 8; - e[5].comps = e[6].comps = e[7].comps = e[8].comps = 2; - e[9].bytes = 1; - e[10].bytes = 2; - e[11].bytes = 4; - e[12].bytes = 8; - e[9].comps = e[10].comps = e[11].comps = e[12].comps = 3; - e[13].bytes = 1; - e[14].bytes = 2; - e[15].bytes = 4; - e[16].bytes = 8; - e[13].comps = e[14].comps = e[15].comps = e[16].comps = 4; -} - - -void pad8(unsigned int &s) { - if((s & 0x00000007) != 0) { - s>>=3; s++; s<<=3; - } -} -void pad(unsigned int &size) { - while(size&0x3) size++; -} - -void shuffle(float *buffer, unsigned int size, unsigned int stride) { - float *tmp = new float[size]; - unsigned int count = 0; - - unsigned int nelem = size/stride; - for(unsigned int s = 0; s < stride; s++) { - float *ptr = buffer + s; - for(unsigned int i = 0; i < nelem; i++) { - tmp[count++] = *ptr; - ptr += stride; - } - } - memcpy(buffer, tmp, size * sizeof(float)); - delete []tmp; -} - -void unshuffle(float *buffer, unsigned int size, unsigned int stride) { - float *tmp = new float[size]; - - unsigned int count = 0; - unsigned int nelem = size/stride; - for(unsigned int s = 0; s < stride; s++) { - float *ptr = tmp + s; - for(unsigned int i = 0; i < nelem; i++) { - *ptr = buffer[count++]; - ptr += stride; - } - } - memcpy(buffer, tmp, size * sizeof(float)); - delete []tmp; -} - -void subtract(float *buffer, unsigned int size) { - float p = buffer[0]; - float q; - for(unsigned int i = 1; i < size; i++) { - q = buffer[i]; - buffer[i] -= p; - p = q; - } -} - -void unsubtract(float *buffer, unsigned int size) { - for(unsigned int i = 1; i < size; i++) - buffer[i] += buffer[i-1]; -} - - -Patch::Patch(Signature &signature, char *s, - unsigned short nvert, unsigned short nface): - fstart(s) { - Init(signature, nvert, nface); -} - -void Patch::Init(Signature &signature, - unsigned short nvert, unsigned short nface) { - nv = nvert; - nf = nface; - - unsigned int offset = 0; - - if(signature.face == Signature::TRIANGLES) - offset += nf * 3 * sizeof(unsigned short); - else if (signature.face == Signature::STRIPS) - offset += nf * sizeof(unsigned short); - else if (signature.face == Signature::TETRAS) - offset += nf * 4 * sizeof(unsigned short); - else if (signature.face == Signature::SLICE) { - assert(0); - //non lo so... - } - pad8(offset); - - fstartc = fstart + offset; - offset += encodings[signature.fcolor].size(nf); - fstartn = fstart + offset; - offset += encodings[signature.fnorm].size(nf); - fstartt = fstart + offset; - offset += encodings[signature.ftext].size(nf); - fstartd = fstart + offset; - offset += encodings[signature.fdata].size(nf); - - vstart = fstart + offset; - if(signature.vert == Signature::POINT3F) - offset += nv * sizeof(float) * 3; - else if(signature.vert == Signature::POINT4F) - offset += nv * sizeof(float) * 4; - else - assert(0); - pad8(offset); - - vstartc = fstart + offset; - offset += encodings[signature.vcolor].size(nv); - vstartn = fstart + offset; - offset += encodings[signature.vnorm].size(nv); - vstartt = fstart + offset; - offset += encodings[signature.vtext].size(nv); - vstartd = fstart + offset; - offset += encodings[signature.vdata].size(nv); - - - /* if(signature & NXS_FACES) - vstart = (float *)(((char *)start) + nf * sizeof(unsigned short) * 3); - else if(signature & NXS_STRIP) - vstart = (float *)(((char *)start) + nf * sizeof(unsigned short)); - else - vstart = (float *)start; - - //align memory - if(((int)vstart) & 0x2) vstart = (float *)(((char *)vstart) + 2); - - cstart = nv * 3; - if(signature & NXS_COLORS) - nstart = cstart + nv; - else - nstart = cstart; - - if(signature & NXS_NORMALS_SHORT) - tstart = nstart + nv * 2; - else if(signature & NXS_NORMALS_FLOAT) - tstart = nstart + nv * 3; - else - tstart = nstart; - - if(signature & NXS_TEXTURES_SHORT) - dstart = tstart + nv; - else if(signature & NXS_TEXTURES_FLOAT) - dstart = tstart + nv; - else - dstart = tstart;*/ -} - -unsigned int Patch::ChunkSize(Signature &signature, - unsigned short nvert, - unsigned short nface, - unsigned int chunk_size) { - unsigned int size = ByteSize(signature, nvert, nface); - size = (size/chunk_size + 1); - return size; -} - -unsigned int Patch::ByteSize(Signature &signature, - unsigned short nvert, - unsigned short nface) { - - unsigned int size = 0; - if(signature.face == Signature::TRIANGLES) - size += nface * 3 * sizeof(unsigned short); - else if (signature.face == Signature::STRIPS) - size += nface * sizeof(unsigned short); - else if (signature.face == Signature::TETRAS) - size += nface * 4 * sizeof(unsigned short); - else if (signature.face == Signature::SLICE) { - assert(0); - //non lo so... - } - pad8(size); - - size += encodings[signature.fcolor].size(nface); - size += encodings[signature.fnorm].size(nface); - size += encodings[signature.ftext].size(nface); - size += encodings[signature.fdata].size(nface); - - if(signature.vert == Signature::POINT3F) - size += nvert * sizeof(float) * 3; - else if(signature.vert == Signature::POINT4F) - size += nvert * sizeof(float) * 4; - else - assert(0); - pad8(size); - - size += encodings[signature.vcolor].size(nvert); - size += encodings[signature.vnorm].size(nvert); - size += encodings[signature.vtext].size(nvert); - size += encodings[signature.vdata].size(nvert); - - //this condition should really rarely happen but helps save space - //during construction - if(size < nface * 3 * sizeof(unsigned int)) - size = nface * 3 * sizeof(unsigned int); - - return size; - - - /* unsigned int size = 0; - if(signature & NXS_STRIP) - size += nface * sizeof(unsigned short); - else if(signature & NXS_FACES) - size += nface * 3 * sizeof(unsigned short); - - //memory alignment - pad(size); - - size += nvert * sizeof(vcg::Point3f); - - if(signature & NXS_COLORS) - size += nvert * sizeof(unsigned int); - - if(signature & NXS_NORMALS_SHORT) - size += nvert * 4 * sizeof(short); - - if(signature & NXS_NORMALS_FLOAT) - size += nvert * 3 * sizeof(float); - - if(signature & NXS_TEXTURES_SHORT) - size += nvert * 2 * sizeof(short); - - if(signature & NXS_TEXTURES_FLOAT) - size += nvert * 2 * sizeof(float); - - if(signature & NXS_DATA8) - size += nvert * sizeof(char); - pad(size); - if(signature & NXS_DATA16) - size += nvert * 2 * sizeof(char); - pad(size); - if(signature & NXS_DATA32) - size += nvert * 4 * sizeof(char); - if(signature & NXS_DATA64) - size += nvert * 8 * sizeof(char); - - - //this condition should really rarely happen but helps save space - //during construction - if(size < nface * 3 * sizeof(unsigned int)) - size = nface * 3 * sizeof(unsigned int); - - return size;*/ -} - - -char *Patch::Compress(unsigned int ram_size, unsigned int &size) { - - //lets use differences - // shuffle((float *)VertBegin(), nv * 3, 3); - // subtract((float *)VertBegin(), nv * 3); - - //TODO use OVERLAP and test speed - //TODO fill chunk padding with zeroes? - size = ram_size + ram_size/64 + 23; - char *buffer = new char[size]; -#ifdef WIN32 - lzo1x_1_compress(((unsigned char *)fstart), ram_size, - (unsigned char *)buffer + sizeof(int), &size, - (char *)wrkmem); -#else - lzo1x_999_compress(((unsigned char *)fstart), ram_size, - (unsigned char *)buffer + sizeof(int), &size, - (char *)wrkmem); - - lzo1x_optimize((unsigned char *)buffer + sizeof(int), size, - ((unsigned char *)fstart), &ram_size, - NULL); -#endif - - *(int *)buffer = size; - size += sizeof(int); - - // memcpy(buffer, start, ram_size); - // size = ram_size; - - return buffer; - -} - -void Patch::Decompress(unsigned int ram_size, void *src, unsigned int src_sz) { - - unsigned int size = *(int *)src; - assert(size < src_sz + sizeof(int)); - unsigned int dst_size = ram_size; - - int ret = lzo1x_decompress_safe(((unsigned char *)src) + sizeof(int), size, - (unsigned char *)fstart, &dst_size, 0); - if(ret != 0) { - cerr << "Ret from decompress: " << ret << endl; - exit(-1); - } - assert(dst_size == ram_size); - //TODO add 3 to start... so we can use asm_fast decompressor - - // unsubtract((float *)VertBegin(), nv * 3); - // unshuffle((float *)VertBegin(), nv * 3, 3); -} - diff --git a/apps/nexus/patch.h b/apps/nexus/patch.h deleted file mode 100644 index da77b2b9..00000000 --- a/apps/nexus/patch.h +++ /dev/null @@ -1,169 +0,0 @@ -/**************************************************************************** -* VCGLib o o * -* Visual and Computer Graphics Library o o * -* _ O _ * -* Copyright(C) 2004 \/)\/ * -* Visual Computing Lab /\/| * -* ISTI - Italian National Research Council | * -* \ * -* All rights reserved. * -* * -* This program is free software; you can redistribute it and/or modify * -* it under the terms of the GNU General Public License as published by * -* the Free Software Foundation; either version 2 of the License, or * -* (at your option) any later version. * -* * -* This program is distributed in the hope that it will be useful, * -* but WITHOUT ANY WARRANTY; without even the implied warranty of * -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * -* GNU General Public License (http://www.gnu.org/licenses/gpl.txt) * -* for more details. * -* * -****************************************************************************/ -/**************************************************************************** - History - -$Log: not supported by cvs2svn $ -Revision 1.13 2005/02/19 12:06:55 ponchio -Debug... - -Revision 1.12 2005/02/19 10:45:05 ponchio -Patch generalized and small fixes. - -Revision 1.11 2005/02/08 12:43:03 ponchio -Added copyright - - -****************************************************************************/ - -#ifndef NXS_PATCH_H -#define NXS_PATCH_H - -#include -#include - -namespace nxs { - - struct Signature { - - enum Face { TRIANGLES = 1, STRIPS = 2, TETRAS = 3, SLICE = 4 }; - - enum Vert { POINT2F = 1, POINT2D = 2, - POINT3F = 2, POINT3D = 3, - POINT4F = 4, POINT4D = 5 }; - - enum Compr { LZO = 1 }; - - unsigned char face; - unsigned char vert; - unsigned char compr; - unsigned char future; //who knows... - - unsigned char fcolor; - unsigned char fnorm; - unsigned char ftext; - unsigned char fdata; - - unsigned char vcolor; - unsigned char vnorm; - unsigned char vtext; - unsigned char vdata; - - Signature(): face(1), vert(2), compr(0), future(0), - fcolor(0), fnorm(0), ftext(0), fdata(0), - vcolor(0), vnorm(0), vtext(0), vdata(0) {} - }; - - - struct Encoding { - - unsigned char bytes; //size per element - unsigned char comps; //number of components - void (*pack)(char *start, unsigned int nelem); - void (*unpack)(char *start, unsigned int nelem); - - unsigned int size(unsigned short n) { - unsigned int s = (int)n * (int)bytes * (int)comps; - //padding a 8 bytes - if((s & 0x0000007) != 0) { - s>>=3; s++; s<<=3; - } - return s; - } - }; - - struct Encodings { - enum Name { EMPTY = 0, - BYTE1 = 1, SHORT1 = 2, FLOAT1 = 3, DOUBLE1 = 4, - BYTE2 = 5, SHORT2 = 6, FLOAT2 = 7, DOUBLE2 = 8, - BYTE3 = 9, SHORT3 = 10, FLOAT3 = 11, DOUBLE3 = 12, - BYTE4 = 13, SHORT4 = 14, FLOAT4 = 15, DOUBLE4 = 16 }; - Encodings(); - Encoding &operator[](int n) { return e[n]; } - protected: - Encoding e[17]; - - - }; - -class Patch { - public: - - static Encodings encodings; - - Patch(Signature &signature, char *s, - unsigned short nv, unsigned short nf); - - void Init(Signature &signature, unsigned short nv, unsigned short nf); - - vcg::Point3f *Vert3fBegin() { return (vcg::Point3f *)vstart; } - vcg::Point3f &Vert3f(int n) { return Vert3fBegin()[n]; } - unsigned short *FaceBegin() { return (unsigned short *)fstart; } - unsigned short *Face(int n) { return FaceBegin() + 3 * n; } - - //vcg::Point3f &Vert(unsigned short v) { return VertBegin()[v]; } - // unsigned short *Face(unsigned short f) { return FaceBegin() + f * 3; } - - char *VColorBegin() { return vstartc; } - char *VNormBegin() { return vstartn; } - char *VTextBegin() { return vstartt; } - char *VDataBegin() { return vstartd; } - - char *FColorBegin() { return fstartc; } - char *FNormBegin() { return fstartn; } - char *FTextBegin() { return fstartt; } - char *FDataBegin() { return fstartd; } - - static unsigned int ChunkSize(Signature &signature, - unsigned short nvert, - unsigned short nface, - unsigned int chunk_size); - - static unsigned int ByteSize(Signature &signature, - unsigned short nvert, - unsigned short nface); - - char *Compress(unsigned int ram_size, unsigned int &size); - void Decompress(unsigned int ram_size, void *src, unsigned int src_sz); - - - char *fstart; - char *vstart; - - unsigned short nf; - unsigned short nv; - - char *fstartc; - char *fstartn; - char *fstartt; - char *fstartd; - - char *vstartc; - char *vstartn; - char *vstartt; - char *vstartd; -}; - -} //namespace - -#endif diff --git a/apps/nexus/ply2crude.cpp b/apps/nexus/ply2crude.cpp deleted file mode 100644 index ef6e71a2..00000000 --- a/apps/nexus/ply2crude.cpp +++ /dev/null @@ -1,167 +0,0 @@ -/**************************************************************************** -* VCGLib o o * -* Visual and Computer Graphics Library o o * -* _ O _ * -* Copyright(C) 2004 \/)\/ * -* Visual Computing Lab /\/| * -* ISTI - Italian National Research Council | * -* \ * -* All rights reserved. * -* * -* This program is free software; you can redistribute it and/or modify * -* it under the terms of the GNU General Public License as published by * -* the Free Software Foundation; either version 2 of the License, or * -* (at your option) any later version. * -* * -* This program is distributed in the hope that it will be useful, * -* but WITHOUT ANY WARRANTY; without even the implied warranty of * -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * -* GNU General Public License (http://www.gnu.org/licenses/gpl.txt) * -* for more details. * -* * -****************************************************************************/ -/**************************************************************************** - History - -$Log: not supported by cvs2svn $ -Revision 1.3 2004/07/15 14:32:49 ponchio -Debug. - -Revision 1.2 2004/07/05 15:49:39 ponchio -Windows (DevCpp, mingw) port. - -Revision 1.1 2004/07/04 15:30:00 ponchio -Changed directory structure. - -Revision 1.2 2004/07/02 13:09:57 ponchio -*** empty log message *** - -Revision 1.1 2004/06/23 00:08:05 ponchio -Created - - -****************************************************************************/ - -///TODO: allow other kinds of ply to be readed. - -#include -#include -#include -#include "crude.h" - -using namespace std; -using namespace vcg; -using namespace vcg::ply; -using namespace nxs; - -struct PlyVertex { - float v[3]; -}; - -struct PlyFace { - unsigned int f[3]; - unsigned char flags; -}; - -PropDescriptor plyprop1[3]= { - {"vertex","x",T_FLOAT,T_FLOAT,offsetof(PlyVertex,v[0]),0,0,0,0,0}, - {"vertex","y",T_FLOAT,T_FLOAT,offsetof(PlyVertex,v[1]),0,0,0,0,0}, - {"vertex","z",T_FLOAT,T_FLOAT,offsetof(PlyVertex,v[2]),0,0,0,0,0} -}; - -PropDescriptor plyprop2[1]= { - {"face", "vertex_indices",T_INT,T_UINT,offsetof(PlyFace,f[0]), - 1,0,T_UCHAR,T_UCHAR,offsetof(PlyFace,flags) } -}; - -int main(int argc, char *argv[]) { - if(argc <= 2) { - cerr << "Usage: " << argv[0] << " <...> \n"; - return 0; - } - string output = argv[argc-1]; - //test last one is not a ply - if(output.size() > 4 && - output.substr(output.size()-4, output.size()) == ".ply") { - cerr << "Last argument is output (so not a .ply)\n"; - return -1; - } - Crude crude; - if(!crude.Create(output, 0, 0)) { - cerr << "Could not create crude output\n"; - return -1; - } - Box3f box; - box.SetNull(); - for(int k = 1; k < argc-1; k++) { - PlyFile pf; - //Opening ply file - int val = pf.Open(argv[k], PlyFile::MODE_READ); - if(val == -1) { - cerr << "Could not open file '" << argv[k] << "'\n"; - return false; - } - - //testing for required vertex fields. - if( pf.AddToRead(plyprop1[0])==-1 || - pf.AddToRead(plyprop1[1])==-1 || - pf.AddToRead(plyprop1[2])==-1) { - cerr << "Error Ply file has not one of the required elements :" - << "xyz coords\n"; - return false; - } - - //testing for required face fields. - if( pf.AddToRead(plyprop2[0])==-1 ) { - cerr << "Error Ply file has not one of the required elements:" - << "faces\n"; - return false; - } - - unsigned int vertex_offset = crude.Vertices(); - for(unsigned int i = 0; i < pf.elements.size(); i++) { - if(!strcmp( pf.ElemName(i),"vertex")) { - unsigned int n_vertices = pf.ElemNumber(i); - unsigned int offset = crude.Vertices(); - crude.Resize(offset + n_vertices, crude.Faces()); - - cerr << "Adding " << n_vertices << " n_vertices" << endl; - pf.SetCurElement(i); - PlyVertex vertex; - Point3f p; - for(unsigned v = offset; v < offset + n_vertices; v++) { - pf.Read((void *) &vertex); - p[0] = vertex.v[0]; - p[1] = vertex.v[1]; - p[2] = vertex.v[2]; - box.Add(p); - crude.SetVertex(v, vertex.v); - } - - } else if( !strcmp( pf.ElemName(i),"face") ) { - unsigned int n_faces = pf.ElemNumber(i); - unsigned int offset = crude.Faces(); - crude.Resize(crude.Vertices(), offset + n_faces); - - cerr << "Adding " << n_faces << " n_faces" << endl; - pf.SetCurElement(i); - PlyFace face; - for(unsigned v = offset; v < offset + n_faces; v++) { - pf.Read((void *) &face); - face.f[0] += vertex_offset; - face.f[1] += vertex_offset; - face.f[2] += vertex_offset; - assert(face.f[0] < crude.Vertices() && - face.f[1] < crude.Vertices() && - face.f[2] < crude.Vertices()); - - crude.SetFace(v, face.f); - } - } - } - pf.Destroy(); - } - crude.GetBox() = box; - - return 0; -} diff --git a/apps/nexus/preload.cpp b/apps/nexus/preload.cpp deleted file mode 100644 index 1dbea185..00000000 --- a/apps/nexus/preload.cpp +++ /dev/null @@ -1,82 +0,0 @@ -/**************************************************************************** -* VCGLib o o * -* Visual and Computer Graphics Library o o * -* _ O _ * -* Copyright(C) 2004 \/)\/ * -* Visual Computing Lab /\/| * -* ISTI - Italian National Research Council | * -* \ * -* All rights reserved. * -* * -* This program is free software; you can redistribute it and/or modify * -* it under the terms of the GNU General Public License as published by * -* the Free Software Foundation; either version 2 of the License, or * -* (at your option) any later version. * -* * -* This program is distributed in the hope that it will be useful, * -* but WITHOUT ANY WARRANTY; without even the implied warranty of * -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * -* GNU General Public License (http://www.gnu.org/licenses/gpl.txt) * -* for more details. * -* * -****************************************************************************/ -/**************************************************************************** - History - -$Log: not supported by cvs2svn $ -Revision 1.7 2005/02/17 15:39:44 ponchio -Reorderes statistics a bit. - -Revision 1.6 2005/02/08 12:43:03 ponchio -Added copyright - - -****************************************************************************/ - -#include "preload.h" -#include "nexusmt.h" -#include - -using namespace std; -using namespace nxs; - - void Preload::execute() { - - total_disk = 0; - disk = 0; - - assert(mt); - while(!get_signaled()) { - trigger.wait(); - lock.enter(); - while(!queue.size()) { - trigger.reset(); - lock.leave(); - trigger.wait(); - lock.enter(); - } - //TODO check we are not loading too much memory! - assert(queue.size()); - Item &item = queue.back(); - if(item.error == 0 || mt->CanAdd(item)) { - //we cannot flush since we are not in the openGL thread - //and flushing includes VBO buffer flushing also. - Entry &entry = (*mt)[item.id]; - if(!entry.patch) { - disk += entry.disk_size; - disk_tri += entry.nvert * 2; - } - - Patch &patch = mt->GetPatch(item.id, item.error, false); - - //test... make sure memory is in ram (if not on vbo that is. - if(!entry.vbo_array) - total_disk += patch.Face(0)[0]; - - queue.pop_back(); - } else - queue.clear(); - lock.leave(); - } - } - diff --git a/apps/nexus/preload.h b/apps/nexus/preload.h deleted file mode 100644 index 34c7a406..00000000 --- a/apps/nexus/preload.h +++ /dev/null @@ -1,87 +0,0 @@ -/**************************************************************************** -* VCGLib o o * -* Visual and Computer Graphics Library o o * -* _ O _ * -* Copyright(C) 2004 \/)\/ * -* Visual Computing Lab /\/| * -* ISTI - Italian National Research Council | * -* \ * -* All rights reserved. * -* * -* This program is free software; you can redistribute it and/or modify * -* it under the terms of the GNU General Public License as published by * -* the Free Software Foundation; either version 2 of the License, or * -* (at your option) any later version. * -* * -* This program is distributed in the hope that it will be useful, * -* but WITHOUT ANY WARRANTY; without even the implied warranty of * -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * -* GNU General Public License (http://www.gnu.org/licenses/gpl.txt) * -* for more details. * -* * -****************************************************************************/ -/**************************************************************************** - History - -$Log: not supported by cvs2svn $ -Revision 1.5 2005/02/17 15:39:44 ponchio -Reorderes statistics a bit. - -Revision 1.4 2005/02/08 12:43:03 ponchio -Added copyright - - -****************************************************************************/ - -#ifndef NXS_PRELOAD_H -#define NXS_PRELOAD_H - -#include - -#include - -#include - -#include "extraction.h" - -namespace nxs { - -class NexusMt; - -class Preload: public pt::thread{ - public: - - NexusMt *mt; - - pt::mutex lock; - pt::trigger trigger; - - std::vector queue; - - unsigned int disk; //kbytes readed from disk - unsigned int disk_tri; //number of triangles readed from disk - unsigned int total_disk; - Preload(): thread(false), trigger(false, false) {} - ~Preload() { - waitfor(); - } - - void execute(); - - void post(std::vector &patches) { - trigger.reset(); - lock.enter(); - - queue.reserve(patches.size()); - for(int i = patches.size() -1; i >= 0; i--) - queue.push_back(patches[i]); - - trigger.post(); - lock.leave(); - } - - void cleanup() {} -}; - -} -#endif diff --git a/apps/nexus/remapping.cpp b/apps/nexus/remapping.cpp deleted file mode 100644 index 2f118a13..00000000 --- a/apps/nexus/remapping.cpp +++ /dev/null @@ -1,520 +0,0 @@ -/**************************************************************************** -* VCGLib o o * -* Visual and Computer Graphics Library o o * -* _ O _ * -* Copyright(C) 2004 \/)\/ * -* Visual Computing Lab /\/| * -* ISTI - Italian National Research Council | * -* \ * -* All rights reserved. * -* * -* This program is free software; you can redistribute it and/or modify * -* it under the terms of the GNU General Public License as published by * -* the Free Software Foundation; either version 2 of the License, or * -* (at your option) any later version. * -* * -* This program is distributed in the hope that it will be useful, * -* but WITHOUT ANY WARRANTY; without even the implied warranty of * -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * -* GNU General Public License (http://www.gnu.org/licenses/gpl.txt) * -* for more details. * -* * -****************************************************************************/ -/**************************************************************************** - History - -$Log: not supported by cvs2svn $ -Revision 1.11 2005/02/19 14:00:43 ponchio -Small opt. - -Revision 1.10 2005/02/19 10:45:05 ponchio -Patch generalized and small fixes. - -Revision 1.9 2005/02/08 12:43:03 ponchio -Added copyright - - -****************************************************************************/ - -#include - -#include "remapping.h" -#include "watch.h" - - -using namespace std; -using namespace vcg; -using namespace nxs; - -bool BlockIndex::Save(const string &file) { - FILE *fp = fopen(file.c_str(), "wb+"); - if(!fp) { - cerr << "Could not save: " << file << endl; - return false; - } - unsigned int nsize = size(); - fwrite(&nsize, sizeof(unsigned int), 1, fp); - fwrite(&*begin(), sizeof(BlockEntry), nsize, fp); - fclose(fp); - return true; -} - -bool BlockIndex::Load(const string &file) { - FILE *fp = fopen(file.c_str(), "rb"); - if(!fp) { - cerr << "Could not load: " << file << endl; - return false; - } - unsigned int nsize; - fread(&nsize, sizeof(unsigned int), 1, fp); - resize(nsize); - fread(&*begin(), sizeof(BlockEntry), nsize, fp); - fclose(fp); - return true; -} - -void nxs::Remap(VChain &chain, - VFile &points, - VFile &remap, - BlockIndex &index, - unsigned int target_size, - unsigned int min_size, - unsigned int max_size, - float scaling, - int steps) { - - VPartition *finepart = new VPartition; - chain.push_back(finepart); - BuildPartition(*finepart, points, target_size, min_size, max_size, steps); - - VPartition *coarsepart = new VPartition; - chain.push_back(coarsepart); - BuildPartition(*coarsepart, points, - (int)(target_size/scaling), min_size, max_size, steps); - - - cerr << "Fine size: " << finepart->size() << endl; - cerr << "Coarse size: " << coarsepart->size() << endl; - - -// typedef map, unsigned int> FragIndex; - typedef map > FragIndex; - FragIndex patches; - - unsigned int totpatches = 0; - vector count; - - Point3f bari; - for(unsigned int i = 0; i < points.Size(); i++) { - bari = points[i]; - - unsigned int fine = finepart->Locate(bari); - unsigned int coarse = coarsepart->Locate(bari); - - unsigned int patch; - if(!patches.count(coarse) || !patches[coarse].count(fine)) { - patch = totpatches; - patches[coarse][fine] = totpatches++; - } else - patch = patches[coarse][fine]; - - remap[i] = patch; - - while(count.size() <= patch) - count.push_back(0); - count[patch]++; - } - - for(unsigned int i = 0; i < totpatches; i++) { - if(count[i] > 32000) { - //TODO do something to reduce patch size... :P - cerr << "Found a patch too big... sorry\n"; - exit(0); - } - } - - unsigned int mean = 0; - for(unsigned int i = 0; i < count.size(); i++) - mean += count[i]; - mean /= count.size(); - - min_size /= 4; - cerr << "Pruning small patches... < " << min_size << " mean: " << mean << endl; - - - //prune small patches - - vector patch_map; - patch_map.resize(totpatches); - for(unsigned int i = 0; i < totpatches; i++) - patch_map[i] = i; - - for(FragIndex::iterator s = patches.begin(); s != patches.end(); s++) { - map &fines = (*s).second; - - while(1) { - if(fines.size() <= 1) break; - unsigned int inf_fine = 0xffffffff; - unsigned int inf_count, min_count; - unsigned int min_fine = 0xffffffff; - unsigned int min_patch, inf_patch; - map::iterator t; - for(t = fines.begin(); t != fines.end(); t++) { - unsigned int c = count[(*t).second]; - if(inf_fine == 0xffffffff || c < inf_count) { - if(inf_fine != 0xffffffff) { - min_fine = inf_fine; - min_count = inf_count; - min_patch = inf_patch; - } - inf_fine = (*t).first; - inf_count = c; - inf_patch = (*t).second; - } else if(min_fine == 0xffffffff || c < min_count) { - min_fine = (*t).first; - min_count = c; - min_patch = (*t).second; - } - } - if(inf_count >= min_size || - inf_count + min_count > max_size) break; - - count[min_patch] += count[inf_patch]; - patch_map[inf_patch] = min_patch; - fines.erase(inf_fine); - } - } - for(unsigned int i = 0; i < totpatches; i++) - while(patch_map[patch_map[i]] != patch_map[i]) - patch_map[i] = patch_map[patch_map[i]]; - - //now we remap remaining patches into 0 - n. - unsigned int new_totpatches = 0; - vector patch_remap; - patch_remap.resize(totpatches, -1); - for(unsigned int i = 0; i < totpatches; i++) { - unsigned int p = patch_map[i]; - if(patch_remap[p] == -1) - patch_remap[p] = new_totpatches++; - patch_remap[i] = patch_remap[p]; - } - - cerr << "Building fragments\n"; - - //building fragments - for(FragIndex::iterator s = patches.begin(); s != patches.end(); s++) { - unsigned int coarse = (*s).first; - map &fines = (*s).second; - map::iterator t; - for(t = fines.begin(); t != fines.end(); t++) { - unsigned int fine = (*t).first; - unsigned int oldpatch = (*t).second; - assert(oldpatch < patch_remap.size()); - unsigned int patch = patch_remap[oldpatch]; - if(patch != -1) //not deleted... - chain.oldfragments[coarse].insert(patch); - } - } - - cerr << "remapping faces again\n"; - //remapping faces - index.resize(new_totpatches); - for(unsigned int i = 0; i < remap.Size(); i++) { - unsigned int patch = remap[i]; -#ifdef CONTROLS - if(patch == 0xffffffff) { - cerr << "RESIGH\n"; - exit(0); - } - if(patch_remap[patch] == -1) {//must relocate this thing.... - //TODO - cerr << "Could not do this\n"; - exit(0); - } -#endif - - - unsigned int newpatch = patch_remap[patch]; - assert(newpatch < index.size()); - remap[i] = newpatch; - BlockEntry &entry = index[newpatch]; - entry.size++; - } - - cerr << "fixing offsets in index\n"; - //Fixing offset - int64 offset = 0; - for(unsigned int i = 0; i < index.size(); i++) { - assert(index[i].size < 65000); - index[i].offset = offset; - offset += index[i].size; - } - -} - - -void nxs::BuildPartition(VPartition &part, - VFile &points, - unsigned int target_size, - unsigned int min_size, - unsigned int max_size, - int steps) { - - //TODO: improve quality of patches and implement threshold. - unsigned int ncells = points.Size()/target_size; - cerr << "Target partition size: " << ncells - << " mean: " << points.Size()/ncells << endl; - srand(0); - - for(unsigned int i = 0; i < points.Size(); i++) { - int f = (int)(target_size * (float)rand()/(RAND_MAX + 1.0)); - if(f == 2) { - Point3f &point = points[i]; - part.push_back(point); - } - } - - //TODO! Check for duplicates (use the closest :P) - part.Init(); - - - vector centroids; - vector counts; - - for(int step = 0; step < steps; step++) { - cerr << "Optimization step: " << step+1 << "/" << steps << endl; - - centroids.clear(); - counts.clear(); - centroids.resize(part.size(), Point3f(0, 0, 0)); - counts.resize(part.size(), 0); - - Report report(points.Size()); - - for(unsigned int v = 0; v < points.Size(); v++) { - if(v & 0xffff == 0xffff) - report.Step(v); - - unsigned int target = part.Locate(points[v]); - centroids[target] += points[v]; - counts[target]++; - } - - for(unsigned int v = 0; v < centroids.size(); v++) - if(counts[v] != 0) - centroids[v]/= counts[v]; - - double quality = 0; - for(int i = 0; i < part.size(); i++) - quality += (counts[i] - target_size) * (counts[i] - target_size); - - cerr << "Quality: " << quality << endl; - - if(step == steps-1) { - if(!Optimize(part, ncells, target_size, min_size, max_size, - centroids, counts, false)) - step--; - } else - Optimize(part, ncells, target_size, min_size, max_size, - centroids, counts, true); - } - cerr << "Partition size: " << part.size() - << " mean: " << (float)(points.Size()/part.size()) << endl << endl; -} - -void nxs::BuildLevel(VChain &chain, - Nexus &nexus, - unsigned int offset, - float scaling, - unsigned int target_size, - unsigned int min_size, - unsigned int max_size, - int steps) { - - unsigned int totface = 0; - unsigned int totvert = 0; - for(unsigned int idx = offset; idx < nexus.size(); idx++) { - totface += nexus[idx].nface; - totvert += nexus[idx].nvert; - } - - VPartition *fine = chain[chain.size()-1]; - fine->Init(); - - VPartition *coarse = new VPartition; - chain.push_back(coarse); - - //unsigned int ncells = (unsigned int)(fine.size() * scaling); - unsigned int ncells = (unsigned int)(scaling * totface/target_size); - - //TODO this method for selecting the seeds is ugly! - float ratio = ncells/(float)(nexus.size() - offset); - float cratio = 0; - for(unsigned int idx = offset; idx < nexus.size(); idx++) { - cratio += ratio; - if(cratio > 1) { - Patch patch = nexus.GetPatch(idx); - Point3f &v = patch.Vert3f(0); - coarse->push_back(v); - cratio -= 1; - } - } - - if(coarse->size() == 0) { - Patch patch = nexus.GetPatch(0); - coarse->push_back(patch.Vert3f(0)); - } - - float coarse_vmean = totface/(float)coarse->size(); - - coarse->Init(); - cerr << "Ncells: " << ncells << endl; - cerr << "Coarse size: " << coarse->size() << endl; - cerr << "Coarse mean: " << coarse_vmean << " mean_size: " << target_size << endl; - - //here goes some optimization pass. - //Coarse optimization. - vector centroids; - vector counts; - - for(int step = 0; step < steps; step++) { - cerr << "Optimization step: " << step+1 << "/" << steps << endl; - centroids.clear(); - counts.clear(); - centroids.resize(coarse->size(), Point3f(0, 0, 0)); - counts.resize(coarse->size(), 0); - - Report report(nexus.size()); - for(unsigned int idx = offset; idx < nexus.size(); idx++) { - report.Step(idx); - Patch patch = nexus.GetPatch(idx); - for(unsigned int i = 0; i < patch.nf; i++) { - unsigned short *face = patch.Face(i); - Point3f bari = (patch.Vert3f(face[0]) + - patch.Vert3f(face[1]) + - patch.Vert3f(face[2]))/3; - assert(coarse->size() > 0); - unsigned int target = coarse->Locate(bari); - assert(target < coarse->size()); - centroids[target] += bari; - counts[target]++; - } - } - - for(unsigned int v = 0; v < centroids.size(); v++) - if(counts[v] != 0) - centroids[v]/= counts[v]; - - if(step == steps-1) { - if(!Optimize(*coarse, ncells, (int)coarse_vmean, min_size, max_size, - centroids, counts, false)) - step--; - } else - Optimize(*coarse, ncells, (int)coarse_vmean, min_size, max_size, - centroids, counts, true); - } - chain.newfragments.clear(); -} - -int nxs::GetBest(VPartition &part, unsigned int seed, - vector &mark, - vector &counts) { - - vector nears; - vector dists; - int nnear = 7; - if(part.size() < 7) nnear = part.size()/2; - if(!nnear) return -1; - - part.Closest(part[seed], nnear, nears, dists); - int best = -1; - int bestcount = -1; - int bestdist = -1; - - for(int k = 0; k < nnear; k++) { - int c = nears[k]; - if(c == seed) continue; - assert(c >= 0); - assert(c < part.size()); - if(mark[c]) continue; - - if(bestcount < 0 || - (counts[c] < bestcount)) { - best = c; - bestcount = counts[c]; - } - } - return best; -} - -bool nxs::Optimize(VPartition &part, - unsigned int target_cells, - unsigned int target_size, - unsigned int min_size, - unsigned int max_size, - vector ¢roids, - vector &counts, - bool join) { - - if(max_size > target_size *3) - max_size = target_size * 3; - min_size = (unsigned int)(target_size * 0.3f); - - unsigned int toobig = 0; - unsigned int toosmall = 0; - for(unsigned int i = 0; i < part.size(); i++) { - if(counts[i] > max_size) toobig++; - if(counts[i] < min_size) toosmall--; - } - - unsigned int close = part.size()/2; - if(close < 1) close = 1; - if(close > 10) close = 10; - - unsigned int failed = 0; - vector seeds; - vector mark; - mark.resize(part.size(), false); - - vector nears; - vector dists; - //removing small ones. - for(unsigned int i = 0; i < part.size(); i++) { - if(counts[i] > max_size) { - float radius; - if(part.size() == 1) - radius = 0.00001; - else - radius = part.Radius(i)/4; - seeds.push_back(centroids[i] + Point3f(1, -1, 1) * radius); - seeds.push_back(centroids[i] + Point3f(-1, 1, 1) * radius); - seeds.push_back(centroids[i] + Point3f(-1, -1, -1) * radius); - seeds.push_back(centroids[i] + Point3f(1, 1, -1) * radius); - continue; - } - if(counts[i] < min_size) - continue; - - part.Closest(part[i], close, nears, dists); - Point3f dir(0,0,0); - - for(unsigned int k = 0; k < close; k++) { - unsigned int n = nears[k]; - float c = (target_size - (float)counts[n])/ - ((float)target_size * close); - - dir += (centroids[i] - part[n]) * c; - } - seeds.push_back(centroids[i] + dir); - } - part.clear(); - for(unsigned int i = 0; i < seeds.size(); i++) - part.push_back(seeds[i]); - - if(part.size() == 0) { - cerr << "OOOPS i accidentally deleted all seeds... backup :P\n"; - part.push_back(Point3f(0,0,0)); - } - part.Init(); - return true; -} diff --git a/apps/nexus/remapping.h b/apps/nexus/remapping.h deleted file mode 100644 index 51d6d3f4..00000000 --- a/apps/nexus/remapping.h +++ /dev/null @@ -1,95 +0,0 @@ -/**************************************************************************** -* VCGLib o o * -* Visual and Computer Graphics Library o o * -* _ O _ * -* Copyright(C) 2004 \/)\/ * -* Visual Computing Lab /\/| * -* ISTI - Italian National Research Council | * -* \ * -* All rights reserved. * -* * -* This program is free software; you can redistribute it and/or modify * -* it under the terms of the GNU General Public License as published by * -* the Free Software Foundation; either version 2 of the License, or * -* (at your option) any later version. * -* * -* This program is distributed in the hope that it will be useful, * -* but WITHOUT ANY WARRANTY; without even the implied warranty of * -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * -* GNU General Public License (http://www.gnu.org/licenses/gpl.txt) * -* for more details. * -* * -****************************************************************************/ -/**************************************************************************** - History - -$Log: not supported by cvs2svn $ - -****************************************************************************/ - -#ifndef NXS_REMAPPING_H -#define NXS_REMAPPING_H - -#include -#include -#include "nxstypes.h" -#include "vchain.h" -#include "nexus.h" -#include "vfile.h" - -namespace nxs { - - struct BlockEntry { - BlockEntry(int64 o = 0, unsigned int s = 0): offset(o), size(s) {} - int64 offset; - unsigned int size; - }; - - class BlockIndex: public std::vector { - public: - bool Save(const std::string &file); - bool Load(const std::string &file); - }; - - void Remap(VChain &chain, - VFile &points, - VFile &remap, - BlockIndex &index, - unsigned int target_size, - unsigned int min_size, - unsigned int max_size, - float scaling, - int step); - - void BuildPartition(VPartition &part, - VFile &points, - unsigned int target_size, - unsigned int min_size, - unsigned int max_size, - int steps); - - void BuildLevel(VChain &chain, - Nexus &nexus, - unsigned int offset, - float scaling, - unsigned int target_size, - unsigned int min_size, - unsigned int max_size, - int steps); - - //removes small or really big patches. - bool Optimize(VPartition &part, - unsigned int target_cells, - unsigned int target_size, - unsigned int min_size, - unsigned int max_size, - std::vector ¢roids, - std::vector &counts, - bool join); - - int GetBest(VPartition &part, unsigned int seed, - std::vector &mark, - std::vector &counts); -} - -#endif diff --git a/apps/nexus/strip.cpp b/apps/nexus/strip.cpp deleted file mode 100644 index 8fe4ad85..00000000 --- a/apps/nexus/strip.cpp +++ /dev/null @@ -1,67 +0,0 @@ -#include - -//These header are neede byt tristipper... -#include -#include -#include - -#include "tristripper/tri_stripper.h" -using namespace triangle_stripper; - -#include "strip.h" - -using namespace std; -using namespace nxs; - -void nxs::ComputeTriStrip(unsigned short nfaces, unsigned short *faces, - vector &strip) { - - vector index; - index.resize(nfaces*3); - - for(int i = 0; i < nfaces*3; i++) - index[i] = faces[i]; - - int cache_size = 16; - tri_stripper stripper(index); - stripper.SetCacheSize(cache_size); - // = 0 will disable the cache optimizer - stripper.SetMinStripSize(0); - tri_stripper::primitives_vector primitives; - stripper.Strip(&primitives); - - if(primitives.back().m_Indices.size() < 3) - primitives.pop_back(); - - //TODO do this when mounting strips together. - if(primitives.back().m_Type == tri_stripper::PT_Triangles) { - tri_stripper::primitives p; - p = primitives.back(); - primitives.pop_back(); - for(unsigned int i = 0; i < p.m_Indices.size(); i += 3) { - tri_stripper::primitives s; - s.m_Type = tri_stripper::PT_Triangle_Strip; - s.m_Indices.push_back(p.m_Indices[i]); - s.m_Indices.push_back(p.m_Indices[i+1]); - s.m_Indices.push_back(p.m_Indices[i+2]); - primitives.push_back(s); - } - } - - for(unsigned int i = 0; i < primitives.size(); i++) { - tri_stripper::primitives &primitive = primitives[i]; - assert(primitive.m_Indices.size() != 0); - int len = primitive.m_Indices.size(); - for(int l = 0; l < len; l++) - strip.push_back(primitive.m_Indices[l]); - - - if(i < primitives.size()-1) { //not the last primitive. - strip.push_back(primitive.m_Indices[len-1]); - //TODO optimize this! - if((len%2) == 1) //do not change orientation.... - strip.push_back(primitive.m_Indices[len-1]); - strip.push_back(primitives[i+1].m_Indices[0]); - } - } -} diff --git a/apps/nexus/strip.h b/apps/nexus/strip.h deleted file mode 100644 index dcf315e6..00000000 --- a/apps/nexus/strip.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef NXS_TRISTRIP_H -#define NXS_TRISTRIP_H - -#include - -namespace nxs { - - void ComputeTriStrip(unsigned short nfaces, unsigned short *faces, - std::vector &strip); -} - -#endif diff --git a/apps/nexus/tristripper/graph_array.h b/apps/nexus/tristripper/graph_array.h deleted file mode 100644 index bea8f0f2..00000000 --- a/apps/nexus/tristripper/graph_array.h +++ /dev/null @@ -1,419 +0,0 @@ -// graph_array.h: interface for the graph_array class. -// -////////////////////////////////////////////////////////////////////// -// -// Copyright (C) 2002 Tanguy Fautré. -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would be -// appreciated but is not required. -// 2. Altered source versions must be plainly marked as such, and must not be -// misrepresented as being the original software. -// 3. This notice may not be removed or altered from any source distribution. -// -// Tanguy Fautré -// softdev@pandora.be -// -////////////////////////////////////////////////////////////////////// -// -// Semi-dynamic directed graph -// *************************** -// -// Current version: 3.00 BETA 3 (04/12/2002) -// -// Comment: graph_array is equivalent to an array of nodes linked by -// arcs. -// This means you can't change the size (the number of nodes) -// of the graph once you created it (setsize() will delete -// any previous nodes and arcs). -// But you can add or remove arcs. -// -// History: - 3.00 BETA 3 (04/12/2002) - Added empty() -// - Changed some parameters from copy to reference -// - Fixed a bug with erase_arc -// - Un-inlined external functions -// - Added "insert_arc" which is equivalent to "insert" -// - 3.00 BETA 2 (16/11/2002) - Improved portability -// - 3.00 BETA 1 (27/08/2002) - First public release -// -////////////////////////////////////////////////////////////////////// - -#pragma once - -// namespace common_structures -namespace common_structures { - - - - -// graph_array main class -template -class graph_array -{ -public: - - class arc; - class node; - - // New types - typedef size_t nodeid; - typedef std::vector::iterator node_iterator; - typedef std::vector::const_iterator const_node_iterator; - typedef std::vector::reverse_iterator node_reverse_iterator; - typedef std::vector::const_reverse_iterator const_node_reverse_iterator; - - typedef graph_array _mytype; - - - // graph_array::arc class - class arc - { - public: - arc & mark() { m_Marker = true; return (* this); } - arc & unmark() { m_Marker = false; return (* this); } - bool marked() const { return m_Marker; } - - node_iterator initial() const { return m_Initial; } - node_iterator terminal() const { return m_Terminal; } - - arctype & operator * () { return m_Elem; } - arctype * operator -> () { return &m_Elem; } - const arctype & operator * () const { return m_Elem; } - const arctype * operator -> () const { return &m_Elem; } - - protected: - friend class graph_array; - - arc(const node_iterator & Initial, const node_iterator & Terminal) - : m_Initial(Initial), m_Terminal(Terminal), m_Marker(false) { } - - arc(const node_iterator & Initial, const node_iterator & Terminal, const arctype & Elem) - : m_Initial(Initial), m_Terminal(Terminal), m_Elem(Elem), m_Marker(false) { } - - node_iterator m_Initial; - node_iterator m_Terminal; - arctype m_Elem; - bool m_Marker; - }; - - - // New types - typedef std::list::iterator out_arc_iterator; - typedef std::list::const_iterator const_out_arc_iterator; - - - // graph_array::node class - class node - { - public: - node & mark() { m_Marker = true; return (* this); } - node & unmark() { m_Marker = false; return (* this); } - bool marked() const { return m_Marker; } - - bool out_empty() const { return m_OutArcs.empty(); } - size_t number_of_out_arcs() const { return m_OutArcs.size(); } - - out_arc_iterator out_begin() { return m_OutArcs.begin(); } - out_arc_iterator out_end() { return m_OutArcs.end(); } - const_out_arc_iterator out_begin() const { return m_OutArcs.begin(); } - const_out_arc_iterator out_end() const { return m_OutArcs.end(); } - - nodetype & operator * () { return m_Elem; } - nodetype * operator -> () { return &m_Elem; } - const nodetype & operator * () const { return m_Elem; } - const nodetype * operator -> () const { return &m_Elem; } - - nodetype & operator = (const nodetype & Elem) { return (m_Elem = Elem); } - - protected: - friend class graph_array; - friend class std::vector; - - node() : m_Marker(false) { } - - std::list m_OutArcs; - nodetype m_Elem; - bool m_Marker; - }; - - - // Construction/Destruction - graph_array(); - explicit graph_array(const size_t NbNodes); - - // Node related member functions - void clear(); - bool empty() const; - void setsize(const size_t NbNodes); - size_t size() const; - - node & operator [] (const nodeid & i); - const node & operator [] (const nodeid & i) const; - - node_iterator begin(); - node_iterator end(); - const_node_iterator begin() const; - const_node_iterator end() const; - - node_reverse_iterator rbegin(); - node_reverse_iterator rend(); - const_node_reverse_iterator rbegin() const; - const_node_reverse_iterator rend() const; - - // Arc related member functions - size_t number_of_arcs() const; - - void erase_arcs(); - void erase_arcs(const node_iterator & Initial); - out_arc_iterator erase_arc(const out_arc_iterator & Pos); - - out_arc_iterator insert_arc(const nodeid & Initial, const nodeid & Terminal); - out_arc_iterator insert_arc(const nodeid & Initial, const nodeid & Terminal, const arctype & Elem); - out_arc_iterator insert_arc(const node_iterator & Initial, const node_iterator & Terminal); - out_arc_iterator insert_arc(const node_iterator & Initial, const node_iterator & Terminal, const arctype & Elem); - - // Another interface for insert_arc - out_arc_iterator insert(const nodeid & Initial, const nodeid & Terminal) { return insert_arc(Initial, Terminal); } - out_arc_iterator insert(const nodeid & Initial, const nodeid & Terminal, const arctype & Elem) { return insert_arc(Initial, Terminal, Elem); } - out_arc_iterator insert(const node_iterator & Initial, const node_iterator & Terminal) { return insert_arc(Initial, Terminal); } - out_arc_iterator insert(const node_iterator & Initial, const node_iterator & Terminal, const arctype & Elem) { return insert_arc(Initial, Terminal, Elem); } - - // Optimized (overloaded) functions - void swap(_mytype & Right); - friend void swap(_mytype & Left, _mytype & Right) { Left.swap(Right); } - -protected: - size_t m_NbArcs; - std::vector m_Nodes; -}; - - - -// Additional "low level", graph related, functions -template -void unmark_nodes(graph_array & G); - -template -void unmark_arcs_from_node(graph_array::node & N); - -template -void unmark_arcs(graph_array & G); - - - - -////////////////////////////////////////////////////////////////////////// -// graph_array Inline functions -////////////////////////////////////////////////////////////////////////// - -template -inline graph_array::graph_array() : m_NbArcs(0) { } - - -template -inline graph_array::graph_array(const size_t NbNodes) : m_NbArcs(0), m_Nodes(NbNodes) { } - - -template -inline void graph_array::clear() { - m_NbArcs = 0; - m_Nodes.clear(); -} - - - -template -inline bool graph_array::empty() const { - return m_Nodes.empty(); -} - - -template -inline size_t graph_array::size() const { - return m_Nodes.size(); -} - - -template -inline void graph_array::setsize(const size_t NbNodes) { - clear(); - m_Nodes.resize(NbNodes); -} - - -template -inline graph_array::node & graph_array::operator [] (const nodeid & i) { - // Debug check - assert(i < size()); - - return m_Nodes[i]; -} - - -template -inline const graph_array::node & graph_array::operator [] (const nodeid & i) const { - // Debug check - assert(i < size()); - - return m_Nodes[i]; -} - - -template -inline graph_array::node_iterator graph_array::begin() { - return m_Nodes.begin(); -} - - -template -inline graph_array::node_iterator graph_array::end() { - return m_Nodes.end(); -} - - -template -inline graph_array::const_node_iterator graph_array::begin() const { - return m_Nodes.begin(); -} - - -template -inline graph_array::const_node_iterator graph_array::end() const { - return m_Nodes.end(); -} - - -template -inline graph_array::node_reverse_iterator graph_array::rbegin() { - return m_Nodes.rbegin(); -} - - -template -inline graph_array::node_reverse_iterator graph_array::rend() { - return m_Nodes.rend(); -} - - -template -inline graph_array::const_node_reverse_iterator graph_array::rbegin() const { - return m_Nodes.rbegin(); -} - - -template -inline graph_array::const_node_reverse_iterator graph_array::rend() const { - return m_Nodes.rend(); -} - - -template -inline size_t graph_array::number_of_arcs() const { - return m_NbArcs; -} - - -template -inline graph_array::out_arc_iterator graph_array::insert_arc(const nodeid & Initial, const nodeid & Terminal) { - return (insert(begin() + Initial, begin() + Terminal)); -} - - -template -inline graph_array::out_arc_iterator graph_array::insert_arc(const nodeid & Initial, const nodeid & Terminal, const arctype & Elem) { - return (insert(begin() + Initial, begin() + Terminal, Elem)); -} - - -template -inline graph_array::out_arc_iterator graph_array::insert_arc(const node_iterator & Initial, const node_iterator & Terminal) { - ++m_NbArcs; - Initial->m_OutArcs.push_back(arc(Initial, Terminal)); - return (--(Initial->m_OutArcs.end())); -} - - -template -inline graph_array::out_arc_iterator graph_array::insert_arc(const node_iterator & Initial, const node_iterator & Terminal, const arctype & Elem) { - ++m_NbArcs; - Initial->m_OutArcs.push_back(arc(Initial, Terminal, Elem)); - return (--(Initial->m_OutArcs.end())); -} - - -template -inline graph_array::out_arc_iterator graph_array::erase_arc(const out_arc_iterator & Pos) { - --m_NbArcs; - return (Pos->initial()->m_OutArcs.erase(Pos)); -} - - -template -inline void graph_array::erase_arcs(const node_iterator & Initial) { - m_NbArcs -= (Initial->m_OutArcs.size()); - Initial->m_OutArcs.clear(); -} - - -template -inline void graph_array::erase_arcs() { - m_NbArcs = 0; - for (nodeid i = 0; i < Size(); ++i) - m_Nodes[i].m_OutArcs.clear(); -} - - -template -inline void graph_array::swap(_mytype & Right) { - std::swap(m_NbArcs, Right.m_NbArcs); - std::swap(m_Nodes, Right.m_Nodes); -} - - - -////////////////////////////////////////////////////////////////////////// -// additional functions -////////////////////////////////////////////////////////////////////////// - -template -void unmark_nodes(graph_array & G) -{ - typedef graph_array::node_iterator node_it; - - for (node_it NodeIt = G.begin(); NodeIt != G.end(); ++NodeIt) - NodeIt->unmark(); -} - - -template -void unmark_arcs_from_node(graph_array::node & N) -{ - typedef graph_array::out_arc_iterator arc_it; - - for (arc_it ArcIt = N.out_begin(); ArcIt != N.out_end(); ++ArcIt) - ArcIt->unmark(); -} - - -template -void unmark_arcs(graph_array & G) -{ - typedef graph_array::node_iterator node_it; - - for (node_it NodeIt = G.begin(); NodeIt != G.end(); ++NodeIt) - unmark_arcs_from_node(* NodeIt); -} - - - - -}; // namespace common_structures diff --git a/apps/nexus/tristripper/heap_array.h b/apps/nexus/tristripper/heap_array.h deleted file mode 100644 index b164e91f..00000000 --- a/apps/nexus/tristripper/heap_array.h +++ /dev/null @@ -1,275 +0,0 @@ -// heap_array.h: interface for the heap_array class. -// -////////////////////////////////////////////////////////////////////// -// -// Copyright (C) 2002 Tanguy Fautré. -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would be -// appreciated but is not required. -// 2. Altered source versions must be plainly marked as such, and must not be -// misrepresented as being the original software. -// 3. This notice may not be removed or altered from any source distribution. -// -// Tanguy Fautré -// softdev@pandora.be -// -////////////////////////////////////////////////////////////////////// -// -// Semi-dynamic indexed heap -// ************************* -// -// Current version: 1.00 BETA 1 (24/10/2002) -// -// Comment: heap_array acts like a normal heap, you can push elements -// and then get the greatest one. -// However you cannot push any more element once an element -// has been removed (pop, erase, etc...). -// Elements can be modified after they've been pushed into -// the heap via their indice. -// -// History: - -// -////////////////////////////////////////////////////////////////////// - -#pragma once - - - -// namespace common_structures -namespace common_structures { - - - - -template > -class heap_array -{ -public: - - struct heap_is_locked { }; - - - // heap_array main interface. Pre = PreCondition, Post = PostCondition - - heap_array() : m_Locked(false) { } // Post: ((size() == 0) && ! locked()) - - void clear(); // Post: ((size() == 0) && ! locked()) - - void reserve(size_t Size); - size_t size() const; - - bool empty() const; - bool locked() const; - bool removed(size_t i) const; // Pre: (valid(i)) - bool valid(size_t i) const; - - const T & top() const; // Pre: (! empty()) - const T & peek(size_t i) const; // Pre: (valid(i) && ! removed(i)) - const T & operator [] (size_t i) const; // Pre: (valid(i) && ! removed(i)) - - size_t push(const T & Elem); // Pre: (! locked()) else throw (heap_is_locked) - - void pop(); // Pre: (! empty()) Post: (locked()) - void erase(size_t i); // Pre: (valid(i) && ! removed(i)) Post: (locked()) - void update(size_t i, const T & Elem); // Pre: (valid(i) && ! removed(i)) Post: (locked()) - -protected: - - struct linker { - linker(const T & Elem, size_t i) : m_Elem(Elem), m_Indice(i) { } - - T m_Elem; - size_t m_Indice; - }; - - typedef std::vector linked_heap; - typedef std::vector finder; - - void Adjust(size_t i); - void Swap(size_t a, size_t b); - bool Less(const linker & a, const linker & b) const; - - linked_heap m_Heap; - finder m_Finder; - CmpT m_Compare; - bool m_Locked; -}; - - - - -////////////////////////////////////////////////////////////////////////// -// heap_indexed Inline functions -////////////////////////////////////////////////////////////////////////// - -template -inline void heap_array::clear() { - m_Heap.clear(); - m_Finder.clear(); - m_Locked = false; -} - - -template -inline bool heap_array::empty() const { - return m_Heap.empty(); -} - - -template -inline bool heap_array::locked() const { - return m_Locked; -} - - -template -inline void heap_array::reserve(size_t Size) { - m_Heap.reserve(Size); - m_Finder.reserve(Size); -} - - -template -inline size_t heap_array::size() const { - return m_Heap.size(); -} - - -template -inline const T & heap_array::top() const { - // Debug check to ensure heap is not empty - assert(! empty()); - - return m_Heap.front().m_Elem; -} - - -template -inline const T & heap_array::peek(size_t i) const { - // Debug check to ensure element is still present - assert(! removed(i)); - - return (m_Heap[m_Finder[i]].m_Elem); -} - - -template -inline const T & heap_array::operator [] (size_t i) const { - return peek(i); -} - - -template -inline void heap_array::pop() { - m_Locked = true; - - // Debug check to ensure heap is not empty - assert(! empty()); - - Swap(0, size() - 1); - m_Heap.pop_back(); - Adjust(0); -} - - -template -inline size_t heap_array::push(const T & Elem) { - if (m_Locked) - throw heap_is_locked(); - - size_t Id = size(); - m_Finder.push_back(Id); - m_Heap.push_back(linker(Elem, Id)); - Adjust(Id); - - return Id; -} - - -template -inline void heap_array::erase(size_t i) { - m_Locked = true; - - // Debug check to ensure element is still present - assert(! removed(i)); - - size_t j = m_Finder[i]; - Swap(j, size() - 1); - m_Heap.pop_back(); - Adjust(j); -} - - -template -inline bool heap_array::removed(size_t i) const { - return (m_Finder[i] >= m_Heap.size()); -} - - -template -inline bool heap_array::valid(size_t i) const { - return (i < m_Finder.size()); -} - - -template -inline void heap_array::update(size_t i, const T & Elem) { - // Debug check to ensure element is still present - assert(! removed(i)); - - size_t j = m_Finder[i]; - m_Heap[j].m_Elem = Elem; - Adjust(j); -} - - -template -inline void heap_array::Adjust(size_t i) { - size_t j; - - // Check the upper part of the heap - for (j = i; (j > 0) && (Less(m_Heap[(j - 1) / 2], m_Heap[j])); j = ((j - 1) / 2)) - Swap(j, (j - 1) / 2); - - // Check the lower part of the heap - for (i = j; (j = 2 * i + 1) < size(); i = j) { - if ((j + 1 < size()) && (Less(m_Heap[j], m_Heap[j + 1]))) - ++j; - - if (Less(m_Heap[j], m_Heap[i])) - return; - - Swap(i, j); - } -} - - -template -inline void heap_array::Swap(size_t a, size_t b) { - std::swap(m_Heap[a], m_Heap[b]); - - // use (size_t &) to get rid of a bogus compile warning - (size_t &) (m_Finder[(m_Heap[a].m_Indice)]) = a; - (size_t &) (m_Finder[(m_Heap[b].m_Indice)]) = b; -} - - -template -inline bool heap_array::Less(const linker & a, const linker & b) const { - return m_Compare(a.m_Elem, b.m_Elem); -} - - - - -}; // namespace common_structures \ No newline at end of file diff --git a/apps/nexus/tristripper/tri_stripper.cpp b/apps/nexus/tristripper/tri_stripper.cpp deleted file mode 100644 index 6e7dbb14..00000000 --- a/apps/nexus/tristripper/tri_stripper.cpp +++ /dev/null @@ -1,586 +0,0 @@ -// tri_stripper.cpp: implementation of the Tri Stripper class. -// -// Copyright (C) 2002 Tanguy Fautré. -// For conditions of distribution and use, -// see copyright notice in tri_stripper.h -// -////////////////////////////////////////////////////////////////////// - -#include -#include - -#include -#include -//#include -//#include -#include -#include -#include -#include -using namespace std; -#include "tri_stripper.h" - - - -// namespace triangle_stripper -namespace triangle_stripper { - - - - -////////////////////////////////////////////////////////////////////// -// Construction/Destruction -////////////////////////////////////////////////////////////////////// - - - -////////////////////////////////////////////////////////////////////// -// Members Functions -////////////////////////////////////////////////////////////////////// - -void tri_stripper::Strip(primitives_vector * out_pPrimitivesVector) -{ - // verify that the number of indices is correct - if (m_TriIndices.size() % 3 != 0) - throw triangles_indices_error(); - - // clear possible garbage - m_PrimitivesVector.clear(); - out_pPrimitivesVector->clear(); - - // Initialize the triangle graph - InitTriGraph(); - - // Initialize the triangle priority queue - InitTriHeap(); - - // Initialize the cache simulator - InitCache(); - - // Launch the triangle strip generator - Stripify(); - - // Add the triangles that couldn't be stripped - AddLeftTriangles(); - - // Free ressources - m_Triangles.clear(); - - // Put the results into the user's vector - std::swap(m_PrimitivesVector, (* out_pPrimitivesVector)); -} - - - -void tri_stripper::InitTriGraph() -{ - // Set up the graph size and complete the triangles data - // note: setsize() completely resets the graph as well as the node markers - m_Triangles.setsize(m_TriIndices.size() / 3); - size_t i; - for (i = 0; i < m_Triangles.size(); ++i) - m_Triangles[i] = triangle(m_TriIndices[i * 3 + 0], m_TriIndices[i * 3 + 1], m_TriIndices[i * 3 + 2]); - - // Build the edges lookup table - triangle_edges TriInterface; - TriInterface.reserve(m_Triangles.size() * 3); - - for (i = 0; i < m_Triangles.size(); ++i) { - TriInterface.push_back(triangle_edge(m_Triangles[i]->A(), m_Triangles[i]->B(), i)); - TriInterface.push_back(triangle_edge(m_Triangles[i]->B(), m_Triangles[i]->C(), i)); - TriInterface.push_back(triangle_edge(m_Triangles[i]->C(), m_Triangles[i]->A(), i)); - } - - // Sort the lookup table for faster searches - std::sort(TriInterface.begin(), TriInterface.end(), _cmp_tri_interface_lt()); - - // Link neighbour triangles together using the edges lookup table - for (i = 0; i < m_Triangles.size(); ++i) { - - const triangle_edge EdgeBA(m_Triangles[i]->B(), m_Triangles[i]->A(), i); - const triangle_edge EdgeCB(m_Triangles[i]->C(), m_Triangles[i]->B(), i); - const triangle_edge EdgeAC(m_Triangles[i]->A(), m_Triangles[i]->C(), i); - - LinkNeighboursTri(TriInterface, EdgeBA); - LinkNeighboursTri(TriInterface, EdgeCB); - LinkNeighboursTri(TriInterface, EdgeAC); - } -} - - - -void tri_stripper::LinkNeighboursTri(const triangle_edges & TriInterface, const triangle_edge Edge) -{ - typedef triangle_edges::const_iterator edge_const_it; - - // Find the first edge equal to Edge - edge_const_it It = std::lower_bound(TriInterface.begin(), TriInterface.end(), Edge, _cmp_tri_interface_lt()); - - // See if there are any other edges that are equal - // (if so, it means that more than 2 triangles are sharing the same edge, - // which is unlikely but not impossible) - for (; (It != TriInterface.end()) && ((It->A() == Edge.A()) && (It->B() == Edge.B())); ++It) - m_Triangles.insert(Edge.TriPos(), It->TriPos()); - - // Note: degenerated triangles will also point themselves as neighbour triangles -} - - - -void tri_stripper::InitTriHeap() -{ - m_TriHeap.clear(); - m_TriHeap.reserve(m_Triangles.size()); - - // Set up the triangles priority queue - // The lower the number of available neighbour triangles, the higher the priority. - for (size_t i = 0; i < m_Triangles.size(); ++i) - m_TriHeap.push(triangle_degree(i, m_Triangles[i].number_of_out_arcs())); - - // Remove useless triangles - // (Note: we had to put all of them into the heap before to ensure coherency of the heap_array object) - while ((! m_TriHeap.empty()) && (m_TriHeap.top().Degree() == 0)) - m_TriHeap.pop(); -} - - - -void tri_stripper::InitCache() -{ - m_IndicesCache.clear(); - - if (m_CacheSize > 0) - m_IndicesCache.resize(m_CacheSize, static_cast(-1)); -} - - - -void tri_stripper::Stripify() -{ - // Reset the triangle strip id selector - m_StripID = 0; - - // Reset the candidate list - m_NextCandidates.clear(); - - // Loop untill there is no available candidate triangle left - while (! m_TriHeap.empty()) { - - // There is no triangle in the candidates list, refill it with the loneliest triangle - const size_t HeapTop = m_TriHeap.top().TriPos(); - m_NextCandidates.push_back(HeapTop); - - // Loop while BuildStrip can find good candidates for us - while (! m_NextCandidates.empty()) { - - // Choose the best strip containing that triangle - // Note: FindBestStrip empties m_NextCandidates - const triangle_strip TriStrip = FindBestStrip(); - - // Build it if it's long enough, otherwise discard it - // Note: BuildStrip refills m_NextCandidates - if (TriStrip.Size() >= m_MinStripSize) - BuildStrip(TriStrip); - } - - // We must discard the triangle we inserted in the candidate list from the heap - // if it led to nothing. (We simply removed it if it hasn't been removed by BuildStrip() yet) - if (! m_TriHeap.removed(HeapTop)) - m_TriHeap.erase(HeapTop); - - - // Eliminate all the triangles that have now become useless - while ((! m_TriHeap.empty()) && (m_TriHeap.top().Degree() == 0)) - m_TriHeap.pop(); - } -} - - - -inline tri_stripper::triangle_strip tri_stripper::FindBestStrip() -{ - triangle_strip BestStrip; - size_t BestStripDegree = 0; - size_t BestStripCacheHits = 0; - - // Backup the cache, because it'll be erased during the simulations - indices_cache CacheBackup = m_IndicesCache; - - while (! m_NextCandidates.empty()) { - - // Discard useless triangles from the candidates list - if ((m_Triangles[m_NextCandidates.back()].marked()) || (m_TriHeap[m_NextCandidates.back()].Degree() == 0)) { - m_NextCandidates.pop_back(); - - // "continue" is evil! But it really makes things easier here. - // The useless triangle is discarded, and the "while" just rebegins again - continue; - } - - // Invariant: (CandidateTri's Degree() >= 1) && (CandidateTri is not marked). - // So it can directly be used. - const size_t CandidateTri = m_NextCandidates.back(); - m_NextCandidates.pop_back(); - - // Try to extend the triangle in the 3 possible directions - for (size_t i = 0; i < 3; ++i) { - - // Reset the cache hit count - m_CacheHits = 0; - - // Try a new strip with that triangle in a particular direction - const triangle_strip TempStrip = ExtendTriToStrip(CandidateTri, triangle_strip::start_order(i)); - - // Restore the cache (modified by ExtendTriToStrip) - m_IndicesCache = CacheBackup; - - // We want to keep the best strip - // Discard strips that don't match the minimum required size - if (TempStrip.Size() >= m_MinStripSize) { - - // Cache simulator disabled? - if (m_CacheSize == 0) { - - // Cache is disabled, take the longest strip - if (TempStrip.Size() > BestStrip.Size()) - BestStrip = TempStrip; - - // Cache simulator enabled - // Use other criteria to find the "best" strip - } else { - - // Priority 1: Keep the strip with the best cache hit count - if (m_CacheHits > BestStripCacheHits) { - BestStrip = TempStrip; - BestStripDegree = m_TriHeap[TempStrip.StartTriPos()].Degree(); - BestStripCacheHits = m_CacheHits; - - } else if (m_CacheHits == BestStripCacheHits) { - - // Priority 2: Keep the strip with the loneliest start triangle - if ((BestStrip.Size() != 0) && (m_TriHeap[TempStrip.StartTriPos()].Degree() < BestStripDegree)) { - BestStrip = TempStrip; - BestStripDegree = m_TriHeap[TempStrip.StartTriPos()].Degree(); - - // Priority 3: Keep the longest strip - } else if (TempStrip.Size() > BestStrip.Size()) { - BestStrip = TempStrip; - BestStripDegree = m_TriHeap[TempStrip.StartTriPos()].Degree(); - } - } - } - } - - } - - } - - return BestStrip; -} - - - -tri_stripper::triangle_strip tri_stripper::ExtendTriToStrip(const size_t StartTriPos, const triangle_strip::start_order StartOrder) -{ - typedef triangles_graph::const_out_arc_iterator const_tri_link_iter; - typedef triangles_graph::node_iterator tri_node_iter; - - size_t Size = 1; - bool ClockWise = false; - triangle_strip::start_order Order = StartOrder; - - // Begin a new strip - ++m_StripID; - - // Mark the first triangle as used for this strip - m_Triangles[StartTriPos]->SetStripID(m_StripID); - - // Update the indice cache - AddTriToCache((* m_Triangles[StartTriPos]), Order); - - - // Loop while we can further extend the strip - for (tri_node_iter TriNodeIt = (m_Triangles.begin() + StartTriPos); - (TriNodeIt != m_Triangles.end()) && ((m_CacheSize <= 0) || ((Size + 2) < m_CacheSize)); - ++Size) { - - // Get the triangle edge that would lead to the next triangle - const triangle_edge Edge = GetLatestEdge(** TriNodeIt, Order); - - // Link to a neighbour triangle - const_tri_link_iter LinkIt; - for (LinkIt = TriNodeIt->out_begin(); LinkIt != TriNodeIt->out_end(); ++LinkIt) { - - // Get the reference to the possible next triangle - const triangle & Tri = (** ((*LinkIt).terminal())); - - // Check whether it's already been used - if ((Tri.StripID() != m_StripID) && (! ((*LinkIt).terminal()->marked()))) { - - // Does the current candidate triangle match the required for the strip? - - if ((Edge.B() == Tri.A()) && (Edge.A() == Tri.B())) { - Order = (ClockWise) ? triangle_strip::ABC : triangle_strip::BCA; - AddIndiceToCache(Tri.C(), true); - break; - } - - else if ((Edge.B() == Tri.B()) && (Edge.A() == Tri.C())) { - Order = (ClockWise) ? triangle_strip::BCA : triangle_strip::CAB; - AddIndiceToCache(Tri.A(), true); - break; - } - - else if ((Edge.B() == Tri.C()) && (Edge.A() == Tri.A())) { - Order = (ClockWise) ? triangle_strip::CAB : triangle_strip::ABC; - AddIndiceToCache(Tri.B(), true); - break; - } - } - } - - // Is it the end of the strip? - if (LinkIt == TriNodeIt->out_end()) { - TriNodeIt = m_Triangles.end(); - --Size; - } else { - TriNodeIt = (*LinkIt).terminal(); - - // Setup for the next triangle - (* TriNodeIt)->SetStripID(m_StripID); - ClockWise = ! ClockWise; - } - } - - - return triangle_strip(StartTriPos, StartOrder, Size); -} - - - -inline tri_stripper::triangle_edge tri_stripper::GetLatestEdge(const triangle & Triangle, const triangle_strip::start_order Order) const -{ - switch (Order) { - case triangle_strip::ABC: - return triangle_edge(Triangle.B(), Triangle.C(), 0); - case triangle_strip::BCA: - return triangle_edge(Triangle.C(), Triangle.A(), 0); - case triangle_strip::CAB: - return triangle_edge(Triangle.A(), Triangle.B(), 0); - default: - return triangle_edge(0, 0, 0); - } -} - - - -void tri_stripper::BuildStrip(const triangle_strip TriStrip) -{ - typedef triangles_graph::const_out_arc_iterator const_tri_link_iter; - typedef triangles_graph::node_iterator tri_node_iter; - - const size_t StartTriPos = TriStrip.StartTriPos(); - - bool ClockWise = false; - triangle_strip::start_order Order = TriStrip.StartOrder(); - - // Create a new strip - m_PrimitivesVector.push_back(primitives()); - m_PrimitivesVector.back().m_Type = PT_Triangle_Strip; - - // Put the first triangle into the strip - AddTriToIndices((* m_Triangles[StartTriPos]), Order); - - // Mark the first triangle as used - MarkTriAsTaken(StartTriPos); - - - // Loop while we can further extend the strip - tri_node_iter TriNodeIt = (m_Triangles.begin() + StartTriPos); - - for (size_t Size = 1; Size < TriStrip.Size(); ++Size) { - - // Get the triangle edge that would lead to the next triangle - const triangle_edge Edge = GetLatestEdge(** TriNodeIt, Order); - - // Link to a neighbour triangle - const_tri_link_iter LinkIt; - for (LinkIt = TriNodeIt->out_begin(); LinkIt != TriNodeIt->out_end(); ++LinkIt) { - - // Get the reference to the possible next triangle - const triangle & Tri = (** ((*LinkIt).terminal())); - - // Check whether it's already been used - if (! ((*LinkIt).terminal()->marked())) { - - // Does the current candidate triangle match the required for the strip? - // If it does, then add it to the Indices - if ((Edge.B() == Tri.A()) && (Edge.A() == Tri.B())) { - Order = (ClockWise) ? triangle_strip::ABC : triangle_strip::BCA; - AddIndice(Tri.C()); - break; - } - - else if ((Edge.B() == Tri.B()) && (Edge.A() == Tri.C())) { - Order = (ClockWise) ? triangle_strip::BCA : triangle_strip::CAB; - AddIndice(Tri.A()); - break; - } - - else if ((Edge.B() == Tri.C()) && (Edge.A() == Tri.A())) { - Order = (ClockWise) ? triangle_strip::CAB : triangle_strip::ABC; - AddIndice(Tri.B()); - break; - } - } - } - - // Debug check: we must have found the next triangle - assert(LinkIt != TriNodeIt->out_end()); - - // Go to the next triangle - TriNodeIt = (*LinkIt).terminal(); - MarkTriAsTaken(TriNodeIt - m_Triangles.begin()); - - // Setup for the next triangle - ClockWise = ! ClockWise; - } -} - - - -void tri_stripper::MarkTriAsTaken(const size_t i) -{ - typedef triangles_graph::node_iterator tri_node_iter; - typedef triangles_graph::out_arc_iterator tri_link_iter; - - // Mark the triangle node - m_Triangles[i].mark(); - - // Remove triangle from priority queue if it isn't yet - if (! m_TriHeap.removed(i)) - m_TriHeap.erase(i); - - // Adjust the degree of available neighbour triangles - for (tri_link_iter LinkIt = m_Triangles[i].out_begin(); LinkIt != m_Triangles[i].out_end(); ++LinkIt) { - - const size_t j = (*LinkIt).terminal() - m_Triangles.begin(); - - if ((! m_Triangles[j].marked()) && (! m_TriHeap.removed(j))) { - triangle_degree NewDegree = m_TriHeap.peek(j); - NewDegree.SetDegree(NewDegree.Degree() - 1); - m_TriHeap.update(j, NewDegree); - - // Update the candidate list if cache is enabled - if ((m_CacheSize > 0) && (NewDegree.Degree() > 0)) - m_NextCandidates.push_back(j); - } - } -} - - - -inline void tri_stripper::AddIndiceToCache(const indice i, bool CacheHitCount) -{ - // Cache simulator enabled? - if (m_CacheSize > 0) { - - // Should we simulate the cache hits and count them? - if (CacheHitCount) { - if (std::find(m_IndicesCache.begin(), m_IndicesCache.end(), i) != m_IndicesCache.end()) - ++m_CacheHits; - } - - // Manage the indices cache as a FIFO structure - m_IndicesCache.pop_back(); - m_IndicesCache.push_front(i); - } -} - - - -inline void tri_stripper::AddIndice(const indice i) -{ - // Add the indice to the current indices array - m_PrimitivesVector.back().m_Indices.push_back(i); - - // Run cache simulator - AddIndiceToCache(i); -} - - - -inline void tri_stripper::AddTriToCache(const triangle & Tri, const triangle_strip::start_order Order) -{ - // Add Tri indices in the right order into the indices cache simulator. - // And enable the cache hit count - switch (Order) { - case triangle_strip::ABC: - AddIndiceToCache(Tri.A(), true); - AddIndiceToCache(Tri.B(), true); - AddIndiceToCache(Tri.C(), true); - return; - case triangle_strip::BCA: - AddIndiceToCache(Tri.B(), true); - AddIndiceToCache(Tri.C(), true); - AddIndiceToCache(Tri.A(), true); - return; - case triangle_strip::CAB: - AddIndiceToCache(Tri.C(), true); - AddIndiceToCache(Tri.A(), true); - AddIndiceToCache(Tri.B(), true); - return; - } -} - - - -inline void tri_stripper::AddTriToIndices(const triangle & Tri, const triangle_strip::start_order Order) -{ - // Add Tri indices in the right order into the latest Indices vector. - switch (Order) { - case triangle_strip::ABC: - AddIndice(Tri.A()); - AddIndice(Tri.B()); - AddIndice(Tri.C()); - return; - case triangle_strip::BCA: - AddIndice(Tri.B()); - AddIndice(Tri.C()); - AddIndice(Tri.A()); - return; - case triangle_strip::CAB: - AddIndice(Tri.C()); - AddIndice(Tri.A()); - AddIndice(Tri.B()); - return; - } -} - - - -void tri_stripper::AddLeftTriangles() -{ - // Create the latest indices array - // and fill it with all the triangles that couldn't be stripped - primitives Primitives; - Primitives.m_Type = PT_Triangles; - m_PrimitivesVector.push_back(Primitives); - indices & Indices = m_PrimitivesVector.back().m_Indices; - - for (size_t i = 0; i < m_Triangles.size(); ++i) - if (! m_Triangles[i].marked()) { - Indices.push_back(m_Triangles[i]->A()); - Indices.push_back(m_Triangles[i]->B()); - Indices.push_back(m_Triangles[i]->C()); - } - - // Undo if useless - if (Indices.size() == 0) - m_PrimitivesVector.pop_back(); -} - - - - -}; // namespace triangle_stripper diff --git a/apps/nexus/tristripper/tri_stripper.h b/apps/nexus/tristripper/tri_stripper.h deleted file mode 100644 index 80c1701b..00000000 --- a/apps/nexus/tristripper/tri_stripper.h +++ /dev/null @@ -1,372 +0,0 @@ -// tri_stripper.h: interface for the tri_stripper class. -// -////////////////////////////////////////////////////////////////////// -// -// Copyright (C) 2002 Tanguy Fautré. -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would be -// appreciated but is not required. -// 2. Altered source versions must be plainly marked as such, and must not be -// misrepresented as being the original software. -// 3. This notice may not be removed or altered from any source distribution. -// -// Tanguy Fautré -// softdev@pandora.be -// -////////////////////////////////////////////////////////////////////// -// -// Tri Stripper -// ************ -// -// Current version: 1.00 BETA 5 (10/12/2002) -// -// Comment: Triangle stripper in O(n.log(n)). -// -// Currently there are no protection against crazy values -// given via SetMinStripSize() and SetCacheSize(). -// So be careful. (Min. strip size should be equal or greater -// than 2, cache size should be about 10 for GeForce 256/2 -// and about 16-18 for GeForce 3/4.) -// -// History: - 1.00 BETA 5 (10/12/2002) - Fixed a bug in Stripify() that could sometimes -// cause it to go into an infinite loop. -// (thanks to Remy for the bug report) -// - 1.00 BETA 4 (18/11/2002) - Removed the dependency on OpenGL: -// modified gl_primitives to primitives, -// and gl_primitives_vector to primitives_vector; -// and added primitive_type. -// (thanks to Patrik for noticing this useless dependency) -// - 1.00 BETA 3 (18/11/2002) - Fixed a bug in LinkNeightboursTri() that could cause a crash -// (thanks to Nicolas for finding it) -// - 1.00 BETA 2 (16/11/2002) - Improved portability -// - 1.00 BETA 1 (27/10/2002) - First public release -// -////////////////////////////////////////////////////////////////////// - -#pragma once - -#include - -// namespace triangle_stripper -namespace triangle_stripper { - - - -//#include "../Common Structures/graph_array.h" -//#include "../Common Structures/heap_array.h" -#include "graph_array.h" -#include "heap_array.h" - - - -class tri_stripper -{ -public: - - // New Public types - typedef unsigned int indice; - typedef std::vector indices; - - enum primitive_type { - PT_Triangles = 0x0004, // = GL_TRIANGLES - PT_Triangle_Strip = 0x0005 // = GL_TRIANGLE_STRIP - }; - - struct primitives - { - indices m_Indices; - primitive_type m_Type; - }; - - typedef std::vector primitives_vector; - - struct triangles_indices_error { }; - - - // constructor/initializer - tri_stripper(const indices & TriIndices); - - // Settings functions - void SetCacheSize(const size_t CacheSize = 16); // = 0 will disable the cache optimizer - void SetMinStripSize(const size_t MinStripSize = 2); - - // Stripper - void Strip(primitives_vector * out_pPrimitivesVector); // throw triangles_indices_error(); - -private: - - friend struct _cmp_tri_interface_lt; - - - class triangle - { - public: - triangle(); - triangle(const indice A, const indice B, const indice C); - - void SetStripID(const size_t StripID); - - indice A() const; - indice B() const; - indice C() const; - size_t StripID() const; - - private: - indice m_A; - indice m_B; - indice m_C; - size_t m_StripID; - }; - - - class triangle_edge - { - public: - triangle_edge(const indice A, const indice B, const size_t TriPos); - - indice A() const; - indice B() const; - size_t TriPos() const; - - private: - indice m_A; - indice m_B; - size_t m_TriPos; - }; - - - class triangle_degree - { - public: - triangle_degree(); - triangle_degree(const size_t TriPos, const size_t Degree); - - size_t Degree() const; - size_t TriPos() const; - - void SetDegree(const size_t Degree); - - private: - size_t m_TriPos; - size_t m_Degree; - }; - - - class triangle_strip - { - public: - enum start_order { ABC = 0, BCA = 1, CAB = 2 }; - - triangle_strip(); - triangle_strip(size_t StartTriPos, start_order StartOrder, size_t Size); - - size_t StartTriPos() const; - start_order StartOrder() const; - size_t Size() const; - - private: - size_t m_StartTriPos; - start_order m_StartOrder; - size_t m_Size; - }; - - - struct _cmp_tri_interface_lt - { - bool operator() (const triangle_edge & a, const triangle_edge & b) const; - }; - - - struct _cmp_tri_degree_gt - { - bool operator () (const triangle_degree & a, const triangle_degree & b) const; - }; - - - typedef common_structures::graph_array triangles_graph; - typedef common_structures::heap_array triangles_heap; - typedef std::vector triangle_edges; - typedef std::vector triangle_indices; - typedef std::deque indices_cache; - - - void InitCache(); - void InitTriGraph(); - void InitTriHeap(); - void Stripify(); - void AddLeftTriangles(); - - void LinkNeighboursTri(const triangle_edges & TriInterface, const triangle_edge Edge); - void MarkTriAsTaken(const size_t i); - - triangle_edge GetLatestEdge(const triangle & Triangle, const triangle_strip::start_order Order) const; - - triangle_strip FindBestStrip(); - triangle_strip ExtendTriToStrip(const size_t StartTriPos, const triangle_strip::start_order StartOrder); - void BuildStrip(const triangle_strip TriStrip); - void AddIndice(const indice i); - void AddIndiceToCache(const indice i, bool CacheHitCount = false); - void AddTriToCache(const triangle & Tri, const triangle_strip::start_order Order); - void AddTriToIndices(const triangle & Tri, const triangle_strip::start_order Order); - - const indices & m_TriIndices; - - size_t m_MinStripSize; - size_t m_CacheSize; - - primitives_vector m_PrimitivesVector; - triangles_graph m_Triangles; - triangles_heap m_TriHeap; - triangle_indices m_NextCandidates; - indices_cache m_IndicesCache; - size_t m_StripID; - size_t m_CacheHits; -}; - - - - -////////////////////////////////////////////////////////////////////////// -// tri_stripper Inline functions -////////////////////////////////////////////////////////////////////////// - -inline tri_stripper::tri_stripper(const indices & TriIndices) : m_TriIndices(TriIndices) { - SetCacheSize(); - SetMinStripSize(); -} - - -inline void tri_stripper::SetCacheSize(const size_t CacheSize) { - m_CacheSize = CacheSize; -} - - -inline void tri_stripper::SetMinStripSize(const size_t MinStripSize) { - m_MinStripSize = MinStripSize; -} - - -inline tri_stripper::triangle::triangle() { } - - -inline tri_stripper::triangle::triangle(const indice A, const indice B, const indice C) : m_A(A), m_B(B), m_C(C), m_StripID(0) { } - - -inline void tri_stripper::triangle::SetStripID(const size_t StripID) { - m_StripID = StripID; -} - - -inline tri_stripper::indice tri_stripper::triangle::A() const { - return m_A; -} - - -inline tri_stripper::indice tri_stripper::triangle::B() const { - return m_B; -} - - -inline tri_stripper::indice tri_stripper::triangle::C() const { - return m_C; -} - - -inline size_t tri_stripper::triangle::StripID() const { - return m_StripID; -} - - -inline tri_stripper::triangle_edge::triangle_edge(const indice A, const indice B, const size_t TriPos) : m_A(A), m_B(B), m_TriPos(TriPos) { } - - -inline tri_stripper::indice tri_stripper::triangle_edge::A() const { - return m_A; -} - - -inline tri_stripper::indice tri_stripper::triangle_edge::B() const { - return m_B; -} - - -inline size_t tri_stripper::triangle_edge::TriPos() const { - return m_TriPos; -} - - -inline tri_stripper::triangle_degree::triangle_degree() { } - - -inline tri_stripper::triangle_degree::triangle_degree(const size_t TriPos, const size_t Degree) : m_TriPos(TriPos), m_Degree(Degree) { } - - -inline size_t tri_stripper::triangle_degree::Degree() const { - return m_Degree; -} - - -inline size_t tri_stripper::triangle_degree::TriPos() const { - return m_TriPos; -} - - -inline void tri_stripper::triangle_degree::SetDegree(const size_t Degree) { - m_Degree = Degree; -} - - -inline tri_stripper::triangle_strip::triangle_strip() : m_StartTriPos(0), m_StartOrder(ABC), m_Size(0) { } - - -inline tri_stripper::triangle_strip::triangle_strip(const size_t StartTriPos, const start_order StartOrder, const size_t Size) - : m_StartTriPos(StartTriPos), m_StartOrder(StartOrder), m_Size(Size) { } - - -inline size_t tri_stripper::triangle_strip::StartTriPos() const { - return m_StartTriPos; -} - - -inline tri_stripper::triangle_strip::start_order tri_stripper::triangle_strip::StartOrder() const { - return m_StartOrder; -} - - -inline size_t tri_stripper::triangle_strip::Size() const { - return m_Size; -} - - -inline bool tri_stripper::_cmp_tri_interface_lt::operator() (const triangle_edge & a, const triangle_edge & b) const { - const tri_stripper::indice A1 = a.A(); - const tri_stripper::indice B1 = a.B(); - const tri_stripper::indice A2 = b.A(); - const tri_stripper::indice B2 = b.B(); - - if ((A1 < A2) || ((A1 == A2) && (B1 < B2))) - return true; - else - return false; -} - - -inline bool tri_stripper::_cmp_tri_degree_gt::operator () (const triangle_degree & a, const triangle_degree & b) const { - // the triangle with a smaller degree has more priority - return a.Degree() > b.Degree(); -} - - - - -}; // namespace triangle_stripper diff --git a/apps/nexus/vchain.cpp b/apps/nexus/vchain.cpp deleted file mode 100644 index faf9dadc..00000000 --- a/apps/nexus/vchain.cpp +++ /dev/null @@ -1,134 +0,0 @@ -/**************************************************************************** -* VCGLib o o * -* Visual and Computer Graphics Library o o * -* _ O _ * -* Copyright(C) 2004 \/)\/ * -* Visual Computing Lab /\/| * -* ISTI - Italian National Research Council | * -* \ * -* All rights reserved. * -* * -* This program is free software; you can redistribute it and/or modify * -* it under the terms of the GNU General Public License as published by * -* the Free Software Foundation; either version 2 of the License, or * -* (at your option) any later version. * -* * -* This program is distributed in the hope that it will be useful, * -* but WITHOUT ANY WARRANTY; without even the implied warranty of * -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * -* GNU General Public License (http://www.gnu.org/licenses/gpl.txt) * -* for more details. * -* * -****************************************************************************/ -/**************************************************************************** - History - -$Log: not supported by cvs2svn $ - -****************************************************************************/ - -#include "vchain.h" -#include -#include - -using namespace std; -using namespace vcg; -using namespace nxs; - -VChain::~VChain() { - for(iterator i = begin(); i != end(); i++) - delete *i; -} - -bool VChain::Save(const string &file) { - FILE *fp = fopen(file.c_str(), "wb+"); - if(!fp) { - cerr << "Could not save vchain data.\n"; - return false; - } - - unsigned int nlevels = size(); - fwrite(&nlevels, sizeof(unsigned int), 1, fp); - for(unsigned int i = 0; i < nlevels; i++) { - VPartition &level = *operator[](i); - unsigned int npoints = level.size(); - fwrite(&npoints, sizeof(unsigned int), 1, fp); - fwrite(&(level[0]), sizeof(Point3f), npoints, fp); - } - //writing fragments - - unsigned int nfrag = newfragments.size(); - fwrite(&nfrag, sizeof(unsigned int), 1, fp); - - std::map >::iterator j; - for(j = newfragments.begin(); j != newfragments.end(); j++) { - unsigned int n = (*j).second.size(); - fwrite(&((*j).first), sizeof(unsigned int), 1, fp); - fwrite(&n, sizeof(unsigned int), 1, fp); - set::iterator k; - for(k = (*j).second.begin(); k != (*j).second.end(); k++) - fwrite(&*k, sizeof(unsigned int), 1, fp); - } - nfrag = oldfragments.size(); - fwrite(&nfrag, sizeof(unsigned int), 1, fp); - - for(j = oldfragments.begin(); j != oldfragments.end(); j++) { - unsigned int n = (*j).second.size(); - fwrite(&((*j).first), sizeof(unsigned int), 1, fp); - fwrite(&n, sizeof(unsigned int), 1, fp); - set::iterator k; - for(k = (*j).second.begin(); k != (*j).second.end(); k++) - fwrite(&*k, sizeof(unsigned int), 1, fp); - } - fclose(fp); - return true; -} - -bool VChain::Load(const string &file) { - FILE *fp = fopen(file.c_str(), "rb"); - if(!fp) { - cerr << "Could not load vchain data\n"; - return false; - } - unsigned int nlevels; - fread(&nlevels, sizeof(unsigned int), 1, fp); - for(unsigned int i = 0; i < nlevels; i++) { - push_back(new VPartition()); - VPartition &level = *back(); - - unsigned int npoints; - fread(&npoints, sizeof(unsigned int), 1, fp); - level.resize(npoints); - fread(&(level[0]), sizeof(Point3f), npoints, fp); - level.Init(); - } - //reading fragments - unsigned int nfrag; - fread(&nfrag, sizeof(unsigned int), 1, fp); - for(unsigned int i = 0; i < nfrag; i++) { - unsigned int p, n; - fread(&p, sizeof(unsigned int), 1, fp); - set &s = newfragments[p]; - fread(&n, sizeof(unsigned int), 1, fp); - for(unsigned int k = 0; k < n; k++) { - unsigned int j; - fread(&j, sizeof(unsigned int), 1, fp); - s.insert(j); - } - } - - fread(&nfrag, sizeof(unsigned int), 1, fp); - for(unsigned int i = 0; i < nfrag; i++) { - unsigned int p, n; - fread(&p, sizeof(unsigned int), 1, fp); - set &s = oldfragments[p]; - fread(&n, sizeof(unsigned int), 1, fp); - for(unsigned int k = 0; k < n; k++) { - unsigned int j; - fread(&j, sizeof(unsigned int), 1, fp); - s.insert(j); - } - } - fclose(fp); - return true; -} diff --git a/apps/nexus/vchain.h b/apps/nexus/vchain.h deleted file mode 100644 index 5d5a58e1..00000000 --- a/apps/nexus/vchain.h +++ /dev/null @@ -1,51 +0,0 @@ -/**************************************************************************** -* VCGLib o o * -* Visual and Computer Graphics Library o o * -* _ O _ * -* Copyright(C) 2004 \/)\/ * -* Visual Computing Lab /\/| * -* ISTI - Italian National Research Council | * -* \ * -* All rights reserved. * -* * -* This program is free software; you can redistribute it and/or modify * -* it under the terms of the GNU General Public License as published by * -* the Free Software Foundation; either version 2 of the License, or * -* (at your option) any later version. * -* * -* This program is distributed in the hope that it will be useful, * -* but WITHOUT ANY WARRANTY; without even the implied warranty of * -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * -* GNU General Public License (http://www.gnu.org/licenses/gpl.txt) * -* for more details. * -* * -****************************************************************************/ -/**************************************************************************** - History - -$Log: not supported by cvs2svn $ - -****************************************************************************/ - -#ifndef NXS_VCHAIN_H -#define NXS_VCHAIN_H - -#include -#include -#include -#include "vpartition.h" - -namespace nxs { - -class VChain: public std::vector { - public: - ~VChain(); - bool Save(const std::string &file); - bool Load(const std::string &file); - - std::map > newfragments; - std::map > oldfragments; -}; - -} -#endif diff --git a/apps/nexus/vfile.h b/apps/nexus/vfile.h deleted file mode 100644 index eb194c71..00000000 --- a/apps/nexus/vfile.h +++ /dev/null @@ -1,317 +0,0 @@ -/**************************************************************************** -* VCGLib o o * -* Visual and Computer Graphics Library o o * -* _ O _ * -* Copyright(C) 2004 \/)\/ * -* Visual Computing Lab /\/| * -* ISTI - Italian National Research Council | * -* \ * -* All rights reserved. * -* * -* This program is free software; you can redistribute it and/or modify * -* it under the terms of the GNU General Public License as published by * -* the Free Software Foundation; either version 2 of the License, or * -* (at your option) any later version. * -* * -* This program is distributed in the hope that it will be useful, * -* but WITHOUT ANY WARRANTY; without even the implied warranty of * -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * -* GNU General Public License (http://www.gnu.org/licenses/gpl.txt) * -* for more details. * -* * -****************************************************************************/ -/**************************************************************************** - History - -$Log: not supported by cvs2svn $ -Revision 1.19 2004/12/03 01:20:56 ponchio -Debug - -Revision 1.18 2004/12/01 03:24:32 ponchio -Level 2. - -Revision 1.17 2004/11/30 22:49:39 ponchio -Level 0. - -Revision 1.16 2004/11/28 04:12:04 ponchio -winsockapi include problem - -Revision 1.15 2004/11/18 18:30:14 ponchio -Using baricenters... lotsa changes. - -Revision 1.14 2004/10/19 16:50:27 ponchio -Added row file access .... - -Revision 1.13 2004/10/08 15:12:04 ponchio -Working version (maybe) - -Revision 1.12 2004/10/04 16:49:54 ponchio -Daily backup. Preparing for compression. - -Revision 1.11 2004/10/01 16:00:12 ponchio -Added include - -Revision 1.10 2004/09/30 23:56:33 ponchio -Backup (added strips and normals) - -Revision 1.9 2004/07/20 14:04:32 ponchio -Improved efficience in operator[] - -Revision 1.8 2004/07/15 14:32:49 ponchio -Debug. - -Revision 1.7 2004/07/05 15:49:39 ponchio -Windows (DevCpp, mingw) port. - -Revision 1.6 2004/07/04 15:23:48 ponchio -Debug - -Revision 1.5 2004/07/02 17:41:37 ponchio -Debug. - -Revision 1.4 2004/07/02 13:02:39 ponchio -Added GetRegion, Read and Write - -Revision 1.3 2004/07/01 21:36:54 ponchio -*** empty log message *** - -Revision 1.2 2004/06/25 16:47:13 ponchio -Various debug - -Revision 1.1 2004/06/24 14:32:45 ponchio -Moved from wrap/nexus - -Revision 1.3 2004/06/22 15:32:09 ponchio -Tested - -Revision 1.2 2004/06/22 10:27:16 ponchio -*** empty log message *** - -Revision 1.1 2004/06/22 00:39:56 ponchio -Created - - -****************************************************************************/ - -#ifndef VFILE_H -#define VFILE_H - -#include "mfile.h" - -#include -#include -#include -#include - -/**Vector structure on file with simulated mmapping. - * a priority queue of buffers is used - * TODO: port to over 4Gb usable space - * add interface for readonly reads even when file is readwrite... - * instead of queue size use ramsize!!!! - * some mechanism to report errors? - * use an Iterator? - */ - -namespace nxs { - -template class VFile: public MFile { - public: - - struct Buffer { - unsigned int key; - unsigned int size; //in number of elements - T *data; - }; - - protected: - unsigned int n_elements; - std::list buffers; - typedef typename std::list::iterator list_iterator; - - std::map index; //TODO move to hash_map - Buffer *last_buffer; - - unsigned int chunk_size; //default buffer size (expressed in number of T) - unsigned int queue_size; - - public: - class iterator { - public: - iterator(unsigned int p = 0, VFile *b = 0): n(p), buffer(b) {} - T &operator*() { return (*buffer)[n]; } - void operator++() { n++; } - bool operator!=(const iterator &i) { return i.n != n; } - private: - unsigned int n; - VFile *buffer; - }; - - VFile(): last_buffer(NULL) {} - ~VFile() { Close(); } - bool Create(const std::string &filename, - unsigned int _chunk_size = 4096/sizeof(T), - unsigned int _queue_size = 1000) { - - assert(_chunk_size > 0); - n_elements = 0; - last_buffer = NULL; - chunk_size = _chunk_size; - queue_size = _queue_size; - - return MFile::Create(filename); - } - - bool Load(const std:: string &filename, bool rdonly = false, - unsigned int _chunk_size = 4096/sizeof(T), - unsigned int _queue_size = 1000) { - - assert(_chunk_size > 0); - last_buffer = NULL; - chunk_size = _chunk_size; - queue_size = _queue_size; - - if(!MFile::Load(filename, rdonly)) return false; - n_elements = _size/sizeof(T); - return true; - } - - void Close() { - Flush(); - } - - void Delete() { - Flush(); - MFile::Delete(); - } - - void Flush() { - list_iterator i; - for(i = buffers.begin(); i != buffers.end(); i++) - FlushBuffer(*i); - buffers.clear(); - index.clear(); - last_buffer = NULL; - } - - void FlushBuffer(Buffer buffer) { - if(!readonly) { - SetPosition((int64)buffer.key * (int64)chunk_size * (int64)sizeof(T)); - WriteBuffer((char *)(buffer.data), buffer.size * sizeof(T)); - } - delete []buffer.data; - } - - void Resize(unsigned int elem) { - //TODO do i really need to flush? - Flush(); - MFile::Redim((int64)elem * (int64)sizeof(T)); - n_elements = elem; - } - - /** Remember that T is a valid pointer only until next call of - * getElement or setElement - */ - T &operator[](unsigned int n) { - - assert(n < n_elements); - - unsigned int chunk = n/chunk_size; - unsigned int offset = n - chunk*chunk_size; - assert(offset < chunk_size * sizeof(T)); - - if(last_buffer && last_buffer->key == chunk) - return *(last_buffer->data + offset); - - if(index.count(chunk)) { - last_buffer = &*index[chunk]; - return *((*(index[chunk])).data + offset); - } - - if(buffers.size() > queue_size) { - Buffer &buffer= buffers.back(); - assert(buffer.key != chunk); - FlushBuffer(buffer); - index.erase(buffer.key); - buffers.pop_back(); - } - - Buffer buffer; - buffer.key = chunk; - buffer.size = chunk_size; - - if(buffer.size + chunk * chunk_size > n_elements) - buffer.size = n_elements - chunk * chunk_size; - - buffer.data = new T[buffer.size]; - - buffers.push_front(buffer); - index[buffer.key] = buffers.begin(); - last_buffer = &*buffers.begin(); - - SetPosition((int64)chunk * (int64)chunk_size * (int64)sizeof(T)); - ReadBuffer((char *)(buffer.data), buffer.size * sizeof(T)); - - return *(buffer.data + offset); - } - - /** you can get a region instead of an element but: - 1)region must be Chunk aligned. - 2)you get impredictable results if regions overlap or mix with operator[] - */ - T *GetRegion(unsigned int start, unsigned int size, bool flush = true) { - assert(start + size <= n_elements); - assert((size % chunk_size) == 0); - assert((start % chunk_size) == 0); - if(size == 0) return NULL; - - unsigned int chunk = start/chunk_size; - - if(index.count(chunk)) - return ((*(index[chunk])).data); - - while(flush && buffers.size() > queue_size) { - Buffer &buffer= buffers.back(); - FlushBuffer(buffer); - index.erase(buffer.key); - buffers.pop_back(); - } - - Buffer buffer; - buffer.key = chunk; - buffer.size = size; - buffer.data = new T[buffer.size]; - - buffers.push_front(buffer); - index[chunk] = buffers.begin(); - - SetPosition((int64)chunk * (int64)chunk_size * (int64)sizeof(T)); - ReadBuffer((char *)(buffer.data), buffer.size * sizeof(T)); - return buffer.data; - } - //non buffered read only acces. - T read(unsigned int element) { - SetPosition((int64)element * (int64)sizeof(T)); - T t; - ReadBuffer(&t, sizeof(T)); - return t; - } - void write(unsigned int element, T &t) { - SetPosition((int64)element * (int64)sizeof(T)); - WriteBuffer(&t, sizeof(T)); - } - - void PushBack(const T &t) { - Resize(n_elements+1); - operator[](n_elements-1) = t; - } - - unsigned int Size() { return n_elements; } - unsigned int ChunkSize() { return chunk_size; } - unsigned int QueueSize() { return queue_size; } - iterator Begin() { return iterator(0, this); } - iterator End() { return iterator(Size(), this); } -}; - -}//namespace - -#endif diff --git a/apps/nexus/vpartition.cpp b/apps/nexus/vpartition.cpp deleted file mode 100644 index a4b8e027..00000000 --- a/apps/nexus/vpartition.cpp +++ /dev/null @@ -1,171 +0,0 @@ -/**************************************************************************** -* VCGLib o o * -* Visual and Computer Graphics Library o o * -* _ O _ * -* Copyright(C) 2004 \/)\/ * -* Visual Computing Lab /\/| * -* ISTI - Italian National Research Council | * -* \ * -* All rights reserved. * -* * -* This program is free software; you can redistribute it and/or modify * -* it under the terms of the GNU General Public License as published by * -* the Free Software Foundation; either version 2 of the License, or * -* (at your option) any later version. * -* * -* This program is distributed in the hope that it will be useful, * -* but WITHOUT ANY WARRANTY; without even the implied warranty of * -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * -* GNU General Public License (http://www.gnu.org/licenses/gpl.txt) * -* for more details. * -* * -****************************************************************************/ -/**************************************************************************** - History - -$Log: not supported by cvs2svn $ -Revision 1.5 2005/02/22 10:38:17 ponchio -Debug, cleaning and optimization. - -Revision 1.4 2005/02/21 17:55:48 ponchio -debug debug debug - -Revision 1.3 2005/01/21 17:09:13 ponchio -Porting and debug. - -Revision 1.2 2004/12/04 13:24:27 ponchio -Fixed a couple of memory leak... - -Revision 1.1 2004/11/30 22:50:30 ponchio -Level 0. - - -****************************************************************************/ - -#include - -#include "vpartition.h" -#include - -using namespace std; -using namespace vcg; -using namespace nxs; - -VPartition::~VPartition() { - if(bd) delete bd; -} - -void VPartition::Init() { - if(bd) delete bd; - buffer.resize(size() * 3); - for(unsigned int i = 0; i < size(); i++) { - for(int k = 0; k < 3; k++) - buffer[i*3+k] = operator[](i)[k]; - } - points.resize(size()); - for(unsigned int i = 0; i < size(); i++) { - points[i] = &buffer[i*3]; - } - bd = new ANNkd_tree(&*points.begin(), size(), 3); -} - -void VPartition::Closest(const vcg::Point3f &p, unsigned int nsize, - vector &nears, - vector &dist) { - double point[3]; - point[0] = p[0]; - point[1] = p[1]; - point[2] = p[2]; - if(nsize > size()) nsize = size(); - - nears.resize(nsize); - dist.resize(nsize); - vector dists; - dists.resize(nsize); - bd->annkSearch(&point[0], nsize, &*nears.begin(), &*dists.begin()); - for(unsigned int i = 0; i < nsize; i++) - dist[i] = (float)dists[i]; -} - -void VPartition::Closest(const vcg::Point3f &p, - int &target, float &dist) { - double point[3]; - point[0] = p[0]; - point[1] = p[1]; - point[2] = p[2]; - double dists; - bd->annkSearch(&point[0], 1, &target, &dists); - assert(target >= 0); - assert(target < size()); - - dist = (float)dists; -} - -void VPartition::Closest(const vcg::Point3f &p, - vector &targets, - vector &dists, - float max_distance) { - - double point[3]; point[0] = p[0]; point[1] = p[1]; point[2] = p[2]; - - int seeds = 6; - while(1) { - if(seeds > size()) seeds = size(); - targets.resize(seeds); - dists.resize(seeds); - bd->annkSearch(&point[0], seeds, &(targets[0]), &(dists[0])); - for(int i = 0; i < seeds; i++) { - if(dists[i] > max_distance) { - targets.resize(i); - dists.resize(i); - break; - } - } - if(targets.size() < seeds) break; - if(seeds == size()) break; - seeds *= 2; - } -} - -void VPartition::Closest(const vcg::Point3f &p, unsigned int nsize, - int *targets, - double *dists) { - double point[3]; - point[0] = p[0]; - point[1] = p[1]; - point[2] = p[2]; - bd->annkSearch(&point[0], nsize, targets, dists); -} - -int VPartition::Locate(const vcg::Point3f &p) { - - double point[3]; - point[0] = p[0]; - point[1] = p[1]; - point[2] = p[2]; - - int target = -1; - double dists; - bd->annkSearch(&point[0], 1, &target, &dists); - - return target; -} - -float VPartition::Radius(unsigned int seed) { - assert(size() > 1); - int nears[2]; - double dists[2]; - - double point[3]; - Point3f &p = operator[](seed); - point[0] = p[0]; - point[1] = p[1]; - point[2] = p[2]; - bd->annkSearch(&point[0], 2, nears, dists); - - if(dists[1] == 0) return 0.0f; - assert(nears[0] == seed); - assert(dists[0] == 0); - - return (float)sqrt(dists[1]); -} diff --git a/apps/nexus/vpartition.h b/apps/nexus/vpartition.h deleted file mode 100644 index 0453a825..00000000 --- a/apps/nexus/vpartition.h +++ /dev/null @@ -1,99 +0,0 @@ -/**************************************************************************** -* VCGLib o o * -* Visual and Computer Graphics Library o o * -* _ O _ * -* Copyright(C) 2004 \/)\/ * -* Visual Computing Lab /\/| * -* ISTI - Italian National Research Council | * -* \ * -* All rights reserved. * -* * -* This program is free software; you can redistribute it and/or modify * -* it under the terms of the GNU General Public License as published by * -* the Free Software Foundation; either version 2 of the License, or * -* (at your option) any later version. * -* * -* This program is distributed in the hope that it will be useful, * -* but WITHOUT ANY WARRANTY; without even the implied warranty of * -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * -* GNU General Public License (http://www.gnu.org/licenses/gpl.txt) * -* for more details. * -* * -****************************************************************************/ -/**************************************************************************** - History - -$Log: not supported by cvs2svn $ -Revision 1.4 2005/02/21 17:55:49 ponchio -debug debug debug - -Revision 1.3 2005/01/18 22:46:58 ponchio -Small changes. - -Revision 1.2 2004/12/04 13:24:28 ponchio -Fixed a couple of memory leak... - -Revision 1.1 2004/11/30 22:50:30 ponchio -Level 0. - - -****************************************************************************/ - -#ifndef NXS_VPARTITION_H -#define NXS_VPARTITION_H - -#include -#include - -#include - - -//TODO provide a Sort function, to sort spatially the seeds. - -class ANNkd_tree; -class ANNbd_tree; -class ANNbruteForce; - -namespace nxs { - - //WARNING: all distances returned are SQUARED!!!! -class VPartition: public std::vector { - public: - VPartition(): bd(NULL) {} - ~VPartition(); - private: - VPartition &operator=(const VPartition &part) { - for(unsigned int i = 0; i < part.size(); i++) - push_back(part[i]); - Init(); - return *this; - } - public: - void Init(); - int Locate(const vcg::Point3f &p); - - //looks for the min distance point from seed. - float Radius(unsigned int seed); - void Closest(const vcg::Point3f &p, unsigned int nsize, - std::vector &nears, - std::vector &dist); - void Closest(const vcg::Point3f &p, - int &target, float &dist); - - //return all targets widthin that distance (SQUARED!!!) - void Closest(const vcg::Point3f &p, std::vector &targets, - std::vector &dists, - float max_distance); - //most efficient! - void Closest(const vcg::Point3f &p, unsigned int nsize, - int *targets, - double *dists); - - - ANNkd_tree *bd; - std::vector buffer; - std::vector points; -}; - -} //namespace nxs -#endif diff --git a/apps/nexus/watch.cpp b/apps/nexus/watch.cpp deleted file mode 100644 index f35491c6..00000000 --- a/apps/nexus/watch.cpp +++ /dev/null @@ -1,155 +0,0 @@ -/**************************************************************************** -* VCGLib o o * -* Visual and Computer Graphics Library o o * -* _ O _ * -* Copyright(C) 2004 \/)\/ * -* Visual Computing Lab /\/| * -* ISTI - Italian National Research Council | * -* \ * -* All rights reserved. * -* * -* This program is free software; you can redistribute it and/or modify * -* it under the terms of the GNU General Public License as published by * -* the Free Software Foundation; either version 2 of the License, or * -* (at your option) any later version. * -* * -* This program is distributed in the hope that it will be useful, * -* but WITHOUT ANY WARRANTY; without even the implied warranty of * -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * -* GNU General Public License (http://www.gnu.org/licenses/gpl.txt) * -* for more details. * -* * -****************************************************************************/ -/**************************************************************************** - History - -$Log: not supported by cvs2svn $ -Revision 1.3 2004/10/21 13:40:16 ponchio -Debugging. - -Revision 1.2 2004/10/21 12:14:02 ponchio -Support for mfile (>4Gb) - -Revision 1.1 2004/10/19 17:20:24 ponchio -renamed - -Revision 1.5 2004/10/19 17:16:52 ponchio -Changed interface - -Revision 1.4 2004/07/30 12:44:14 ponchio -#ifdef corrected - -Revision 1.3 2004/07/20 14:03:47 ponchio -Changed interface. - -Revision 1.2 2004/07/05 15:49:39 ponchio -Windows (DevCpp, mingw) port. - -Revision 1.1 2004/07/01 21:38:30 ponchio -First draft created. - - -****************************************************************************/ -#include "watch.h" -#include - -#ifdef WIN32 -Watch::Watch(): elapsed(0) { - QueryPerformanceFrequency(&freq); -} - - -void Watch::Start(void) { - QueryPerformanceCounter(&tstart); - elapsed = 0; -} - -double Watch::Pause() { - QueryPerformanceCounter(&tend); - elapsed += Diff(); - return (double)elapsed; -} - -void Watch::Continue() { - QueryPerformanceCounter(&tstart); -} - -double Watch::Time() { - QueryPerformanceCounter(&tend); - return (double)(elapsed + Diff()); -} - -double Watch::Diff() { - return ((double)tend.QuadPart - - (double)tstart.QuadPart)/ - ((double)freq.QuadPart); -} - -#else - -Watch::Watch(): elapsed() {} - -void Watch::Start() { - gettimeofday(&tstart, &tz); - elapsed = 0; -} - -double Watch::Pause() { - gettimeofday(&tend, &tz); - elapsed += Diff(); - return (double)elapsed; -} - -void Watch::Continue() { - gettimeofday(&tstart, &tz); -} - -double Watch::Time() { - gettimeofday(&tend, &tz); - return (double)(elapsed + Diff()); -} - -double Watch::Diff() { - double t1 = (double)tstart.tv_sec + (double)tstart.tv_usec/(1000*1000); - double t2 = (double)tend.tv_sec + (double)tend.tv_usec/(1000*1000); - return t2 - t1; -} -#endif - -void Watch::Reset() { - elapsed = 0; -} - -int Watch::Usec() { -#ifdef WIN32 - return 0; -#else - struct timeval ttime; - gettimeofday(&ttime, &tz); - return ttime.tv_usec; -#endif -} - -void Report::Init(unsigned int t, double inter) { - watch.Start(); - tot = t; - last = 0; - interval = inter; -} - -void Report::Step(unsigned int count) { - if(count == 0) return; - double now = watch.Time(); - if(now - last < interval) return; - //estimate final time - double tot_time = now * tot/(double)count; - printf("%d/%d\telapsed: %.1f\tremaining: %.1f\ttotal: %.1f\n", - count, tot, now, tot_time - now, tot_time); - last = now; -} - -void Report::Finish() { - double now = watch.Time(); - printf("Tot: %.1f\tN: %d\tN/sec: %.1f\n", - now, tot, tot/now); -} diff --git a/apps/nexus/watch.h b/apps/nexus/watch.h deleted file mode 100644 index 160af708..00000000 --- a/apps/nexus/watch.h +++ /dev/null @@ -1,108 +0,0 @@ -/**************************************************************************** -* VCGLib o o * -* Visual and Computer Graphics Library o o * -* _ O _ * -* Copyright(C) 2004 \/)\/ * -* Visual Computing Lab /\/| * -* ISTI - Italian National Research Council | * -* \ * -* All rights reserved. * -* * -* This program is free software; you can redistribute it and/or modify * -* it under the terms of the GNU General Public License as published by * -* the Free Software Foundation; either version 2 of the License, or * -* (at your option) any later version. * -* * -* This program is distributed in the hope that it will be useful, * -* but WITHOUT ANY WARRANTY; without even the implied warranty of * -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * -* GNU General Public License (http://www.gnu.org/licenses/gpl.txt) * -* for more details. * -* * -****************************************************************************/ -/**************************************************************************** - History - -$Log: not supported by cvs2svn $ -Revision 1.6 2004/12/15 13:50:32 ponchio -Optimizing realtime vis. - -Revision 1.5 2004/12/01 16:00:35 ponchio -Level 3 - -Revision 1.4 2004/11/28 04:10:59 ponchio -winsockapi include problem - -Revision 1.3 2004/10/21 13:40:16 ponchio -Debugging. - -Revision 1.2 2004/10/21 12:14:02 ponchio -Support for mfile (>4Gb) - -Revision 1.1 2004/10/19 17:20:24 ponchio -renamed - -Revision 1.4 2004/10/19 17:16:53 ponchio -Changed interface - -Revision 1.3 2004/07/20 14:03:47 ponchio -Changed interface. - -Revision 1.2 2004/07/05 15:49:39 ponchio -Windows (DevCpp, mingw) port. - -Revision 1.1 2004/07/01 21:38:30 ponchio -First draft created. - - -****************************************************************************/ - -#ifndef VCG_WATCH_H -#define VCG_WATCH_H - -#ifdef WIN32 -#ifndef _WINDOWS_ -#define _WINSOCKAPI_ -#include -#endif -#else -#include -#include -#endif - -class Watch { -public: - Watch(); - void Start(); - double Pause(); - void Continue(); - void Reset(); - double Time(); - int Usec(); -private: - double Diff(); - -#ifdef WIN32 - LARGE_INTEGER tstart, tend; - LARGE_INTEGER freq; -#else - struct timeval tstart, tend; - struct timezone tz; -#endif - double elapsed; -}; - -class Report { - public: - Report(unsigned int tot = 1, double inter = 30.0f) { Init(tot, inter); } - void Init(unsigned int tot, double inter = 30.0f); - void Step(unsigned int count); - void Finish(); - private: - Watch watch; - int tot; - double last; - double interval; -}; - -#endif diff --git a/apps/nexus/zcurve.h b/apps/nexus/zcurve.h deleted file mode 100644 index 8aa5a9ff..00000000 --- a/apps/nexus/zcurve.h +++ /dev/null @@ -1,46 +0,0 @@ -#ifndef VCG_ZCURVE_H - -#include - -namespace vcg { - -class ZCurve: public Box3f { -public: - - unsigned int side; - - ZCurve(): side(1024) {} - - void SetSide(int s) { assert(s <= (1<<10)); side = s; } - - unsigned int Pos(const Point3f &p) const { - assert(!IsNull()); - unsigned int position = 0; - - float x = (p[0] - min[0])/(max[0] - min[0]); - float y = (p[1] - min[1])/(max[1] - min[1]); - float z = (p[2] - min[2])/(max[2] - min[2]); - - unsigned int s = side; - while(s > 1) { - position *= 8; - x *= 2; - y *= 2; - z *= 2; - int dx = (int)floor(x); - int dy = (int)floor(y); - int dz = (int)floor(z); - position += dx + 2 * dy + 4 * dz; - x -= dx; - y -= dy; - z -= dz; - s /= 2; - } - return position; - } -}; - -} - - -#endif