<?xml version="1.0"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>fhtagn.net</title>
    <link>http://fhtagn.net</link>
    <atom:link href="http://fhtagn.net/rss.xml" rel="self" type="application/rss+xml" />
    <description>fhtagn.net blog posts</description>
    <language>en-us</language>
    <pubDate>Thu, 25 Aug 2022 10:01:27 +0000</pubDate>
    <lastBuildDate>Thu, 25 Aug 2022 10:01:27 +0000</lastBuildDate>

    
      
        <item>
          <title>An educational python implementation of a bitcoin-like blockchain</title>
          <link>http://fhtagn.net/prog/2017/12/17/dumbcoin.html</link>
          <pubDate>Sun, 17 Dec 2017 00:00:00 +0000</pubDate>
          <author>julien@fhtagn.net (Julien Rebetez)</author>
          <guid>http://fhtagn.net/prog/2017/12/17/dumbcoin</guid>
          <description>&lt;p&gt;I’ve been loosely following the cryptocurrency stories over the past few years.
When someone posted &lt;a href=&quot;https://news.ycombinator.com/item?id=15883186&quot;&gt;a link to the original Bitcoin paper on Hacker News&lt;/a&gt; a few days ago, I was amazed at how concise and elegant the paper was.&lt;/p&gt;

&lt;p&gt;After reading it, I decided to do a toy blockchain implementation in Python to understand the inner workings better.&lt;/p&gt;

&lt;p&gt;The result is a &lt;a href=&quot;https://github.com/julienr/ipynb_playground/blob/master/bitcoin/dumbcoin/dumbcoin.ipynb&quot;&gt;jupyter notebook&lt;/a&gt; that implements most of the ideas found in the Bitcoin paper.
It’s pretty far from being a full implementation of the whole Bitcoin protocol, but that wasn’t the goal.&lt;/p&gt;

&lt;p&gt;I posted it to &lt;a href=&quot;https://news.ycombinator.com/item?id=15945490&quot;&gt;Hacker News&lt;/a&gt; and the reception was pretty positive. I even made it to the top \o/&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/prog/post_files/2017-12-17/dumbcoin_hn.png&quot; width=&quot;600px&quot; /&gt;&lt;/p&gt;

</description>
        </item>
      
    
      
        <item>
          <title>Kaggle Ultrasound Nerve Segmentation (25th with 0.70679 final ranking)</title>
          <link>http://fhtagn.net/prog/2016/08/19/kaggle-uns.html</link>
          <pubDate>Fri, 19 Aug 2016 00:00:00 +0000</pubDate>
          <author>julien@fhtagn.net (Julien Rebetez)</author>
          <guid>http://fhtagn.net/prog/2016/08/19/kaggle-uns</guid>
          <description>&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;#data&quot;&gt;1. Data&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#model&quot;&gt;2. Model and results&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#dreaming&quot;&gt;3. Dreaming nerves&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#conclusion&quot;&gt;4. Conclusion&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I participated in the &lt;a href=&quot;https://www.kaggle.com/c/ultrasound-nerve-segmentation/leaderboard&quot;&gt;Ultrasound Nerve Segmentation&lt;/a&gt; Kaggle challenge
and it looks like my final rank is 25th (I was 48th on the public leaderboard).&lt;/p&gt;

&lt;p&gt;The github repo with my code is available &lt;a href=&quot;https://github.com/julienr/kaggle_uns&quot;&gt;here&lt;/a&gt;. I should warn you that since this was a 3 months
competition, the code is not optimized for reuse and probably quite messy
with a lot of copy-paste.&lt;/p&gt;

&lt;h1 id=&quot;data&quot;&gt;1. Data&lt;/h1&gt;
&lt;p&gt;The goal of the competition was to label the area containing a collection of
nerves called the &lt;a href=&quot;https://en.wikipedia.org/wiki/Brachial_plexus&quot;&gt;Brachial plexus&lt;/a&gt; in ultrasound images. So the model is given an grayscale image
as input and should output a binary image (= a binary mask). Some images (about 60% of the training set) do not contain the Brachial plexus area and should
therefore have an empty mask. It basically looks like this :
&lt;img src=&quot;/prog/post_files/2016-08-19/image_example.png&quot; width=&quot;600px&quot; /&gt;&lt;/p&gt;

&lt;p&gt;(left is the image, right is the image and the label area overlayed in red)&lt;/p&gt;

&lt;p&gt;You can have also a look at this &lt;a href=&quot;https://www.kaggle.com/chefele/ultrasound-nerve-segmentation/animated-images-with-outlined-nerve-area/code&quot;&gt;script on kaggle&lt;/a&gt; which has a nice animation of some of the images.&lt;/p&gt;

&lt;p&gt;The images have a size of 580x420 pixels. There are 5635 training images
and 5508 test images (of which 20% were used for public ranking and 80% for
the final ranking).&lt;/p&gt;

&lt;h2&gt;Contradictory labelling in the training data&lt;/h2&gt;
&lt;p&gt;As many people &lt;a href=&quot;https://www.kaggle.com/c/ultrasound-nerve-segmentation/forums/t/21081/non-continuous-score-function/123201#post123201&quot;&gt;found out&lt;/a&gt; during the competition, the training dataset contains many contradictory examples.
By contradictory examples, I mean two images that are &lt;b&gt;very&lt;/b&gt; similar but
with one image having a non-empty mask and the other one having an empty mask.&lt;/p&gt;

&lt;p&gt;Here is an example. The top image has no mask while the one at the bottom has
one.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/prog/post_files/2016-08-19/contradictory_samples.png&quot; width=&quot;600px&quot; /&gt;&lt;/p&gt;

&lt;p&gt;There are a huge number of similar examples in the training set and this puts
a (somewhat low) upper bound on the best result you can achieve, regardless of
the model.&lt;/p&gt;

&lt;p&gt;I believe the problem is partly due to the fact that the images are actually
video frames. So the human expert who is putting the label does so using the
video. But the challenge was set up in a way that we had to labellize individual
images and they shuffled the frames to force us to NOT rely on the temporal
information. I wonder why this choice was made since having videos instead
of images could have been very interesting (CNN-RNN !).&lt;/p&gt;

&lt;h1 id=&quot;model&quot;&gt;2. Model and results&lt;/h1&gt;
&lt;p&gt;This is an image segmentation problem. Like many people in the challenge, I
decided to use some deep learning as it works so well on images. I tried
multiple architectures, but they are all based on &lt;a href=&quot;https://people.eecs.berkeley.edu/~jonlong/long_shelhamer_fcn.pdf&quot;&gt;fully-connected CNN&lt;/a&gt; or &lt;a href=&quot;http://arxiv.org/abs/1505.04597&quot;&gt;U-net&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Before talking about model, here is the evolution of my score on the public LB.
As you can see, I had a pretty solid start and then spent much time trying to
get really small incremental improvements (the red line indicates my best).
&lt;img src=&quot;/prog/post_files/2016-08-19/public_score.png&quot; width=&quot;600px&quot; /&gt;&lt;/p&gt;

&lt;p&gt;The &lt;a href=&quot;https://github.com/julienr/kaggle_uns/blob/master/submissions/subnotes.txt&quot;&gt;subnotes.txt&lt;/a&gt; file in my repo contains some notes about each
submission so I could keep track of what was helpful or not.&lt;/p&gt;

&lt;h2&gt;Pre-processing&lt;/h2&gt;

&lt;h3&gt;Image scaling&lt;/h3&gt;
&lt;p&gt;The images have a size of 580x420. This is quite big and when I first tried
to train a CNN (using a GTX 960) on those images, I quickly ran into memory
and performance problems.&lt;/p&gt;

&lt;p&gt;Also, since I wanted to do a fully-connected network, it’s much easier if
the size of the image is a power of two, so you can pool and unpool without
having to fiddle with padding.&lt;/p&gt;

&lt;p&gt;I quickly decided to rescale my images to 128x128. I don’t have much data to
back that claim, but this helped me train my networks much faster without
loosing predictive power. This also mean I stretched the images (the scale
factor isn’t the same for both axes), but this didn’t seem to hinder
performances much.&lt;/p&gt;

&lt;h3&gt;Removing contradictory images&lt;/h3&gt;
&lt;p&gt;Based on what I highlighted above about contradictory labelling in the training
set, I decided to remove the training images without a mask that were close to
another training image with a mask.&lt;/p&gt;

&lt;p&gt;I computed the similary between two images
by computing a signature for each image as follow : I divided the image in small
20x20 blocks and then compute a histogram of intensity in each block. All the
histograms for the image are then concatenated into a big vector. The disimilary
is the the cosine distance between the two signature vectors of two images.
This is what is done in the &lt;a href=&quot;https://github.com/julienr/kaggle_uns/blob/master/13_clean/0_filter_incoherent_images.ipynb&quot;&gt;13_clean/0_filter_incoherent_images.ipynb&lt;/a&gt; notebook.&lt;/p&gt;

&lt;p&gt;This results in a distance matrix for all the training set images, which is
then thresholded to decide which images should be removed. In the end, I kept
3906 training images (out of the 5500).&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/prog/post_files/2016-08-19/train_img_dists.png&quot; width=&quot;300px&quot; /&gt;&lt;/p&gt;

&lt;p&gt;I also tried &lt;a href=&quot;https://github.com/julienr/kaggle_uns/blob/master/30_clean2/0_filter_incoherent_images.ipynb&quot;&gt;propagating masks&lt;/a&gt; instead of removing
images, but this didn’t seem to help.&lt;/p&gt;

&lt;h2&gt;Architecture&lt;/h2&gt;
&lt;p&gt;My best single-model submission is &lt;a href=&quot;https://github.com/julienr/kaggle_uns/blob/master/42_fcnn_auxiliary.correct_topo.pool_upsampling/1_train_fcnn_auxiliary.ipynb&quot;&gt;from this notebook&lt;/a&gt;. It scored 0.69167 on the public LB nad 0.69234
on the private.&lt;/p&gt;

&lt;p&gt;This is a multiple objective model as you can see in the following diagram :
&lt;img src=&quot;/prog/post_files/2016-08-19/single_model.png&quot; width=&quot;600px&quot; /&gt;&lt;/p&gt;

&lt;p&gt;The left part is a traditional CNN. After all the convolutions + pooling, there
is a small dense network that has a single output (called &lt;em&gt;outbin&lt;/em&gt;) which
is the probability that the image has a non-empty mask.&lt;/p&gt;

&lt;p&gt;The right part is similar to the U-net where we upsample and merge at each
level.&lt;/p&gt;

&lt;p&gt;The real output is the &lt;em&gt;outmap&lt;/em&gt; one (the top green box) which contains the
predicted mask.&lt;/p&gt;

&lt;p&gt;In addition, I added two auxiliary outputs (&lt;em&gt;outmap4&lt;/em&gt; and &lt;em&gt;outmap5&lt;/em&gt;) which are
trained to predict very coarse (4x4 and 8x8) masks. This is only used for
training and it looked like it helped a bit regularize the training.&lt;/p&gt;

&lt;p&gt;I also found that using &lt;a href=&quot;https://arxiv.org/pdf/1302.4389.pdf&quot;&gt;Maxout&lt;/a&gt;
activations seemed to help the training a bit. I am not sure if I could have
achieved the same perf by just increasing the number of epochs or by fine-tuning
the learning rate.&lt;/p&gt;

&lt;p&gt;This model has 95000 parameters. I found difficult to train models with more
parameters without overfitting and I got really good results with 50000 parameter
models as well.&lt;/p&gt;

&lt;p&gt;I used some very simple data augmentation (small rotation, zoom, shear and translation). From some posts on the forum, it looks like doing some horizontal
flips helped a lot, but I (wrongly apparently) thought that was a bad idea because
the masks are not symmetric and so I didn’t explore that.&lt;/p&gt;

&lt;h3&gt;My best submission (0.70679 private LB)&lt;/h3&gt;
&lt;p&gt;This was submission 54 which scored 0.69237 on the public LB.
This is an ensemble of the 4 models which got the best public LB scores.
The ensembling is done in &lt;a href=&quot;https://github.com/julienr/kaggle_uns/blob/master/38_merge_submissions/merge_11_30_34_38.sub42.ipynb&quot;&gt;this notebook&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;Post-processing&lt;/h2&gt;
&lt;p&gt;Sometimes, the predicted mask has some “holes” or incoherent shape. I tried
three different post-processing approaches :&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Morphological close to remove small holes. This helped a bit&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/julienr/kaggle_uns/blob/master/notebooks/_ellipse_clean.ipynb&quot;&gt;Fitting an ellipse&lt;/a&gt; to the mask and filling the ellipse (since the mask
      are often somewhat ellipse-like). This didn't help and even sometimes
      decreased the performance.&lt;/li&gt;
  &lt;li&gt;Using a PCA decomposition of the training masks and reconstruct the
      predicted mask using a limited number of principal components.
      This seemed to help more consistently (although just a little bit).&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;PCA cleaning&lt;/h3&gt;
&lt;p&gt;The idea of using PCA to post-process came from the &lt;a href=&quot;https://en.wikipedia.org/wiki/Eigenface&quot;&gt;Eigenface&lt;/a&gt; concept. Basically, you consider your image
as a big vector and you then do PCA on the training masks to learn “eigenmasks”.&lt;/p&gt;

&lt;p&gt;To clean a predicted mask using this method, you project the cleaned mask on
the subspace found by PCA and you then reconstruct using only the 20 (in my case)
first principal components. This forces the reconstructed mask to have a shape
similar to the training masks.&lt;/p&gt;

&lt;p&gt;Here are two extreme examples (predicted mask is left, PCA-cleaned is right) :&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/prog/post_files/2016-08-19/pca_clean.png&quot; width=&quot;400px&quot; /&gt;&lt;/p&gt;

&lt;h2&gt;Loss and mask percentage&lt;/h2&gt;
&lt;p&gt;I tried using dice coefficient as a loss, but I always got better results
by using binary cross-entropy.&lt;/p&gt;

&lt;p&gt;An empty submission on the public leaderboard gets a score of 0.51. This means
51% of the images have no mask. So 49% of the images should have mask and I
tried to optimize the threshold on the binary and mask output to get close to
49% predicted masks. But in the end, my best submissions have around 35%-38%
of predicted masks. I guess this is because lowering the thresholds to get
higher number of predicted masks leads to too many false positive.&lt;/p&gt;

&lt;h1 id=&quot;dreaming&quot;&gt;3. Dreaming nerves&lt;/h1&gt;
&lt;p&gt;Once you have a trained CNN, you can make the network “dream” to visualize
what the networks wants to see to maximize some output or some intermediate
layer. This gives a pretty picture that’s also useful for debugging.&lt;/p&gt;

&lt;p&gt;In the image below, you can see some example input images that maximizes the
activation of specific filters (each row has 4 filters of a given depth).&lt;/p&gt;

&lt;p&gt;The fourth row is the innermost convolutional layer and you can clearly see
that the network reacts to interleaved nerve structure.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/prog/post_files/2016-08-19/dreaming_nerves.png&quot; width=&quot;600px&quot; /&gt;&lt;/p&gt;

&lt;h1 id=&quot;conclusion&quot;&gt;4. Conclusion&lt;/h1&gt;
&lt;p&gt;This was an interesting competition. I learnt a lot by playing with various
architectures and trying various pre/post-processing techniques.&lt;/p&gt;

&lt;p&gt;One problem was the dataset labelling quality. Although it is a good challenge
(and something common in everyday applications) to deal with contradictory
or inconsistent labels, I think it hurts the competition because people
spend time trying to predict the labelling mistakes instead of trying to build
a better model of the problem.&lt;/p&gt;
</description>
        </item>
      
    
      
        <item>
          <title>Kinfu for Google Tango devkit</title>
          <link>http://fhtagn.net/prog/2016/05/30/kinfu.html</link>
          <pubDate>Mon, 30 May 2016 00:00:00 +0000</pubDate>
          <author>julien@fhtagn.net (Julien Rebetez)</author>
          <guid>http://fhtagn.net/prog/2016/05/30/kinfu</guid>
          <description>&lt;p&gt;I have been playing with &lt;a href=&quot;https://www.google.com/atap/project-tango/&quot;&gt;Google’s Project Tango&lt;/a&gt; devkit recently.&lt;/p&gt;

&lt;p&gt;Although Tango (or at least the current tablet) is more oriented towards
scanning house-scale areas, I have been experimenting with smaller scale
scanning to get a 3D model of humans. Tango uses optical features and its IMU
to determine camera orientation. Although this works quite well in most cases,
it does suffer from drift and that’s a bit of a problem to get good precision
point clouds.&lt;/p&gt;

&lt;p&gt;For example, that is the raw tango point cloud for a scan. You can clearly
see the drift in the front view (left image).&lt;/p&gt;

&lt;div class=&quot;thumbnails&quot;&gt;
  &lt;a href=&quot;/prog/post_files/2016-05-30/tango_raw_cloud1.png&quot;&gt;
    &lt;img src=&quot;/prog/post_files/2016-05-30/tango_raw_cloud1.png&quot; width=&quot;300px&quot; /&gt;
  &lt;/a&gt;

  &lt;a href=&quot;/prog/post_files/2016-05-30/tango_raw_cloud2.png&quot;&gt;
    &lt;img src=&quot;/prog/post_files/2016-05-30/tango_raw_cloud2.png&quot; width=&quot;200px&quot; /&gt;
  &lt;/a&gt;
&lt;/div&gt;

&lt;p&gt;To solve this, I implemented (inspired by the &lt;a href=&quot;https://github.com/PointCloudLibrary/pcl/tree/master/gpu/kinfu/src&quot;&gt;open source PCL implementation&lt;/a&gt;) the kinect fusion algorithm from &lt;a href=&quot;http://homes.cs.washington.edu/~newcombe/papers/newcombe_etal_ismar2011.pdf&quot;&gt;Newcombe et al&lt;/a&gt;. It’s currently
a Python/C/OpenCL implementation, so it’s not running on the tablet.&lt;/p&gt;

&lt;p&gt;Here is the resulting point cloud after kinect fusion. As you can see, the
drift has been mostly corrected, although there are still some problems on the
arms.&lt;/p&gt;

&lt;div class=&quot;thumbnails&quot;&gt;
  &lt;a href=&quot;/prog/post_files/2016-05-30/kinfu_cloud1.png&quot;&gt;
    &lt;img src=&quot;/prog/post_files/2016-05-30/kinfu_cloud1.png&quot; width=&quot;200px&quot; /&gt;
  &lt;/a&gt;

  &lt;a href=&quot;/prog/post_files/2016-05-30/kinfu_cloud2.png&quot;&gt;
    &lt;img src=&quot;/prog/post_files/2016-05-30/kinfu_cloud2.png&quot; width=&quot;300px&quot; /&gt;
  &lt;/a&gt;
&lt;/div&gt;

&lt;p&gt;We can also mesh the kinect fusion volume :&lt;/p&gt;

&lt;div class=&quot;thumbnails&quot;&gt;
  &lt;a href=&quot;/prog/post_files/2016-05-30/kinfu_mesh1.png&quot;&gt;
    &lt;img src=&quot;/prog/post_files/2016-05-30/kinfu_mesh1.png&quot; width=&quot;200px&quot; /&gt;
  &lt;/a&gt;

  &lt;a href=&quot;/prog/post_files/2016-05-30/kinfu_mesh2.png&quot;&gt;
    &lt;img src=&quot;/prog/post_files/2016-05-30/kinfu_mesh2.png&quot; width=&quot;200px&quot; /&gt;
  &lt;/a&gt;
&lt;/div&gt;

&lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/0kR_4gkFQIY&quot; frameborder=&quot;0&quot;&gt; &lt;/iframe&gt;

&lt;p&gt;If you’re interested in the inner workings, here is a video of log plots to
verify everything is working correctly. You can see the input color map, the
input depth map, the raycasted depth from the kinfu volume, the raycasted color and normal maps. I still have an issue with my ray skipping algorithm that
creates some holes in the raycast, but this should be fixed soon.&lt;/p&gt;

&lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/Xrw3kGoqT9k&quot; frameborder=&quot;0&quot;&gt; &lt;/iframe&gt;
</description>
        </item>
      
    
      
        <item>
          <title>Exposing aligned Eigen::Quaternionf with boost::python</title>
          <link>http://fhtagn.net/prog/2015/04/16/quaternion_boost_python.html</link>
          <pubDate>Thu, 16 Apr 2015 00:00:00 +0000</pubDate>
          <author>julien@fhtagn.net (Julien Rebetez)</author>
          <guid>http://fhtagn.net/prog/2015/04/16/quaternion_boost_python</guid>
          <description>&lt;h3 id=&quot;introduction&quot;&gt;Introduction&lt;/h3&gt;
&lt;p&gt;This post is about how to expose C++ struct/classes that have alignment
requirements using boost::python.&lt;/p&gt;

&lt;p&gt;In the general case, the easiest solution is to use a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;shared_ptr&amp;lt;Type&amp;gt;&lt;/code&gt;
as the holder (second argument to bp::class_) and make sure the class
has an operatore new that enforces alignment.&lt;/p&gt;

&lt;p&gt;But sometimes, you want to expose a class that requires alignment by value,
without using a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;shared_ptr&amp;lt;Type&amp;gt;&lt;/code&gt; (typically because you don’t want to
write tons of wrappers for your existing C++ codebase). That is what we do
here with Eigen::Quaternion.&lt;/p&gt;

&lt;p&gt;If you are not interested in the analysis, go directly to
the solution near the end.&lt;/p&gt;

&lt;h3 id=&quot;exposing-eigenquaternion&quot;&gt;Exposing Eigen::Quaternion&lt;/h3&gt;

&lt;p&gt;I was trying to expose an Eigen::Quaternion using boost::python&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;bp::class_&amp;lt;Quaternionf&amp;gt;(&quot;Quaternion&quot;, bp::init&amp;lt;float, float, float, float&amp;gt;())
  .def(bp::init&amp;lt;Matrix3f&amp;gt;())
  .add_property(&quot;w&quot;, get_prop_const(&amp;amp;Quaternionf::w))
  .add_property(&quot;x&quot;, get_prop_const(&amp;amp;Quaternionf::x))
  .add_property(&quot;y&quot;, get_prop_const(&amp;amp;Quaternionf::y))
  .add_property(&quot;z&quot;, get_prop_const(&amp;amp;Quaternionf::z))
  .def(&quot;matrix&quot;, &amp;amp;Quaternionf::matrix)
  .def(&quot;rotvec&quot;, &amp;amp;quaternion_to_rotvec);
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Now, I also want to be able to export &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;vector&amp;lt;Quaternionf&amp;gt;&lt;/code&gt;. So I want
to expose the Quaternion by value and do &lt;strong&gt;not&lt;/strong&gt; want to use a
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;shared_ptr&amp;lt;Quaternion&amp;gt;&lt;/code&gt; as a Holder.&lt;/p&gt;

&lt;p&gt;The problem is, Eigen Quaternion &lt;a href=&quot;http://eigen.tuxfamily.org/dox/group__TopicUnalignedArrayAssert.html&quot;&gt;need to be aligned to 16 bytes&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;With the code above, there is a high probability that you’ll trigger an
assertion like the following (meaning Eigen detects that the Quaternion
coefficients are not aligned) :&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Assertion failed: ((reinterpret_cast&amp;lt;size_t&amp;gt;(array) &amp;amp; 0xf) == 0 &amp;amp;&amp;amp; &quot;this assertion is explained here: &quot; &quot;ht
tp://eigen.tuxfamily.org/dox-devel/group__TopicUnalignedArrayAssert.html&quot; &quot; **** READ THIS WEB PAGE !!! ****&quot;), function plain_array, file /Users/julien/shapetwin/dev/shapy/libs/_install/_all/include/eigen3/Eigen/s
rc/Core/DenseStorage.h, line 86.
Process 93520 stopped
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The full stacktrace is &lt;a href=&quot;/prog/post_files/2015-04-16/trace.txt&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h3 id=&quot;problem-analysis&quot;&gt;Problem analysis&lt;/h3&gt;
&lt;p&gt;You can see &lt;em&gt;frame #15&lt;/em&gt; is &lt;em&gt;boost/python/object/make_instance.hpp:71&lt;/em&gt; :&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;template &amp;lt;class T, class Holder&amp;gt;
struct make_instance
    : make_instance_impl&amp;lt;T, Holder, make_instance&amp;lt;T,Holder&amp;gt; &amp;gt;
{
    template &amp;lt;class U&amp;gt;
    static inline PyTypeObject* get_class_object(U&amp;amp;)
    {
        return converter::registered&amp;lt;T&amp;gt;::converters.get_class_object();
    }
    
    static inline Holder* construct(void* storage, PyObject* instance, reference_wrapper&amp;lt;T const&amp;gt; x)
    {
-&amp;gt;        return new (storage) Holder(instance, x);
    }
};
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The -&amp;gt; indicate the line. Ok so the problem is that boost is trying to create a new Quaternion in a memory area (storage) that is not guaranteed to be aligned. To fix this, we have to find how to tell boost to allocate storage for our Quaternion using Eigen’s &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;aligned_allocator&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Ok, so the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;make_instance::construct&lt;/code&gt; method is called (&lt;em&gt;frame #16&lt;/em&gt;) in &lt;em&gt;make_instance.hpp:45&lt;/em&gt; :&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;template &amp;lt;class T, class Holder, class Derived&amp;gt;
struct make_instance_impl
{
    typedef objects::instance&amp;lt;Holder&amp;gt; instance_t;
      
    template &amp;lt;class Arg&amp;gt;
    static inline PyObject* execute(Arg&amp;amp; x)
    {
        BOOST_MPL_ASSERT((mpl::or_&amp;lt;is_class&amp;lt;T&amp;gt;, is_union&amp;lt;T&amp;gt; &amp;gt;));

        PyTypeObject* type = Derived::get_class_object(x);

        if (type == 0)
            return python::detail::none();

        PyObject* raw_result = type-&amp;gt;tp_alloc(
            type, objects::additional_instance_size&amp;lt;Holder&amp;gt;::value);
        
        if (raw_result != 0)
        {
            python::detail::decref_guard protect(raw_result);
          
            instance_t* instance = (instance_t*)raw_result;
          
            // construct the new C++ object and install the pointer
            // in the Python object.
      -&amp;gt;    Derived::construct(&amp;amp;instance-&amp;gt;storage, 
                (PyObject*)instance, x)-&amp;gt;install(raw_result);
            
            // Note the position of the internally-stored Holder,
            // for the sake of destruction
            Py_SIZE(instance) = offsetof(instance_t, storage);

            // Release ownership of the python object
            protect.cancel();
        }
        return raw_result;
    }
};
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;And we see it passes &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;amp;instance-&amp;gt;storage&lt;/code&gt; as the storage and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;instance&lt;/code&gt; is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;raw_result&lt;/code&gt; which is allocated with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;type-&amp;gt;tp_alloc&lt;/code&gt;. We can see the size is determined by &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;objects::additional_instance_size&amp;lt;Holder&amp;gt;::value&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In our case, we find the type of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Holder&lt;/code&gt; from the second template param to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;make_instance_impl&lt;/code&gt; :&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;frame #16: 0x00000001029d81c1 volumit_human.so`_object* boost::python::objects::make_instance_impl&amp;lt;
    Eigen::Quaternion&amp;lt;float, 0&amp;gt;, 
    boost::python::objects::value_holder&amp;lt;Eigen::Quaternion&amp;lt;float, 0&amp;gt; &amp;gt;, 
    boost::python::objects::make_instance&amp;lt;
        Eigen::Quaternion&amp;lt;float, 0&amp;gt;, 
        boost::python::objects::value_holder&amp;lt;Eigen::Quaternion&amp;lt;float, 0&amp;gt;&amp;gt;
    &amp;gt;
&amp;gt;::execute&amp;lt;boost::reference_wrapper&amp;lt;Eigen::Quaternion&amp;lt;float, 0&amp;gt; const&amp;gt; const&amp;gt;(x=0x00007fff5fbfd618) + 145 at make_instance.hpp:45
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;So our &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Holder&lt;/code&gt; is&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;boost::python::objects::value_holder&amp;lt;Eigen::Quaternion&amp;lt;float, 0&amp;gt;&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Now, if we look at &lt;em&gt;boost/python/object/instance.hpp:40&lt;/em&gt;, where &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;additional_instance_size&lt;/code&gt; is defined :&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;template &amp;lt;class Data&amp;gt;
struct additional_instance_size
{
    typedef instance&amp;lt;Data&amp;gt; instance_data;
    typedef instance&amp;lt;char&amp;gt; instance_char;
    BOOST_STATIC_CONSTANT(
        std::size_t, value = sizeof(instance_data)
                           - BOOST_PYTHON_OFFSETOF(instance_char,storage));
};
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This computes the additional size by the particular instance (the substraction of a char instance is to get only the additional size without all the common members - &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;dict, weakrefs, objects&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;offsetof(type, var)&lt;/code&gt; returns the offset in bytes of the variable inside the struct of the given type.&lt;/p&gt;

&lt;p&gt;With a bit more digging, we see that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;additional_instance_size&lt;/code&gt; uses the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;instance&lt;/code&gt; class which is defined just above in the same file :&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;// Each extension instance will be one of these
template &amp;lt;class Data = char&amp;gt;
struct instance
{
    PyObject_VAR_HEAD
    PyObject* dict;
    PyObject* weakrefs; 
    instance_holder* objects;

    typedef typename type_with_alignment&amp;lt;
        ::boost::alignment_of&amp;lt;Data&amp;gt;::value
    &amp;gt;::type align_t;
        
    union
    {
        align_t align;
        char bytes[sizeof(Data)];
    } storage;
};
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This, in turn, figures out the type alignment using &lt;a href=&quot;http://www.boost.org/doc/libs/1_57_0/libs/type_traits/doc/html/index.html&quot;&gt;boost.typetraits&lt;/a&gt; and specifically &lt;a href=&quot;http://www.boost.org/doc/libs/1_57_0/libs/type_traits/doc/html/boost_typetraits/reference/alignment_of.html&quot;&gt;alignment_of&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The union type is a way to force the alignment. The C++ standard requires the alignment of a struct to be at least the lowest common multiple of the alignments of all member of the struct. See the &lt;a href=&quot;https://gcc.gnu.org/onlinedocs/gcc-3.1/gcc/Type-Attributes.html&quot;&gt;gcc doc about alignment&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;So it looks like we can just specialize &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;alignment_of&lt;/code&gt; for our type.&lt;/p&gt;

&lt;p&gt;But it is already correct. Adding the following log&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;LOG(INFO) &amp;lt;&amp;lt; &quot;Alignment of Quaternion : &quot; &amp;lt;&amp;lt; boost::alignment_of&amp;lt;Quaternionf&amp;gt;::value;
LOG(INFO) &amp;lt;&amp;lt; &quot;Alignment of QuaternionHolder : &quot; &amp;lt;&amp;lt; boost::alignment_of&amp;lt;QuaternionfHolder&amp;gt;::value;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;prints&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;0414 18:06:27.344784 2072736528 human_mod.cc:1072] Alignment of Quaternion : 16
I0414 18:06:27.344817 2072736528 human_mod.cc:1073] Alignment of QuaternionHolder : 16
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;If we specialize &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;make_instance&lt;/code&gt; to LOG when a Quaternion is created, as follow :&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;namespace boost { namespace python { namespace objects {

//template &amp;lt;class T, class Holder&amp;gt;
template&amp;lt;&amp;gt;
struct make_instance&amp;lt;Quaternionf, QuaternionfHolder&amp;gt;
  : make_instance_impl&amp;lt;Quaternionf, QuaternionfHolder, make_instance&amp;lt;Quaternionf,QuaternionfHolder&amp;gt; &amp;gt;
{
    template &amp;lt;class U&amp;gt;
    static inline PyTypeObject* get_class_object(U&amp;amp;)
    {
        return converter::registered&amp;lt;Quaternionf&amp;gt;::converters.get_class_object();
    }

    static inline QuaternionfHolder* construct(void* storage, PyObject* instance, reference_wrapper&amp;lt;Quaternionf const&amp;gt; x)
    {
        LOG(INFO) &amp;lt;&amp;lt; &quot;Into make_instance&quot;;
        LOG(INFO) &amp;lt;&amp;lt; &quot;storage : &quot; &amp;lt;&amp;lt; storage;
        LOG(INFO) &amp;lt;&amp;lt; &quot;&amp;amp;x : &quot; &amp;lt;&amp;lt; x.get_pointer();
        LOG(INFO) &amp;lt;&amp;lt; &quot;&amp;amp;x alignment (0 = aligned): &quot; &amp;lt;&amp;lt; (reinterpret_cast&amp;lt;size_t&amp;gt;(x.get_pointer()) &amp;amp; 0xf);
        QuaternionfHolder* new_holder = new (storage) QuaternionfHolder(instance, x);
        LOG(INFO) &amp;lt;&amp;lt; &quot;&amp;amp;new_holder : &quot; &amp;lt;&amp;lt; new_holder;
        return new_holder;
    }
};

}}} // namespace boost::python::objects
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;We get the following log&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;I0416 11:49:48.403352 2072736528 quaternionf_specializations.h:103] Into make_instance
I0416 11:49:48.403367 2072736528 quaternionf_specializations.h:104] storage : 0x10593a698
I0416 11:49:48.403373 2072736528 quaternionf_specializations.h:105] &amp;amp;x : 0x1060d10e0
I0416 11:49:48.403378 2072736528 quaternionf_specializations.h:106] &amp;amp;x alignment (0 = aligned): 0
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Now, I think that’s the problem. Our storage at &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x106239698&lt;/code&gt; is not 16-bytes aligned. A 16-bytes aligned address has its 4 last bits (the last hex digit) at 0.&lt;/p&gt;

&lt;h3 id=&quot;first-idea---using-an-aligned-python-allocation-function&quot;&gt;First idea - using an aligned python allocation function&lt;/h3&gt;

&lt;p&gt;CPython PyTypeObject allows to specify a custom allocation function, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tp_alloc&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Ok so the real problem is the call to&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;PyObject* raw_result = type-&amp;gt;tp_alloc(
    type, objects::additional_instance_size&amp;lt;Holder&amp;gt;::value);
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;In &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;make_instance_impl.hpp&lt;/code&gt;. This means the boost::python::objects instance holding
the storage where our QuaternionHolder (and therefore Quaternion) is newed is
allocated using Python allocators. But we actually need this to be allocated
using an aligned allocator, because it is holding our Quaternion instance and
as explained in the &lt;a href=&quot;http://eigen.tuxfamily.org/dox/group__TopicStructHavingEigenMembers.html&quot;&gt;Eigen docs&lt;/a&gt;, a structure holding an aligned type should be aligned itself.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Remark&lt;/strong&gt;: even if we suceeded in doing this, we would
need to use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;EIGEN_MAKE_ALIGNED_OPERATOR_NEW&lt;/code&gt; in the structure holding our quaternion)&lt;/p&gt;

&lt;p&gt;Ok so we could specify the usage of a custom &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tp_alloc&lt;/code&gt; like this :&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;#define GC_UNTRACKED                    _PyGC_REFS_UNTRACKED

static PyObject*
aligned_PyObject_malloc(Py_ssize_t size) {
    void* memptr;
    int ret = posix_memalign(&amp;amp;memptr, 16, size);
    if (ret != 0) {
        return PyErr_NoMemory();
    }
    return (PyObject*)memptr;
}


// https://github.com/python/cpython/blob/2.7/Modules/gcmodule.c

// https://github.com/python/cpython/blob/2.7/Objects/typeobject.c
PyObject *
aligned_PyType_GenericAlloc(PyTypeObject *type, Py_ssize_t nitems)
{
    PyObject *obj;
    const size_t size = _PyObject_VAR_SIZE(type, nitems+1);
    /* note that we need to add one, for the sentinel */

    // TODO: use posix_aligned_malloc
    if (PyType_IS_GC(type)) {
      // This would involve rewriting _PyObject_GC_malloc with posix_memalign.
      // The problem is that _PyObject_GC_malloc access some gc-internal
      // statis variables that we cannot access here. So we do not support
      // objects with special GC requirements (boost class type doesn't
      // have PyType_IS_GC anyway)
      // https://docs.python.org/2/c-api/gcsupport.html#c.PyObject_GC_NewVar
        //obj = aligned_PyObject_GC_malloc(size);
        LOG(ERROR) &amp;lt;&amp;lt; &quot;Aligned allocator does not support GC objects&quot;;
        return PyErr_NoMemory();
    } else
        obj = aligned_PyObject_malloc(size);

    if (obj == NULL)
        return PyErr_NoMemory();

    memset(obj, '\0', size);

    if (type-&amp;gt;tp_flags &amp;amp; Py_TPFLAGS_HEAPTYPE)
        Py_INCREF(type);

    if (type-&amp;gt;tp_itemsize == 0)
        (void)PyObject_INIT(obj, type);
    else
        (void) PyObject_INIT_VAR((PyVarObject *)obj, type, nitems);

    if (PyType_IS_GC(type))
        _PyObject_GC_TRACK(obj);
    return obj;
}
  
template&amp;lt;&amp;gt;
struct make_instance&amp;lt;Quaternionf, QuaternionfHolder&amp;gt;
    : make_instance_impl&amp;lt;Quaternionf, QuaternionfHolder, make_instance&amp;lt;Quaternionf,QuaternionfHolder&amp;gt; &amp;gt;
{
    template &amp;lt;class U&amp;gt;
    static inline PyTypeObject* get_class_object(U&amp;amp;)
    {
        //return converter::registered&amp;lt;Quaternionf&amp;gt;::converters.get_class_object();
        PyTypeObject* type = converter::registered&amp;lt;Quaternionf&amp;gt;::converters.get_class_object();
        type-&amp;gt;tp_alloc = aligned_PyType_GenericAlloc;
        return type;
    }

    static inline QuaternionfHolder* construct(void* storage, PyObject* instance, reference_wrapper&amp;lt;Quaternionf const&amp;gt; x)
    {
      LOG(INFO) &amp;lt;&amp;lt; &quot;Into make_instance&quot;;
      LOG(INFO) &amp;lt;&amp;lt; &quot;storage : &quot; &amp;lt;&amp;lt; storage;
      LOG(INFO) &amp;lt;&amp;lt; &quot;&amp;amp;x : &quot; &amp;lt;&amp;lt; x.get_pointer();
      LOG(INFO) &amp;lt;&amp;lt; &quot;&amp;amp;x alignment (0 = aligned): &quot; &amp;lt;&amp;lt; (reinterpret_cast&amp;lt;size_t&amp;gt;(x.get_pointer()) &amp;amp; 0xf);

      // From the specialized make_instance_impl above, we are guaranteed to
      // be able to align our storage
      //void* aligned_storage = reinterpret_cast&amp;lt;void*&amp;gt;(
          //(reinterpret_cast&amp;lt;size_t&amp;gt;(storage) &amp;amp; ~(size_t(15))) + 16);
      QuaternionfHolder* new_holder = new (storage) QuaternionfHolder(instance, x);
      LOG(INFO) &amp;lt;&amp;lt; &quot;&amp;amp;new_holder : &quot; &amp;lt;&amp;lt; &amp;amp;new_holder;
      return new_holder;
      //return new (storage) QuaternionfHolder(instance, x);
    }
};
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The problem is, this only works for python type that are not &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;PyType_IS_GC&lt;/code&gt;. But 
boost::class are managed by the GC cyclic collector (in boost class.cpp, tp_is_gc is a function that returns true). So we would have to define our own &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;_PyObject_GC_malloc&lt;/code&gt; but we cannot do that because it relies on some static variables in python &lt;a href=&quot;https://github.com/python/cpython/blob/2.7/Modules/gcmodule.c&quot;&gt;gcmodule&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;There is &lt;a href=&quot;https://bugs.python.org/issue18835&quot;&gt;some discussions on allowing aligned allocators&lt;/a&gt; in Python and for Python 3.4, we could use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;PyMem_SetAllocator&lt;/code&gt; but there seem to be no solution for 2.7&lt;/p&gt;

&lt;h3 id=&quot;solution---specialize-boostpythonmake_instance&quot;&gt;Solution - Specialize boost::python::make_instance&lt;/h3&gt;

&lt;p&gt;We can specialize some of the classes &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;boost/python/object/make_instance.hpp&lt;/code&gt; .
We will make sure we get a storage area large enough so that we can align
our Quaternion instance. To do so, we’ll request the size of our Quaternion
struct plus 16 bytes. This means that we’ll use a bit more memory than what
is required.&lt;/p&gt;

&lt;p&gt;We need to do 3 modifications :&lt;/p&gt;

&lt;p&gt;Force &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;instance&amp;lt;QuaternionfHolder&amp;gt;&lt;/code&gt; to allocate 16 bytes more than the size
of QuaternionfHolder. This will allow us to align our QuaternionfHolder&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;union
{
  align_t align;
  char bytes[sizeof(Data) + 16];
} storage;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Have &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;make_instance_impl&lt;/code&gt; correctly set the size of the python object&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Holder* holder = Derived::construct(
  &amp;amp;instance-&amp;gt;storage, (PyObject*)instance, x);
holder-&amp;gt;install(raw_result);
   
// Note the position of the internally-stored Holder,
// for the sake of destruction
// Since the holder not necessarily allocated at the start of
// storage (to respect alignment), we have to add the holder
// offset relative to storage
size_t holder_offset = reinterpret_cast&amp;lt;size_t&amp;gt;(holder)
                        - reinterpret_cast&amp;lt;size_t&amp;gt;(&amp;amp;instance-&amp;gt;storage)
                        + offsetof(instance_t, storage);
Py_SIZE(instance) = holder_offset;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Have &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;make_instance::construct&lt;/code&gt; new our QuaternionfHolder in an aligned memory block.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;static inline QuaternionfHolder* construct(void* storage, PyObject* instance, reference_wrapper&amp;lt;Quaternionf const&amp;gt; x)
{
  // From the specialized make_instance_impl above, we are guaranteed to
  // be able to align our storage
  void* aligned_storage = reinterpret_cast&amp;lt;void*&amp;gt;(
    (reinterpret_cast&amp;lt;size_t&amp;gt;(storage) &amp;amp; ~(size_t(15))) + 16);
  QuaternionfHolder* new_holder = new (aligned_storage) 
    QuaternionfHolder(instance, x);
  return new_holder;
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Here is the full code :&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;typedef bp::objects::value_holder&amp;lt;Eigen::Quaternionf&amp;gt; QuaternionfHolder;

namespace boost { namespace python { namespace objects {

using namespace Eigen;

//template &amp;lt;class Data = char&amp;gt;
template&amp;lt;&amp;gt;
struct instance&amp;lt;QuaternionfHolder&amp;gt;
{
  typedef QuaternionfHolder Data;
    PyObject_VAR_HEAD
    PyObject* dict;
    PyObject* weakrefs;
    instance_holder* objects;

    typedef typename type_with_alignment&amp;lt;
        ::boost::alignment_of&amp;lt;Data&amp;gt;::value
    &amp;gt;::type align_t;

    union
    {
        align_t align;
        char bytes[sizeof(Data) + 16];
    } storage;
};


// Adapted from boost/python/object/make_instance.hpp

//template &amp;lt;class T, class Holder, class Derived&amp;gt;
template&amp;lt;class Derived&amp;gt;
struct make_instance_impl&amp;lt;Quaternionf, QuaternionfHolder, Derived&amp;gt;
{
    typedef Quaternionf T;
    typedef QuaternionfHolder Holder;

    typedef objects::instance&amp;lt;Holder&amp;gt; instance_t;

    template &amp;lt;class Arg&amp;gt;
    static inline PyObject* execute(Arg&amp;amp; x)
    {
        BOOST_MPL_ASSERT((mpl::or_&amp;lt;is_class&amp;lt;T&amp;gt;, is_union&amp;lt;T&amp;gt; &amp;gt;));

        PyTypeObject* type = Derived::get_class_object(x);

        if (type == 0)
            return python::detail::none();

        PyObject* raw_result = type-&amp;gt;tp_alloc(
            type, objects::additional_instance_size&amp;lt;Holder&amp;gt;::value);

        if (raw_result != 0)
        {
            python::detail::decref_guard protect(raw_result);

            instance_t* instance = (instance_t*)raw_result;

            // construct the new C++ object and install the pointer
            // in the Python object.
            //Derived::construct(&amp;amp;instance-&amp;gt;storage, (PyObject*)instance, x)-&amp;gt;install(raw_result);
            Holder* holder = Derived::construct(
                &amp;amp;instance-&amp;gt;storage, (PyObject*)instance, x);
            holder-&amp;gt;install(raw_result);

            // Note the position of the internally-stored Holder,
            // for the sake of destruction
            // Since the holder not necessarily allocated at the start of
            // storage (to respect alignment), we have to add the holder
            // offset relative to storage
            size_t holder_offset = reinterpret_cast&amp;lt;size_t&amp;gt;(holder)
                                 - reinterpret_cast&amp;lt;size_t&amp;gt;(&amp;amp;instance-&amp;gt;storage)
                                 + offsetof(instance_t, storage);
            Py_SIZE(instance) = holder_offset;

            // Release ownership of the python object
            protect.cancel();
        }
        return raw_result;
    }
};


//template &amp;lt;class T, class Holder&amp;gt;
template&amp;lt;&amp;gt;
struct make_instance&amp;lt;Quaternionf, QuaternionfHolder&amp;gt;
    : make_instance_impl&amp;lt;Quaternionf, QuaternionfHolder, make_instance&amp;lt;Quaternionf,QuaternionfHolder&amp;gt; &amp;gt;
{
    template &amp;lt;class U&amp;gt;
    static inline PyTypeObject* get_class_object(U&amp;amp;)
    {
        return converter::registered&amp;lt;Quaternionf&amp;gt;::converters.get_class_object();
    }

    static inline QuaternionfHolder* construct(void* storage, PyObject* instance, reference_wrapper&amp;lt;Quaternionf const&amp;gt; x)
    {
      LOG(INFO) &amp;lt;&amp;lt; &quot;Into make_instance&quot;;
      LOG(INFO) &amp;lt;&amp;lt; &quot;storage : &quot; &amp;lt;&amp;lt; storage;
      LOG(INFO) &amp;lt;&amp;lt; &quot;&amp;amp;x : &quot; &amp;lt;&amp;lt; x.get_pointer();
      LOG(INFO) &amp;lt;&amp;lt; &quot;&amp;amp;x alignment (0 = aligned): &quot; &amp;lt;&amp;lt; (reinterpret_cast&amp;lt;size_t&amp;gt;(x.get_pointer()) &amp;amp; 0xf);

      // From the specialized make_instance_impl above, we are guaranteed to
      // be able to align our storage
      void* aligned_storage = reinterpret_cast&amp;lt;void*&amp;gt;(
          (reinterpret_cast&amp;lt;size_t&amp;gt;(storage) &amp;amp; ~(size_t(15))) + 16);
      QuaternionfHolder* new_holder = new (aligned_storage) QuaternionfHolder(instance, x);
      LOG(INFO) &amp;lt;&amp;lt; &quot;&amp;amp;new_holder : &quot; &amp;lt;&amp;lt; new_holder;
      return new_holder;
      //return new (storage) QuaternionfHolder(instance, x);
    }
};


}}} // namespace boost::python::objects
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;alternative-solution---disable-quaternion-alignment&quot;&gt;Alternative solution - disable Quaternion alignment&lt;/h3&gt;
&lt;p&gt;This require changes in the code, but one option is to use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Quaternion&amp;lt;float, Eigen::DontAlign&amp;gt;&lt;/code&gt; instead of Quaternionf. This disable alignment and should solve the problem.&lt;/p&gt;

&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/furgalep/numpy_eigen/blob/master/include/numpy_eigen/boost_python_headers.hpp&quot;&gt;boost_python_headers.hpp&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/python/cpython/blob/2.7/Modules/gcmodule.c&quot;&gt;python gcmalloc.c&lt;/a&gt;&lt;/p&gt;
</description>
        </item>
      
    
      
        <item>
          <title>D-Link DWA-131 USB key wifi adapter with Ubuntu 13.04</title>
          <link>http://fhtagn.net/prog/2013/08/30/dwa-131.html</link>
          <pubDate>Fri, 30 Aug 2013 00:00:00 +0000</pubDate>
          <author>julien@fhtagn.net (Julien Rebetez)</author>
          <guid>http://fhtagn.net/prog/2013/08/30/dwa-131</guid>
          <description>&lt;p&gt;Some quick notes on how to get the DWA-131 &lt;b&gt;rev B&lt;/b&gt; working under Ubuntu 13.04.
First, &lt;a href=&quot;http://bernaerts.dyndns.org/linux/74-ubuntu/277-ubuntu-precise-dwa-131-rev-b1&quot;&gt;this webpage&lt;/a&gt; explains how to check what revision you’ve got. The rest of the explanations (upgrading to 3.8.10 to use the rtl8192cu driver included in the kernel) worked, but only for some networks. The device would just fail to connect to other networks.&lt;/p&gt;

&lt;p&gt;Instead, I installed a precompiled version of the chipset (RTL8192CU) drivers, found &lt;a href=&quot;https://code.google.com/p/realtek-8188cus-wireless-drivers-3444749-ubuntu-1304/&quot;&gt;here&lt;/a&gt;.
Then, add three lines to /etc/modprobe.d/blacklist.conf :&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;# Blacklist native RealTek 8188CUs drivers
blacklist rtl8192cu
blacklist rtl8192c_common
blacklist rtlwifi
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;One line to /etc/modules to load the module :&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;8192cu
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;And one line to /etc/rc.local to force the driver to recognize the DWA-131 (‘2001 330D’ is the USB id of the DWA-131) :&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;echo &quot;2001 330D&quot; | tee /sys/bus/usb/drivers/rtl8192cu/new_id
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
</description>
        </item>
      
    
      
        <item>
          <title>myzivi.ch : swiss civilian service search</title>
          <link>http://fhtagn.net/prog/2013/02/15/myzivi.html</link>
          <pubDate>Fri, 15 Feb 2013 00:00:00 +0000</pubDate>
          <author>julien@fhtagn.net (Julien Rebetez)</author>
          <guid>http://fhtagn.net/prog/2013/02/15/myzivi</guid>
          <description>&lt;h3&gt;Background / the problem&lt;/h3&gt;
&lt;p&gt;In Switzerland, we still have mandatory military service. For those who don’t
want to serve in the military, there is a replacement &lt;a href=&quot;http://en.wikipedia.org/wiki/Swiss_Civilian_Service&quot;&gt;civilian service&lt;/a&gt; where you work for non-profits.
After having completed he military boot camp, I couldn’t stand the idleness of the swiss army anymore and decided to do civilian service instead.&lt;/p&gt;

&lt;p&gt;Non-profits that are interested in having civilian service men working for them
can announce themselves to the administration. There is an &lt;a href=&quot;https://www.eis.zivi.admin.ch/ZiviEis/default.aspx?lang=fr&quot;&gt;official search engine&lt;/a&gt; that allows people to search for those civilian service jobs. The thing is, this official page is kind of clunky : it’s slow, doesn’t always return the same results and it doesn’t allow geographical filtering. Since I wanted to find a job that’s close to my home, I really wanted to be able to visualize the offers on a map.&lt;/p&gt;

&lt;h3&gt;Solution&lt;/h3&gt;
&lt;p&gt;So I created &lt;a href=&quot;http://myzivi.ch&quot;&gt;http://myzivi.ch&lt;/a&gt;. It’s a website that shows a map of the civilian jobs offer from non-profits.&lt;/p&gt;

&lt;div class=&quot;thumbnails&quot;&gt;
  &lt;a href=&quot;/images/myzivi/map-screen.png&quot; target=&quot;_blank&quot;&gt;&lt;img src=&quot;/images/myzivi/map-screen.png&quot; alt=&quot;screenshot&quot; width=&quot;240&quot; /&gt;&lt;/a&gt;
  &lt;a href=&quot;/images/myzivi/map-screen-clicked.png&quot; target=&quot;_blank&quot;&gt;&lt;img src=&quot;/images/myzivi/map-screen-clicked.png&quot; alt=&quot;screenshot&quot; width=&quot;240&quot; /&gt;&lt;/a&gt;

&lt;/div&gt;

&lt;p&gt;The data is scraped from the official page using &lt;a href=&quot;http://scrapy.org&quot;&gt;scrapy&lt;/a&gt;. I use OpenStreetMap’s &lt;a href=&quot;http://wiki.openstreetmap.org/wiki/Nominatim&quot;&gt;Nominatim&lt;/a&gt; to do the geocoding.&lt;/p&gt;

&lt;p&gt;The web frontend is a Django app that uses Backbone.js and django-tastypie to communicate between them. The Google Maps javascript API is used to display the map and MarkerClustererPlus does client-side clustering of the job offers. I’m thinking about doing (partial) server-side clustering to avoid having to send all the data to the client beforehand.&lt;/p&gt;

&lt;p&gt;I’ve also used &lt;a href=&quot;http://getsentry.com/welcome/&quot;&gt;Sentry&lt;/a&gt; on the production server to monitor crawling/scraping errors.&lt;/p&gt;

&lt;p&gt;That’s a lot of technological hype for a simple tool that I hope will be useful for others.&lt;/p&gt;

&lt;p&gt;The sources are available on &lt;a href=&quot;http://github.com/julienr/myzivi&quot;&gt;github&lt;/a&gt; and contributions are welcome !&lt;/p&gt;

</description>
        </item>
      
    
      
        <item>
          <title>Some notes on OpenCV findFundamentalMat</title>
          <link>http://fhtagn.net/prog/2012/09/27/opencv-fundamentalmat.html</link>
          <pubDate>Thu, 27 Sep 2012 00:00:00 +0000</pubDate>
          <author>julien@fhtagn.net (Julien Rebetez)</author>
          <guid>http://fhtagn.net/prog/2012/09/27/opencv-fundamentalmat</guid>
          <description>&lt;p&gt;These are some notes about OpenCV’s findFundamentalMat function.
It all started while trying to write unittests that rely on the fundamental
matrix. I created a set of points matches projected from an artificial shape
(so they are near perfect matches) and realized that depending on the number
of points, I was getting very different results from findFundamentalMat (in
term of error).&lt;/p&gt;

&lt;p&gt;I wrote a quick script to test findFundamentalMat function. I also wanted to
test if it handled 32 and 64 bit floats/double correctly (because initially,
I thought the bad results were due to some float/double conversion bug
between python and C++).&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;import cv2
import numpy as np
import numpy.linalg as la

# 15 Points
p1 = [[245.77, 248.66, 263.39, 251.11, 249.88, 287.57, 240.93, 206.84,
       224.95, 231.47, 257.55, 264.71, 227.67, 246.01, 244.15],
      [169.57, 105.82, 182.45, 146.54, 197.99, 137.11, 113.15, 171.57,
       170.34, 170.21, 124.43, 176.16, 127.05, 113.26, 154.41]]

p2 = [[267.07, 252.92, 254.22, 284.33, 236.82, 220.04, 255.9, 259.09,
       241.73, 258.62, 277.83, 219.62, 262.91, 250.93, 287.09],
      [172.34, 105.02, 190.25, 145.1, 190.63, 135.11, 114.37, 165.9,
       164.27, 168.3, 112.98, 170.46, 129.03, 114.5, 155.89]]

x1_32 = np.array(p1, dtype='f4')
x1_64 = np.array(p1, dtype='f8')
x2_32 = np.array(p2, dtype='f4')
x2_64 = np.array(p2, dtype='f8')

def compute_F_error(F):
    errs = []
    for i, p in enumerate(zip(x1_32.T, x2_32.T)):
        e = np.r_[p[1], 1].T.dot(F_32).dot(np.r_[p[0], 1])
        # normalize error by the norm of F since F is defined up to scale
        e /= la.norm(F)
        errs.append(e)
    return np.mean(errs)

np.set_printoptions(suppress=True, precision=6)

print '-- 15 points (RANSAC)'
F_32, status = cv2.findFundamentalMat(x1_32.T, x2_32.T)
print &quot;F 32 : &quot;, F_32/F_32[2,2]
print &quot;Avg error : &quot;, compute_F_error(F_32/F_32[2,2])
print &quot;status : &quot;, np.ravel(status)
F_64, status = cv2.findFundamentalMat(x1_64.T, x2_64.T)
print &quot;F 64 : &quot;, F_64/F_64[2,2]
print &quot;Avg error : &quot;, compute_F_error(F_64/F_64[2,2])
print &quot;status : &quot;, np.ravel(status)

print '-- 12 points (LMEDS)'
x1_32 = x1_32[:,:12]
x2_32 = x2_32[:,:12]
x1_64 = x1_64[:,:12]
x2_64 = x2_64[:,:12]
F_32, status = cv2.findFundamentalMat(x1_32.T, x2_32.T)
print &quot;F 32 : &quot;, F_32/F_32[2,2]
print &quot;Avg error : &quot;, compute_F_error(F_32/F_32[2,2])
print &quot;status : &quot;, np.ravel(status)
F_64, status = cv2.findFundamentalMat(x1_64.T, x2_64.T)
print &quot;F 64 : &quot;, F_64/F_64[2,2]
print &quot;Avg error : &quot;, compute_F_error(F_64/F_64[2,2])
print &quot;status : &quot;, np.ravel(status)

print '-- 7 points'
x1_32 = x1_32[:,:7]
x2_32 = x2_32[:,:7]
x1_64 = x1_64[:,:7]
x2_64 = x2_64[:,:7]
F_32, status = cv2.findFundamentalMat(x1_32.T, x2_32.T)
print &quot;F 32 : &quot;, F_32/F_32[2,2]
print &quot;Avg error : &quot;, compute_F_error(F_32/F_32[2,2])
print &quot;status : &quot;, np.ravel(status)
F_64, status = cv2.findFundamentalMat(x1_64.T, x2_64.T)
print &quot;F 64 : &quot;, F_64/F_64[2,2]
print &quot;Avg error : &quot;, compute_F_error(F_64/F_64[2,2])
print &quot;status : &quot;, np.ravel(status)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This program gives the following output. Keep in mind that the fundamental
matrix is defined only up to scale. So even if the matrices look very
different, they are, in fact, all valid fundamental matrices.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;~|=&amp;gt; python cvf.py
-- 15 points (RANSAC)
F 32 :  [[-0.        0.000013 -0.002001]
 [ 0.000013  0.       -0.004486]
 [-0.001997 -0.002184  1.      ]]
Avg error :  3.52578346368e-06
status :  [1 1 1 1 1 1 1 1 1 1 1 1 1 1 1]
F 64 :  [[-0.        0.000013 -0.002001]
 [ 0.000013  0.       -0.004486]
 [-0.001997 -0.002184  1.      ]]
Avg error :  3.52578346367e-06
status :  [1 1 1 1 1 1 1 1 1 1 1 1 1 1 1]
-- 12 points (LMEDS)
F 32 :  [[-0.00002  -0.000007  0.007063]
 [ 0.000093 -0.000031 -0.022699]
 [-0.00931   0.011469  1.      ]]
Avg error :  -0.00957514987137
status :  [1 0 1 0 1 0 0 1 1 1 1 0]
F 64 :  [[-0.        0.000013 -0.001986]
 [ 0.000013  0.       -0.004512]
 [-0.002002 -0.002178  1.      ]]
Avg error :  -0.00957874125736
status :  [1 1 0 1 0 0 1 0 0 1 1 1]
-- 7 points
F 32 :  [[ 0.000023 -0.000003 -0.005589]
 [-0.000007 -0.000006  0.002998]
 [-0.0045    0.001153  1.      ]]
Avg error :  -7.55324825546e-15
status :  [1 1 1 1 1 1 1]
F 64 :  [[ 0.000023 -0.000003 -0.005589]
 [-0.000007 -0.000006  0.002998]
 [-0.0045    0.001153  1.      ]]
Avg error :  -7.55324825538e-15
status :  [1 1 1 1 1 1 1]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;As you can see, the average error is ok for the 15 and 7 points case, but
is relatively high (with some outliers) for the 12 points case.&lt;/p&gt;

&lt;p&gt;If you look at &lt;a href=&quot;http://docs.opencv.org/modules/calib3d/doc/camera_calibration_and_3d_reconstruction.html#findfundamentalmat&quot;&gt;findFundamentalMat’s documentation&lt;/a&gt;,
it says it uses RANSAC if the number of points is greater or equal to 7.
But this is kind of misleading (&lt;a href=&quot;http://code.opencv.org/issues/2394&quot;&gt;OpenCV bug&lt;/a&gt;)
because actually, OpenCV does the following :&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Use the 7-point algorithm if N == 7&lt;/li&gt;
  &lt;li&gt;Use LMeDS if 7 &amp;lt; N &amp;lt; 15&lt;/li&gt;
  &lt;li&gt;Use RANSAC otherwise&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So our test with 12 points uses LMeDS, which, according to a paper[1], is not
very good when the number of outliers is small (figure 3 of the paper, you
can see RANSAC is better until the outliers percentage growth over 50%).&lt;/p&gt;

&lt;p&gt;Since this script tests with near-perfect matches, we don’t benefit at all
from LMeDS’s robustness to high outliers percentage.&lt;/p&gt;

&lt;p&gt;Conclusion : float/double conversion from python to C++ works fine, but be
choice of the fundamental matrix estimation algorithm matters.&lt;/p&gt;

&lt;p&gt;[1]: &lt;em&gt;Robust Estimation of the Fundamental Matrix and Stereo Correspondences&lt;/em&gt;,
     by Nuno Gracias , José Santos-Victor&lt;/p&gt;
</description>
        </item>
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
        <item>
          <title>NDK : loading resources and assets from native code</title>
          <link>http://fhtagn.net/prog/2010/08/27/ndk-resources-assets-loading.html</link>
          <pubDate>Fri, 27 Aug 2010 00:00:00 +0000</pubDate>
          <author>julien@fhtagn.net (Julien Rebetez)</author>
          <guid>http://fhtagn.net/prog/2010/08/27/ndk-resources-assets-loading</guid>
          <description>&lt;p&gt;One of the first problem I ran into when I started developing &lt;a href=&quot;http://zoob.fhtagn.net/&quot;&gt;Zoob&lt;/a&gt; with the Android NDK is to load resources (mainly textures to be used by OpenGL) from the APK. And here is a solution to this problem.&lt;br /&gt;
&lt;br /&gt;
This sample code consists of a very simple Android Java App that basically delegate all the rendering to native code (using NDK). Additionally (and I think that’s the interesting part), I’ve added libzip and libpng to the NDK code so you can load you application APK from the C/C++ code and load resources from there (example include loading a PNG file using libpng and libzip). &lt;br /&gt;
&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;The code is probably not the most efficient nor bugfree, but it works. &lt;br /&gt;
&lt;br /&gt;
The archive file contains a whole ndk “project” (to put under NDK_HOME/apps). &lt;br /&gt;
In the project/jni directory, there are 3 modules. &lt;a href=&quot;http://www.libpng.org/pub/png/libpng.html&quot;&gt;libpng&lt;/a&gt; and &lt;a href=&quot;http://nih.at/libzip/&quot;&gt;libzip&lt;/a&gt; are stripped-down version of the original libs (retaining only c sources basically). The “moob” project contain the main C++ code used for rendering and loading texture. Just dive in it, it’s pretty small and the function names should be understandable. &lt;br /&gt;
&lt;br /&gt;
To load the APK and read resources from it, the APK path is sent to the nativeInit method, which then load the APK using libzip. libzip provides fread like functionnality for reading compressed files so that’s pretty easy then. &lt;br /&gt;
&lt;br /&gt;
There is an eclipse Java/C++ project included in the code. You might have to tweak the configuration to work with your NDK_ROOT configuration. This code was tested on the emulator and on a HTC Magic.&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;
The zip file is available &lt;a href=&quot;http://fhtagn.net/files/android/android-ndk-assets.zip&quot;&gt;here&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
I first posted this on &lt;a href=&quot;http://www.anddev.org/android-2d-3d-graphics-opengl-tutorials-f2/ndk-opengl-loading-resources-and-assets-from-native-code-t11978.html&quot;&gt;anddev.org&lt;/a&gt;.&lt;/p&gt;

</description>
        </item>
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
        <item>
          <title>Modèles MD5 - Chargement &amp; Animation</title>
          <link>http://fhtagn.net/prog/2004/10/05/md5.html</link>
          <pubDate>Tue, 05 Oct 2004 00:00:00 +0000</pubDate>
          <author>julien@fhtagn.net (Julien Rebetez)</author>
          <guid>http://fhtagn.net/prog/2004/10/05/md5</guid>
          <description>&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;Le sujet de cette documentation est le format de modèles MD5 version 10(et non l'algorithme de vérification d'intégrité), crée pour le moteur de Doom 3.&lt;br /&gt;&lt;br /&gt;
Ce format utilise l'animation par 'joints'(='bones'), ce qui le rend plus flexible (mais également un peu plus compliqué) que le MD3(Quake 3).&lt;br /&gt;&lt;br /&gt;
Les 'joints' forment la partie centrale de l'animation d'un modèle. C'est eux qui définissent la position de la peau (les vertices du modèle qui seront ensuite rendus). Chaque 'vertice' du modèle est influencé par plusieurs poids, qui définissent l'influence qu'un 'joint' a sur tel ou tel 'vertice'.
&lt;br /&gt;&lt;br /&gt;
Une hiérarchie de 'bones' est également définie, c'est à  dire que chaque 'joint' a un parent et sa position est liée à  celle de son parent. (Si vous bougez votre bras, votre poignet va également bouger)&lt;br /&gt;&lt;br /&gt;
Il faut également savoir que les MD5 utilisent les quaternions. Nous ne discuterons pas en détail des quaternions ici. &lt;a href=&quot;http://skal.planet-d.net/demo/matrixfaq.htm&quot;&gt;Cette page&lt;/a&gt; contient une FAQ sur les quaternions.&lt;br /&gt;&lt;br /&gt;
Le format MD5 utilise des accolades pour délimiter les différentes section et des espaces pour séparer les informations.&lt;br /&gt;
&lt;br /&gt;
Le code source accompagnant ce tutorial est disponible &lt;a href=&quot;http://www.fhtagn.net/archives/md5_tut1.tar.bz2&quot;&gt;ici&lt;/a&gt;. Il contient une Makefile linux, utilise SDL et SDL_image et devrait donc normalement compiler sans problème sur les autres plateformes.
&lt;/p&gt;
&lt;h2&gt;Du format .md5mesh&lt;/h2&gt;
&lt;h3&gt;Survol&lt;/h3&gt;
&lt;p&gt;
Le fichier .md5mesh contient des listes de 'vertices', de triangles, de poids, de 'bones'. Nous l'examinerons en détail ici.&lt;br /&gt;
La première ligne nous donne des informations sur la version du format. Nous somme uniquement intéressés par la version 10, la version 6, celle utilisé dans l'alpha de Doom 3, étant trè;s différente.&lt;br /&gt;
La deuxiè;me ligne donne, apparement, des informations sur différentes choses, comme les noms des 'bones' qui peuvent être détachés du mesh ou qui éjecte des douilles. Nous n'en tiendrons pas compte.&lt;br /&gt;
La ligne 'numJoints' nous donne le nombre de 'joints' que contient le modè;le.&lt;br /&gt;
Enfin, le nombre de mesh(list de 'vertices', triangles et poids) que contient le modèle.
&lt;/p&gt;
&lt;div class=&quot;source&quot;&gt;
MD5Version 10&lt;br /&gt;
commandline (...)

numJoints 72&lt;br /&gt;
numMeshes 3&lt;br /&gt;
&lt;/div&gt;
&lt;p&gt;
Ensuite commencent les informations sur les 'joints'. Chaque 'joints' a un parent (c'est le premier nombre. Un -1 indique que le 'joint' n'a pas de parent). Les 3 nombres suivants entre parenthèses donnent la position du 'joint' (en coordonnées objets). Enfin, les 3 derniers nombres entre parenthèses nous donnent les composantes x,y,z du quaternion. La partie r (parfois nommé w) du quaternion est calculée par la formule :&lt;br /&gt;
&lt;/p&gt;
&lt;div class=&quot;source&quot;&gt;
float t = 1.0f-(x*x)-(y*y)-(z*z); &lt;br /&gt;
r = (t &amp;lt; 0.0f) ? 0.0f : -(float)sqrt(t);
&lt;/div&gt;
&lt;p&gt;
Voilà  à  quoi ressemble une ligne d'information sur les 'joints' :
&lt;/p&gt;
&lt;div class=&quot;source&quot;&gt;
joints {&lt;br /&gt;
	&quot;origin&quot;	-1 ( 0 0 0 ) ( -0.5 -0.5 -0.5 )// &lt;br /&gt;
&lt;/div&gt;
&lt;p&gt;
Ensuite, il y a autant de sections 'mesh' que le 'numMeshes' du début. C'est là  que sont décrit les meshes:&lt;br /&gt;
Tout d'abord, le 'shader' du mesh, c'est à  dire les textures qu'il utilise (dans doom3, beaucoup de textures sont utilisés pour notamment le bump-mapping. Elle ont toutes le même nom, avec des préfixes (_d, _local, ...) différents). Nous en déduirons plus tard le nom de la texture a utiliser.&lt;br /&gt;
Ensuite, le nombre de 'vertices' du mesh est indiqué, puis chaque 'vertice' est décrit :&lt;br /&gt;
Le premier nombre donne simplement le numéro du vertice.&lt;br /&gt;
Ensuite, entre parenthèses, vienent les coordonnées de textures du 'vertice'.&lt;br /&gt;
L'avant-dernier nombre indique l'index dans le tableau des poids du poids qui influence ce vertice.&lt;br /&gt;
Enfin, le dernier nombre donne le nombre de poids qui ont une influence sur ce vertice(ces poids sont obligatoirement consécutifs dans le tableau des poids).&lt;/p&gt;
&lt;div class=&quot;source&quot;&gt;
mesh {
	// meshes: tounge
	shader &quot;models/monsters/guardian/tongue&quot;

	numverts 34
	vert 0 ( 0 0.7843043804 ) 0 2
&lt;/div&gt;
&lt;p&gt;Viennent ensuite des informations sur les triangles:&lt;br /&gt;
Tout d'abord, le nombre de triangles (numtris).&lt;br /&gt;
Puis, chaque triangle est décrit individuellement :&lt;br /&gt;
Le premier nombre est le numéro du triangle.&lt;br /&gt;
Les trois nombres suivants sont les indices des 'vertices' qui composent la face.&lt;/p&gt;
&lt;div class=&quot;source&quot;&gt;
numtris 58&lt;br /&gt;
tri 0 2 1 0
&lt;/div&gt;
&lt;p&gt;
Enfin, des informations sur les poids:&lt;br /&gt;
Tout d'abord, le nombre de poids, puis chaque poids individuellement.
Ensuite, l'index du bone duquel dépend le poids.&lt;br /&gt;
Puis, le bias, qui définit la 'force' d'un poids.&lt;br /&gt;
Enfin, les 3 nombres entre parenthèses donnent la position du poid.(qui sera mixé avec les positions des autres poids pour donner la position d'un vertice)&lt;/p&gt;
&lt;div class=&quot;source&quot;&gt;
numweights 83&lt;br /&gt;
weight 0 57 0.499899447 ( -0.0000004443 6.0386610031 2.2817306519 )
&lt;/div&gt;

&lt;h3&gt;Structures utilisées&lt;/h3&gt;
&lt;p&gt;Nous discuterons ici les différentes structures c/c++ utilisées pour représenter les données du .md5mesh.&lt;br /&gt;
Tout d'abord, il y a deux structures qui ne sont pas directement en rapport avec le MD5, 'Face' et 'Vertice' :&lt;/p&gt;
&lt;div class=&quot;source&quot;&gt;
&lt;pre&gt;struct Face
{
	unsigned int pIndex[3];
	Plane plane;
	bool visible;
};
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;span style=&quot;color:blue&quot;&gt;pIndex&lt;/span&gt; est un tableau qui donne les index des trois vertice qui composent la face.&lt;br /&gt;
&lt;span style=&quot;color:blue&quot;&gt;Plane&lt;/span&gt; n'est pas utilisé pour l'instant.&lt;br /&gt;
&lt;span style=&quot;color:blue&quot;&gt;visible&lt;/span&gt; n'est pas utilisé non plus pour l'instant.&lt;br /&gt;&lt;/p&gt;
&lt;div class=&quot;source&quot;&gt;
&lt;pre&gt;
struct Vertice
{
	Vector3 vPosition;
	float s, t;
	Vector3 sTangent, tTangent;
	Vector3 vNormal;
	Vector3 vTangentSpaceLight;
};
&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;&lt;span style=&quot;color:blue&quot;&gt;vPosition&lt;/span&gt; est la position du 'vertice'.&lt;br /&gt;
&lt;span style=&quot;color:blue&quot;&gt;s et t&lt;/span&gt; sont les coordonnées de textures.&lt;br /&gt;
Le reste n'est d'aucune utilité pour l'instant.&lt;br /&gt;
&lt;/p&gt;
&lt;div class=&quot;source&quot;&gt;
&lt;pre&gt;
struct _MD5Joint
{
	std::string sName;
	int iNumber;
	int iParent;
	Vector3 vPosition;
	Quaternion qOrientation;
	
	_MD5Joint* pParent;
	_MD5Joint** pChildrens;
	int iNumChildrens;
};
&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;
&lt;span style=&quot;color:blue&quot;&gt;sName&lt;/span&gt; est le nom du 'joint'.&lt;br /&gt;
&lt;span style=&quot;color:blue&quot;&gt;iNumber&lt;/span&gt; est le numéro du 'joint'.&lt;br /&gt;
&lt;span style=&quot;color:blue&quot;&gt;iParent&lt;/span&gt; est le numéro du 'joint' parent.&lt;br /&gt;
&lt;span style=&quot;color:blue&quot;&gt;vPosition&lt;/span&gt; est la position du 'joint'.&lt;br /&gt;
&lt;span style=&quot;color:blue&quot;&gt;qOrientation&lt;/span&gt; est le quaternion représentant l'orientation(rotation) du 'joint'.&lt;br /&gt;
&lt;span style=&quot;color:blue&quot;&gt;pParent&lt;/span&gt; est un pointeur sur le 'joint' parent.&lt;br /&gt;
&lt;span style=&quot;color:blue&quot;&gt;pChildrens&lt;/span&gt; est un tableau de &lt;span style=&quot;color:blue&quot;&gt;iNumChildrens&lt;/span&gt; pointeurs sur les 'joints' enfants(qui ont pour parent ce 'joint'-ci.&lt;br /&gt;
&lt;/p&gt;
&lt;div class=&quot;source&quot;&gt;
&lt;pre&gt;struct _MD5Mesh
{
	int iNumVerts;
	_MD5Vert* pVerts;
	
	int iNumWeights;
	_MD5Weight* pWeights;
	
	int iNumTris;
	_MD5Triangle* pTriangles;
	
	unsigned int* pIndexes;
	
	Material* pMaterial;
	std::string sColor;
	std::string sNormal;
};&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;
&lt;span style=&quot;color:blue&quot;&gt;pVerts&lt;/span&gt; est un tableau de &lt;span style=&quot;color:blue&quot;&gt;iNumVerts&lt;/span&gt; structures &lt;span style=&quot;color:blue&quot;&gt;_MD5Vert&lt;/span&gt; qui stockent des informations sur les 'vertices' du modè;le.&lt;br /&gt;
&lt;span style=&quot;color:blue&quot;&gt;pWeights&lt;/span&gt; est un tableau de &lt;span style=&quot;color:blue&quot;&gt;iNumWeights&lt;/span&gt; structures &lt;span style=&quot;color:blue&quot;&gt;_MD5Weight&lt;/span&gt; qui stockent des informations sur les poids du modè;le.&lt;br /&gt;
&lt;span style=&quot;color:blue&quot;&gt;pTriangles&lt;/span&gt; est un tableau de &lt;span style=&quot;color:blue&quot;&gt;iNumTris&lt;/span&gt; structures &lt;span style=&quot;color:blue&quot;&gt;_MD5Triangle&lt;/span&gt; qui stockent des informations sur les triangles du modè;le.&lt;br /&gt;
&lt;span style=&quot;color:blue&quot;&gt;pIndexes&lt;/span&gt; est une copie des index &lt;span style=&quot;color:blue&quot;&gt;pIndex&lt;/span&gt; des différent triangles, simplement pour pouvoir le passer en argument à  glDrawElements.&lt;br /&gt;
&lt;span style=&quot;color:blue&quot;&gt;Material&lt;/span&gt; est un pointeur sur le material du mesh.&lt;br /&gt;
&lt;span style=&quot;color:blue&quot;&gt;sColor et sNormal&lt;/span&gt; sont les noms des textures de couleur et de normales.
&lt;/p&gt;

&lt;div class=&quot;source&quot;&gt;
&lt;pre&gt;
struct _MD5Vert
{
	int iWeightIndex;
	int iNumWeights;
	float pTexCoords[2];
};
&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;&lt;span style=&quot;color:blue&quot;&gt;iWeightIndex&lt;/span&gt; est l'index dans le tableau des poids du premier poid dont dépend le 'vertice'.&lt;br /&gt;
&lt;span style=&quot;color:blue&quot;&gt;iNumWeights&lt;/span&gt; est le nombre de poids qui ont une influence sur le 'vertice'. Ils sont consécutifs au premier (donné par iWeighIndex).&lt;br /&gt;&lt;/p&gt;

&lt;div class=&quot;source&quot;&gt;
&lt;pre&gt;
struct _MD5Weight
{
	int iBoneIndex;
	float fBias;
	Vector3 vWeights;
};
&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;&lt;span style=&quot;color:blue&quot;&gt;iBoneIndex&lt;/span&gt; est l'index dans le tableau des 'bones' du 'bone' duquel dépend ce poids.&lt;br /&gt;
&lt;span style=&quot;color:blue&quot;&gt;fBias&lt;/span&gt; donne la force du poids. (un poids avec plus de force 'attire' les 'vertices' vers lui)&lt;br /&gt;
&lt;span style=&quot;color:blue&quot;&gt;vWeights&lt;/span&gt; donne la position du poids.&lt;br /&gt;
&lt;/p&gt;
&lt;h2&gt;Du format .md5anim&lt;/h2&gt;
&lt;h3&gt;Survol&lt;/h3&gt;
&lt;p&gt;
Le fichier .md5anim contient des informations sur une animation disponible pour un modè;le. Le MD5 utilisant des 'bones', les seules (ou presque) informations nécessaires pour une animation sont celles concernant les mouvements (translation et rotation) des 'bone' pendant ladite animation.&lt;br /&gt;
C'est pourquoi le fichier .md5anim contient les informations sur les composantes des positions et rotations qui changent.
&lt;/p&gt;
&lt;div class=&quot;source&quot;&gt;
MD5Version 10
commandline (...)
 
numFrames 201
numJoints 72
frameRate 24
numAnimatedComponents 197
&lt;/div&gt;
&lt;p&gt;
Comme dans le fichier .md5mesh, on a une information sur la version et une 'commandline' qui ne nous sera pas d'une grande utilité.&lt;br /&gt;
Suivent des choses plus intéressantes, à  savoir le nombre d'images ('frames') que contient notre animation (&lt;span style=&quot;color:blue&quot;&gt;numFrames&lt;/span&gt;), le nombre de 'bones' que contient notre animation (&lt;span style=&quot;color:blue&quot;&gt;numJoints&lt;/span&gt;), le nombre d'image par seconde de l'animation (&lt;span style=&quot;color:blue&quot;&gt;frameRate&lt;/span&gt;) et enfin, le nombre de composantes qui changent chaque frame (&lt;span style=&quot;color:blue&quot;&gt;numAnimatedComponents&lt;/span&gt;, qui sera expliqué plus tard).&lt;br /&gt;
&lt;span style=&quot;color:blue&quot;&gt;Notez que le nombre ainsi que la hiérarchie de l'animation et du fichier .md5mesh sont les mêmes et qu'à  priori, ceci est valable pour tout les modèles de Doom3. Nous ignorerons donc les informations sur le nombre de joints et la hiérarchie du fichier .md5anim et utiliseront uniquement celles du fichier .md5mesh.&lt;/span&gt;&lt;br /&gt;
&lt;/p&gt;
&lt;div class=&quot;source&quot;&gt;
&lt;pre&gt;
hierarchy {
     &quot;origin&quot;        -1 0 0  //
     &quot;Body&quot;  0 63 0  // origin ( Tx Ty Tz Qx Qy Qz )
&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;
La seule utilitée de la section 'hierarchy' et de nous informer sur quelles composantes de chaque 'joint' sont modifiées pendant l'animation.
Cela est indiqué par le deuxième nombre, qui doit être utilisé comme un 'flag'. On peut les 'décrypter' avec la 'formule' suivante :&lt;br /&gt;
si 'flags &amp;amp; 1' est vrai, la position sur les X change&lt;br /&gt;
si 'flags &amp;amp; 2' est vrai, la position sur les Y change&lt;br /&gt;
si 'flags &amp;amp; 4' est vrai, la position sur les Z change&lt;br /&gt;
si 'flags &amp;amp; 8' est vrai, la composante X du quaternion de rotation change&lt;br /&gt;
si 'flags &amp;amp; 16' est vrai, la composante Y du quaternion de rotation change&lt;br /&gt;
si 'flags &amp;amp; 32' est vrai, la composante Z du quaternion de rotation change&lt;br /&gt;
&lt;/p&gt;
&lt;p&gt;
Nous ignorerons donc le reste de la section 'hierarchy' pour les raisons ci-dessus.&lt;br /&gt;
La section 'bounds' donne les coordonnées min et max des boà®tes englobantes (Bounding Box) du modèle pendant l'animation. Cela n'entre pas en ligne de compte dans ce tutorial.&lt;br /&gt;
Nous sautons donc directement à  la section 'baseframe'.&lt;br /&gt;
&lt;/p&gt;
&lt;div class=&quot;source&quot;&gt;
&lt;pre&gt;
baseframe {
    ( 0 0 0 ) ( -0.5 -0.5 -0.5 )
&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;
Cette section contient &lt;span style=&quot;color:blue&quot;&gt;numJoints&lt;/span&gt; lignes et donne la position (3 premiers nombres) et les composantes x,y,z du quaternion représentant la rotation de chaque joint &lt;span style=&quot;color:red&quot;&gt;à  la première image de l'animation&lt;/span&gt;.&lt;br /&gt;
Ces positions/rotations servent de base pour toutes les autres informations du fichier .md5anim .
&lt;/p&gt;
&lt;div class=&quot;source&quot;&gt;
&lt;pre&gt;frame 0 { 
    111.1 141.4 -11.5 -0.0 0.9 0.3
&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;
Suivent ensuite &lt;span style=&quot;color:blue&quot;&gt;numAnimatedComponents&lt;/span&gt; nombres qui représentent les composantes qui sont modifiées par l'animation pour chaque joint(une ligne par 'joint', contenant un nombre variable d'élément, cf ci-dessus).
&lt;/p&gt;
&lt;h3&gt;Structure&lt;/h3&gt;
&lt;div class=&quot;source&quot;&gt;
&lt;pre&gt;
struct _MD5Anim
{
	std::string sName;
	int iNumFrames;
	int iNumJoints;
	int iFrameRate;
	int iNumAnimatedComponents;
	float** pFrames;
	float** pBaseFrame; 
	struct _MD5JointInfos
	{
		int iParent;
		int iFlags;
		int iStartIndex;
	};
	_MD5JointInfos* pJointInfos;
};
&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;
&lt;span style=&quot;color:blue&quot;&gt;sName&lt;/span&gt; est le nom de l'animation.&lt;br /&gt;
&lt;span style=&quot;color:blue&quot;&gt;iNumFrames&lt;/span&gt; est le nombre d'images de l'animation.&lt;br /&gt;
&lt;span style=&quot;color:blue&quot;&gt;iFrameRate&lt;/span&gt; est le nombre d'images par seconde de l'animation.&lt;br /&gt;
&lt;span style=&quot;color:blue&quot;&gt;iNumAnimatedComponents&lt;/span&gt; est le nombre de composants animés dans l'animation.&lt;br /&gt;
&lt;span style=&quot;color:blue&quot;&gt;pFrames&lt;/span&gt; est un tableau de [iNumFrames][iNumAnimatedComponents] float représentant les valeures modifiées (cf flags ci-dessus).&lt;br /&gt;
&lt;span style=&quot;color:blue&quot;&gt;pBaseFrame&lt;/span&gt; est un tableau de [iNumJoints][6], stockant, dans l'ordre, Tx, Ty, Tz, Qx, Qy, Qz a la frame de base de l'animation.&lt;br /&gt;
&lt;span style=&quot;color:blue&quot;&gt;_MD5JointInfos&lt;/span&gt; est une structure regroupant des informations sur les 'joints', dont le champ iFlags, donnant les 'flags' du 'joint'.&lt;br /&gt;
&lt;span style=&quot;color:blue&quot;&gt;pJointInfos&lt;/span&gt; est une invocation pour le grand Cthulhu.&lt;br /&gt;
&lt;/p&gt;
&lt;h2&gt;De l'utilisation de ces données&lt;/h2&gt;
&lt;p&gt;Les deux fonctions les plus intéressantes et qui s'occupent réellement de gérer ces structures sont &lt;span style=&quot;color:blue&quot;&gt;void MD5Mesh::_SkinMesh&lt;/span&gt; et &lt;span style=&quot;color:blue&quot;&gt;void MD5Mesh::_BuildBone&lt;/span&gt;. Intéressons-nous d'abord à  cette dernière :&lt;/p&gt;
&lt;div class=&quot;source&quot;&gt;
&lt;pre&gt;
void MD5Mesh::_BuildBone (int iFrame, _MD5Joint* pJoint,const Quaternion&amp;amp; q, const Vector3&amp;amp; v)
{
	Vector3 animatedPosition;
	animatedPosition.x = pAnimations[iCurrentAnimation].pBaseFrame[pJoint-&amp;gt;iNumber][0];
	animatedPosition.y = pAnimations[iCurrentAnimation].pBaseFrame[pJoint-&amp;gt;iNumber][1];
	animatedPosition.z = pAnimations[iCurrentAnimation].pBaseFrame[pJoint-&amp;gt;iNumber][2];
	
	Quaternion animatedOrientation;
	animatedOrientation.x = pAnimations[iCurrentAnimation].pBaseFrame[pJoint-&amp;gt;iNumber][3];
	animatedOrientation.y = pAnimations[iCurrentAnimation].pBaseFrame[pJoint-&amp;gt;iNumber][4];
	animatedOrientation.z = pAnimations[iCurrentAnimation].pBaseFrame[pJoint-&amp;gt;iNumber][5];
	
	
	int flags = pAnimations[iCurrentAnimation].pJointInfos[pJoint-&amp;gt;iNumber].iFlags;
	int n=0;
	int sIndex = pAnimations[iCurrentAnimation].pJointInfos[pJoint-&amp;gt;iNumber].iStartIndex;

	if (flags &amp;amp; 1) //Tx est anime
	{
		animatedPosition.x = pAnimations[iCurrentAnimation].pFrames[iFrame][sIndex+n];
		n++;
	}
	if (flags &amp;amp; 2) //Ty est anime
	{
		animatedPosition.y = pAnimations[iCurrentAnimation].pFrames[iFrame][sIndex+n];
		n++;
	}
	if (flags &amp;amp; 4) //Tz est anime
	{
		animatedPosition.z = pAnimations[iCurrentAnimation].pFrames[iFrame][sIndex+n];
		n++;
	}
	if (flags &amp;amp; 8) //Qx est anime
	{
		animatedOrientation.x = pAnimations[iCurrentAnimation].pFrames[iFrame][sIndex+n];
		n++;
	}
	if (flags &amp;amp; 16) //Qy est anime
	{
		animatedOrientation.y = pAnimations[iCurrentAnimation].pFrames[iFrame][sIndex+n];
		n++;
	}
	if (flags &amp;amp; 32) //Qz est anime
	{
		animatedOrientation.z = pAnimations[iCurrentAnimation].pFrames[iFrame][sIndex+n];
		n++;
	}

	animatedOrientation.ComputeR();
	if (pJoint-&amp;gt;iParent &amp;lt; 0) //pas de parent
	{
		pJoint-&amp;gt;vPosition = animatedPosition;
		pJoint-&amp;gt;qOrientation = animatedOrientation;
	}
	else //parent
	{
		pJoint-&amp;gt;vPosition = q.Rotate(animatedPosition);
		pJoint-&amp;gt;vPosition += v;
		pJoint-&amp;gt;qOrientation = q*animatedOrientation;
	}

	for (int i = 0; i &amp;lt; pJoint-&amp;gt;iNumChildrens; i++)
	{
		_BuildBone(iFrame,pJoint-&amp;gt;pChildrens[i], pJoint-&amp;gt;qOrientation, pJoint-&amp;gt;vPosition);
	}
}
&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;
Cette fonction sera appelée une fois pour chaque 'bone' racine. (qui n'a pas de parent)
Pour commencer, on prend les positions/rotation de l'image de base (tout est relatif à  cette image).&lt;br /&gt;
Ensuite, on test ce qu'on doit animer. &lt;span style=&quot;color:blue&quot;&gt;sIndex&lt;/span&gt; nous donne l'index de base pour ce 'bone' dans le tableau des AnimatedComponents.&lt;br /&gt;
On doit ensuite multiplier la rotation et additioner la position du 'bone' parent (histoire que la hiérachie serve à  quelque chose). Puis, on lance cette même fonction sur tout les 'bones' enfants.
&lt;/p&gt;
&lt;div class=&quot;source&quot;&gt;
&lt;pre&gt;
Vector3 pos;
for (int i=0; i&amp;lt;iNumMeshes; i++) 
{
	for (int j=0; j&amp;lt;pMeshes[i].iNumVerts; j++)
	{
		pVerticesListTab[i][j].vPosition.Null();
		//assignation des texcoords.
		//FIXME: On pourrait éviter à§a et ne le faire qu'une seule fois nan ?
		pVerticesListTab[i][j].s = pMeshes[i].pVerts[j].pTexCoords[0];
		pVerticesListTab[i][j].t = pMeshes[i].pVerts[j].pTexCoords[1];

		for (int k=0; k&amp;lt;pMeshes[i].pVerts[j].iNumWeights; k++) 
		{
			int baseIndex = pMeshes[i].pVerts[j].iWeightIndex;
			int boneIndex = pMeshes[i].pWeights[baseIndex+k].iBoneIndex;
		
			pos = pJoints[boneIndex].qOrientation.Rotate(pMeshes[i].pWeights
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;[baseIndex+k].vWeights);
			pVerticesListTab[i][j].vPosition += (pos + pJoints[boneIndex].vPosition)*&lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;pMeshes[i].pWeights[baseIndex+k].fBias;
		}
	}
}
&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;
Ici, pour chaque vertice, on fait la somme des poids qui ont une influence sur le vertice en question.&lt;br /&gt;
Il s'agit simplement de multiplier la position de chaque poids par son 'bias' et de faire la somme pour tout les poids qui ont une influence sur le vertice.
&lt;/p&gt;

</description>
        </item>
      
    

  </channel> 
</rss>
