In [ ]:
from pythreejs import *
import numpy as np
from IPython.display import display
try:
    from IPython.html.widgets import HTML, Text
    from traitlets import link, dlink
except ImportError:
    from IPython.html.widgets import HTML, Text
    from IPython.utils.traitlets import link, dlink

Simple sphere and text


In [ ]:
ball = Mesh(geometry=SphereGeometry(radius=1), material=LambertMaterial(color='red'), position=[2,1,0])
scene = Scene(children=[ball, AmbientLight(color=0x777777), make_text('Hello World!', height=.6)])
c = PerspectiveCamera(position=[0,5,5], up=[0,0,1], children=[DirectionalLight(color='white', 
                                                                             position=[3,5,1], 
                                                                             intensity=0.5)])
renderer = Renderer(camera=c, scene = scene, controls=[OrbitControls(controlling=c)])
display(renderer)

In [ ]:
ball.geometry.radius=0.5

In [ ]:
import time, math
ball.material.color = 0x4400dd
for i in range(1,150,2):
    ball.geometry.radius=i/100.
    ball.material.color +=0x000300
    ball.position = [math.cos(i/10.), math.sin(i/50.), i/100.]
    time.sleep(.05)

In [ ]:

Clickable Surface


In [ ]:
nx,ny=(20,20)
xmax=1
x = np.linspace(-xmax,xmax,nx)
y = np.linspace(-xmax,xmax,ny)
xx, yy = np.meshgrid(x,y)
z = xx**2-yy**2
#z[6,1] = float('nan')
surf_g = SurfaceGeometry(z=list(z[::-1].flat), 
                          width=2*xmax,
                          height=2*xmax,
                          width_segments=nx-1,
                          height_segments=ny-1)

surf = Mesh(geometry=surf_g, material=LambertMaterial(map=height_texture(z[::-1], 'YlGnBu_r')))
surfgrid = SurfaceGrid(geometry=surf_g, material=LineBasicMaterial(color='black'))
hover_point = Mesh(geometry=SphereGeometry(radius=0.05), material=LambertMaterial(color='hotpink'))
scene = Scene(children=[surf, surfgrid, hover_point, AmbientLight(color=0x777777)])
c = PerspectiveCamera(position=[0,3,3], up=[0,0,1], 
                      children=[DirectionalLight(color='white', position=[3,5,1], intensity=0.6)])
click_picker = Picker(root=surf, event='dblclick')
hover_picker = Picker(root=surf, event='mousemove')
renderer = Renderer(camera=c, scene = scene, controls=[OrbitControls(controlling=c), click_picker, hover_picker])

def f(name, value):
    print "Clicked on %s"%value
    point = Mesh(geometry=SphereGeometry(radius=0.05), 
                              material=LambertMaterial(color='red'),
                             position=value)
    scene.children = list(scene.children)+[point]
click_picker.on_trait_change(f, 'point')

link((hover_point, 'position'), (hover_picker, 'point'))

h = HTML()
def g(name, value):
    h.value="Green point at (%.3f, %.3f, %.3f)"%tuple(value)
g(None, hover_point.position)
hover_picker.on_trait_change(g, 'point')
display(h)
display(renderer)

In [ ]:
# when we change the z values of the geometry, we need to also change the height map
surf_g.z = list((-z[::-1]).flat)
surf.material.map = height_texture(-z[::-1])

Design our own texture


In [ ]:
import numpy as np
from scipy import ndimage
import matplotlib
import matplotlib.pyplot as plt
from skimage import img_as_ubyte 

jet = matplotlib.cm.get_cmap('jet')

np.random.seed(int(1)) # start random number generator
n = int(5) # starting points
size = int(32) # size of image
im = np.zeros((size,size)) # create zero image
points = size*np.random.random((2, n**2)) # locations of seed values
im[(points[0]).astype(np.int), (points[1]).astype(np.int)] = size # seed high values
im = ndimage.gaussian_filter(im, sigma=size/(float(4)*n)) # smooth high values into surrounding areas
im *= 1/np.max(im)# rescale to be in the range [0,1]
rgba_im = img_as_ubyte(jet(im)) # convert the values to rgba image using the jet colormap
rgba_list = list(rgba_im.flat) # make a flat list

t = DataTexture(data=rgba_list, format='RGBAFormat', width=size, height=size)

geometry = SphereGeometry()#TorusKnotGeometry(radius=2, radialSegments=200)
material = LambertMaterial(map=t)

myobject = Mesh(geometry=geometry, material=material)
c = PerspectiveCamera(position=[0,3,3], fov=40, children=[DirectionalLight(color=0xffffff, position=[3,5,1], intensity=0.5)])
scene = Scene(children=[myobject, AmbientLight(color=0x777777)])

renderer = Renderer(camera=c, scene = scene, controls=[OrbitControls(controlling=c)])
display(renderer)

Lines


In [ ]:
# On windows, linewidth of the material has no effect
size = 4
linesgeom = PlainGeometry(vertices=[[0,0,0],[size,0,0],[0,0,0],[0,size,0],[0,0,0],[0,0,size]],
                          colors = ['red', 'red', 'green', 'green', 'white', 'orange'])
lines = Line(geometry=linesgeom, 
             material=LineBasicMaterial( linewidth=5, vertexColors='VertexColors'), 
             type='LinePieces')
scene = Scene(children=[lines, DirectionalLight(color=0xccaabb, position=[0,10,0]),AmbientLight(color=0xcccccc)])
c = PerspectiveCamera(position=[0,10,10])
renderer = Renderer(camera=c, scene = scene, controls=[OrbitControls(controlling=c)])
display(renderer)

Camera


In [ ]:
geometry = SphereGeometry(radius=4)
t = ImageTexture(imageuri="")
material = LambertMaterial(color='white', map=t)

sphere = Mesh(geometry=geometry, material=material)

point = Mesh(geometry=SphereGeometry(radius=.1), 
                material=LambertMaterial(color='red'))


c = PerspectiveCamera(position=[0,10,10], fov=40, children=[DirectionalLight(color='white', 
                                                                             position=[3,5,1], 
                                                                             intensity=0.5)])

scene = Scene(children=[sphere, point, AmbientLight(color=0x777777)])
p=Picker(event='mousemove', root=sphere)
renderer = Renderer(camera=c, scene = scene, controls=[OrbitControls(controlling=c), p])
coords = Text()
display(coords)
display(renderer)

#dlink((p,'point'), (point, 'position'), (coords, 'value'))
#
#camera=WebCamera()
#display(camera)
#display(Link(widgets=[[camera, 'imageurl'], [t, 'imageuri']]))

Parametric Functions

To use the ParametricGeometry class, you need to specify a javascript function as a string. The function should take two parameters that vary between 0 and 1, and return a new THREE.Vector3(x,y,z).

If you want to build the surface in Python, you'll need to explicitly construct the vertices and faces and build a basic geometry from the vertices and faces.


In [ ]:
f = """
function f(origu,origv) {
    // scale u and v to the ranges I want: [0, 2*pi]
    var u = 2*Math.PI*origu;
    var v = 2*Math.PI*origv;
    
    var x = Math.sin(u);
    var y = Math.cos(v);
    var z = Math.cos(u+v);
    
    return new THREE.Vector3(x,y,z)
}
"""
surf_g = ParametricGeometry(func=f);

surf = Mesh(geometry=surf_g,material=LambertMaterial(color='green', side ='FrontSide'))
surf2 = Mesh(geometry=surf_g,material=LambertMaterial(color='yellow', side ='BackSide'))
scene = Scene(children=[surf, surf2, AmbientLight(color=0x777777)])
c = PerspectiveCamera(position=[5,5,3], up=[0,0,1],children=[DirectionalLight(color='white', position=[3,5,1], intensity=0.6)])
renderer = Renderer(camera=c,scene = scene,controls=[OrbitControls(controlling=c)])
display(renderer)

In [ ]:


In [ ]:


In [ ]:

Examples to do

  • image texture (with webcam picture!)
  • set background color
  • animate something through space
  • scaled object: point that doesn't change size
  • vertex shade
  • parametric geometry
  • switch between phong, lambert, depth, and wireframe materials, normalmaterial

In [ ]: