Categories

Meta

Month: May 2017

I’ve always loved holograms, those virtual objects intermingled with the real world in so many of my favorite films, from Star Wars to Zenon: Girl of the 21st Century. But I wasn’t looking forward to learning Unity game development and Windows system APIs before I could make my first animation for the hololens platform.

So while I still have to dig into Windows-Guts and Direct3D to make interactive applications, I was excited to find a straight forward way to generate hololens-compatible animations with just a few lines of python.

Using the python embedded in the open source Blender project, we can read files, make database queries, do whatever data science we want to do, and then import meshes or generate cubes, apply colors and materials, define keyframes, and export an FBX file that can be displayed in Hololens or on web pages. Hololens lets you open multiple animations and place them around the room, so while I can’t define any gaze-and-click behaviors, I can still move and scale and rotate my animation in the mixed-real world.

The first step of course, is to head to blender.org and download the latest. I’m going to be really verbose and try to help out people on both Windows and Mac, because I had to figure it out on both myself. Follow all the default options, and on Mac move blender.app to /Applications like you normally do. From here, you can check out a million youtube videos on what Blender is for (That’s how I learned it!) but next we’re going to add ‘blender’ to our path so we can execute it from the command line anywhere in our system and not even have to learn how to use the GUI.

For MacOS, you can run this in your terminal, or add to your bash.rc:

export PATH="/Applications/blender.app/Contents/MacOS:$PATH"

For Windows, open up powershell (right click, ‘run as administrator’, which you’ll need to do for any commands that save to disk) and run:

Now anytime you open your terminal/powershell, you can type ‘blender’ to launch blender. (On MacOS, you may need to restart your shell for it to take effect, or type ‘source bash profile’ to force bash to reload your saved preferences, including path) (Another option for windows is to search for ‘edit system variables’ from the start menu, click ‘environment variables’ and use the GUI to add C:Program FilesBlender FoundationBlender to your Path)

But going through all that trouble just to open Blender isn’t the point. The point is now we can save python files and pass them to Blender as a command line argument. Before we do tho, there’s one last step: we have to re-save the start-up scene to be a blank slate, otherwise our animations will all have a cube sitting in the middle of the scene (Blender’s default start up scene).

So open blender, and hit Select -> (De)select All, then Object → Delete, confirm. (or just ‘a’, ‘x’, ‘Enter’ if you want to use keyboard shortcuts). Next click File → Save Startup File. We’re finally ready to generate some animations with python!

Save the following code as helloworld.py, navigate to the folder you saved it in terminal, and type:

blender -b -P helloworld.py

And you should see Blender printing out a load of information about what’s happening, then it should create an fbx file and exit.

To make it easy to deploy these to Hololens, I just drop them in the onedrive belonging to the account I created with the hololens. There’s a python API for uploading direct to onedrive, too, so I’ll probably explore that in the future.

Optional: import interesting python modules like numpy and pandas and all the rest.

Blender comes packaged with its own python executable hooked into all of Blender’s guts, so to install any modules that aren’t built-in to Python3 we need to run get-pip.py with Blender’s python. First, download get-pip.py, I’ll put in in my desktop. Then, navigate to blender’s python executable.

command on windows:

cd "C:Program FilesBlender FoundationBlender2.78pythonbin"

command on MacOS (assuming Blender was moved to Applications):

cd /Applications/blender.app/Contents/Resources/2.78/python/bin

(Note that 2.78 is the blender version, not the python version) Run ‘ls’ and take note of the python exectuable’s name. On windows it was just python.exe, on mac it was python3.5m. Once you’ve cd’d into python/bin:

Install Pip on MacOS:

./python3.5m ~/Desktop/get-pip.py

For Windows I had to include to the full path of get-pip.py. Also this requires administrator privileges. So run powershell “As Administrator”

./python "C:UsersColten JacksonDesktopget-pip.py"

If that exits successfully, you can run ‘pip install pandas’ and whatever python modules you want to use from within Blender. On Mac, pip added itself to my path and I could use it right away, but on Windows I had to reference the pip.exe to run it from the python directory, so it ends up looking like this (again as Admin so pip can save files to disk, your permissions may vary)

Let me know what questions you have, tho of course I would appreciate it if you googled it first !

Here’s the situation I found myself in: Annalect Labs acquired a Hololens for purposes of producing holographic data visualizations and here I am, a lowly javascript developer wishing he could just make holograms with CSS!

Reviewing the options for game development with Unity and Visual Studio was intimidating to say the least. It looked like I would need to learn C# while adjusting to the Unity → export to Visual Studio → compile to Hololens toolchain. Worse, while I could follow along the Unity introduction to make a ball roll around a plane, I wasn’t able to export this basic demo to Hololens after hours of re-installing various versions of software.

I started wondering if Blender might let me produce animations for hololens, knowing that it allows for python scripting, which might allow my pythonic-data-scientist-coworkers to jump into producing holograms much faster than writing our own video game without any game engine experience.

Now, there are many guides on how to design things in Blender, import the meshes and actions into Unity, which can then export the project to Visual Studio for compilation. I hate the idea of dealing with that toolchain, dealing with incompatibility and export quirks each step of the way. I want to write a python script that produces an animation for Hololens.

With a little googling, I discovered that Hololens can indeed display animations in the FBX file format which Blender is happy to export, so I started playing around with the following code to make some cubes dance around:

How about something a little more interesting: arranging a subset of the collection in a line. From here I hope you can use some imagination on how you could tie this in with data retrieval and visualization.

For Annalect Lab’s minimum viable hologram, we’re interested in visualizations of populations, and talking about subsets. So I’ll adjust the previous code to use meshes representing people. There’s a million ways to make meshes, but there’s a tool perfectly suited for my task:

I won’t say much about MakeHuman cause I think it’s pretty intuitive. You can customize everything about your character and use some pre-loaded outfits and poses, and then export the mesh as a .obj. To make it easy on myself I saved these obj files (man.obj, woman.obj) in the same directory I’ll output my animations. Now, these objs are made up of multiple meshes, and are fairly high resolution so there’s a lot of code to work through modifying them and reducing the poly-count to get to an acceptable file size for the default FBX file viewer on hololens, but the result is a lot of fun:

The main flow of the program is like this:

Import an object, which will select all 4 meshes of that object and join them.

Decimate the mesh so it isn’t so high resolution.

Create copies of each mesh.

Create an array of x,y coordinates along a normal distribution.

Loop through an array of all the objects and set their location to the next random coordinate.

Select the first 5 objects in the shuffled array and set their keyframes to animate them as they move into a line elevated from the group.

Do the same with the next 5 objects, but to the other side of the plane.

This is my first few days using the python API to blender, so there’s surely a better way to make all the selections and de-selections, and if you know how please let me in on it! In any case, I hope this gives you a glimpse over the kind of scripted animations Blender can help you with, and there’s a million other things in the docs I haven’t touched yet. In the future I’ll have some examples of how to hook these animations up to pandas dataframes for dealing with data retrieved from SQL queries 😀