Browse Source

Merge branch 'dev' into python

teseoch 6 years ago
parent
commit
e9468f9f33

+ 7 - 0
.travis.yml

@@ -35,13 +35,20 @@ matrix:
     env:
     - MATRIX_EVAL="export CC=gcc-7 CXX=g++-7 CONFIG=Release CMAKE_EXTRA='-DLIBIGL_USE_STATIC_LIBRARY=OFF'"
   - os: osx
+    osx_image: xcode10.2
     compiler: clang
     env:
     - MATRIX_EVAL="export CONFIG=Debug LIBIGL_NUM_THREADS=1"
   - os: osx # same config like above but with -DLIBIGL_USE_STATIC_LIBRARY=OFF to test static and header-only builds
+    osx_image: xcode10.2
     compiler: clang
     env:
     - MATRIX_EVAL="export CONFIG=Debug LIBIGL_NUM_THREADS=1 CMAKE_EXTRA='-DLIBIGL_USE_STATIC_LIBRARY=OFF'"
+  - os: osx
+    osx_image: xcode10.2
+    compiler: clang
+    env:
+    - MATRIX_EVAL="export CONFIG=Debug PYTHON=python3 LIBIGL_NUM_THREADS=1 CMAKE_EXTRA='-DLIBIGL_EIGEN_VERSION=3.3.7'""
 
 install:
 - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then export PATH="/usr/local/opt/ccache/libexec:$PATH"; fi

+ 8 - 0
cmake/libigl-cgal.yml

@@ -0,0 +1,8 @@
+# This is a conda environment that can be used to compile libigl with CGAL on Windows
+# Only boost is required to be installed on the system, CGAL is automatically downloaded
+# by CMake and is built with libigl.
+name: libigl-cgal
+channels:
+  - conda-forge
+dependencies:
+  - boost-cpp=1.65.0

+ 42 - 16
include/igl/file_dialog_open.cpp

@@ -1,9 +1,9 @@
 // This file is part of libigl, a simple c++ geometry processing library.
-// 
+//
 // Copyright (C) 2014 Daniele Panozzo <[email protected]>
-// 
-// This Source Code Form is subject to the terms of the Mozilla Public License 
-// v. 2.0. If a copy of the MPL was not distributed with this file, You can 
+//
+// This Source Code Form is subject to the terms of the Mozilla Public License
+// v. 2.0. If a copy of the MPL was not distributed with this file, You can
 // obtain one at http://mozilla.org/MPL/2.0/.
 #include "file_dialog_open.h"
 #include <cstdio>
@@ -13,7 +13,7 @@
   #include <windows.h>
   #undef max
   #undef min
-  
+
   #include <Commdlg.h>
 #endif
 
@@ -21,7 +21,9 @@ IGL_INLINE std::string igl::file_dialog_open()
 {
   const int FILE_DIALOG_MAX_BUFFER = 1024;
   char buffer[FILE_DIALOG_MAX_BUFFER];
-  
+  buffer[0] = '\0';
+  buffer[FILE_DIALOG_MAX_BUFFER - 1] = 'x'; // Initialize last character with a char != '\0'
+
 #ifdef __APPLE__
   // For apple use applescript hack
   FILE * output = popen(
@@ -32,11 +34,22 @@ IGL_INLINE std::string igl::file_dialog_open()
     "   end tell\n"
     "   set existing_file_path to (POSIX path of (existing_file))\n"
     "\" 2>/dev/null | tr -d '\n' ","r");
-  while ( fgets(buffer, FILE_DIALOG_MAX_BUFFER, output) != NULL )
+  if (output)
   {
+    auto ret = fgets(buffer, FILE_DIALOG_MAX_BUFFER, output);
+    if (ret == NULL || ferror(output))
+    {
+      // I/O error
+      buffer[0] = '\0';
+    }
+    if (buffer[FILE_DIALOG_MAX_BUFFER - 1] == '\0')
+    {
+      // File name too long, buffer has been filled, so we return empty string instead
+      buffer[0] = '\0';
+    }
   }
 #elif defined _WIN32
-  
+
   // Use native windows file dialog box
   // (code contributed by Tino Weinkauf)
 
@@ -48,7 +61,7 @@ IGL_INLINE std::string igl::file_dialog_open()
   ofn.lStructSize = sizeof(ofn);
   ofn.hwndOwner = NULL;
   ofn.lpstrFile = new char[100];
-  // Set lpstrFile[0] to '\0' so that GetOpenFileName does not 
+  // Set lpstrFile[0] to '\0' so that GetOpenFileName does not
   // use the contents of szFile to initialize itself.
   ofn.lpstrFile[0] = '\0';
   ofn.nMaxFile = sizeof(szFile);
@@ -59,7 +72,7 @@ IGL_INLINE std::string igl::file_dialog_open()
   ofn.lpstrInitialDir = NULL;
   ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
 
-  // Display the Open dialog box. 
+  // Display the Open dialog box.
   int pos = 0;
   if (GetOpenFileName(&ofn)==TRUE)
   {
@@ -68,20 +81,33 @@ IGL_INLINE std::string igl::file_dialog_open()
       buffer[pos] = (char)ofn.lpstrFile[pos];
       pos++;
     }
-  } 
+  }
   buffer[pos] = 0;
 #else
-  
+
   // For linux use zenity
   FILE * output = popen("/usr/bin/zenity --file-selection","r");
-  while ( fgets(buffer, FILE_DIALOG_MAX_BUFFER, output) != NULL )
+  if (output)
   {
+    auto ret = fgets(buffer, FILE_DIALOG_MAX_BUFFER, output);
+    if (ret == NULL || ferror(output))
+    {
+      // I/O error
+      buffer[0] = '\0';
+    }
+    if (buffer[FILE_DIALOG_MAX_BUFFER - 1] == '\0')
+    {
+      // File name too long, buffer has been filled, so we return empty string instead
+      buffer[0] = '\0';
+    }
   }
-  
-  if (strlen(buffer) > 0)
+
+  // Replace last '\n' by '\0'
+  if(strlen(buffer) > 0)
   {
-    buffer[strlen(buffer)-1] = 0;
+    buffer[strlen(buffer)-1] = '\0';
   }
+
 #endif
   return std::string(buffer);
 }

+ 38 - 11
include/igl/file_dialog_save.cpp

@@ -1,9 +1,9 @@
 // This file is part of libigl, a simple c++ geometry processing library.
-// 
+//
 // Copyright (C) 2014 Daniele Panozzo <[email protected]>
-// 
-// This Source Code Form is subject to the terms of the Mozilla Public License 
-// v. 2.0. If a copy of the MPL was not distributed with this file, You can 
+//
+// This Source Code Form is subject to the terms of the Mozilla Public License
+// v. 2.0. If a copy of the MPL was not distributed with this file, You can
 // obtain one at http://mozilla.org/MPL/2.0/.
 #include "file_dialog_save.h"
 #include <cstdio>
@@ -18,6 +18,9 @@ IGL_INLINE std::string igl::file_dialog_save()
 {
   const int FILE_DIALOG_MAX_BUFFER = 1024;
   char buffer[FILE_DIALOG_MAX_BUFFER];
+  buffer[0] = '\0';
+  buffer[FILE_DIALOG_MAX_BUFFER - 1] = 'x'; // Initialize last character with a char != '\0'
+
 #ifdef __APPLE__
   // For apple use applescript hack
   // There is currently a bug in Applescript that strips extensions off
@@ -31,8 +34,19 @@ IGL_INLINE std::string igl::file_dialog_save()
     "   end tell\n"
     "   set existing_file_path to (POSIX path of (existing_file))\n"
     "\" 2>/dev/null | tr -d '\n' ","r");
-  while ( fgets(buffer, FILE_DIALOG_MAX_BUFFER, output) != NULL )
+  if (output)
   {
+    auto ret = fgets(buffer, FILE_DIALOG_MAX_BUFFER, output);
+    if (ret == NULL || ferror(output))
+    {
+      // I/O error
+      buffer[0] = '\0';
+    }
+    if (buffer[FILE_DIALOG_MAX_BUFFER - 1] == '\0')
+    {
+      // File name too long, buffer has been filled, so we return empty string instead
+      buffer[0] = '\0';
+    }
   }
 #elif defined _WIN32
 
@@ -47,7 +61,7 @@ IGL_INLINE std::string igl::file_dialog_save()
   ofn.lStructSize = sizeof(ofn);
   ofn.hwndOwner = NULL;//hwnd;
   ofn.lpstrFile = new char[100];
-  // Set lpstrFile[0] to '\0' so that GetOpenFileName does not 
+  // Set lpstrFile[0] to '\0' so that GetOpenFileName does not
   // use the contents of szFile to initialize itself.
   ofn.lpstrFile[0] = '\0';
   ofn.nMaxFile = sizeof(szFile);
@@ -58,7 +72,7 @@ IGL_INLINE std::string igl::file_dialog_save()
   ofn.lpstrInitialDir = NULL;
   ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
 
-  // Display the Open dialog box. 
+  // Display the Open dialog box.
   int pos = 0;
   if (GetSaveFileName(&ofn)==TRUE)
   {
@@ -73,14 +87,27 @@ IGL_INLINE std::string igl::file_dialog_save()
 #else
   // For every other machine type use zenity
   FILE * output = popen("/usr/bin/zenity --file-selection --save","r");
-  while ( fgets(buffer, FILE_DIALOG_MAX_BUFFER, output) != NULL )
+  if (output)
   {
+    auto ret = fgets(buffer, FILE_DIALOG_MAX_BUFFER, output);
+    if (ret == NULL || ferror(output))
+    {
+      // I/O error
+      buffer[0] = '\0';
+    }
+    if (buffer[FILE_DIALOG_MAX_BUFFER - 1] == '\0')
+    {
+      // File name too long, buffer has been filled, so we return empty string instead
+      buffer[0] = '\0';
+    }
   }
-  
-  if (strlen(buffer) > 0)
+
+  // Replace last '\n' by '\0'
+  if(strlen(buffer) > 0)
   {
-    buffer[strlen(buffer)-1] = 0;
+    buffer[strlen(buffer)-1] = '\0';
   }
+
 #endif
   return std::string(buffer);
 }

+ 19 - 0
include/igl/opengl/ViewerData.cpp

@@ -26,6 +26,7 @@ IGL_INLINE igl::opengl::ViewerData::ViewerData()
   show_overlay_depth(true),
   show_vertid(false),
   show_faceid(false),
+  show_labels(false),
   show_texture(false),
   point_size(30),
   line_width(0.5f),
@@ -288,6 +289,11 @@ IGL_INLINE void igl::opengl::ViewerData::add_points(const Eigen::MatrixXd& P,  c
   dirty |= MeshGL::DIRTY_OVERLAY_POINTS;
 }
 
+IGL_INLINE void igl::opengl::ViewerData::clear_points()
+{
+  points.resize(0, 6);
+}
+
 IGL_INLINE void igl::opengl::ViewerData::set_edges(
   const Eigen::MatrixXd& P,
   const Eigen::MatrixXi& E,
@@ -337,6 +343,11 @@ IGL_INLINE void igl::opengl::ViewerData::add_edges(const Eigen::MatrixXd& P1, co
   dirty |= MeshGL::DIRTY_OVERLAY_LINES;
 }
 
+IGL_INLINE void igl::opengl::ViewerData::clear_edges()
+{
+  lines.resize(0, 9);
+}
+
 IGL_INLINE void igl::opengl::ViewerData::add_label(const Eigen::VectorXd& P,  const std::string& str)
 {
   Eigen::RowVectorXd P_temp;
@@ -356,6 +367,14 @@ IGL_INLINE void igl::opengl::ViewerData::add_label(const Eigen::VectorXd& P,  co
   labels_strings.push_back(str);
 }
 
+IGL_INLINE void igl::opengl::ViewerData::set_labels(const Eigen::MatrixXd& P, const std::vector<std::string>& str)
+{
+  assert(P.rows() == str.size() && "position # and label # do not match!");
+  assert(P.cols() == 3 && "dimension of label positions incorrect!");
+  labels_positions = P;
+  labels_strings = str;
+}
+
 IGL_INLINE void igl::opengl::ViewerData::clear_labels()
 {
   labels_positions.resize(0,3);

+ 13 - 1
include/igl/opengl/ViewerData.h

@@ -107,6 +107,10 @@ public:
     const Eigen::MatrixXd& P,
     const Eigen::MatrixXd& C);
   IGL_INLINE void add_points(const Eigen::MatrixXd& P,  const Eigen::MatrixXd& C);
+
+  // Clear the point data
+  IGL_INLINE void clear_points();
+
   // Sets edges given a list of edge vertices and edge indices. In constrast
   // to `add_edges` this will (purposefully) clober existing edges.
   //
@@ -114,14 +118,20 @@ public:
   //   P  #P by 3 list of vertex positions
   //   E  #E by 2 list of edge indices into P
   //   C  #E|1 by 3 color(s)
+
   IGL_INLINE void set_edges (const Eigen::MatrixXd& P, const Eigen::MatrixXi& E, const Eigen::MatrixXd& C);
   // Alec: This is very confusing. Why does add_edges have a different API from
   // set_edges?
   IGL_INLINE void add_edges (const Eigen::MatrixXd& P1, const Eigen::MatrixXd& P2, const Eigen::MatrixXd& C);
 
-  // Adds text labels at the given positions in 3D.
+  // Clear the edge data
+  IGL_INLINE void clear_edges();
+
+  // Sets / Adds text labels at the given positions in 3D.
   // Note: This requires the ImGui viewer plugin to display text labels.
   IGL_INLINE void add_label (const Eigen::VectorXd& P,  const std::string& str);
+  IGL_INLINE void set_labels (const Eigen::MatrixXd& P,  const std::vector<std::string>& str);
+
   // Clear the label data
   IGL_INLINE void clear_labels ();
 
@@ -211,6 +221,7 @@ public:
   unsigned int show_lines;
   bool show_vertid; // shared across viewports for now
   bool show_faceid; // shared across viewports for now
+  bool show_labels; // shared across viewports for now
 
   // Point size / line width
   float point_size;
@@ -275,6 +286,7 @@ namespace igl
       SERIALIZE_MEMBER(show_overlay_depth);
       SERIALIZE_MEMBER(show_vertid);
       SERIALIZE_MEMBER(show_faceid);
+      SERIALIZE_MEMBER(show_labels);
       SERIALIZE_MEMBER(show_texture);
       SERIALIZE_MEMBER(point_size);
       SERIALIZE_MEMBER(line_width);

+ 2 - 1
include/igl/opengl/glfw/imgui/ImGuiMenu.cpp

@@ -303,6 +303,7 @@ IGL_INLINE void ImGuiMenu::draw_viewer_menu()
     make_checkbox("Fill", viewer->data().show_faces);
     ImGui::Checkbox("Show vertex labels", &(viewer->data().show_vertid));
     ImGui::Checkbox("Show faces labels", &(viewer->data().show_faceid));
+    ImGui::Checkbox("Show extra labels", &(viewer->data().show_labels));
   }
 }
 
@@ -365,7 +366,7 @@ IGL_INLINE void ImGuiMenu::draw_labels(const igl::opengl::ViewerData &data)
     }
   }
 
-  if (data.labels_positions.rows() > 0)
+  if (data.show_labels)
   {
     for (int i = 0; i < data.labels_positions.rows(); ++i)
     {

+ 6 - 6
include/igl/opengl/glfw/imgui/ImGuiTraits.h

@@ -26,42 +26,42 @@ template<>
 class ImGuiDataTypeTraits<int>
 {
 	static constexpr ImGuiDataType value = ImGuiDataType_S32;
-	static constexpr char format [] = "%d";
+	static constexpr const char *format = "%d";
 };
 
 template<>
 class ImGuiDataTypeTraits<unsigned int>
 {
 	static constexpr ImGuiDataType value = ImGuiDataType_U32;
-	static constexpr char format [] = "%u";
+	static constexpr const char *format = "%u";
 };
 
 template<>
 class ImGuiDataTypeTraits<long long>
 {
 	static constexpr ImGuiDataType value = ImGuiDataType_S64;
-	static constexpr char format [] = "%lld";
+	static constexpr const char *format = "%lld";
 };
 
 template<>
 class ImGuiDataTypeTraits<unsigned long long>
 {
 	static constexpr ImGuiDataType value = ImGuiDataType_U64;
-	static constexpr char format [] = "%llu";
+	static constexpr const char *format = "%llu";
 };
 
 template<>
 class ImGuiDataTypeTraits<float>
 {
 	static constexpr ImGuiDataType value = ImGuiDataType_Float;
-	static constexpr char format [] = "%.3f";
+	static constexpr const char *format = "%.3f";
 };
 
 template<>
 class ImGuiDataTypeTraits<double>
 {
 	static constexpr ImGuiDataType value = ImGuiDataType_Double;
-	static constexpr char format [] = "%.6f";
+	static constexpr const char *format = "%.6f";
 };
 
 } // namespace ImGui