Archive for December, 2015

CGAL’s cmake file overriding all cmake flags

Wednesday, December 30th, 2015

I recently ran into many annoying issues with the way that CGAL has setup its default use with CMake. One issue is that its use of CMAKE_SOURCE_DIR instead of PROJECT_SOURCE_DIR makes it impossible to add CGAL via add_subdirectory. As far as I can tell CGAL must always be “installed” and then found using find_package. This makes it difficult to package up source code that will install and build all dependencies via cmake.

The second issue is that cmake suggests:

find_package(CGAL REQUIRE)
include(${CGAL_USE_FILE})

But the include(${CGAL_USE_FILE}) line is like dropping a bomb all over your cmake settings. I tried to prevent this by adding above it:

set(CGAL_DONT_OVERRIDE_CMAKE_FLAGS TRUE)

But this has no effect due to cmake nonsense. Instead adding CACHE seems to work:

set(CGAL_DONT_OVERRIDE_CMAKE_FLAGS TRUE CACHE BOOL "Force CGAL to maintain CMAKE flags")

So, I guess, the cmake entry for cgal should be:

find_package(CGAL REQUIRE)
include(${CGAL_USE_FILE})
set(CGAL_DONT_OVERRIDE_CMAKE_FLAGS TRUE CACHE BOOL "Force CGAL to maintain CMAKE flags")

dyld symbol not found, matlab c++

Sunday, December 27th, 2015

I upgrade to the newest Matlab 2015b and suddenly got some unexpected runtime errors in my command line programs compiled with matlab:

dyld: Symbol not found: _mxDestroyArray
  Referenced from: /Users/ajx/./.main
  Expected in: /usr/lib/libSystem.B.dylib
 in /Users/ajx/./.main

I finally tracked this down to a problem in my DYLD_FALLBACK_LIBRARY_PATH. The path to matlab was there but after /usr/lib/ and for some reason that order was throwing off the dynamic linker. I put the matlab path first and that fixed the problem.

Moved libSystem.B.dylib recovery

Sunday, December 27th, 2015

I recently, foolishly moved the libSystem.B.dylib file to a temporary location libSystem.B.dylib.off.

This immediately brought my mac to a useless state. Simple commands like ls, mv and renaming files in Finder.app stopped working.

I fixed the problem by using another mac to download the mac os x installer. Go to the App Store and select the most recent OS to download. Once it does you can quit the installer and find /Applications/Install\ OS\ X\ El\ Capitan.app. Then from the command line you can issue something like:

sudo /Applications/Install\ OS\ X\ El\ Capitan.app/Contents/Resources/createinstallmedia --volume /Volumes/MyVolume --applicationpath /Applications/Install\ OS\ X\ El\ Capitan.app

Change /Volumes/MyVolume to the location of a usb drive. This will erase the contents of the thumb drive.

Back on the broken mac I restarted holding option and selected to boot from the usb. This was a bit slow but eventually started up and from the utilities at the top I could select Terminal. From there I could re-instate my libSystem.B.dylib.

Purge big files (and their version history) from a git repository

Wednesday, December 23rd, 2015
  1. fork the repo (e.g. using github web interface) and never touch the original again until confident that everything below worked
  2. clone fork
  3. cd fork
  4. git rm all big files
  5. git commit -m “removed big files”
  6. bfg –strip-blobs-bigger-than 20K .
  7. git reflog expire –expire=now –all && git gc –prune=now –aggressive
  8. git push origin –force master

Verify (e.g. on github website) that both repositories look as expected.

Convert relative path to full path in C++

Monday, December 21st, 2015

Here’s one way to convert a relative path like ~/Downloads/../Documents/file.txt to an absolute path /Users/ajx/Documents/file.txt

#include <stdlib.h>
#include <iostream>
...
std::string filename = [](const char * rel_path)
{
  char *real_path = realpath(rel_path, NULL);
  std::string filename = real_path;
  free(real_path);
  return filename;
}(mxArrayToString(prhs[0]));

Unfortunately this seems to crash MATLAB when inserted into a C++ Mex file.

This worked:

string filename;
{
  wordexp_t exp_result;
  wordexp(mxArrayToString(prhs[0]), &exp_result, 0);
  filename = exp_result.we_wordv[0];
}

Strange activation issues with MATLAB

Friday, December 18th, 2015

I recently tried to reinstall matlab. Downloading via the installer was taking forever and crashing halfway through so I tried zipping up the MATLAB_R2015b.app from a different machine and unzipping it into /Applications/. Upon launching matlab I got an error saying I needed to activate using the activation app.

First of all this app is a bit hidden. It’s inside MATLAB_R2015b.app/ (treated as a directory).

Upon double-clicking on Activate.app, nothing.

Launching it via the command line:

./Activate.app/Contents/MacOS/Activate

I saw:

---------------------------------------------------------------------------
Error: Cannot locate Java Runtime Environment (JRE).
The directory /Applications/MATLAB_R2015b.app/Activate.app/Contents/sys/java/jre/maci64/jre does not exist.
---------------------------------------------------------------------------

I tried to fix this by copying the sys directory but then got

No configuration file found at /Applications/MATLAB_R2015b.app/Activate.app/Contents/java/config/activation/launcher.config

To fix both these problems I created MATLAB_R2015b.app/tmp then copied the activate program there and ran it:

mkdir tmp
cp ./Activate.app/Contents/MacOS/Activate tmp/
./tmp/Activate

That worked.

Write a triangle mesh to xml file in libigl using Eigen matrix templated on CGAL’s Exact Kernel

Thursday, December 17th, 2015

Lately I’ve been working with CGAL and its arbitrary precision kernel. These are convenient, but writing to standard floating point precision mesh file formats requires rounding. Here’s a relatively straightforward way of using libigl‘s existing xml serialization routines to write an Eigen matrix tempalated on the CGAL Exact kernels number type (e.g. a matrix of vertex positions) to an xml file (using ASCII or base64 binary encoding).

Notice that there’s a bit of gnarly template specialization that needs to be done inside the igl::xml::serialization_xml namespace. The structure of the libigl xml serialization code is unfortunately not very flexible.

#include <igl/xml/serialize_xml.h>
#include <Eigen/Core>
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
#include <iostream>

typedef CGAL::Epeck::FT EScalar;
typedef Eigen::Matrix<EScalar,Eigen::Dynamic,Eigen::Dynamic> MatrixXE;

namespace igl
{
  namespace xml
  {
    namespace serialization_xml
    {
      template <> inline void serialize(
        const MatrixXE & obj,
        tinyxml2::XMLDocument* doc,
        tinyxml2::XMLElement* element,
        const std::string& name)
      {
        const std::function<std::string(const MatrixXE::Scalar &) > to_string = 
          [](const MatrixXE::Scalar & v)->std::string
          {
            return
              STR(CGAL::exact(v));
          };
        serialize(obj,name,to_string,doc,element);
      }
      template <> inline void deserialize(
        MatrixXE & obj,
        const tinyxml2::XMLDocument* doc,
        const tinyxml2::XMLElement* element,
        const std::string& name)
      {
        const std::function<void(const std::string &,MatrixXE::Scalar &)> & 
          from_string = 
          [](const std::string & s, MatrixXE::Scalar & v)
          {
            std::stringstream(s)>>v;
          };
        deserialize(doc,element,name,from_string,obj);
      }
    }
  }
}

int main(int argc, char * argv[])
{
  using namespace std;
  using namespace Eigen;
  // Little 4-vertex, 2-face mesh with rational coordinates
  MatrixXE V(4,3),W;
  V<<
    EScalar(1)/EScalar(3),  EScalar(1)/EScalar(13), EScalar(1)/EScalar(7),
    EScalar(1)/EScalar(7),  EScalar(1)/EScalar(3),  EScalar(1)/EScalar(13),
    EScalar(1)/EScalar(13), EScalar(1)/EScalar(7),  EScalar(1)/EScalar(3),
    EScalar(1)/EScalar(13), EScalar(1)/EScalar(7), -EScalar(1)/EScalar(3);
  MatrixXi F(2,3),G;
  F<<0,1,2,0,2,3;

  // Write mesh
  const bool binary = false;
  // Write vertices, overwriting file (true)
  igl::xml::serialize_xml(V,"vertices","exact.xml",binary,true);
  // Write faces to same file, appending (false)
  igl::xml::serialize_xml(F,"faces","exact.xml",binary,false);

  // Read mesh
  igl::xml::deserialize_xml(W,"vertices","exact.xml");
  igl::xml::deserialize_xml(G,"faces","exact.xml");

  // Verify 
  cout<<"V "<<(V.isApprox(W,0) ? "equals" : "does not equal")<<" W"<<endl;
}

Here’s a little feeling for the overhead of this format on a big single-precision mesh cast to the exact kernel (the expressions are simple and short, so this is sort of a best case scenario):

|           | .ply|.xml ascii|.xml binary| .obj|
|-----------|-----|----------|-----------|-----|
|File size: |172MB|     511MB|      330MB|288MB|
|Zip size:  |  68M|     134MB|       74MB| 81MB|
|Read time: |   8s|      270s|         9s|  32s|
|Write time:|  13s|       46s|        13s|  28s|

CGAL gotcha when trying to modify coordinates of a point etc.

Saturday, December 12th, 2015

Today I ran into a CGAL gotcha. If you try to directly modify, say, the x-coordinate of a point like this:

#include <CGAL/Point_2.h>
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
#include <iostream>
int main(int argc, char * argv[])
{
  using namespace std;
  using namespace CGAL;
  Point_2<CGAL::Epeck> A(0,0);
  Point_2<CGAL::Epeck> B(1,2);
  A.x() = B.x();
  cout<<"A: "<<A.x()<<","<<A.y()<<endl;
}

The program will silently compile without warning or error, but the run time behavior is not what you’d expect. The program prints:

A: 0,0

That is, A was unchanged by the line A.x() = B.x();

The CGAL doc suggests instead always creating a new point: A = Point_2(B.x(),A.y()); Too bad.