Archive for December, 2012

(Re)define assert macro to behave the same in mex file without crashing matlab

Monday, December 31st, 2012

I recently posted a find and replace regex for changing asserts into mex error messages. Here’s a fancier way to do it without the find and replace.

#undef assert
#ifdef NDEBUG
#  define assert( isOK ) ((void)0)
#else
#  define assert( isOK ) ( (isOK) ? (void)0 : (void) mexErrMsgTxt(C_STR(__FILE__<<":"<<__LINE__<<": failed assertion `"<<#isOK<<"'"<<std::endl) ) )
#endif

Now any asserts will trigger a mex error and the message will be the same as a gcc assertion message. Source

Note: I updated this so that’s it’s not defined when NDEBUG is defined (just like the usual assert).

Use vim to replace asserts with mexErrMsgTxt

Monday, December 31st, 2012

Snippet to find and replace appropriately:


%s/assert(\(.*\));/if(!(\1)) mexErrMsgTxt("\1");/g

Colours I AM A MAN MAN MAN MAN REMIX ft. Grouplove

Monday, December 24th, 2012


Download high resolution video
Download mp3

Bounded biharmonic weights c++ demo for surfaces/volumes in 3d

Monday, December 24th, 2012

By popular demand I’ve created a quick-and-dirty 3d C++ demo of our paper “Bounded Biharmonic Weights for Real-time Deformation” [Jacobson et al. 2011].

The demo takes a mesh (.obj or .off) and a description of a skeleton (in my own ridiculous .bf and .tgf file formats) and computes a tetrahedral volume mesh using tetgen (saved to a .mesh file) and then computed bounded biharmonic weights for each handle over this mesh (save to my not-so-ridiculous .dmat file format).

This is a small program that illustrates how to compute Bounded Biharmonic Weights (BBW) for a given surface mesh and skeleton description. This only supports point handles and skeleton trees (bones). Cages are not supported. This program only computes and outputs the weight function values. You should be able to load them into matlab or maya or whatever.

COMPILE

First install the dependencies (e.g. mosek). If your on a mac, and why wouldn’t you be, then you *should* with any luck and by the grace of God be able to compile with:


make

RUN

Then run an example with (e.g.):


./bbw_demo examples/brick.obj examples/brick.tgf

This will produce at least 2 files:


  examples/brick-volume.mesh  Tetrahedral mesh over which weights were computed
  examples/brick-volume.dmat  Coefficients of weights defined over .mesh

File Formats

See file-formats/index.html

The dependencies are:

  igl_lib
    eigen3
    tetgen
    mosek

Igl lib

IGL_lib is our groups internal library. It will someday be publicly available, but not yet. Thus I only include here a bare minimum to get this demo to work. The library functions as an inlined header library. All the source is located in ./igl_lib/include/igl

Eigen3: The igl dependencies rely on a depracted version of the Sparse Matrix suite in eigen 3. Thus you need the correct version of eigen. To make this easier I have included the necessary version of eigen here: ./eigen3

Mosek: Mosek is free for academics and has its own installation instructions. Adjust your makefile accordingly.

Tetgen Tetgen is also free and easy to install. Be sure to compile the library version, i.e.:


make tetlib

To make life a little easier I include a working version of tetgen in ./igl_lib/external/tetgen/. You can go there and compile libtet.a or download the tetgen source and do that on your own. Whatever.

You can try to contact me with questions. Especially regarding the algorithm described in “Bounded biharmonic weights for real-time deformation” by [Jacobson et al. 2011]. However, please
please
please
please
please
please
please
please
please
please
please
please
please
please
please
please
please
please
try to solve compilation troubles on your own. I didn’t intend for this code to be machine independent or even necessarily easy to compile. This is a quick and dirty demo because so many people requested it.

Sometime in the not too distant future I still plan to release a *nice* 3d, C++ demo.

Update: I have updated this demo to use the libigl library. Please find the new version on the bbw project page.

FTDI’s libftd2xx.1.2.2 broken for macbook air running 10.7.4 (workaround)

Friday, December 21st, 2012

I recently got my device working on my iMac at work using the libftd2xx.1.2.2 available from the drivers page of FTDI. Unfortunately the code I wrote that worked with that version of the library on my iMac did not work on my macbook air (despite running the same mac os x 10.7). My problem was that FT_Open was returning -1, which as far as I can tell is not a valid FT_STATUS enum value.

After a (not so) brief stint trying to get the libftdi open source library to work (I gave up because it was slow and crashed on ftdi_usb_close and ftdi_usb_reset), I tried to see if any of the old releases of libftd2xx would work for me. I tried all I could find and report the following:


Name                    Source   Problem
libftd2xx.1.1.0.dylib,  macports,          random "bus error 10" after ~30secs (otherwise pretty good)
libftd2xx.0.1.7.dylib,  D2xx drivers page, "Error FT_ListDevices(18)" and reading garbage occasionally
libftd2xx.1.0.4.dylib,  D2xx hidden page,  reading occasional garbage
libftd2xx.1.1.0.dylib,  D2xx hidden page,  "bus error 10" after ~30secs (otherwise pretty good)
libftd2xx.1.1.12.dylib, D2xx Drivers page, FT_Open(-1)
libftd2xx.1.2.2.dylib,  D2xx Drivers page, FT_Open(-1)

As you can see, one of the sources is “D2xx hidden page”. I found this accidentally.

The version 1.1.0 seemed like the best bet. But like clockwork the device would send a Bus error: 10 and crash after 30 seconds. I flipped a bunch of switches and toggled a bunch of comments and I think I found the issue.

I was reading in a tight loop using something like:


ftStatus = FT_Read(ftHandle, buffer, BUF_SIZE, &dwRxSize);

But what works is to do something like:


ftStatus = FT_GetStatus(ftHandle, &dwAmountInRxQueue, &dwAmountInTxQueue, &dwEventStatus);
if(dwAmountInRxQueue)                                      
{                                                          
  ftStatus = FT_Read(ftHandle, buffer, (dwAmountInRxQueue<BUF_SIZE?dwAmountInRxQueue:BUF_SIZE), &dwRxSize);
} 

I understand why the second is better, but I don’t understand why the first should crash. In any case, my device has been running with no problems for going on 8 minutes. So I’m happy again.

FTDI FT_Read from usb lag

Friday, December 21st, 2012

Yesterday, we hunted down a problem using FTDI’s D2XX drivers on my mac that was causing reading from our device to lag unevenly. We timed our reading routines and couldn’t find where we were losing framerate. Finally we found two issues, both fixed by changing parameters immediately after opening the device:

Originally we had


FT_SetTimeouts(ftHandle, 100, 100);

And we should have had


FT_SetTimeouts(ftHandle, 1, 1);

This function controls the maximum wait time during any call to FT_Read and FT_write.

Finally, the major cause of the lag was the absence of the following:


FT_SetUSBParameters(ftHandle, 64,64))

This defines the amount of data read and written each time from and to the device in bytes. It seems the default values were 4096 bytes. Our device sends a small amount of data at high frequency, so this number was way to high and was the major bottleneck causing the lag.

Create new directory on svn repository trunk

Friday, December 14th, 2012

Here’s a small script to add a new folder [NEW_DIR] to your svn repository at [SVN_REPO_URL]:


svn co --non-recursive [SVN_REPO_URL]/trunk trunk
cd trunk/
svn mkdir [NEW_DIR]
svn ci -m "added [NEW_DIR]"
cd ..
rm -rf trunk/
svn co --non-recursive [SVN_REPO_URL]/trunk/[NEW_DIR] [NEW_DIR]

Waly Gisnep T-shirt

Wednesday, December 12th, 2012

waly gisnep tshirt
I’m going to have these made in America over christmas. Tell me what size you want (American S/M/L/XL etc.) They’ll probably be $10 – $20. Pick up Rochester or Zurich, otherwise I can mail it.

Bijective mappings with generalized barycentric coordinates: a counterexample

Tuesday, December 11th, 2012

bijective barycentric coordinates: counter example

After attending the NFS Workshop on Barycentric Coordinates this summer I wrote up a quick counterexample showing that generalized barycentric coordinates cannot be designed to always produce bijective mappings. To be clear, no existing coordinates have claimed to obtain this property, but as far as I know no one has written explicitly that it’s out of reach.

Abstract
Many recent works attempt to generalize barycentric coordinates to arbitrary polygons. I construct a counterexample proving that no such generalization will produce purely bijective mappings in the plane provided the coordinates meet the Lagrange, reproduction, and partition of unity properties. The proof concerns generalized barycentric coordinates in a square, but trivially generalizes to arbitrary polygons with degree greater than three.

Sketch
Consider the four corners of square above. As we move c3 towards c1 the point x originally at the origin will either:

  1. be overrun by c3 before c3=c1 (not bijective),
  2. reach (and thus overrun) c1 before c3=c1 (not bijective)
  3. or the coordinate function of w3(x)=0.5 (bijective)

But by rotational symmetry we may apply the same logic for all 4 corners implying that to get a bijection we have all four coordinates =0.5 contradicting the partition of unity assumption.

Keys pressed while holding down mouse are repeated using AntTweakBar

Monday, December 10th, 2012

I found a strange bug in AntTweakBar, that causes key press events to be repeated when holding the mouse down. Here’s a tiny self-compiling cpp program to reproduce the error:


#!/bin/bash
/*/../bin/ls > /dev/null
# BEGIN BASH SCRIPT
printf "//" | cat - $0 | g++ -g -I/opt/local/igl/igl_lib/include -Wall -Wextra -O3 -o .main -x c++ - -L/opt/local/igl/igl_lib/external/AntTweakBar/lib -lAntTweakBar -framework AppKit -framework GLUT -framework OpenGL && ./.main $@
rm -f .main
# END BASH SCRIPT
exit
*/

#include <AntTweakBar.h>

#ifdef __APPLE__
#  include <OpenGL/gl.h>
#  include <GLUT/glut.h>
#elif defined(_WIN32)
#  include <GL/freeglut.h>
#  define NOMINMAX
#  include <Windows.h>
#  undef NOMINMAX
#else
#  define GL_GLEXT_PROTOTYPES
#  include <GL/gl.h>
#  include <GL/glext.h>
#  include <GL/glut.h>
#endif

#include <iostream>

using namespace std;
bool bool_var = true;

void reshape(int width, int height)
{
  TwWindowSize(width,height);
}

void display()
{
  if(bool_var)
  {
    glClearColor(0,0,0,0);
  }else
  {
    glClearColor(1,1,1,0);
  }
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  TwDraw();
  glutSwapBuffers();
  glutPostRedisplay();
}

int main(int argc, char * argv[])
{
  using namespace std;
  cout<<"1) Click+hold the mouse button in the window but do not drag."<<endl;
  cout<<"2) Press and release 'a'."<<endl;

  glutInit(&argc,argv);
  TwInit(TW_OPENGL, NULL);
  TwBar * bar = TwNewBar("bar");
  TwDefine("bar label='bar' size='200 200' text=light alpha='200' color='68 68 68'");
  TwAddVarRW(bar,"bool_var",TW_TYPE_BOOLCPP,&bool_var,"key=a");
  glutInitWindowSize(500,250);
  glutCreateWindow(__FILE__);
  glutDisplayFunc(display);
  glutReshapeFunc(reshape);
  glutMouseFunc((GLUTmousebuttonfun)TwEventMouseButtonGLUT);
  glutMotionFunc((GLUTmousemotionfun)TwEventMouseMotionGLUT);
  glutPassiveMotionFunc((GLUTmousemotionfun)TwEventMouseMotionGLUT); // same as MouseMotion
  glutKeyboardFunc((GLUTkeyboardfun)TwEventKeyboardGLUT);
  glutSpecialFunc((GLUTspecialfun)TwEventSpecialGLUT);
  glutMainLoop();
  TwTerminate();
  return 0;
}

To reproduce the problem, run the code and do the following:

  1. Click the left mouse button in the middle of the window and hold it without moving the cursor
  2. Press and release ‘a’

You should see the background change just once, but instead it flashes because the key press event is being repeatedly sent.

I dug around in the AntTweakBar source code and found that it’s not exactly that the key press event is being repeated. It’s that when you click and hold the mouse in the same position, AntTweakbar is simulating a repeated mouse click every time the bar is drawn (TwDraw()). Now, when you press a key AntTweakBar processes the key event and then highlights the appropriate bar item. This highlighting is then used by the repeated mouse clicks as if the highlighted item were under the mouse.

To fix this bug you can replace line ~2058 in TwMgr.cpp:


TwMouseButton(TW_MOUSE_PRESSED, g_TwMgr->m_LastMousePressedButtonID);

with:


TwMouseMotion(g_TwMgr->m_LastMouseX,g_TwMgr->m_LastMouseY);
TwMouseButton(TW_MOUSE_PRESSED, g_TwMgr->m_LastMousePressedButtonID);

This just tells AntTweakBar to first consider the mouse position before simulating a click.