Simple .obj mesh reader for MATLAB

March 8th, 2010

matlab obj mesh reader screenshotI wrote a little .obj file format reader in MATLAB. It only reads the vertices and faces of a triangle mesh (ignoring all the other commands and features). I use it to extract the vertex and face arrays.

Here’s the code, I save it in a file called read_vertices_and_faces_from_obj_file.m:


function [V,F] = read_vertices_and_faces_from_obj_file(filename)
  % Reads a .obj mesh file and outputs the vertex and face list
  % assumes a 3D triangle mesh and ignores everything but:
  % v x y z and f i j k lines
  % Input:
  %  filename  string of obj file's path
  %
  % Output:
  %  V  number of vertices x 3 array of vertex positions
  %  F  number of faces x 3 array of face indices
  %
  V = zeros(0,3);
  F = zeros(0,3);
  vertex_index = 1;
  face_index = 1;
  fid = fopen(filename,'rt');
  line = fgets(fid);
  while ischar(line)
    vertex = sscanf(line,'v %f %f %f');
    face = sscanf(line,'f %d %d %d');
    face_long = sscanf(line,'f %d/%d/%d %d/%d/%d %d/%d/%d');

    % see if line is vertex command if so add to vertices
    if(size(vertex)>0)
      V(vertex_index,:) = vertex;
      vertex_index = vertex_index+1;
    % see if line is simple face command if so add to faces
    elseif(size(face)>0)
      F(face_index,:) = face;
      face_index = face_index+1;
    % see if line is a long face command if so add to faces
    elseif(size(face_long)>0)
      % remove normal and texture indices
      face_long = face_long(1:3:end)
      F(face_index,:) = face_long;
      face_index = face_index+1;
    else
      fprintf('Ignored: %s',line);
    end

    line = fgets(fid);
  end
  fclose(fid);
end

Then I can read and render a mesh with phong shading:


[V,F] = read_vertices_and_faces_from_obj_file('path/to/your/mesh.obj');
trisurf(F,V(:,1),V(:,2),V(:,3),'FaceColor',[0.26,0.33,1.0 ]);
light('Position',[-1.0,-1.0,100.0],'Style','infinite');
lighting phong;

Toggle Brightness Menulet

March 4th, 2010

I took a first crack at making a Cocoa menulet for Mac OS X. I wasn’t quite able to do what I wanted to do. But it looks like it might be possible.
What I wanted was to make a brightness slider menulet. It would function the same as the System Volume menulet:
system volume vertical slider
I couldn’t yet figure out how to put the slider in the menu bar, so for now I have a brightness toggler:
system volume vertical slider

It was also my first real coding with xcode. Here’s my project and the app for intel and power pc (not sure if ppc will work). I assume this will only work on OS X 10.5 but you tell me.

ToggleBrightnessMenulet Xcode Project
Toggle Brightness Menulet (Intel)
Toggle Brightness Menulet (Power PC)

Most (almost all) of this code is unoriginal. See: the brightness source, the menulet tutorial.

Make make show which commands it’s executing

March 4th, 2010

I’ve started using cmake which generates a whole bunch of make files automatically. Then I call make. But since the makefiles are generated automatically I have no idea what it’s actually executing. To show those compilation commands just use:


make VERBOSE=1

g++ error: can’t map file, errno=22 or the case of the missing space

March 1st, 2010

I was trying to build and opencv hello world program from the command line with g++ and I got a funny error. When I issued the compile command the site had listed:


g++ hello-world.cpp -o hello-world -I /opt/local/include/opencv -L /opt/local/lib -lcxcore -lm -lcv -lhighgui -lcvaux

it would crash with:


ld: in /opt/local/lib, can't map file, errno=22

After some fruitless searching, I realized it was just the space between -L and /opt/local/lib. I removed the space:


g++ hello-world.cpp -o hello-world -I /opt/local/include/opencv -L/opt/local/lib -lcxcore -lm -lcv -lhighgui -lcvaux

And everything worked!

Batch create torrents, using mktorrent ctorrent and bash scripting

March 1st, 2010

I been hunting for a long while for a simple way to batch create .torrent metainfo files for a list of files. What I want is one .torrent file for every .avi file say in the current directory.

I found the handy tool, mktorrent ctorrent and with a little bash scripting one-liner came up with what I think is a decent solution for the command line:


for filename in *.avi; do \
ctorrent -t -u "[your announce url]" -s "$filename".torrent -p "$filename"; \
done

You may omit the -p if you don’t want the torrent to be private.

And you should replace *.avi with whatever files you are batch creating torrents for.

Note: I began this post thinking I would be using createtorrent to generate the .torrent files but it seems that it doesn’t have private tracker support…so I went with mktorrent

Note: I had to edit this post to remove the mktorrent, too! It made bogus metainfo files that Transmission wouldn’t verify against the real data… Augh. ctorrent has been working though.

mktorrent Segmentation fault error on Mac OS X 10.4

March 1st, 2010

I compile mktorrent from source using their suggested one-liner for OSX:


make USE_PTHREADS=1 USE_OPENSSL=1 USE_LONG_OPTIONS=1
sudo make install

I have Mac OS X 10.4 running on a power pc macbook pro. When I ran mktorrent, I got an ominous error:


Segmentation fault

When I recompiled with just:


make USE_OPENSSL=1 USE_LONG_OPTIONS=1
sudo make install

everything worked just fine.

How to create a silverlight xna game (using silverarcade)

March 1st, 2010

Also, useful if you want to convert your existing XNA game to a silverlight app.

The silverarcade libraries help you keep most of you existing XNA code intact. I’ll assume that you are using Visual Studio and have all the proper Silverlight SDK stuff installed (if you haven’t, good luck. It took me way too long to figure that out. Maybe I will post details if I ever recover).

I typed up these instructions after my first conversion and have followed them to get few of my own games converted. So hopefully they will help you, too:

  • In Visual Studio, Choose new project > Silverlight > Silverlight Application. Click NO to the prompt about “Host as a new web site”
  • Open MainPage.xaml and add the following the <UserControl> tag as an atribute:
    
    xmlns:game="clr-namespace:[your project name here]"
    
  • In MainPage.xaml, Add the following to the <Grid> contents:
    
      <Canvas>
        <game:Game2D x:Name="Game1"/>
      </Canvas>
    
  • Right click on project name in Solution Explorer > add > class…
    Call the class Game2D.cs
  • In Game2D.cs, replace the “using…” lines with:
    
    
        using System;
        using System.Collections.Generic;
        using System.Linq;
    
        #if(SILVERLIGHT)
        using SilverArcade.SilverSprite;
        using SilverArcade.SilverSprite.Audio;
        using SilverArcade.SilverSprite.Content;
        using SilverArcade.SilverSprite.GamerServices;
        using SilverArcade.SilverSprite.Graphics;
        using SilverArcade.SilverSprite.Input;
        using SilverArcade.SilverSprite.Media;
        using SilverArcade.SilverSprite.Storage;
        #else
        using Microsoft.Xna.Framework;
        using Microsoft.Xna.Framework.Audio;
        using Microsoft.Xna.Framework.Content;
        using Microsoft.Xna.Framework.GamerServices;
        using Microsoft.Xna.Framework.Graphics;
        using Microsoft.Xna.Framework.Input;
        using Microsoft.Xna.Framework.Media;
        using Microsoft.Xna.Framework.Net;
        using Microsoft.Xna.Framework.Storage;
        #endif
    
  • In Game2D.cs, replace the class declaration with:
    
        public class Game2D : SilverArcade.SilverSprite.Game
    
  • In Game2D.cs, Add global variables:
    
            GraphicsDeviceManager graphics;
            SpriteBatch spriteBatch;
    
  • In Game2D.cs, add constructor:
    
            public Game2D()
            {
                graphics = new GraphicsDeviceManager(this);
                Content.RootDirectory = "Content";
                graphics.PreferredBackBufferWidth = 1000;
                graphics.PreferredBackBufferHeight = 600;
            }
    
  • In Game2D.cs, Add initialize method:
    
            protected override void Initialize()
            {
                // TODO: Add your initialization logic here
    
                base.Initialize();
            }
    
  • In Game2D.cs, Add loadcontent method:
    
            protected override void LoadContent()
            {
                // Create a new SpriteBatch, which can be used to draw textures.
                spriteBatch = new SpriteBatch(GraphicsDevice);
                // TODO: use this.Content to load your game content here
            }
    
  • In Game2D.cs, Add unloadcontent method:
    
            protected override void UnloadContent()
            {
                // TODO: Unload any non ContentManager content here
            }
    
  • In Game2D.cs, Add update method:
    
            protected override void Update(GameTime gameTime)
            {
                // Allows the game to exit
                if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
                    this.Exit();
                // TODO: Add your update logic here
                base.Update(gameTime);
            }
    
  • In Game2D.cs, Add draw method:
    
            protected override void Draw(GameTime gameTime)
            {
                GraphicsDevice.Clear(Color.Gray);
                spriteBatch.Begin();
                spriteBatch.End();
                base.Draw(gameTime);
            }
    
  • Add silversprite.dll to project by right clicking on references and add existing item and choose your silversprite.dll (probably put this in debug or release folder or wherever).

Important notes:

When adding content you must click each image file/etc. and go to properties and change Build action to Content.

.wav files are not allowed as silversprite audio, must use mp3 or wav

Don’t need graphics.applyChanges() line when requesting preferred size

The trials and tribulations of building a simple mesh viewer

February 26th, 2010

I am beginning a new project and to start I needed to install a peer’s CGAL-based mesh viewer. The mesh viewer has many dependencies which in turn have even more dependencies. I will try to recap my struggle and eventual success, here. My warned that this is not an installation guide and is probably missing many things I did and maybe even advertising bad solutions.

64-bit on Mac OS X 10.5

Short story: Don’t bother.

Long story: My peer has his whole setup all running on 64 bits. This requires building all the dependencies running on 64 bits, which for Mac OS X 10.4 (Leopard) this means compiling everything from source and being really careful about flags. It also means, as far as I know, not using macports.
I tried to mimic his compilations and installs but without knowing the exact flags I got almost to the point of having everything working but then my 32-bit installs from macports started really getting in the way. I ended up uninstalling all my macports in vain only to realize that my python(s) were not 64-bit or at least couldn’t find 32-bit framework libraries. I recompiled python and pyqt but only found new errors. In the end I gave up on 64-bit (which I’d spent 3 days on) and switched (back) to 32-bit (which only took 1 day).

Dependencies for CGAL using macports

CGAL itself has a macport but it’s poorly maintained and will often not compile correctly with your current setup. It seems that a lot of people are having trouble getting this to even build correctly much less work correctly. Instead use macports to install the dependencies then build cgal from source by hand (not so bad).

CGAL depends on or supports the following libraries that you don’t already have on your mac:

  • boost
  • Gmp
  • Mpfr
  • zlib
  • BLAS*
  • LAPACK*
  • taucs*

Qt3, Qt4 and libqglviewer are only necessary for building the examples and demos which require them and not necessary for the install. Really the only dependency is boost. The rest add more features: exact arithmetic, linear algebra solvers, etc. Those with a *, I’ll write more about later on.

To install most of the above with macports just issue:


sudo port install boost gmp mpfr zlib

Now, you should be ready to build CGAL.

Installing CGAL

cd to the CGAL directory and issue

cmake -i .

You’ll see a prompt for advanced options, I was paranoid so I typed Yes:


Would you like to see advanced options? [No]:Yes

You need to change all library and include directories to point to the macports install directory: /opt/local/lib/WHATEVER or /opt/local/include.

For example:


Variable Name: Boost_INCLUDE_DIR
Description: Path to a file.
Current Value: /usr/local/include
New Value (Enter to keep current value): /opt/local/include

Do this for boost, gmp, mpfr etc. Watch out for the CMAKE_INSTALL_PREFIX prompt. If you want CGAL to hang out with your macports then change this to /opt/local like so:


Variable Name: CMAKE_INSTALL_PREFIX
Description: Install path prefix, prepended onto install directories.
Current Value: /usr/local
New Value (Enter to keep current value): /opt/local

In the end, my hackish solution to a later problem prevents all this /opt/local business from mattering but it seems like good practice to have related software in the same place. Unless you feel like macports should be the only one touching /opt/local/ stuff, but it's your computer so why not.

Then you can make, sudo make install to finish with CGAL.

Python 2.6 and PyQt4

Simply issue:


sudo port install python26 py26-pyqt4 py26-opengl
sudo python_select python26

These should install fine and work on a simple example. Getting CGAL to recognize your python (and subsequently PyQt) is another problem.

taucs with LU

I was trying to install and unsupported version of the math software taucs. This version had LU decomposition necessary for a feature of the mesh viewer. I ran into trouble forcing the taucs build to see my blas and lapack and to make a proper 32 bit file.

After running configure if I tried to run make I would see an error:


build/darwin9.0/makefile:14: config/darwin9.0.mk: No such file or directory
make: *** No rule to make target `config/darwin9.0.mk'.  Stop.

This is because the taucs only cam with a premade make file for darwin, not darwin9.0 as configure has recognized my OS.

For the most part you can just copy the darwin make file:


cp config/darwin.mk config/darwin9.0.mk

But make a few changes, namely edit the following lines:


CFLAGS    = -arch i386 -O3 -faltivec

LIBBLAS   = -framework Accelerate
LIBLAPACK = -framework Accelerate

One more thing. The LIBF77 = -Lexternal/lib/darwin -lf2c line is pointing to the right place but the file there is wrong. If you ar -x external/lib/darwin/libf2c.a you'll find out it's full of x86_64 .o files, which will lead to a confused architecture build. My solution was to download the taucs_full from the CGAL download page and copy the libf2c.a on top of this file. Maybe the same is true for the lbmetis.a, I don't remember. Just check that after you
make your libtaus.a unarchives to i386 mach-o files.

After running make you should move your taucs to the /opt/local area. I just did


sudo mkdir /opt/local/taucs_with_lu
sudo cp -r taucs_with_lu/* /opt/local/taucs_with_lu/.

Hacks

At this point things seemed to work but our meshviewer uses swig to combine cpp code and python. swig was easy enough to install:


sudo port install swig swig-python

But CGAL was not playing nicely. When I built our CGAL meshviewer, CGAL's cmake finders were not locating the libraries I had installed with macports. It kept trying to look in /usr/local/. My hack was to move /usr/local to /usr/local-off and simple link it to /opt/local. Everyone I told this too agreed it was ugly.


sudo mv /usr/local /usr/local-off
sudo ln -s /opt/local /usr/local

This is basically saying, I agree to use macports for everything or I must be very careful.

At this point CGAL would play along and build the toy version of our meshviewer. But python would not display it. I think it was because swig would not read the headers from the right place (/opt/local/WHATEVER) instead it was looking in


/Library/Frameworks/Python.Framework/WHATEVER. To handle this I also hacked:
cd /Library/Frameworks/Python.framework/Versions
ln -s /opt/local/Library/Frameworks/Python.framework/Versions/Current Current
cd /Library/Frameworks/Python.framework/
mv Headers Headers-off
ln -s /opt/local/Library/Frameworks/Python.framework/Headers Headers

Again, everyone I told this too said it was a poor man's hack.

CGAL and a deprecated header

Finally, I had everything in order to build the full version of my meshviewer. But I got funny errors about a certain boost header no existing, namely /opt/local/include/boost/property_map.hpp.

Upon inspection I noticed that indeed this file does not exist. On my peer's boost install (he did not use macports) he had this file but opening it we saw that it had been long deprecated by boost and simple pointed to the real header in property_map/property_map.hpp one directory lower. I copied my peer's deprecated property_map.hpp and put it in /opt/local/include/boost/ and CGAL found the file correctly.

Everything is up and running currently with the exception that my LAPACK is complaining more than my peer's about instantiating primitives correctly. When I solve this (hopefully not with another hack) I will post the results.

Hope this helps somebody. Please let me know if you find non-hack solutions to any of these.

Update:
I think I figured out Blas and Lapack...

In my cmake CONFIG.cmake file I have


    SET(CMAKE_CXX_FLAGS "-arch i386")
    SET(CMAKE_C_FLAGS   "-arch i386")
    SET(BLAS_LIBRARIES "/System/Library/Frameworks/Accelerate.framework")
    SET(BLAS_DEFINITIONS "-DBLAS_USE_F2C")
    INCLUDE_DIRECTORIES("/opt/local/include")
    LINK_DIRECTORIES("/opt/local/lib" "lib")
    INCLUDE_DIRECTORIES(/usr/X11/include)
    LINK_DIRECTORIES(/usr/X11/lib)
    SET(TAUCS_INCLUDE_DIR "/opt/local/taucs_with_lu/src/" "/opt/local/taucs_with
    SET(TAUCS_LIBRARIES "/opt/local/taucs_with_lu/lib/darwin9.0/libtaucs.a")
    SET(METIS_LIBRARIES "/opt/local/lib/libmetis.a")

In some files it worked to just above the line where you include the Acceleration framework


#include 

put instead:


#define __LP64__
#include 

For other directories I added this line to the CMakeLists.txt file:


ADD_DEFINITIONS("-D__LP64__")

If I find an elegant way to do this I will repost and update...

Two thousand results on google for “How to turn off google buzz” only three days after release

February 22nd, 2010

2010 results for how to turn off google buzz three days after release

Only three days after its release (one day after google’s “skip this ad” on gmail), I searched for “How to turn of google buzz” (in quotes) and found about 2010 pages containing that quote.

Interleave rows of two n by m matrices, using matlab

February 16th, 2010

I have to 3 by 2 matrices:


     /1 2\
A = | 3 4 |
     \5 6/

     /9 8\
B = | 7 6 |
     \5 4/

and I want to interleave leave their rows into a 6 by 2 matrix, C:



     /1 2\
    | 9 8 |
C = | 3 4 |
    | 7 6 |
    | 5 6 |
     \5 4/

To achieve this in matlab I use the following:


reshape([A(:) B(:)]',size(A,1)+size(B,1), [])

Perhaps there is a better way?