diff --git a/apps/nexus/border.h b/apps/nexus/border.h new file mode 100644 index 00000000..f78c6217 --- /dev/null +++ b/apps/nexus/border.h @@ -0,0 +1,55 @@ +/**************************************************************************** +* 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_BORDER_H +#define NXS_BORDER_H + +namespace nxs { + +struct Link { + Link(): start_vertex(0xffff), end_vertex(0xffff), end_patch(0xffffffff) {} + + unsigned short start_vertex; + unsigned short end_vertex; + unsigned int end_patch; + bool IsNull() { return start_vertex == 0xffff; } +}; + +class Border { + public: + unsigned int Size() { return size; } + Link &operator[](unsigned int i) { return start[i]; } + private: + unsigned short size; + Link *start; +}; + +} + + +#endif diff --git a/apps/nexus/nexus.cpp b/apps/nexus/nexus.cpp new file mode 100644 index 00000000..a13364b5 --- /dev/null +++ b/apps/nexus/nexus.cpp @@ -0,0 +1,89 @@ +#include +#include "nexus.h" + +using namespace std; +using namespace vcg; +using namespace nxs; + +Nexus::Nexus(): index_file(NULL) {} +Nexus::~Nexus() { + Close(); +} + +bool Nexus::Create(const string &file) { + index_file = fopen((file + ".nxs").c_str(), "wb+"); + if(!index_file) { + cerr << "Could not create file: " << file << ".nxs\n"; + return false; + } + + totvert = 0; + totface = 0; + totchunks = 0; + totlinks = 0; + sphere = Sphere3f(); + + //Important: chunk_size must be 1 so that i can use Region in VFile. + if(!patches.Create(file + ".nxp", 1)) { + cerr << "Could not create file: " << file << ".nxp" << endl; + return false; + } + if(!borders.Create(file + ".nxb")) { + cerr << "Could not create file: " << file << ".nxp" << endl; + return false; + } + return true; +} + +bool Nexus::Load(const string &file) { + index_file = fopen((file + ".nxs").c_str(), "rb+"); + if(!index_file) return false; + + unsigned int readed; + readed = fread(&totvert, sizeof(unsigned int), 1, index_file); + if(!readed) return false; + readed = fread(&totface, sizeof(unsigned int), 1, index_file); + if(!readed) return false; + readed = fread(&totchunks, sizeof(unsigned int), 1, index_file); + if(!readed) return false; + readed = fread(&totlinks, sizeof(unsigned int), 1, index_file); + if(!readed) return false; + readed = fread(&sphere, sizeof(Sphere3f), 1, index_file); + if(!readed) return false; + + unsigned int size; //size of index + readed = fread(&size, sizeof(unsigned int), 1, index_file); + if(!readed) return false; + + index.resize(size); + readed = fread(&index[0], sizeof(Entry), size, index_file); + if(readed != size) return false; + + if(!patches.Load(file + ".nxp")) return false; + if(!borders.Load(file + ".nxb")) return false; + return true; +} + +void Nexus::Close() { + if(!index_file) return; + rewind(index_file); + + fwrite(&totvert, sizeof(unsigned int), 1, index_file); + fwrite(&totface, sizeof(unsigned int), 1, index_file); + fwrite(&totchunks, sizeof(unsigned int), 1, index_file); + fwrite(&totlinks, sizeof(unsigned int), 1, index_file); + fwrite(&sphere, sizeof(Sphere3f), 1, index_file); + + unsigned int size = index.size(); //size of index + fwrite(&size, sizeof(unsigned int), 1, index_file); + fwrite(&index[0], sizeof(Entry), size, index_file); + fclose(index_file); + patches.Close(); + borders.Close(); +} + +Patch Nexus::GetPatch(unsigned int patch) { + Entry &entry = index[patch]; + Chunk *start = patches.GetRegion(entry.patch_offset, entry.patch_size); + return Patch(start); +} diff --git a/apps/nexus/nexus.h b/apps/nexus/nexus.h new file mode 100644 index 00000000..16ea789d --- /dev/null +++ b/apps/nexus/nexus.h @@ -0,0 +1,56 @@ +#ifndef NXS_NEXUS_H +#define NXS_NEXUS_H + +#include +#include +#include +#include "vfile.h" +#include "patch.h" +#include "border.h" + +namespace nxs { + + + +class Nexus { + public: + + class Entry { + public: + Entry(): patch_offset(0xffffffff), border_offset(0xffffffff), + patch_size(0), border_size(0), sphere(vcg::Sphere3f()) {} + unsigned int patch_offset; //granularita' Chunk + unsigned int border_offset; //granuralita' Link + unsigned short patch_size; //in cuhnks + unsigned short border_size; //in Links + vcg::Sphere3f sphere; + }; + + Nexus(); + ~Nexus(); + bool Create(const std::string &filename); + bool Load(const std::string &filename); + void Close(); + + Patch GetPatch(unsigned int patch); + void GetBorder(unsigned int border, Border &border); + + // unsigned int addPatch(Patch *builder); + void AddBorder(unsigned int patch, std::vector &links); + + unsigned int totvert; + unsigned int totface; + unsigned int totchunks; //number of chunks. + unsigned int totlinks; + vcg::Sphere3f sphere; + + std::vector index; + + FILE *index_file; + VFile patches; + VFile borders; +}; + +} + +#endif diff --git a/apps/nexus/patch.h b/apps/nexus/patch.h new file mode 100644 index 00000000..fd0eaf27 --- /dev/null +++ b/apps/nexus/patch.h @@ -0,0 +1,60 @@ +#ifndef NXS_PATCH_H +#define NXS_PATCH_H + +#include + +namespace nxs { + +struct Chunk { + unsigned char p[4096]; +}; + +class Patch { + public: + + Patch(Chunk *s = NULL): start(s) {} + + unsigned short &VertSize() { return *(unsigned short *)start; } + + vcg::Point3f *VertBegin() { + return (vcg::Point3f *)(start + 2*sizeof(short)); } + + unsigned short &FaceSize() { return *(((unsigned short *)start) + 1); } + + unsigned short *FaceBegin() { + return (unsigned short *)(start + 2*sizeof(short) + + VertSize() * sizeof(vcg::Point3f)); } + + unsigned int ChunkSize() { + return ChunkSize(VertSize(), FaceSize()); + } + + unsigned int ByteSize() { + return ByteSize(VertSize(), FaceSize()); + } + + static unsigned int ChunkSize(unsigned short nvert, unsigned short nface) { + unsigned int size = ByteSize(nvert, nface); + size = (size/sizeof(Chunk) + 1); + return size; + } + + static unsigned int ByteSize(unsigned short nvert, unsigned short nface) { + unsigned int size = nvert * sizeof(vcg::Point3f); + size += nface * 3 * sizeof(unsigned short); + + //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); + + size = 2 * sizeof(unsigned short); + return size; + } + private: + Chunk *start; +}; + +}; + +#endif