Diary #1 – Looking through a Boost.Python project; Mesh repair

This is the start of my attempt to write a daily account of the things I do. There won’t be much in-depth detail in these diaries, and I’m mostly writing for myself so that I have some sort of continuity of thought that persists beyond one day, so I’ll put Diary in the title to make it easy for you, the reader, to quickly skip these if you want.

I have been looking into Boost.Python recently and today I looked at the CGAL Python Bindings project. In retrospect, I should have known when I saw the handmade Makefile and instructions for the previous major version of CGAL that I was getting into some old, unmaintained code. On the other hand, it is a good thing I went through the exercise of going through the code and compiling some parts of it. For future reference, the current Python wrapper project for CGAL is actually called cgal-bindings and actually uses SWIG. I still don’t really want to get into SWIG because it’s another thing I have to learn, and my project already incorporates Boost so I’ll stick to that.

The other thing that I spent most of my time on was repairing the skull meshes that we have in the lab. A lot of these meshes have twists, tangles, and foldovers that are really gnarly and I didn’t know how to deal with them until recently I learned a thing or two about Blender. I remember when I first opened Blender up, couldn’t find a way to import my .off file, and just wanted to close it and be done with it. Now, I know enough to be able to do what I want as far as untangling these contorted meshes. I repaired 7 today, and I think I can finish the remaining 10 tomorrow.

twistedMesh

Above is an example of a gnarly part of the monkey skull mesh. What happened is that a narrow U-shaped patch actually crossed over on itself to become something like the lowercase Greek letter gamma. Here, you’re looking at it from the side, and the highlighted triangles indicate where two faces intersect with each other — this doesn’t happen in reality, so I have to manually pull them apart. Of course, the other gnarly part is the sharp triangles along the ridge line. I write a program to flatten meshes, but it blows up if the input mesh has such configuration of triangles.

untwistedMesh

Here’s an example of what I’m able to do through Blender now. I can pull the sides apart so that the self-intersections go away, and I can clean up the tuft of triangles along the ridge. It takes a bit of time, and it’s up to you to rebuild the shape in a reasonable way. But I’m glad that I can fix it now. I might make a video to demonstrate the technique at some point.

I didn’t get to read as much as I wanted to today. I have a paper on my stack about LDDMM and hippocampus shape that looks interesting, so I’ll read it tomorrow. For general reading, I’ve been saying that I want to get back into reading Chinese, but I’m sick of just reading the news. I bookmarked two blog portals (here and here) that my friends linked articles from on Facebook. I’ll probably spend a bit of time just browsing for a blog or two in a category I’m interested in tomorrow.

Boost.Python hello world example using CMake

Somehow it seems I’m the only one among my labmates who is working mainly in C++/CMake and not Python. I want to do more than help them by discussing code — I want to share my code. So let’s use Boost.Python wrap our C++ library so it can be called from Python code. This tutorial is based on the Hello world example in the Boost.Python docs and uses CMake.

To begin with, here’s a mention of the versions of everything I’m using when I wrote this post so you can judge if stuff is still applicable:

  • Ubuntu 13.04
  • cmake version 2.8.10.1
  • gcc version 4.7.3
  • Boost 1.49 with Python component
  • Python 2.7.4

Here, we create a simple C++ library called libgreet, and we make a wrapper library called greet_ext. The wrapper library can be loaded as a Python module that exposes the function in the C++ library. The files are shown below, and the full example can be downloaded here. To use it, just download it and run these commands:

tar xf BoostPythonHelloWorld.tar.gz
cd BoostPythonHelloWorld
cmake .
make
./test.py

greet.h:

#ifndef GREET_H
#define GREET_H
char const* greet( );
#endif // GREET_H

greet.cpp:

#include "greet.h";

char const* greet( )
{
    return "Hello world";
}

greet_ext.cpp:

#include "greet.h";
#include <boost/python.hpp>;

BOOST_PYTHON_MODULE(greet_ext)
{
    using namespace boost::python;
    def( "greet", greet );
}
  • The parameter to BOOST_PYTHON_MODULE must match the name of the wrapper library we import in Python below. Note where greet_ext appears throughout the different files.

CMakeLists.txt:

cmake_minimum_required( VERSION 2.8 )

project( BoostPythonHelloWorld )

# Find necessary packages
find_package( PythonLibs 2.7 REQUIRED )
include_directories( ${PYTHON_INCLUDE_DIRS} )

find_package( Boost COMPONENTS python REQUIRED )
include_directories( ${Boost_INCLUDE_DIR} )

# Build our library
add_library( greet SHARED greet.cpp )

# Define the wrapper library that wraps our library
add_library( greet_ext SHARED greet_ext.cpp )
target_link_libraries( greet_ext ${Boost_LIBRARIES} greet )
# don't prepend wrapper library name with lib
set_target_properties( greet_ext PROPERTIES PREFIX "" )
  • The line with PythonLibs locates the python includes, which are necessary because the Boost.Python header pulls in a config file from there.
  • By default, CMake builds library targets with the lib prefix, but we actually want our wrapper library to be named greet_ext.so so we can import it with the name below.

test.py:

#!/usr/bin/python

import greet_ext

print greet_ext.greet()
  • This python script works for me if I put it in the same folder as the greet_ext.so wrapper library after it is built.

What I need to figure out
This is a nice, simple example to get started with, but I have to figure out more details.

  • How do I wrap functions that take/return C++ types? How about pointers and references to those types? How about global operators?
  • How does a wrapper library deal with C++ templates? Is it the case that you have to instantiate some of those template classes are just work with those when you’re in Python?
  • Is Boost.Python the right choice? There’s a fairly recent webpage that discusses SWIG versus Boost.Python, and I think I’ve made the right choice for my project.

I’m looking forward to working on this further. This probably will be one of the things I work on this coming Christmas break.

P.S. God WordPress is so annoying when it escapes your code when you toggle between visual and text editing modes. Note to self, don’t switch modes.

One of my new year’s resolutions is com …

One of my new year’s resolutions is complete: contribute code to an open source project! It was just a simple rewrite of a function and some cleanup in a Python script of a dice game for the Freerunner. It’s available here:

http://dl.getdropbox.com/u/508241/ko-dice.2.tar.gz

Couple of notes. (1) It’s fun tweaking code that’s already been written: I don’t have the stamina to put down all the boilerplate, but once it’s there, aha! I can learn from it. (2) Mixing tabs and spaces in Python code is annoying. (3) The guys on the mailing list are really nice and give lots of feedback. It’s great fun!