Friday, April 3, 2015

Blender as Shader for Mathematica Output - Visualizing a Hertz Dipole and the Klein Bottle

Background

Since many year I am interested in computer graphics and the visualization of scientific matters. Especially for the scientific - exact - part, Mathematica is my favorite to do calculations and to visualize the results of these calculations. Here I do not want to advertise Mathematica, but I simply started using it as tool for my purposes and never had the nerves to dig into another tool like Matlab or Maple.
On the other - artistic - end of the visualization business, I am a big fan of Blender, a freeware 3D modeling, rendering and animation environment offering top notch functionality for all kinds of 3D computer graphics.

Goal

My idea was to bring these two favorite tools of mine together and to use Blender as post-processing tool to beautify Mathematica output.

Example: Visualization of the E-Field of a Hertz Dipole

One technique is the processing of mathematical data with rotational symmetry. Normally these kind of calculations are performed by calculating a section of the rotationally symmetric function in the x-y plane and to visualize the data of this section in graphs. Mathematica offers the possibility to export 2D-graphs as scalable vector graphics (SVG) which can be imported as (Bezier) curves into Blender and are the base for further processing.
One famous example of the visualization of mathematical/physical matters is the form of the electromagnetic fields generated by a Hertz' dipole. In the web there are several resources for Mathematica to base the graphical output on, e.g. http://demonstrations.wolfram.com/ReadingHertzsOwnDipoleTheory/
Important for our purposes is only the part, where the contour plot of the field strength is defined. This has to be used as base for the input into Blender. Code (roughly):
Param = <some number>
thePlot := ContourPlot[2D-parametric function(Param), arguments]
Export["theFile.svg",thePlot,"SVG"]
The contour graph looks something like this (dependent on the settings of Parameter "Param": ¨



This SVG-file with information about curves can be imported into Blender (make sure the corresponding SVG-import addon is active). We know that the electromagnetic field is rotationally symmetric around the axis of the dipole. So all one has to do is to turn the Bezier curves around a symmetry axis. This can be achieved either by the "Bevel" functionality applied to the un-converted Bezier curves, or to apply the "spin" modification on the Bezier curves converted to meshes.
After having created the "spinned" representation of the curves, one can - as usual - apply materials to the created 3D-objects and create a "beautyfied", artistic representation of the mathematically correct content. Here an example of my Hertz' dipole E-field lines:

Rendering Mathematics Graphics3D

Blender can as well be used to generate images of 3D-parametric functions (like the Klein bottle and alike). Mathematica offers the possibility to export 3D graphics in a couple of 3D-exchange formats (3DS, DXF, OBJ, PLY, STL, X3D) which can be imported into Blender directly as 3D-object and shaded to your needs.
As Example I created an image based on the Klein bottle definition available in Wikipedia. The corresponding Mathematica script looks like this:

thePlot =
 ParametricPlot3D[{-200000/15 Cos[
     u] (6 Cos[v] - 30 Sin[u] + 90 (Cos[u])^4 Sin[u] -
      60 (Cos[u])^6 Sin[u] + 5 Cos[u] Cos[v] Sin[u]), -100000/15 Sin[
     u] (6 Cos[v] - 3 (Cos[u])^2 Cos[v] - 48 (Cos[u])^4 Cos[v] +
      48 (Cos[u])^6 Cos[v] - 60 Sin[u] - 5 Cos[u] Cos[v] Sin[u] -
      10 (Cos[u])^3 Cos[v] Sin[u] - 80 (Cos[u])^5 Cos[v] Sin[u] +
      150 (Cos[u])^7 Cos[v] Sin[u]),
   300000/15 (3 + 5 Cos[u] Sin[u]) Sin[v]}, {u, -Pi, Pi}, {v, 0,
   2 Pi}, Axes -> None, Boxed -> False, PlotPoints -> 30, Mesh -> None
  ]

Export["KleinBottle.dxf", thePlot]
 Please note that the scaling factors in my function differ slightly from the original definition in Wikipedia. The result of my efforts look like this:


Klein bottle with glass shading (Cycles)


Klein bottle with glossy shading (Cycles)

The Journey to Beautiful 3D Graphics

At the first glance I thought, it would be no problem to get the Graphics3D output of Mathematica into Blender via some exchange format and create some nicely rendered image from it. But as it came out, it was very simple to exchange data between Mathematica and Blender (say via 3DS), but it was a mayor challenge to create beautiful/undistorted graphics from the Mathematica output.
Whereas Mathematica with its own shading engine is able to produce smooth graphics, it was very hard for me to transfer a mesh object from Mathematica into Blender which is reasonably smooth and undistorted. But one after another...
The Mathematica output of the script above looks like this:

As one can see, the surface is reasonably smooth. However, if you add the option NormalsFunction->None to the ParametricPlot3D the output looks like this:

...the surface is now distorted/jagged. Obviously Mathematica does not re-calculate the mesh data based on its own smooth shading algorithm but exports the raw data of the Graphics3D object.
I tried many things to export the ParatericPlot3D to some reasonable mesh object in all the available mesh formats (3DS, OBJ, PLY, X3D). All of these resulted in ugly surface meshes of the latter kind, none of these could really be used to produce some reasonable Blender output.
The only workaround I found was the following:
  1. Export the Graphics3D object from Mathematica to Autodesk DXF.  This will result in a spline hull object 
  2. Import the dxf-file to Autodesk 3D Studio Max. Here one can create a surface mesh with reasonable smoothness from the hull definition
  3. Export the mesh object from 3D Studio Max to some format of your choice (I used 3DS) and import into Blender
  4. Don't ask me why one should use Blender if you already have 3D Studio available ;)
If someone reads this blog and knows a better solution - in the best case how to play with the Mathematica options, I'd be happy if he/she shared this knowledge.

Klein Bottle Revised

The problems described above are not general ones but seem to depend on the actual shape. I tried the Klein botlle figure 8 immersion (See Wikipedia) in the follwoing script:
a = 1
thePlot =
 ParametricPlot3D[{Cos[u] (a + Cos[u/2] Sin[v] - Sin[u/2] Sin[2 v]),
   Sin[u] (a + Cos[u/2] Sin[v] - Sin[u/2] Sin[2 v]),
   Sin[u/2] Sin[v] + Cos[u/2] Sin[2 v]}, {u, -Pi, Pi}, {v, 0, 2 Pi},
  Axes -> None, Boxed -> False, PlotPoints -> 5, MaxRecursion -> 5,
  Mesh -> None, NormalsFunction -> None
  ]


Export["KleinBottle1.ply", thePlot]

Which leads to very reasonable output that can be imported to Blender directly. The result of rendering the above PLY-file looks like this:
which is satisfactory to my standards.

More post-processed Mathematica output can be seen in a series of follow up posts called "Math Gems".

I hope you liked my post, all the best & keep on geekin', your
WolfiG