diff --git a/examples/dmat/Makefile b/examples/dmat/Makefile new file mode 100644 index 000000000..4979986ff --- /dev/null +++ b/examples/dmat/Makefile @@ -0,0 +1,23 @@ + +.PHONY: all + +all: example + +.PHONY: example + +igl_lib=../../ +eigen=/usr/local/include/eigen3 + +CFLAGS=-g +inc=-I$(igl_lib) -I$(eigen) +lib= + +example: example.o + g++ $(CFLAGS) -o example example.o $(lib) + rm example.o + +example.o: example.cpp + g++ $(CFLAGS) -c example.cpp -o example.o $(inc) +clean: + rm -f example.o + rm -f example diff --git a/examples/dmat/README b/examples/dmat/README new file mode 100644 index 000000000..755477b05 --- /dev/null +++ b/examples/dmat/README @@ -0,0 +1,22 @@ +This is a simple example program that shows how to use the readDMAT and +writeDMAT functions of the igl library + + +To Build: + make + +To Run: + ./example [input path] [output path] + +Example Run #1: + Issuing: + ./example example.dmat output.dmat + cat output.dmat + should produce: + 3 2 + 1 + 4 + 2 + 5 + 3 + 6 diff --git a/examples/dmat/example.cpp b/examples/dmat/example.cpp new file mode 100644 index 000000000..da4fb8e54 --- /dev/null +++ b/examples/dmat/example.cpp @@ -0,0 +1,18 @@ +#include +#include "readDMAT.h" +#include "writeDMAT.h" +using namespace igl; +#include + +int main(int argc, char * argv[]) +{ + if(argc <= 2) + { + printf("USAGE:\n ./example [input path] [output path]\n"); + return 1; + } + Eigen::MatrixXd M; + readDMAT(argv[1],M); + writeDMAT(argv[2],M); + return 0; +} diff --git a/examples/dmat/example.dmat b/examples/dmat/example.dmat new file mode 100644 index 000000000..7eea30632 --- /dev/null +++ b/examples/dmat/example.dmat @@ -0,0 +1,7 @@ +3 2 +1 +4 +2 +5 +3 +6 diff --git a/examples/glslversion/Makefile b/examples/glslversion/Makefile new file mode 100644 index 000000000..968f67741 --- /dev/null +++ b/examples/glslversion/Makefile @@ -0,0 +1,22 @@ + +.PHONY: all + +all: example + +.PHONY: example + +igl_lib=../../ + +CFLAGS=-g +inc=-I$(igl_lib) +lib=-framework OpenGL -framework GLUT + +example: example.o + g++ $(CFLAGS) -o example example.o $(lib) + rm example.o + +example.o: example.cpp + g++ $(CFLAGS) -c example.cpp -o example.o $(inc) +clean: + rm -f example.o + rm -f example diff --git a/examples/glslversion/README b/examples/glslversion/README new file mode 100644 index 000000000..b1d422c6b --- /dev/null +++ b/examples/glslversion/README @@ -0,0 +1,15 @@ +This is a simple example program that creates a dummy GLUT window to get a +valid opengl context then print the glsl version string + + +To Build: + make + +To Run: + ./example + +Example Run #1: + Issuing: + ./example + should produce something like: + GL_SHADING_LANGUAGE_VERSION: 1.20 diff --git a/examples/glslversion/example.cpp b/examples/glslversion/example.cpp new file mode 100644 index 000000000..21c7dbc57 --- /dev/null +++ b/examples/glslversion/example.cpp @@ -0,0 +1,18 @@ +#include +#include + +int main(int argc,char * argv[]) +{ + // Make GLUT window just to get a valid OpenGL context + glutInit(&argc,argv); + glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); + glutInitWindowSize(640, 480); + glutCreateWindow("Dummy"); + glutCreateMenu(NULL); + + printf("GL_VERSION: %s\n", + glGetString(GL_VERSION)); + printf("GL_SHADING_LANGUAGE_VERSION: %s\n", + glGetString(GL_SHADING_LANGUAGE_VERSION)); + return 0; +} diff --git a/examples/sort/Makefile b/examples/sort/Makefile new file mode 100644 index 000000000..39927522b --- /dev/null +++ b/examples/sort/Makefile @@ -0,0 +1,23 @@ + +.PHONY: all + +all: example + +.PHONY: example + +igl_lib=../../ +eigen=/usr/local/include/eigen3/ + +CFLAGS=-g +inc=-I$(igl_lib) -I$(eigen) +lib= + +example: example.o + g++ $(CFLAGS) -o example example.o $(lib) + rm example.o + +example.o: example.cpp + g++ $(CFLAGS) -c example.cpp -o example.o $(inc) +clean: + rm -f example.o + rm -f example diff --git a/examples/sort/README b/examples/sort/README new file mode 100644 index 000000000..32bb5c0e5 --- /dev/null +++ b/examples/sort/README @@ -0,0 +1,9 @@ +This is a simple example program that shows how to use the sort function on +eigen matrices like matlab's sort function + + +To Build: + make + +To Run: + ./example diff --git a/examples/sort/example.cpp b/examples/sort/example.cpp new file mode 100644 index 000000000..a8df63f55 --- /dev/null +++ b/examples/sort/example.cpp @@ -0,0 +1,69 @@ +// g++ -o main main.cpp -I. -I/usr/local/include/eigen3 +#include +#include +using namespace std; +#include "sort.h" +using namespace igl; + + +template +void matlab_print(const string name, const T & X) +{ + cout<("Y",Y); + matlab_print("IX",IX); + + // Verify that IX really does sort X into Y + int num_outer = (dim == 1 ? X.cols() : X.rows() ); + // get number of rows (or columns) + int num_inner = (dim == 1 ? X.rows() : X.cols() ); + bool verified = true; + for(int i = 0;i <#rows> +// Then the coefficients of the matrix are given separated by whitespace with +// columns running fastest. +// +// Example: +// The matrix m = [1 2 3; 4 5 6]; +// corresponds to a .dmat file containing: +// 3 2 +// 1 4 2 5 3 6 +#include +#include +namespace igl +{ + // Read a matrix from an ascii dmat file + // + // Inputs: + // file_name path to .dmat file + // Outputs: + // W eigen matrix containing read-in coefficients + // Returns true on success, false on error + // + inline bool readDMAT(const std::string file_name, Eigen::MatrixXd & W); +} + +// Implementation +#include "verbose.h" +#include + +inline bool igl::readDMAT(const std::string file_name, Eigen::MatrixXd & W) +{ + FILE * fp = fopen(file_name.c_str(),"r"); + if(fp == NULL) + { + fclose(fp); + fprintf(stderr,"IOError: readDMAT() could not open %s...\n",file_name.c_str()); + return false; + } + // first line contains number of rows and number of columns + int num_cols, num_rows; + int res = fscanf(fp,"%d %d\n",&num_cols,&num_rows); + if(res != 2) + { + fclose(fp); + fprintf(stderr,"IOError: readDMAT() first row should be [num cols] [num rows]...\n"); + return false; + } + verbose("Number of rows: %d\n",num_rows); + verbose("Number of cols: %d\n",num_cols); + + // check that number of columns and rows are sane + if(num_cols < 0) + { + fclose(fp); + fprintf(stderr,"IOError: readDMAT() number of columns %d < 0\n",num_cols); + return false; + } + if(num_rows < 0) + { + fclose(fp); + fprintf(stderr,"IOError: readDMAT() number of rows %d < 0\n",num_rows); + return false; + } + + // Resize output to fit matrix + W.resize(num_rows,num_cols); + + // Loop over columns slowly + for(int j = 0;j < num_cols;j++) + { + // loop over rows (down columns) quickly + for(int i = 0;i < num_rows;i++) + { + if(fscanf(fp," %lg",&W(i,j)) != 1) + { + fclose(fp); + fprintf( + stderr, + "IOError: readDMAT() bad format after reading %d entries\n", + j*num_rows + i); + return false; + } + } + } + fclose(fp); + return true; +} +#endif diff --git a/reorder.h b/reorder.h new file mode 100644 index 000000000..eedf6f5b1 --- /dev/null +++ b/reorder.h @@ -0,0 +1,37 @@ +#ifndef IGL_REORDER_H +#define IGL_REORDER_H + +namespace igl +{ + // Act like matlab's Y = X[I] for std vectors + // where I contains a vector of indices so that after, + // Y[j] = X[I[j]] for index j + // this implies that Y.size() == I.size() + // X and Y are allowed to be the same reference + template< class T > + inline void reorder( + const std::vector & unordered, + std::vector const & index_map, + std::vector & ordered); +} + +// Implementation + +// This implementation is O(n), but also uses O(n) extra memory +template< class T > +inline void igl::reorder( + const std::vector & unordered, + std::vector const & index_map, + std::vector & ordered) +{ + // copy for the reorder according to index_map, because unsorted may also be + // sorted + std::vector copy = unordered; + ordered.resize(index_map.size()); + for(int i = 0; i +# include +#else +# include +# include +#endif + +#include + +namespace igl +{ + // Print last OpenGL error to stderr + // Returns result of glGetError() + inline GLenum report_gl_error(); +} + +// Implementation +#include "verbose.h" + +inline GLenum igl::report_gl_error() +{ + GLenum err = glGetError(); + if(GL_NO_ERROR != err) + { + verbose("GL_ERROR: "); + fprintf(stderr,"%s\n",gluErrorString(err)); + } + return err; +} + +#endif diff --git a/shader_program_uniforms_map.h b/shader_program_uniforms_map.h new file mode 100644 index 000000000..cd0f4c912 --- /dev/null +++ b/shader_program_uniforms_map.h @@ -0,0 +1,65 @@ +#ifndef IGL_SHADER_PROGRAM_UNIFORMS_MAP_H +#define IGL_SHADER_PROGRAM_UNIFORMS_MAP_H +#include +#include + +#ifdef __APPLE__ +# include +#else +# include +#endif + +namespace igl +{ + // Builds a map of *active* uniform names as strings to their respective + // locations as GLuint. + // Input: + // id index id of the program to query + // Output: + // uniforms map of names to locations + // Returns true on success, false on errors + void shader_program_uniforms_map( + const GLuint id, + std::map & uniforms); +} + +// Implementation +#include "verbose.h" +#include "report_gl_error.h" + +void igl::shader_program_uniforms_map( + const GLuint id, + std::map & uniforms) +{ + // empty the map of previous contents + uniforms.clear(); + + // get number of active uniforms + GLint n = 200; + glGetProgramiv(id,GL_ACTIVE_UNIFORMS,&n); + + // get max uniform name length + GLint max_name_length; + glGetProgramiv(id,GL_ACTIVE_UNIFORM_MAX_LENGTH,&max_name_length); + + // buffer for name + GLchar * name = new GLchar[max_name_length]; + // buffer for length + GLsizei length = 100; + GLenum type; + GLint size; + + // loop over active uniforms getting each's name + for(GLuint u = 0;u < n;u++) + { + // I have no idea why glGetActiveUniformName doesn't work but + // glGetActiveUniform does... + //glGetActiveUniformName(id,u,max_name_length,&length,name); + glGetActiveUniform(id,u,max_name_length,&length,&size,&type,name); + // insert into map + uniforms[string(name)] = u; + } + + delete[] name; +} +#endif diff --git a/sort.h b/sort.h new file mode 100644 index 000000000..573de480f --- /dev/null +++ b/sort.h @@ -0,0 +1,151 @@ +#ifndef IGL_SORT_H +#define IGL_SORT_H + +#include +namespace igl +{ + + // Sort the elements of a matrix X along a given dimension like matlabs sort + // function + // + // Templates: + // T should be a eigen matrix primitive type like int or double + // Inputs: + // X m by n matrix whose entries are to be sorted + // dim dimensional along which to sort: + // 1 sort each column (matlab default) + // 2 sort each row + // ascending sort ascending (true, matlab default) or descending (false) + // Outputs: + // Y m by n matrix whose entries are sorted + // IX m by n matrix of indices so that if dim = 1, then in matlab notation + // for j = 1:n, Y(:,j) = X(I(:,j),j); end + template + inline void sort( + const Eigen::Matrix & X, + const int dim, + const bool ascending, + Eigen::Matrix & Y, + Eigen::MatrixXi & IX); + + // Act like matlab's [Y,I] = SORT(X) for std library vectors + // Templates: + // T should be a class that implements the '<' comparator operator + // Input: + // unsorted unsorted vector + // ascending sort ascending (true, matlab default) or descending (false) + // Output: + // sorted sorted vector, allowed to be same as unsorted + // index_map an index map such that sorted[i] = unsorted[index_map[i]] + template + inline void sort( + const std::vector &unsorted, + const bool ascending, + std::vector &sorted, + std::vector &index_map); + +} + +// Implementation +#include +#include "reorder.h" + +template +inline void igl::sort( + const Eigen::Matrix & X, + const int dim, + const bool ascending, + Eigen::Matrix & Y, + Eigen::MatrixXi & IX) +{ + // dim must be 2 or 1 + assert(dim == 1 || dim == 2); + // Resize output + Y.resize(X.rows(),X.cols()); + IX.resize(X.rows(),X.cols()); + // idea is to process each column (or row) as a std vector + // get number of columns (or rows) + int num_outer = (dim == 1 ? X.cols() : X.rows() ); + // get number of rows (or columns) + int num_inner = (dim == 1 ? X.rows() : X.cols() ); + // loop over columns (or rows) + for(int i = 0; i index_map(num_inner); + std::vector data(num_inner); + for(int j = 0;j( + data, + ascending, + data, + index_map); + // Copy into Y and IX + for(int j = 0;j struct index_cmp +{ + index_cmp(const T arr) : arr(arr) {} + bool operator()(const size_t a, const size_t b) const + { + return arr[a] < arr[b]; + } + const T arr; +}; + +template +inline void igl::sort( + const std::vector & unsorted, + const bool ascending, + std::vector & sorted, + std::vector & index_map) +{ + // Original unsorted index map + index_map.resize(unsorted.size()); + for(size_t i=0;i& >(unsorted)); + + // if not ascending then reverse + if(!ascending) + { + std::reverse(index_map.begin(),index_map.end()); + } + // make space for output without clobbering + sorted.resize(unsorted.size()); + // reorder unsorted into sorted using index map + igl::reorder(unsorted,index_map,sorted); +} + +#endif diff --git a/writeDMAT.h b/writeDMAT.h new file mode 100644 index 000000000..efed074cb --- /dev/null +++ b/writeDMAT.h @@ -0,0 +1,44 @@ +#ifndef IGL_WRITEDMAT_H +#define IGL_WRITEDMAT_H +// See writeDMAT.h for a description of the .dmat file type +#include +#include +namespace igl +{ + // Write a matrix using ascii dmat file type + // + // Inputs: + // file_name path to .dmat file + // W eigen matrix containing to-be-written coefficients + // Returns true on success, false on error + // + inline bool writeDMAT(const std::string file_name, const Eigen::MatrixXd & W); +} + +// Implementation +#include + +inline bool igl::writeDMAT(const std::string file_name, const Eigen::MatrixXd & W) +{ + FILE * fp = fopen(file_name.c_str(),"w"); + if(fp == NULL) + { + fclose(fp); + fprintf(stderr,"IOError: writeDMAT() could not open %s...",file_name.c_str()); + return false; + } + // first line contains number of rows and number of columns + fprintf(fp,"%d %d\n",(int)W.cols(),(int)W.rows()); + // Loop over columns slowly + for(int j = 0;j < W.cols();j++) + { + // loop over rows (down columns) quickly + for(int i = 0;i < W.rows();i++) + { + fprintf(fp,"%lg\n",W(i,j)); + } + } + fclose(fp); + return true; +} +#endif