Interactive 3D content in LaTeX

Movie15 Package

The movie15 package can be used to include interactive 3D content (in U3D format) within a LaTeX document. When opening the resulting PDF with Adobe Acrobat, the content can be visualized interactively.

Code snippet to include example.u3d

\usepackage[3D]{movie15}
...
\includemovie[
poster,
toolbar,
label=example.u3d,
text=(example.u3d),
3Daac=60.000000, 3Droll=0.000000,
3Dc2c=0.613500 -7.545900 0.855200,
3Droo=7.618947,
3Dcoo=0.613470 0.649878 -0.855214,
3Dlights=CAD,
]
{\linewidth}
{\linewidth}
{example.u3d}

Conversion of X3D to U3D

The free software MeshLab can import X3D and export U3D file formats.

X3D example: Elastic modulus cube

To visualize the directional elastic modulus of cubic crystals based on the C11, C12, and C44 values of the elastic stiffness tensor, use below script

#!/usr/bin/env python
'''Create a unitsphere recursively by subdividing all triangles in an octahedron recursively.

A unitsphere has a radius of 1, which also means that all points in this sphere
have an absolute value of 1.
Another feature of an unitsphere is that the normals of this sphere are exactly the same as the vertices.

This recursive method will avoid the common problem of the polar singularity,
produced by 2D parameterization methods.

If you wish a sphere with a radius other than 1, simply multiply every single
value in the vertex array with this new radius
(although this will break the "vertex array equal to normal array" property)
'''

import sys,numpy as np

octahedron_vertices = np.array( [
  [ 1.0, 0.0, 0.0], # 0
  [-1.0, 0.0, 0.0], # 1
  [ 0.0, 1.0, 0.0], # 2
  [ 0.0,-1.0, 0.0], # 3
  [ 0.0, 0.0, 1.0], # 4
  [ 0.0, 0.0,-1.0]  # 5
  ] )
octahedron_triangles = np.array( [
  [ 0, 2, 4 ],
  [ 2, 1, 4 ],
  [ 1, 3, 4 ],
  [ 3, 0, 4 ],
  [ 0, 5, 2 ],
  [ 2, 5, 1 ],
  [ 1, 5, 3 ],
  [ 3, 5, 0 ],
  ] )

def E_hkl(stiffness,arr): # stiffness = (c11,c12,c44)
  S11 = (stiffness[0]+stiffness[1])/(stiffness[0]*stiffness[0]+stiffness[0]*stiffness[1]-2.0*stiffness[1]*stiffness[1])
  S12 = ( -stiffness[1])/(stiffness[0]*stiffness[0]+stiffness[0]*stiffness[1]-2.0*stiffness[1]*stiffness[1])
  S44 = 1.0/stiffness[2]

  invE = S11-(S11-S12-0.5*S44)* (1.0 - \
  (arr[:,0]**4+arr[:,1]**4+arr[:,2]**4) \
  /#------------------------------------------------
  (arr[:,0]**2+arr[:,1]**2+arr[:,2]**2)**2)

  arr[:,0] /= invE
  arr[:,1] /= invE
  arr[:,2] /= invE
  return arr

 

def normalize_v3(arr):
  ''' Normalize a np array of 3 component vectors shape=(n,3) '''
  lens = np.sqrt( arr[:,0]**2 + arr[:,1]**2 + arr[:,2]**2 )
  arr[:,0] /= lens
  arr[:,1] /= lens
  arr[:,2] /= lens
  return arr

def divide_all( vertices, triangles, stiffness=[1,0.5,0.25] ):
  #new_triangles = []
  new_triangle_count = len( triangles ) * 4
  # Subdivide each triangle in the old approximation and normalize
  # the new points thus generated to lie on the surface
  # of the unit sphere.
  # Each input triangle with vertices labeled [0,1,2] as shown
  # below will be turned into four new triangles:
  #
  # Make new points
  # a = (0+1)/2
  # b = (1+2)/2
  # c = (2+0)/2
  #       2
  #      /\ Normalize a, b, c
  #     /  \
  #   c/____\ b Construct new triangles
  #   /\    /\    t1 [0,a,c]
  #  /  \  /  \   t2 [c,b,2]
  # /____\/____\  t3 [a,1,b]
  # 0     a     1 t4 [a,b,c]
  v0 = vertices[ triangles[:,0] ] # all first points (N,3)
  v1 = vertices[ triangles[:,1] ] # all second points
  v2 = vertices[ triangles[:,2] ] # all third points
  a = ( v0+v1 ) * 0.5 # all points between first and second points
  b = ( v1+v2 ) * 0.5 # all points between second and third points
  c = ( v2+v0 ) * 0.5 # all points between third and first points
  normalize_v3( a ) # project onto unit sphere
  normalize_v3( b )
  normalize_v3( c )
  E_hkl( stiffness, a ) # E along a
  E_hkl( stiffness, b ) # E along b
  E_hkl( stiffness, c ) # E along c

  # Stack the triangles together.
  vertices = np.hstack( (v0,a,c, c,b,v2, a,v1,b, a,b,c,) ).reshape(-1,3)
  # Now our vertices are duplicated, and thus our triangle structure are unnecessary.
  return vertices, np.arange( len(vertices) ).reshape( (-1,3) )

def create_E_sphere( stiffness=[1,0.5,0.25], recursion_level=2 ):
  vertex_array, index_array = E_hkl( stiffness,octahedron_vertices), octahedron_triangles
  for i in range( recursion_level - 1 ):
    vertex_array, index_array = divide_all(vertex_array, index_array, stiffness)
  return vertex_array, index_array

def create_unit_sphere( recursion_level=2 ):
  vertex_array, index_array = octahedron_vertices, octahedron_triangles
  for i in range( recursion_level - 1 ):
    vertex_array, index_array = divide_all(vertex_array, index_array)
  return vertex_array, index_array

 

def vertex_array_only_unit_sphere( recursion_level=2 ):
  vertex_array, index_array = create_unit_sphere(recursion_level)
  if recursion_level > 1:
    return vertex_array.reshape( (-1) )
  else:
    return vertex_array[index_array].reshape( (-1) )

(vertices,indices) = create_E_sphere(map(float,sys.argv[2:5]),int(sys.argv[1]))

print '''<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE X3D PUBLIC "ISO//Web3D//DTD X3D 3.0//EN" "http://www.web3d.org/specifications/x3d-3.0.dtd">
<X3D version="3.0" profile="Immersive" xmlns:xsd="http://www.w3.org/2001/XMLSchema-instance" xsd:noNamespaceSchemaLocation="http://www.web3d.org/specifications/x3d-3.0.xsd">
<Scene>
<Viewpoint DEF="Camera" description="Camera" centerOfRotation="0 0 0" position="-20.62 19.76 58.47" orientation="-2.90 -3.99 -0.11 0.41" fieldOfView="0.2" />

<Shape>
<Appearance>
<Material DEF="MA_Material_001" diffuseColor="0.8 0.3 0.2" ambientIntensity="0.167" shininess="0.17" transparency="0.0" />
</Appearance>
'''

print '<IndexedFaceSet solid="true" creaseAngle="0.3" coordIndex="'
for v in indices:
print ' '.join(map(str,v))+' -1,'
print '">'
print '<Coordinate point="'
for v in vertices:
print ' '.join(map(str,v)) + ', '
print '"/>'
print '</IndexedFaceSet>'

print '''
</Shape>
</Scene>
</X3D>'''

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

w

Connecting to %s