Эх сурвалжийг харах

changed interfaces of read*.h to return bool,
added php-like pathinfo, dirname, basename functions,
pathinfo example


Former-commit-id: 2b762bbc9dc4f019824a9dd2f60458658cbe07f7

jalec 14 жил өмнө
parent
commit
0abb7a4d3c

+ 46 - 0
basename.h

@@ -0,0 +1,46 @@
+#ifndef IGL_BASENAME_H
+#define IGL_BASENAME_H
+
+#include <string>
+
+namespace igl
+{
+  // Function like PHP's basename
+  // Input:
+  //  path  string containing input path
+  // Returns string containing basename (see php's basename)
+  std::string basename(const std::string & path);
+}
+
+// Implementation
+#include <algorithm>
+
+std::string igl::basename(const std::string & path)
+{
+  if(path == "")
+  {
+    return std::string("");
+  }
+  // http://stackoverflow.com/questions/5077693/dirnamephp-similar-function-in-c
+  std::string::const_reverse_iterator last_slash =
+    std::find(
+      path.rbegin(), 
+      path.rend(), '/');
+  if( last_slash == path.rend() )
+  {
+    // No slashes found
+    return path;
+  }else if(1 == (last_slash.base() - path.begin()))
+  {
+    // Slash is first char
+    return std::string(path.begin()+1,path.end());
+  }else if(path.end() == last_slash.base() )
+  {
+    // Slash is last char
+    std::string redo = std::string(path.begin(),path.end()-1);
+    return igl::basename(redo);
+  }
+  return std::string(last_slash.base(),path.end());
+}
+#endif
+

+ 47 - 0
dirname.h

@@ -0,0 +1,47 @@
+#ifndef IGL_DIRNAME_H
+#define IGL_DIRNAME_H
+
+#include <string>
+
+namespace igl
+{
+  // Function like PHP's dirname
+  // Input:
+  //  path  string containing input path
+  // Returns string containing dirname (see php's dirname)
+  std::string dirname(const std::string & path);
+}
+
+// Implementation
+#include <algorithm>
+#include "verbose.h"
+
+std::string igl::dirname(const std::string & path)
+{
+  if(path == "")
+  {
+    return std::string("");
+  }
+  // http://stackoverflow.com/questions/5077693/dirnamephp-similar-function-in-c
+  std::string::const_reverse_iterator last_slash =
+    std::find(
+      path.rbegin(), 
+      path.rend(), '/');
+  if( last_slash == path.rend() )
+  {
+    // No slashes found
+    return std::string(".");
+  }else if(1 == (last_slash.base() - path.begin()))
+  {
+    // Slash is first char
+    return std::string("/");
+  }else if(path.end() == last_slash.base() )
+  {
+    // Slash is last char
+    std::string redo = std::string(path.begin(),path.end()-1);
+    return igl::dirname(redo);
+  }
+  return std::string(path.begin(),last_slash.base()-1);
+}
+
+#endif

+ 21 - 0
examples/pathinfo/Makefile

@@ -0,0 +1,21 @@
+
+.PHONY: all
+
+all: example
+
+.PHONY: example
+
+igl_lib=../../
+
+CFLAGS=-g -Wall 
+inc=-I$(igl_lib)
+
+example: example.o
+	g++ $(CFLAGS) -o example example.o $(lib) 
+	rm example.o
+
+example.o: example.cpp
+	g++ $(CFLAGS) $(deps) -c example.cpp -o example.o $(inc)
+clean:
+	rm -f example.o
+	rm -f example

+ 16 - 0
examples/pathinfo/README

@@ -0,0 +1,16 @@
+This pair of .cpp and .php programs demonstrate the use of pathinfo. 
+
+To compile:
+  make
+
+To run C++
+  ./example
+
+To run php:
+  php example.php
+
+To run test:
+  ./example > c++_output.txt
+  php example.php > php_output.txt
+  # should find 0 differences
+  diff c++_output.txt php_output.txt

+ 31 - 0
examples/pathinfo/example.cpp

@@ -0,0 +1,31 @@
+#define VERBOSE
+#include "pathinfo.h"
+using namespace igl;
+#include <string>
+#include <cstdio>
+#include <iostream>
+#include <fstream>
+using namespace std;
+
+int main(int argc, char * argv[])
+{
+  ifstream fin("input.txt");
+  if (fin.is_open() == false)
+  {
+    // error
+    return 1;
+  }
+
+  string line;
+  while( getline(fin, line) )
+  {
+    string dirname,basename,extension,filename;
+    pathinfo(line,dirname,basename,extension,filename);
+    printf("%s -> %s,%s,%s,%s\n",
+      line.c_str(),
+      dirname.c_str(),
+      basename.c_str(),
+      extension.c_str(),
+      filename.c_str());
+  }
+}

+ 17 - 0
examples/pathinfo/example.php

@@ -0,0 +1,17 @@
+<?php
+  $file_handle = fopen("input.txt", "rb");
+  while (!feof($file_handle) )
+  {
+    $string = trim(fgets($file_handle));
+    if(!feof($file_handle) )
+    {
+      $p = pathinfo($string);
+      echo "$string -> ".
+        $p['dirname'].",".
+        $p['basename'].",".
+        $p['extension'].",".
+        $p['filename']."\n";
+    }
+  }
+  fclose($file_handle);
+?>

+ 44 - 0
examples/pathinfo/input.txt

@@ -0,0 +1,44 @@
+/
+//
+/foo
+/foo/
+/foo/bar
+/foo/bar.
+/foo/bar.txt
+/foo/bar.txt.zip
+/foo/bar.dir/
+/foo/bar.dir/file
+/foo/bar.dir/file.txt
+
+foo
+foo/
+foo/bar
+foo/bar.txt
+foo/bar.txt.zip
+foo/bar.dir/
+foo/bar.dir/file
+foo/bar.dir/file.txt
+.bar
+foo.
+./foo
+./foo/
+./foo/bar
+./foo/bar.txt
+./foo/bar.txt.zip
+./foo/bar.dir/
+./foo/bar.dir/file
+./foo/bar.dir/file.txt
+./.bar
+~/foo.
+~/foo
+~/foo/
+~/foo/bar
+~/foo/bar.txt
+~/foo/bar.txt.zip
+~/foo/bar.dir/
+~/foo/bar.dir/file
+~/foo/bar.dir/file.txt
+~/.bar
+~/foo.
+.
+..

+ 4 - 2
examples/trackball/Makefile

@@ -7,7 +7,8 @@ all: example
 
 igl_lib=../../
 
-CFLAGS=-g -Wall
+CFLAGS=-g -Wall 
+#deps=-MMD -MF depends.txt
 inc=-I$(igl_lib)
 
 example: example.o
@@ -15,7 +16,8 @@ example: example.o
 	rm example.o
 
 example.o: example.cpp
-	g++ $(CFLAGS) -c example.cpp -o example.o $(inc)
+	g++ $(CFLAGS) $(deps) -c example.cpp -o example.o $(inc)
 clean:
 	rm -f example.o
 	rm -f example
+	rm -f depends.txt

+ 68 - 0
pathinfo.h

@@ -0,0 +1,68 @@
+#ifndef IGL_PATHINFO_H
+#define IGL_PATHINFO_H
+
+#include <string>
+
+namespace igl
+{
+  //// Decided not to use these
+  //const int PATHINFO_DIRNAME 01
+  //const int PATHINFO_BASENAME 02
+  //const int PATHINFO_EXTENSION 04
+  //const int PATHINFO_FILENAME 08
+
+  // Function like PHP's pathinfo
+  //  returns information about path
+  // Input:
+  //  path  string containing input path
+  // Outputs:
+  //  dirname  string containing dirname (see dirname.h)
+  //  basename  string containing basename (see basename.h)
+  //  extension  string containing extension (characters after last '.')
+  //  filename  string containing extension (characters of basename before last
+  //    '.')
+  void pathinfo(
+    const std::string & path,
+    std::string & dirname,
+    std::string & basename,
+    std::string & extension,
+    std::string & filename);
+
+}
+
+// Implementation
+#include "dirname.h"
+#include "basename.h"
+// Verbose should be removed once everythings working correctly
+#include "verbose.h"
+
+void igl::pathinfo(
+  const std::string & path,
+  std::string & dirname,
+  std::string & basename,
+  std::string & extension,
+  std::string & filename)
+{
+  dirname = igl::dirname(path);
+  basename = igl::basename(path);
+  std::string::reverse_iterator last_dot =
+    std::find(
+      basename.rbegin(), 
+      basename.rend(), '.');
+  // Was a dot found?
+  if(last_dot == basename.rend())
+  {
+    // filename is same as basename
+    filename = basename;
+    // no extension
+    extension = "";
+  }else
+  {
+  // extension is substring of basename
+    extension = std::string(last_dot.base(),basename.end());
+    // filename is substring of basename
+    filename = std::string(basename.begin(),last_dot.base()-1);
+  }
+}
+
+#endif

+ 35 - 24
read.h

@@ -3,38 +3,49 @@
 //
 //  Copyright 2011, Daniele Panozzo. All rights reserved.
 
-#ifndef READ_H
-#define READ_H
+// History:
+//  return type changed from void to bool  Alec 18 Sept 2011
+
+
+#ifndef IGL_READ_H
+#define IGL_READ_H
 
 #include <Eigen/Core>
 #include <string>
 
-#include <readOBJ.h>
-#include <readOFF.h>
-
 namespace igl 
 {
     // read mesh from an ascii file with automatic detection of file format. supported: obj, off)
-    void read(std::string str, Eigen::MatrixXd& V, Eigen::MatrixXi& F)
+  // Inputs:
+  //   str  path to .obj/.off file
+  // Outputs:
+  //   V  eigen double matrix #V by 3
+  //   F  eigen int matrix #F by 3
+  bool read(const std::string str, Eigen::MatrixXd& V, Eigen::MatrixXi& F);
+}
+
+// Implementation
+#include <readOBJ.h>
+#include <readOFF.h>
+bool igl::read(const std::string str, Eigen::MatrixXd& V, Eigen::MatrixXi& F)
+{
+    const char* p;
+    for (p = str.c_str(); *p != '\0'; p++)
+        ;
+    while (*p != '.')
+        p--;
+    
+    if (!strcmp(p, ".obj") || !strcmp(p, ".OBJ"))
+    {
+        return igl::readOBJ(str,V,F);
+    }else if (!strcmp(p, ".off") || !strcmp(p, ".OFF"))
+    {
+        return igl::readOFF(str,V,F);
+    }else
     {
-        const char* p;
-        for (p = str.c_str(); *p != '\0'; p++)
-            ;
-        while (*p != '.')
-            p--;
-        
-        if (!strcmp(p, ".obj") || !strcmp(p, ".OBJ"))
-        {
-            igl::readOBJ(str,V,F);
-            return;
-        }
-        
-        if (!strcmp(p, ".off") || !strcmp(p, ".OFF"))
-        {
-            igl::readOFF(str,V,F);
-            return;
-        }
+      fprintf(stderr,"read() does not recognize extension: %s\n",p);
+      return false;
     }
 }
 
-#endif
+#endif

+ 58 - 34
readOBJ.h

@@ -3,8 +3,11 @@
 //
 //  Copyright 2011, Daniele Panozzo. All rights reserved.
 
-#ifndef READOBJ_H
-#define READOBJ_H
+// History:
+//  return type changed from void to bool  Alec 18 Sept 2011
+
+#ifndef IGL_READOBJ_H
+#define IGL_READOBJ_H
 
 #include <Eigen/Core>
 #include <string>
@@ -14,41 +17,62 @@
 
 namespace igl 
 {
-    //! Read a mesh from an ascii obj file
-    void readOBJ(std::string str, Eigen::MatrixXd& V, Eigen::MatrixXi& F)
+  //! Read a mesh from an ascii obj file
+  // Inputs:
+  //   str  path to .obj file
+  // Outputs:
+  //   V  eigen double matrix #V by 3
+  //   F  eigen int matrix #F by 3
+  //
+  // KNOWN BUG: This only knows how to read *triangle* meshes. It will probably
+  // crash or give garbage on anything else.
+  //
+  // KNOWN BUG: This only knows how to face lines without normal or texture
+  // indices. It will probably crash or give garbage on anything else.
+  bool readOBJ(const std::string str, Eigen::MatrixXd& V, Eigen::MatrixXi& F);
+}
+
+// Implementation
+bool igl::readOBJ(const std::string str, Eigen::MatrixXd& V, Eigen::MatrixXi& F)
+{
+    std::ifstream s(str.c_str());
+    if (s.is_open() == false)
     {
-        std::ifstream s(str.c_str());
-        std::vector<Eigen::Vector3d> Vtemp;
-        std::vector<Eigen::Vector3i> Ftemp;
-        char buf[1000];
-        while(!s.eof())
+      fprintf (stderr, "readOBJ(): could not open file %s", str.c_str());
+      return false;
+    }
+    std::vector<Eigen::Vector3d> Vtemp;
+    std::vector<Eigen::Vector3i> Ftemp;
+    char buf[1000];
+    while(!s.eof())
+    {
+        s.getline(buf, 1000);
+        if (buf[0] == 'v') // vertex coordinates found
+        {
+            char v;
+            double v1,v2,v3;
+            sscanf(buf, "%c %lf %lf %lf",&v,&v1,&v2,&v3);
+            Vtemp.push_back(Eigen::Vector3d(v1,v2,v3));
+        }
+        else if (buf[0] == 'f') // face description found
         {
-            s.getline(buf, 1000);
-            if (buf[0] == 'v') // vertex coordinates found
-            {
-                char v;
-                double v1,v2,v3;
-                sscanf(buf, "%c %lf %lf %lf",&v,&v1,&v2,&v3);
-                Vtemp.push_back(Eigen::Vector3d(v1,v2,v3));
-            }
-            else if (buf[0] == 'f') // face description found
-            {
-                char v;
-                int v1,v2,v3;
-                sscanf(buf, "%c %d %d %d",&v,&v1,&v2,&v3);
-                Ftemp.push_back(Eigen::Vector3i(v1-1,v2-1,v3-1));
-            }
+            char v;
+            int v1,v2,v3;
+            sscanf(buf, "%c %d %d %d",&v,&v1,&v2,&v3);
+            Ftemp.push_back(Eigen::Vector3i(v1-1,v2-1,v3-1));
         }
-        s.close();
-        
-        V = Eigen::MatrixXd(Vtemp.size(),3);
-        for(int i=0;i<V.rows();++i)
-            V.row(i) = Vtemp[i];
-        
-        F = Eigen::MatrixXi(Ftemp.size(),3);
-        for(int i=0;i<F.rows();++i)
-            F.row(i) = Ftemp[i];
     }
+    s.close();
+    
+    V = Eigen::MatrixXd(Vtemp.size(),3);
+    for(int i=0;i<V.rows();++i)
+        V.row(i) = Vtemp[i];
+    
+    F = Eigen::MatrixXi(Ftemp.size(),3);
+    for(int i=0;i<F.rows();++i)
+        F.row(i) = Ftemp[i];
+
+    return true;
 }
 
-#endif
+#endif

+ 37 - 21
readOFF.h

@@ -3,6 +3,9 @@
 //
 //  Copyright 2011, Daniele Panozzo. All rights reserved.
 
+// History:
+//  return type changed from void to bool  Alec 18 Sept 2011
+
 #ifndef READOFF_H
 #define READOFF_H
 
@@ -11,28 +14,41 @@
 
 namespace igl 
 {
-    // read mesh from a ascii off file
-    void readOFF (std::string meshfile, Eigen::MatrixXd& V, Eigen::MatrixXi& F)
+  // read mesh from a ascii off file
+  // Inputs:
+  //   str  path to .off file
+  // Outputs:
+  //   V  eigen double matrix #V by 3
+  //   F  eigen int matrix #F by 3
+  bool readOFF (const std::string meshfile, Eigen::MatrixXd& V, Eigen::MatrixXi& F);
+}
+
+// Implementation
+
+bool igl::readOFF (const std::string meshfile, Eigen::MatrixXd& V, Eigen::MatrixXi& F)
+{
+    int vnum, fnum;
+    FILE *fp = fopen (meshfile.c_str(), "r");
+    
+    if (!fp)
     {
-        int vnum, fnum;
-        FILE *fp = fopen (meshfile.c_str(), "r");
-        
-        if (!fp)
-            fprintf (stderr, "readOFF(): could not open file %s", meshfile.c_str());
-        
-        fscanf (fp, "OFF\n%d %d 0\n",  &vnum, &fnum);
-        
-        V = Eigen::MatrixXd (vnum, 3);
-        F = Eigen::MatrixXi (fnum, 3);
-        
-        for (unsigned i = 0; i < V.rows(); i++)
-            fscanf (fp, "%lf %lf %lf\n", &V(i,0), &V(i,1), &V(i,2));
-        
-        for (unsigned i = 0; i < F.rows(); i++)
-            fscanf (fp, "3 %d %d %d\n", &F(i,0), &F(i,1), &F(i,2));
-        
-        fclose (fp);
+      fprintf (stderr, "readOFF(): could not open file %s", meshfile.c_str());
+      return false;
     }
+    
+    fscanf (fp, "OFF\n%d %d 0\n",  &vnum, &fnum);
+    
+    V = Eigen::MatrixXd (vnum, 3);
+    F = Eigen::MatrixXi (fnum, 3);
+    
+    for (unsigned i = 0; i < V.rows(); i++)
+        fscanf (fp, "%lf %lf %lf\n", &V(i,0), &V(i,1), &V(i,2));
+    
+    for (unsigned i = 0; i < F.rows(); i++)
+        fscanf (fp, "3 %d %d %d\n", &F(i,0), &F(i,1), &F(i,2));
+    
+    fclose (fp);
+    return true;
 }
 
-#endif
+#endif

+ 3 - 0
verbose.h

@@ -1,3 +1,5 @@
+#ifndef IGL_VERBOSE_H
+#define IGL_VERBOSE_H
 // Provide a macro for printf, called verbose that functions exactly like
 // printf if VERBOSE is defined and does exactly nothing if VERBOSE is
 // undefined
@@ -26,3 +28,4 @@ inline int igl::verbose(const char * msg,...)
   return 0;
 #endif
 }
+#endif