diff --git a/Makefile b/Makefile index 061509734..ab55b9f9f 100644 --- a/Makefile +++ b/Makefile @@ -16,9 +16,10 @@ OBJ_FILES=$(addprefix obj/,$(notdir $(CPP_FILES:.cpp=.o))) # include igl headers INC+=-Iinclude/ +CFLAGS += -Wall -arch i386 -arch x86_64 # optimized default settings all: LFLAGS += -all: CFLAGS += -O3 -DNDEBUG -Wall +all: CFLAGS += -O3 -DNDEBUG -j debug: CFLAGS += -g -Wall -Werror # Eigen dependency diff --git a/examples/MatlabWorkspace/Makefile b/examples/MatlabWorkspace/Makefile new file mode 100644 index 000000000..747e75705 --- /dev/null +++ b/examples/MatlabWorkspace/Makefile @@ -0,0 +1,27 @@ +.PHONY: all + +IGL=../../ +IGL_LIB=-L$(IGL)/lib -ligl +IGL_INC=-I$(IGL)/include + +EIGEN3_INC=-I/usr/local/include/eigen3 -I/usr/local/include/eigen3/unsupported + +MATLAB_INC=-I$(MATLAB)/extern/include/ +MATLAB_LIB=-L$(MATLAB)/bin/maci64 -lmx -lmat + +LIB+=$(IGL_LIB) $(MATLAB_LIB) +INC+=$(IGL_INC) $(EIGEN3_INC) $(MATLAB_INC) + +all: example + +CFLAGS += -g + +example: example.o + g++ -o example example.o $(LIB) + +example.o: example.cpp + g++ $(CFLAGS) -o $@ -c $< $(INC) + +clean: + rm -f example.o + rm -f example diff --git a/examples/MatlabWorkspace/README b/examples/MatlabWorkspace/README new file mode 100644 index 000000000..060855533 --- /dev/null +++ b/examples/MatlabWorkspace/README @@ -0,0 +1,13 @@ +This is a simple example program that shows how to use the MatlabWorkspace +class of the igl library + + +To Build: + make + +To Run: + ./example [input path] [output path] + +Example Run #1: + Issuing: + ./example example.dmat output.mat diff --git a/examples/MatlabWorkspace/example.cpp b/examples/MatlabWorkspace/example.cpp new file mode 100644 index 000000000..2b1d90c29 --- /dev/null +++ b/examples/MatlabWorkspace/example.cpp @@ -0,0 +1,32 @@ +#include + +#include +#include + +#ifndef IGL_HEADER_ONLY +# define IGL_HEADER_ONLY +# define IGL_HEADER_ONLY_WAS_NOT_DEFINED +#endif +#include +#include +#ifdef IGL_HEADER_ONLY_WAS_NOT_DEFINED +# undef IGL_HEADER_ONLY +#endif + +int main(int argc, char * argv[]) +{ + using namespace igl; + using namespace Eigen; + if(argc <= 2) + { + printf("USAGE:\n ./example [input path] [output path]\n"); + return 1; + } + MatrixXd M; + readDMAT(argv[1],M); + MatlabWorkspace mat; + mat.save(M,"M"); + mat.write(argv[2]); + + return 0; +} diff --git a/examples/MatlabWorkspace/example.dmat b/examples/MatlabWorkspace/example.dmat new file mode 100644 index 000000000..7eea30632 --- /dev/null +++ b/examples/MatlabWorkspace/example.dmat @@ -0,0 +1,7 @@ +3 2 +1 +4 +2 +5 +3 +6 diff --git a/examples/MatlabWorkspace/example.mat b/examples/MatlabWorkspace/example.mat new file mode 100644 index 000000000..a04b8a123 Binary files /dev/null and b/examples/MatlabWorkspace/example.mat differ diff --git a/include/igl/MatlabWorkspace.cpp b/include/igl/MatlabWorkspace.cpp new file mode 100644 index 000000000..19f8f7a47 --- /dev/null +++ b/include/igl/MatlabWorkspace.cpp @@ -0,0 +1,136 @@ +// Don't let libigl.a compile anything here +#ifdef IGL_HEADER_ONLY + +#include "MatlabWorkspace.h" + +// IGL +#include "list_to_matrix.h" + +// MATLAB +#include "mat.h" + +// STL +#include +#include + +IGL_INLINE igl::MatlabWorkspace::MatlabWorkspace() +{ +} + +IGL_INLINE igl::MatlabWorkspace::~MatlabWorkspace() +{ + // clean up data + clear(); +} + +IGL_INLINE void igl::MatlabWorkspace::clear() +{ + for_each(data.begin(),data.end(),&mxDestroyArray); +} + +IGL_INLINE bool igl::MatlabWorkspace::write(const std::string & path) const +{ + using namespace std; + MATFile * mat_file = matOpen(path.c_str(), "w"); + assert(names.size() == data.size()); + // loop over names and data + for(int i = 0;i < names.size(); i++) + { + // Put variable as LOCAL variable + int status = matPutVariable(mat_file,names[i].c_str(), data[i]); + if(status != 0) + { + cerr<<"^MatlabWorkspace::save Error: matPutVariable ("< +IGL_INLINE igl::MatlabWorkspace::MatlabWorkspace& igl::MatlabWorkspace::save( + const Eigen::PlainObjectBase& M, + const std::string & name) +{ + using namespace std; + const int m = M.rows(); + const int n = M.cols(); + + mxArray * mx_data = mxCreateDoubleMatrix(m,n,mxREAL); + data.push_back(mx_data); + names.push_back(name); + // Copy data immediately + copy(M.data(),M.data()+M.size(),mxGetPr(mx_data)); + return *this; +} + +template +IGL_INLINE igl::MatlabWorkspace::MatlabWorkspace& igl::MatlabWorkspace::save( + const std::vector > & vM, + const std::string & name) +{ + Eigen::MatrixXd M; + list_to_matrix(vM,M); + return this->save(M,name); +} + +template +IGL_INLINE igl::MatlabWorkspace::MatlabWorkspace& igl::MatlabWorkspace::save( + const std::vector & vV, + const std::string & name) +{ + Eigen::MatrixXd V; + list_to_matrix(vV,V); + return this->save(V,name); +} + +template +IGL_INLINE igl::MatlabWorkspace::MatlabWorkspace& + igl::MatlabWorkspace::save_index( + const Eigen::PlainObjectBase& M, + const std::string & name) +{ + DerivedM Mp1 = M; + Mp1.array() += 1; + return this->save(Mp1,name); +} + +template +IGL_INLINE igl::MatlabWorkspace::MatlabWorkspace& igl::MatlabWorkspace::save_index( + const std::vector > & vM, + const std::string & name) +{ + Eigen::MatrixXd M; + list_to_matrix(vM,M); + return this->save_index(M,name); +} + +template +IGL_INLINE igl::MatlabWorkspace::MatlabWorkspace& igl::MatlabWorkspace::save_index( + const std::vector & vV, + const std::string & name) +{ + Eigen::MatrixXd V; + list_to_matrix(vV,V); + return this->save_index(V,name); +} + + +//template +//bool igl::MatlabWorkspace::save(const Data & M, const std::string & name) +//{ +// using namespace std; +// // If I don't know the type then I can't save it +// cerr<<"^MatlabWorkspace::save Error: Unknown data type. "<< +// name<<" not saved."< +#include +#include + +#include "mat.h" + +namespace igl +{ + // Class which contains data of a matlab workspace which can be written to a + // .mat file and loaded from matlab + // + // This depends on matlab at compile time (though it shouldn't necessarily + // have to) but it does not depend on running the matlab engine at run-time. + // + // Known bugs: Treats all matrices as doubles (this may actually be desired + // for some "index" matrices since matlab's sparse command takes doubles + // rather than int class matrices). It is of course not desired when dealing + // with logicals or uint's for images. + class MatlabWorkspace + { + private: + // List of names + std::vector names; + // List of data pointers + std::vector data; + public: + MatlabWorkspace(); + ~MatlabWorkspace(); + // Clear names and data of variables in workspace + IGL_INLINE void clear(); + // Save current list of variables + // + // Inputs: + // path path to .mat file + // Returns true on success, false on failure + IGL_INLINE bool write(const std::string & path) const; + // Assign data to a variable name in the workspace + // + // Template: + // DerivedM eigen matrix (e.g. MatrixXd) + // Inputs: + // M data (usually a matrix) + // name variable name to save into work space + // Returns true on success, false on failure + // + // Known Bugs: Assumes Eigen is using column major ordering + template + IGL_INLINE MatlabWorkspace& save( + const Eigen::PlainObjectBase& M, + const std::string & name); + // Templates: + // ScalarM scalar type, e.g. double + template + IGL_INLINE MatlabWorkspace& save( + const std::vector > & vM, + const std::string & name); + // Templates: + // ScalarV scalar type, e.g. double + template + IGL_INLINE MatlabWorkspace& save( + const std::vector & vV, + const std::string & name); + // Same as save() but adds 1 to each element, useful for saving "index" + // matrices like lists of faces or elements + template + IGL_INLINE MatlabWorkspace& save_index( + const Eigen::PlainObjectBase& M, + const std::string & name); + template + IGL_INLINE MatlabWorkspace& save_index( + const std::vector > & vM, + const std::string & name); + template + IGL_INLINE MatlabWorkspace& save_index( + const std::vector & vV, + const std::string & name); + }; +} + +// Be sure that this is not compiled into libigl.a +#ifdef IGL_HEADER_ONLY +# include "MatlabWorkspace.cpp" +#endif + +#endif + diff --git a/include/igl/boundary_faces.h b/include/igl/boundary_faces.h index 06a16179a..13daaa69b 100644 --- a/include/igl/boundary_faces.h +++ b/include/igl/boundary_faces.h @@ -13,8 +13,8 @@ namespace igl // BOUNDARY_FACES Determine boundary faces of tetrahedra stored in T // // Templates: - // IntegerT integer-value: i.e. int - // IntegerF integer-value: i.e. int + // IntegerT integer-value: e.g. int + // IntegerF integer-value: e.g. int // Input: // T tetrahedron index list, m by 4, where m is the number of tetrahedra // Output: diff --git a/include/igl/list_to_matrix.cpp b/include/igl/list_to_matrix.cpp index 61cc4edc1..a340505d5 100644 --- a/include/igl/list_to_matrix.cpp +++ b/include/igl/list_to_matrix.cpp @@ -83,4 +83,7 @@ template bool igl::list_to_matrix >(std::vector >, std::allocator > > > const&, Eigen::Matrix&); template bool igl::list_to_matrix > >(std::vector > const&, Eigen::PlainObjectBase >&); template bool igl::list_to_matrix > >(std::vector >, std::allocator > > > const&, Eigen::PlainObjectBase >&); +template bool igl::list_to_matrix > >(std::vector > const&, Eigen::PlainObjectBase >&); +template bool igl::list_to_matrix >(std::vector >, std::allocator > > > const&, Eigen::Matrix&); +template bool igl::list_to_matrix >(std::vector > const&, Eigen::Matrix&); #endif diff --git a/include/igl/matlab_workspace.cpp b/include/igl/matlab_workspace.cpp deleted file mode 100644 index a9b3c2521..000000000 --- a/include/igl/matlab_workspace.cpp +++ /dev/null @@ -1 +0,0 @@ -#include "matlab_workspace.h" diff --git a/include/igl/matlab_workspace.h b/include/igl/matlab_workspace.h deleted file mode 100644 index b3091462f..000000000 --- a/include/igl/matlab_workspace.h +++ /dev/null @@ -1,22 +0,0 @@ -#ifndef IGL_WRITE_MATLAB_WORKSPACE -#define IGL_WRITE_MATLAB_WORKSPACE -#include "igl_inline.h" - -namespace igl -{ - // Class which contains data of a matlab workspace which can be written to a - // .mat file and loaded from matlab - // - // This depends on matlab at compile time (though it shouldn't necessarily - // have to) but it does not depend on running the matlab engine at run-time. - class matlab_workspace - { - }; -} - -#ifdef IGL_HEADER_ONLY -# include "matlab_workspace.cpp" -#endif - -#endif - diff --git a/include/igl/on_boundary.cpp b/include/igl/on_boundary.cpp index 6c53492a4..df5e6184d 100644 --- a/include/igl/on_boundary.cpp +++ b/include/igl/on_boundary.cpp @@ -48,8 +48,8 @@ IGL_INLINE void igl::on_boundary( { for(int j = 0;j<4;j++) { + assert(FC[i*4+j] == 2 || FC[i*4+j] == 1); C[i][j] = FC[i*4+j]==1; - assert(C[i][j] == 2 || C[i][j] == 1); // if any are on boundary set to true I[i] = I[i] || C[i][j]; } diff --git a/include/igl/tt.cpp b/include/igl/tt.cpp index 5e5636fab..66919b96c 100644 --- a/include/igl/tt.cpp +++ b/include/igl/tt.cpp @@ -84,4 +84,5 @@ IGL_INLINE void igl::tt(const Eigen::Matrix& // Explicit template specialization // generated by autoexplicit.sh template void igl::tt(Eigen::Matrix const&, Eigen::Matrix const&, Eigen::Matrix&); +template void igl::tt(Eigen::Matrix const&, Eigen::Matrix const&, Eigen::Matrix&, Eigen::Matrix&); #endif diff --git a/include/igl/upsample.cpp b/include/igl/upsample.cpp index e4a88d8e1..e3cf8126e 100644 --- a/include/igl/upsample.cpp +++ b/include/igl/upsample.cpp @@ -89,4 +89,5 @@ IGL_INLINE void igl::upsample( MatV & V,MatF & F) #ifndef IGL_HEADER_ONLY // Explicit template specialization +template void igl::upsample, Eigen::Matrix >(Eigen::Matrix&, Eigen::Matrix&); #endif diff --git a/include/igl/writeOFF.cpp b/include/igl/writeOFF.cpp index 69069e551..e7f08b505 100644 --- a/include/igl/writeOFF.cpp +++ b/include/igl/writeOFF.cpp @@ -18,10 +18,10 @@ IGL_INLINE bool igl::writeOFF( fprintf (fp, "OFF\n%d %d 0\n", (int) V.rows(), (int) F.rows()); - for (unsigned i = 0; i < V.rows(); i++) + for (int i = 0; i < V.rows(); i++) fprintf (fp, "%f %f %f\n", V(i,0), V(i,1), V(i,2)); - for (unsigned i = 0; i < F.rows(); i++) + for (int i = 0; i < F.rows(); i++) fprintf (fp, "3 %d %d %d\n", F(i,0), F(i,1), F(i,2)); fclose (fp); diff --git a/matlab-to-eigen.html b/matlab-to-eigen.html index b7822f095..94f0aa933 100644 --- a/matlab-to-eigen.html +++ b/matlab-to-eigen.html @@ -1,53 +1,6 @@ MATLAB to Eigen - + @@ -245,7 +198,17 @@ tr.gotcha2 td - + + + + + + + @@ -263,5 +226,7 @@ tr.gotcha2 td
B = fliplr(A)
B = flipud(A)
B = A.rowwize().reverse().eval()
B = A.colwise().reverse().eval()
The .eval() is not neccessary is A != BThe .eval() is not necessary if A != B
B = IM(A)
B = A.unaryExpr(bind1st(mem_fun( 
+  static_cast<VectorXi::Scalar&(VectorXi::*)(VectorXi::Index)>
+  (&VectorXi::operator())), &IM)).eval();
+  
Where IM is an "index map" column vector and A is an arbitrary + matrix. The .eval() is not necessary if A != B
Eigen's "ASCII Quick Reference" with MATLAB translations +
+ IGL Lib Tutorial diff --git a/tutorial.html b/tutorial.html index d853af2ed..959703773 100644 --- a/tutorial.html +++ b/tutorial.html @@ -1,71 +1,7 @@ igl_lib tutorial - + igl logo

 ...
-#include <some_other_igl_function.h>
+#include <igl/some_other_igl_function.h>
 #ifndef IGL_HEADER_ONLY
 #  define IGL_HEADER_ONLY
 #  define IGL_HEADER_ONLY_WAS_NOT_DEFINED
 #endif
-#include <igl_function_to_inline.h>
+#include <igl/igl_function_to_inline.h>
 #ifdef IGL_HEADER_ONLY_WAS_NOT_DEFINED
 #  undef IGL_HEADER_ONLY
 #endif
-#include <yet_another_igl_function.h>
+#include <igl/yet_another_igl_function.h>
 ...
       
example examples/XXX also highlights this feature