From 425b462d361286822ee0ed7b5fe00881ba312ea3 Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Fri, 5 Dec 2014 13:32:54 +0000 Subject: Moved into trunk git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/trunk@341 636b058d-ea47-450e-bf9e-a15bfbe3eedb --- src/common/include/gudhi/iofile.h | 236 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 236 insertions(+) create mode 100644 src/common/include/gudhi/iofile.h (limited to 'src/common/include/gudhi/iofile.h') diff --git a/src/common/include/gudhi/iofile.h b/src/common/include/gudhi/iofile.h new file mode 100644 index 00000000..b939d45b --- /dev/null +++ b/src/common/include/gudhi/iofile.h @@ -0,0 +1,236 @@ +//todo remove and use off_reader instead + +#ifndef GUDHI_IOFILE_H_ +#define GUDHI_IOFILE_H_ + +#include +#include +#include +#include +#include +#include +#include +#include + + + +//todo use my new visitor based off instead +/** + * @brief OFF reader, save the content of the file (vertices and maximal faces) in 'complex'. + * The class Complex has to handle the following operations: + * - void add_vertex(double[dim],int dim) + * - void add_face(int dimension ,int[dimension] vertices) + * Source from : http://www.holmes3d.net/graphics/offfiles/OFFLoading.txt + * + * @todo todo ignore comments in the file -> # comment + */ +template inline +bool general_read_off_file(const std::string & file_name, Complex& complex){ + // Declare temporary variables to read data into. + // If the read goes well, we'll copy these into + // our class variables, overwriting what used to + // be there. If it doesn't, we won't have messed up + // our previous data structures. + int tempNumPoints = 0; // Number of x,y,z coordinate triples + int tempNumFaces = 0; // Number of polygon sets + int tempNumEdges = 0; // Unused, except for reading. + int tempDimPoints = 0; + double** tempPoints = NULL; // An array of x,y,z coordinates. + int** tempFaces = NULL; // An array of arrays of point + // pointers. Each entry in this + // is an array of integers. Each + // integer in that array is the + // index of the x, y, and z + // coordinates in the corresponding + // arrays. + int* tempFaceSizes = NULL; // An array of polygon point counts. + // Each of the arrays in the tempFaces + // array may be of different lengths. + // This array corresponds to that + // array, and gives their lengths. + int i; // Generic loop variable. + bool goodLoad = true; // Set to false if the file appears + // not to be a valid OFF file. + char tempBuf[128]; // A buffer for reading strings + // from the file. + + // Create an input file stream for the file the CArchive + // is connected to. This allows use of the overloaded + // extraction operator for conversion from string + // data to doubles and ints. + std::ifstream ifs (file_name.c_str(), std::ios::in); + if(!ifs.is_open()) { + std::cerr << "Unable to open file " << file_name << std::endl; + return false; + } + + // Grab the first string. If it's "OFF", we think this + // is an OFF file and continue. Otherwise we give up. + ifs >> tempBuf; + if (strcmp(tempBuf, "OFF") != 0) { + goodLoad = false; + std::cerr << "No OFF preambule\n"; + } + + // Read the sizes for our two arrays, and the third + // int on the line. If the important two are zero + // sized, this is a messed up OFF file. Otherwise, + // we setup our temporary arrays. + if (goodLoad) { + ifs >> tempNumPoints >> tempNumFaces >> tempNumEdges; + if (tempNumPoints < 1 || tempNumFaces < 0) { + // If either of these were negative, we make + // sure that both are set to zero. This is + // important for later deleting our temporary + // storage. + goodLoad = false; + std::cerr << "tempNumPoints < 1 || tempNumFaces < 0\n"; + tempNumPoints = 0; + tempNumFaces = 0; + } else { + tempPoints = new double*[tempNumPoints]; + tempFaces = new int*[tempNumFaces]; + tempFaceSizes = new int[tempNumFaces]; + } + } + + if (goodLoad) { + // Load all of the points. + + // we start by loading the first one + // the case is difference because then we dont know the dimension by advance + // we discover the point dimension by reading the first line + std::string lineFirstPoint; + std::getline(ifs, lineFirstPoint); + while(lineFirstPoint.size()<3){ + std::getline(ifs, lineFirstPoint); + } + + // we store the first point in a temporary list + std::istringstream lineFirstPointStream(lineFirstPoint); + std::list firstTempPoint; + double coord; + while(lineFirstPointStream>>coord){ + firstTempPoint.push_back(coord); + ++tempDimPoints; + } + // we store the point in our points array + tempPoints[0]=new double[tempDimPoints]; + for( int j = 0 ; j>tempPoints[i][j]; + } + } + + // Load all of the faces. + for (i = 0; i < tempNumFaces; i++) { + // This tells us how many points make up + // this face. + ifs >> tempFaceSizes[i]; + // So we declare a new array of that size + tempFaces[i] = new int[tempFaceSizes[i]]; + // And load its elements with the vertex indices. + for (int j = 0; j < tempFaceSizes[i]; j++) { + ifs >> tempFaces[i][j]; + } + // Clear out any face color data by reading up to + // the newline. 128 is probably considerably more + // space than necessary, but better safe than + // sorry. + ifs.getline(tempBuf, 128); + } + } + + // Here is where we copy the data from the temp + // structures into our permanent structures. We + // probably will do some more processing on the + // data at the same time. This code you must fill + // in on your own. + if (goodLoad) { + // we save vertices first in the complex + for (i = 0; i < tempNumPoints; i++) + complex.add_vertex(tempPoints[i],tempDimPoints); + + // we save faces + for (i = 0; i < tempNumFaces; i++) { + for (int j = 0; j < tempFaceSizes[i]; j++) + complex.add_face(tempFaceSizes[i],tempFaces[i]); + } + } + + // Now that we're done, we have to make sure we + // free our dynamic memory. + for (i = 0; i < tempNumPoints; i++) { + delete []tempPoints[i]; + } + delete []tempPoints; + + for (i = 0; i < tempNumFaces; i++) { + delete tempFaces[i]; + } + delete []tempFaces; + delete []tempFaceSizes; + + // Clean up our ifstream. The MFC framework will + // take care of the CArchive. + ifs.close(); + + return goodLoad; +} + + +template +class Geometric_flag_complex_wrapper{ + Complex& complex_; + typedef typename Complex::Vertex_handle Vertex_handle; + typedef typename Complex::Point Point; + + const bool load_only_points_; + +public: + Geometric_flag_complex_wrapper(Complex& complex,bool load_only_points = false): + complex_(complex), + load_only_points_(load_only_points) +{} + + + void add_vertex(double* xyz,int dim){ + Point p(dim); + for(int i=0;i +bool read_off_file(std::string file_name,Complex &complex,bool load_only_points = false){ + complex.clear(); + Geometric_flag_complex_wrapper complex_wrapper(complex,load_only_points); + return general_read_off_file(file_name,complex_wrapper); + +} + + +#endif -- cgit v1.2.3