예제 #1
0
def convexhull(ch3d):
    poly = tvtk.PolyData()
    poly.points = ch3d.points
    poly.polys = ch3d.simplices
    sphere = tvtk.SphereSource(radius=0.02)
    points3d = tvtk.Glyph3D()
    points3d.set_source_connection(sphere.output_port)
    points3d.set_input_data(poly)
    # 绘制凸多面体的面,设置半透明度
    m1 = tvtk.PolyDataMapper()
    m1.set_input_data(poly)
    a1 = tvtk.Actor(mapper=m1)
    a1.property.opacity = 0.3
    # 绘制凸多面体的边,设置为红色
    m2 = tvtk.PolyDataMapper()
    m2.set_input_data(poly)
    a2 = tvtk.Actor(mapper=m2)
    a2.property.representation = "wireframe"
    a2.property.line_width = 2.0
    a2.property.color = (1.0, 0, 0)
    # 绘制凸多面体的顶点,设置为绿色
    m3 = tvtk.PolyDataMapper(input_connection=points3d.output_port)
    a3 = tvtk.Actor(mapper=m3)
    a3.property.color = (0.0, 1.0, 0.0)
    return [a1, a2, a3]
예제 #2
0
def vtk_convexhull(ch, radius=0.02):
    from tvtk.api import tvtk

    poly = tvtk.PolyData()
    poly.points = ch.points
    poly.polys = ch.simplices

    sphere = tvtk.SphereSource(radius=radius)
    points3d = tvtk.Glyph3D()
    points3d.set_source_connection(sphere.output_port)
    points3d.set_input_data(poly)

    m1 = tvtk.PolyDataMapper()
    m1.set_input_data(poly)
    a1 = tvtk.Actor(mapper=m1)
    a1.property.opacity = 0.3

    m2 = tvtk.PolyDataMapper()
    m2.set_input_data(poly)
    a2 = tvtk.Actor(mapper=m2)
    a2.property.representation = "wireframe"
    a2.property.line_width = 2.0
    a2.property.color = (1.0, 0, 0)

    m3 = tvtk.PolyDataMapper(input_connection=points3d.output_port)
    a3 = tvtk.Actor(mapper=m3)
    a3.property.color = (0.0, 1.0, 0.0)
    return [a1, a2, a3]
def get_sphere(p, radius, res=8):
  if type(p) != tuple:
    p = tuple(p)
  src = tvtk.SphereSource(center=p, radius=radius, phi_resolution=res, theta_resolution=res)
  mapper = tvtk.PolyDataMapper(input=src.output)
  actor = tvtk.Actor(mapper=mapper)
  fig.scene.add_actor(actor)
  return actor
예제 #4
0
 def _glyph_dict_default(self):
     g = {'glyph_source2d': tvtk.GlyphSource2D(glyph_type='arrow', filled=False),
          'arrow_source': tvtk.ArrowSource(),
          'cone_source': tvtk.ConeSource(height=1.0, radius=0.2, resolution=15),
          'cylinder_source': tvtk.CylinderSource(height=1.0, radius=0.15,
                                                 resolution=10),
          'sphere_source': tvtk.SphereSource(),
          'cube_source': tvtk.CubeSource(),
          'axes': tvtk.Axes(symmetric=1)}
     return g
예제 #5
0
 def _drawRealGloms(self):
     ls = []
     for pos in glomRealCoords:
         src = tvtk.SphereSource(center=tuple(pos),
                                 radius=params.GLOM_RADIUS)
         mapper = tvtk.PolyDataMapper(input=src.output)
         actor = tvtk.Actor(mapper=mapper)
         actor.property.color = (1., 0., 0.)
         actor.property.opacity = 0
         self.fig.scene.add_actor(actor)
         ls.append(actor)
     return ls
예제 #6
0
파일: actors.py 프로젝트: victorliun/mayavi
def sphere_actor(center=(0, 0, 0),
                 radius=0.5,
                 resolution=32,
                 color=colors.purple,
                 opacity=1.0):
    """ Creates a sphere and returns the actor. """
    source = tvtk.SphereSource(center=center,
                               radius=radius,
                               theta_resolution=resolution,
                               phi_resolution=resolution)
    mapper = tvtk.PolyDataMapper(input=source.output)
    prop = tvtk.Property(opacity=opacity, color=color)
    actor = tvtk.Actor(mapper=mapper, property=prop)
    return actor
예제 #7
0
 def _update_marker_type(self):
     # not implemented for arrow
     if self.glyph is None or self._view == 'arrow':
         return
     defaults = DEFAULTS['coreg']
     gs = self.glyph.glyph.glyph_source
     res = getattr(gs.glyph_source, 'theta_resolution',
                   getattr(gs.glyph_source, 'resolution', None))
     if self.project_to_surface or self.orient_to_surface:
         gs.glyph_source = tvtk.CylinderSource()
         gs.glyph_source.height = defaults['eegp_height']
         gs.glyph_source.center = (0., -defaults['eegp_height'], 0)
         gs.glyph_source.resolution = res
     else:
         gs.glyph_source = tvtk.SphereSource()
         gs.glyph_source.phi_resolution = res
         gs.glyph_source.theta_resolution = res
예제 #8
0
 def _update_project_to_surface(self):
     if not self.glyph:
         return
     defaults = DEFAULTS['coreg']
     gs = self.glyph.glyph.glyph_source
     res = getattr(gs.glyph_source, 'theta_resolution',
                   getattr(gs.glyph_source, 'resolution', None))
     if self.project_to_surface:
         gs.glyph_source = tvtk.CylinderSource()
         gs.glyph_source.height = defaults['eegp_height']
         gs.glyph_source.center = (0., -defaults['eegp_height'], 0)
         gs.glyph_source.resolution = res
     else:
         gs.glyph_source = tvtk.SphereSource()
         gs.glyph_source.phi_resolution = res
         gs.glyph_source.theta_resolution = res
     self.glyph.glyph.scale_mode = 'data_scaling_off'
예제 #9
0
 def __set_pure_state__(self, state):
     self._unpickling = True
     # First create all the allowed widgets in the widget_list attr.
     handle_children_state(self.widget_list, state.widget_list)
     # Now set their state.
     set_state(self, state, first=['widget_list'], ignore=['*'])
     # Set the widget attr depending on value saved.
     m = [x.__class__.__name__ for x in self.widget_list]
     w_c_name = state.widget.__metadata__['class_name']
     w = self.widget = self.widget_list[m.index(w_c_name)]
     # Set the input.
     if len(self.inputs) > 0:
         self.configure_input(w, self.inputs[0].outputs[0])
     # Fix for the point widget.
     if w_c_name == 'PointWidget':
         w.place_widget()
     # Set state of rest of the attributes ignoring the widget_list.
     set_state(self, state, ignore=['widget_list'])
     # Some widgets need some cajoling to get their setup right.
     w.update_traits()
     if w_c_name == 'PlaneWidget':
         w.origin = state.widget.origin
         w.normal = state.widget.normal
         w.center = state.widget.center
         w.update_placement()
         w.get_poly_data(self.poly_data)
     elif w_c_name == 'SphereWidget':
         # XXX: This hack is necessary because the sphere widget
         # does not update its poly data even when its ivars are
         # set (plus it does not have an update_placement method
         # which is a bug).  So we force this by creating a similar
         # sphere source and copy its output.
         s = tvtk.SphereSource(center=w.center,
                               radius=w.radius,
                               theta_resolution=w.theta_resolution,
                               phi_resolution=w.phi_resolution,
                               lat_long_tessellation=True)
         s.update()
         self.poly_data.shallow_copy(s.output)
     else:
         w.get_poly_data(self.poly_data)
     self._unpickling = False
     # Set the widgets trait so that the widget is rendered if needed.
     self.widgets = [w]
예제 #10
0
    def plot_atoms_3d(self, fig, a, x, y, z):
        #
        #       !!! works on our molecules only !!!
        #       todo: use some python libraries to draw any molecule

        #       always in order: X, H, H, H, H, O
        sphere_radius = [0.3, 0.1, 0.1, 0.1, 0.1, 0.2]
        sphere_color = [(0.0, 0.5, 0.5), (0.1, 0.1, 0.1), (0.1, 0.1, 0.1),
                        (0.1, 0.1, 0.1), (0.1, 0.1, 0.1), (1.0, 0.0, 0.0)]

        #       draw atoms
        #       ----------
        atom = []
        for i in range(len(x)):
            sphere = tvtk.SphereSource(center=(x[i], y[i], z[i]),
                                       radius=sphere_radius[i],
                                       theta_resolution=80,
                                       phi_resolution=80)
            sphere_mapper = tvtk.PolyDataMapper()
            configure_input_data(sphere_mapper, sphere.output)
            sphere.update()
            p = tvtk.Property(opacity=0.8, color=sphere_color[i])
            sphere_actor = tvtk.Actor(mapper=sphere_mapper, property=p)
            fig.scene.add_actor(sphere_actor)
            atom.append(sphere_actor)

#       draw bonds
#       ----------
#       always in order: X, H, H, H, H, O
        pairs = [[0, 1], [0, 2], [5, 3], [5, 4]]
        bond = []
        for i in range(len(pairs)):
            p1 = (x[pairs[i][0]], y[pairs[i][0]], z[pairs[i][0]])
            p2 = (x[pairs[i][1]], y[pairs[i][1]], z[pairs[i][1]])
            line = tvtk.LineSource(point1=p1, point2=p2)
            line_mapper = tvtk.PolyDataMapper()
            configure_input_data(line_mapper, line.output)
            line.update()
            tvtk.Property(opacity=0.8)
            line_actor = tvtk.Actor(mapper=line_mapper)
            line_actor.property.line_width = 1.9
            line_actor.property.color = (0.4, 0.4, 0.4)
            fig.scene.add_actor(line_actor)
            bond.append(line_actor)
예제 #11
0
 def __source_dict_default(self):
     """Default value for source dict."""
     sd = {
         'arrow': tvtk.ArrowSource(),
         'cone': tvtk.ConeSource(),
         'cube': tvtk.CubeSource(),
         'cylinder': tvtk.CylinderSource(),
         'disk': tvtk.DiskSource(),
         'earth': tvtk.EarthSource(),
         'line': tvtk.LineSource(),
         'outline': tvtk.OutlineSource(),
         'plane': tvtk.PlaneSource(),
         'point': tvtk.PointSource(),
         'polygon': tvtk.RegularPolygonSource(),
         'sphere': tvtk.SphereSource(),
         'superquadric': tvtk.SuperquadricSource(),
         'textured sphere': tvtk.TexturedSphereSource(),
         'glyph2d': tvtk.GlyphSource2D()
     }
     return sd
예제 #12
0
 def _update_markers(self):
     if self.glyph is None:
         return
     defaults = DEFAULTS['coreg']
     gs = self.glyph.glyph.glyph_source
     res = getattr(gs.glyph_source, 'theta_resolution',
                   getattr(gs.glyph_source, 'resolution', None))
     if self.project_to_surface or self.orient_to_surface:
         gs.glyph_source = tvtk.CylinderSource()
         gs.glyph_source.height = defaults['eegp_height']
         gs.glyph_source.center = (0., -defaults['eegp_height'], 0)
         gs.glyph_source.resolution = res
     else:
         gs.glyph_source = tvtk.SphereSource()
         gs.glyph_source.phi_resolution = res
         gs.glyph_source.theta_resolution = res
     if self.scale_by_distance:
         self.glyph.glyph.scale_mode = 'scale_by_vector'
     else:
         self.glyph.glyph.scale_mode = 'data_scaling_off'
예제 #13
0
mask = tvtk.MaskPoints(random_mode=True, on_ratio=50)
mask.set_input_data(grid)

arrow_source = tvtk.ArrowSource()
arrows = tvtk.Glyph3D(input_connection=mask.output_port,
                      scale_factor=2 /
                      np.max(grid.point_data.scalars.to_array()))
arrows.set_source_connection(arrow_source.output_port)

arrows_mapper = tvtk.PolyDataMapper(scalar_range=grid.point_data.scalars.range,
                                    input_connection=arrows.output_port)
arrows_actor = tvtk.Actor(mapper=arrows_mapper)

center = grid.center
sphere = tvtk.SphereSource(center=(2, center[1], center[2]),
                           radius=2,
                           phi_resolution=6,
                           theta_resolution=6)
sphere_mapper = tvtk.PolyDataMapper(input_connection=sphere.output_port)

sphere_actor = tvtk.Actor(mapper=sphere_mapper)
sphere_actor.property.set(representation="wireframe", color=(0, 0, 0))

streamer = tvtk.StreamLine(step_length=0.0001,
                           integration_direction="forward",
                           integrator=tvtk.RungeKutta4())
streamer.set_input_data(grid)
streamer.set_source_connection(sphere.output_port)

tube = tvtk.TubeFilter(input_connection=streamer.output_port,
                       radius=0.05,
                       number_of_sides=6,
예제 #14
0
# Author: Gael Varoquaux <*****@*****.**>
# Copyright (c) 2008, Enthought, Inc.
# License: BSD Style.

from mayavi import mlab

# To access any VTK object, we use 'tvtk', which is a Python wrapping of
# VTK replacing C++ setters and getters by Python properties and
# converting numpy arrays to VTK arrays when setting data.
from tvtk.api import tvtk

v = mlab.figure()

# Create a first sphere
# The source generates data points
sphere = tvtk.SphereSource(center=(0, 0, 0), radius=0.5)
# The mapper converts them into position in, 3D with optionally color (if
# scalar information is available).
sphere_mapper = tvtk.PolyDataMapper(input=sphere.output)
# The Property will give the parameters of the material.
p = tvtk.Property(opacity=0.2, color=(1, 0, 0))
# The actor is the actually object in the scene.
sphere_actor = tvtk.Actor(mapper=sphere_mapper, property=p)
v.scene.add_actor(sphere_actor)

# Create a second sphere
sphere2 = tvtk.SphereSource(center=(7, 0, 1), radius=0.2)
sphere_mapper2 = tvtk.PolyDataMapper(input=sphere2.output)
p = tvtk.Property(opacity=0.3, color=(1, 0, 0))
sphere_actor2 = tvtk.Actor(mapper=sphere_mapper2, property=p)
v.scene.add_actor(sphere_actor2)
예제 #15
0

    #print 'Line'
    #line()

    print('Quads')
    quad = show_quads(xyzs, uvws, 1)

    print('Quiver') 
    quiv = quiver(xyzs, uvws)
    show_window()
    remove_actor(cyl)
    remove_actor(quad)
    remove_actor(quiv)

    #clear_window()

    print('Displaying image')
    im = np.random.randint(0, 255, (50, 100, 3))
    im = np.uint8(im)
    im_act = show_img(im)
    show_window()

    remove_actor(im_act)

    print('Colors')
    polydata = tvtk.SphereSource().output
    visualise(polydata, color_by_normals=False, renderer=renderer)

    show_window()
예제 #16
0
def sphericalJoint(joint):
    """
  Return a shpere and the appropriate static transform.
  """
    s = tvtk.SphereSource(radius=0.02)
    return makeActor(s, (1., 1., 1.)), sva.PTransformd.Identity()
예제 #17
0
def maven_orbit_image(time,
                      camera_pos=[1, 0, 0],
                      camera_up=[0, 0, 1],
                      extent=3,

                      parallel_projection=True,

                      view_from_orbit_normal=False,
                      view_from_periapsis=False,

                      show_maven=False,
                      show_orbit=True,
                      label_poles=None,

                      show=True,
                      transparent_background=False,
                      background_color=(0, 0, 0)):
    """Creates an image of Mars and the MAVEN orbit at a specified time.

    Parameters
    ----------
    time : str
        Time to diplay, in a string format interpretable by spiceypy.str2et.

    camera_pos : length 3 iterable
        Position of camera in MSO coordinates.
    camera_up : length 3 iterable
        Vector defining the image vertical.
    extent : float
        Half-width of image in Mars radii.

    parallel_projection : bool
        Whether to display an isomorphic image from the camera
        position. If False, goofy things happen. Defaults to True.

    view_from_orbit_normal : bool
        Override camera_pos with a camera position along MAVEN's orbit
        normal. Defaults to False.
    view_from_periapsis : bool
        Override camera_pos with a camera position directly above
        MAVEN's periapsis. Defaults to False.

    show_maven : bool
        Whether to draw a circle showing the position of MAVEN at the
        specified time. Defaults to False.
    show_orbit : bool
        Whether to draw the MAVEN orbit. Defaults to True.
    label_poles : bool
        Whether to draw an 'N' and 'S' above the visible poles of Mars.

    show : bool
        Whether to show the image when called, or supress
        display. Defaults to True.
    transparent_background : bool
        If True, the image background is transparent, otherwise it is
        set to background_color. Defaults to False.
    background_color : RGB1 tuple
        Background color to use if transparent_background=False.
        Specified as an RGB tuple with values between 0 and 1.

    Returns
    -------
    rgb_array : 1000x1000x3 numpy array of image RGB values
        Image RGB values.
    return_coords : dict
        Description of the image coordinate system useful for plotting
        on top of output image.

    Notes
    -----
    Call maven_iuvs.load_iuvs_spice() before calling this function to
    ensure kernels are loaded.

    """
    myet = spice.str2et(time)

    # disable mlab display (this is done by matplotlib later)
    mlab.options.offscreen = True

    # create a figure window (and scene)
    mlab_pix = 1000
    mfig = mlab.figure(size=(mlab_pix, mlab_pix),
                       bgcolor=background_color)

    # disable rendering as objects are added
    mfig.scene.disable_render = True

    #
    # Set up the planet surface
    #

    # load and map the Mars surface texture
    image_file = os.path.join(anc_dir, 'marssurface_2.jpg')
    img = tvtk.JPEGReader()
    img.file_name = image_file
    texture = tvtk.Texture(input_connection=img.output_port, interpolate=1)

    # attach the texture to a sphere
    mars_radius = 3395.
    sphere_radius = 1  # radius of planet is 1 rM
    sphere_resolution = 180  # 180 points on the sphere
    sphere = tvtk.TexturedSphereSource(radius=sphere_radius,
                                       theta_resolution=sphere_resolution,
                                       phi_resolution=sphere_resolution)
    sphere_mapper = tvtk.PolyDataMapper(input_connection=sphere.output_port)
    mars = tvtk.Actor(mapper=sphere_mapper, texture=texture)

    # adjust the reflection properties for a pretty image
    mars.property.ambient = 0.2  # so the nightside is slightly visible
    mars.property.specular = 0.15  # make it shinier near dayside

    # now apply the rotation matrix to the planet

    # tvtk only thinks about rotations with Euler angles, so we need
    # to use a SPICE routine to get these from the rotation matrix

    # to get from the surface to MSO coordinates we'd normally do
    # this:
    rmat = spice.pxform('IAU_MARS', 'MAVEN_MSO', myet)

    # but we need to use transpose because spice.m2eul assumes the matrix
    # defines a coordinate system rotation, the inverse of the matrix
    # to rotate vectors
    trmat = spice.pxform('MAVEN_MSO', 'IAU_MARS', myet)

    # now we can get the Euler angles
    rangles = np.rad2deg(spice.m2eul(trmat, 2, 1, 3))
    #                                      ^^^^^^^^
    #                                      2,1,3 because vtk performs
    #                                      rotations in the order
    #                                      z,x,y and SPICE wants these
    #                                      in REVERSE order

    mars.orientation = rangles[[1, 0, 2]]
    #                           ^^^^^^^
    #                           orientation must be specified as x,y,z
    #                           rotations in that order even though they
    #                           are applied in the order above

    # OK, that was hard, but now we're good!

    mfig.scene.add_actor(mars)

    #
    # make a lat/lon grid
    #

    line_x = []
    line_y = []
    line_z = []
    line_o = []

    line_t = np.linspace(0, 2*np.pi, 100)
    line_r = 1.0

    longrid = np.arange(0, 360, 30)
    for lon in longrid:
        line_x.append(line_r*np.cos(np.deg2rad(lon))*np.cos(line_t))
        line_x.append([0])
        line_y.append(line_r*np.sin(np.deg2rad(lon))*np.cos(line_t))
        line_y.append([0])
        line_z.append(line_r*np.sin(line_t))
        line_z.append([0])
        line_o.append(np.ones_like(line_t))
        line_o.append([0])

    latgrid = np.arange(-90, 90, 30)[1:]
    for lat in latgrid:
        line_x.append(line_r*np.cos(np.deg2rad(lat))*np.cos(line_t))
        line_x.append([0])
        line_y.append(line_r*np.cos(np.deg2rad(lat))*np.sin(line_t))
        line_y.append([0])
        line_z.append(line_r*np.sin(np.deg2rad(lat))*np.ones_like(line_t))
        line_z.append([0])
        line_o.append(np.ones_like(line_t))
        line_o.append([0])

    line_x = np.concatenate(line_x)
    line_y = np.concatenate(line_y)
    line_z = np.concatenate(line_z)
    line_o = np.concatenate(line_o)

    linearray = [np.matmul(rmat, [x, y, z]) for x, y, z in zip(line_x,
                                                               line_y,
                                                               line_z)]
    (line_x, line_y, line_z) = np.transpose(np.array(linearray))

    grid_linewidth = 0.25*mlab_pix/1000
    mlab.plot3d(line_x, line_y, line_z, line_o,
                transparent=True,
                color=(0, 0, 0),
                tube_radius=None,
                line_width=grid_linewidth)

    #
    # compute the spacecraft orbit
    #

    # for the given time, we determine the orbit period
    maven_state = spice.spkezr('MAVEN', myet,
                               'MAVEN_MME_2000', 'NONE', 'MARS')[0]
    marsmu = spice.bodvrd('MARS', 'GM', 1)[1][0]
    maven_elements = spice.oscltx(maven_state, myet, marsmu)
    orbit_period = 1.001*maven_elements[-1]

    # make an etlist corresponding to the half-orbit ahead and behind
    orbit_subdivisions = 2000
    etlist = (myet
              - orbit_period/2
              + orbit_period*np.linspace(0, 1,
                                         num=orbit_subdivisions))

    # get the position of the orbit in MSO
    statelist = spice.spkezr('MAVEN', etlist,
                             'MAVEN_MSO', 'NONE', 'MARS')[0]
    statelist = np.append(statelist, [statelist[0]], axis=0)  # close the orbit
    poslist = np.transpose(statelist)[:3]/mars_radius  # scale to Mars radius

    # plot the orbit
    orbitcolor = np.array([222, 45, 38])/255  # a nice red
    orbitcolor = tuple(orbitcolor)
    maven_x, maven_y, maven_z = poslist
    if show_orbit:
        mlab.plot3d(maven_x, maven_y, maven_z,
                    color=orbitcolor,
                    tube_radius=None,
                    line_width=3*mlab_pix/1000)

    if not parallel_projection:
        # add a dot indicating the location of the Sun
        # this only makes sense with a perspective transform... with
        # orthographic coordinates we're always too far away
        # TODO: non parallel projection results in goofy images
        sun_distance = 10
        sun_sphere = tvtk.SphereSource(center=(sun_distance, 0, 0),
                                       radius=1*np.pi/180*sun_distance,
                                       theta_resolution=sphere_resolution,
                                       phi_resolution=sphere_resolution)
        sun_sphere_mapper = tvtk.PolyDataMapper(input_connection=sun_sphere.output_port)
        sun_sphere = tvtk.Actor(mapper=sun_sphere_mapper)
        sun_sphere.property.ambient = 1.0
        sun_sphere.property.lighting = False
        # mfig.scene.add_actor(sun_sphere)

        # put a line along the x-axis towards the sun
        # sunline_x=np.arange(0, 5000, 1)
        # mlab.plot3d(sunline_x, 0*sunline_x, 0*sunline_x,
        #             color=(1.0,1.0,1.0),
        #             tube_radius=None,line_width=6)

    #
    # Define camera coordinates
    #

    if view_from_periapsis:
        # to do this we need to get the position of apoapsis and the
        # orbit normal
        rlist = [np.linalg.norm(p) for p in np.transpose(poslist)]
        apoidx = np.argmax(rlist)
        apostate = spice.spkezr('MAVEN', etlist[apoidx],
                                'MAVEN_MSO', 'NONE', 'MARS')[0]
        camera_pos = -1.0 * apostate[:3]
        camera_pos = 5 * (camera_pos/np.linalg.norm(camera_pos))
        camera_up = np.cross(apostate[:3], apostate[-3:])
        camera_up = camera_up/np.linalg.norm(camera_up)
        parallel_projection = True

    if view_from_orbit_normal:
        # to do this we need to get the position of apoapsis and the
        # orbit normal
        rlist = [np.linalg.norm(p) for p in np.transpose(poslist)]
        apoidx = np.argmax(rlist)
        apostate = spice.spkezr('MAVEN', etlist[apoidx],
                                'MAVEN_MSO', 'NONE', 'MARS')[0]
        camera_up = apostate[:3]
        camera_up = camera_up/np.linalg.norm(camera_up)
        camera_pos = np.cross(apostate[:3], apostate[-3:])
        camera_pos = 5 * (camera_pos/np.linalg.norm(camera_pos))
        parallel_projection = True

    # construct an orthonormal coordinate system
    camera_pos = np.array(camera_pos)
    camera_pos_norm = camera_pos/np.linalg.norm(camera_pos)
    camera_up = (camera_up
                 - camera_pos_norm*np.dot(camera_pos_norm,
                                          camera_up))
    camera_up = camera_up/np.linalg.norm(camera_up)
    camera_right = np.cross(-camera_pos_norm, camera_up)

    # set location of camera and orthogonal projection
    camera = mlab.gcf().scene.camera
    if parallel_projection:
        camera_pos = 5*camera_pos_norm
        camera.parallel_projection = True
        camera.parallel_scale = extent  # half box size
    else:
        # TODO: this results in goofy images, fix this
        camera.parallel_projection = False
        camera.view_angle = 50
    camera.position = np.array(camera_pos)
    camera.focal_point = (0, 0, 0)
    camera.view_up = camera_up
    camera.clipping_range = (0.01, 5000)

    #
    # Set up lighting
    #

    # The only light is the Sun, which is fixed on the MSO +x axis.

    # VTK's default lights are uniform and don't fall off with
    # distance, which is what we want
    mfig.scene.light_manager.light_mode = "vtk"
    sun = mfig.scene.light_manager.lights[0]
    sun.activate = True
    sun_vec = (1, 0, 0)

    # The only way to set a light in mayavi/vtk is with respect to the
    # camera position. This means we have to get elevation/azimuth
    # coordinates for the Sun with respect to the camera, which could
    # be anywhere.

    # Here's how the coordinate system is defined:
    # elevation:
    #    [-90 -- +90]
    #    +90 places the light along the direction of camera_up
    # azimuth:
    #    [-180 -- +180],
    #    +90 is in the plane of camera_up and camera_right.
    #    +/-180 is behind, pointing at the camera
    #    -90 places light to the left

    # so, to get elevation we need to put the sun in scene coordinates
    sun_scene = np.matmul([camera_right, camera_up, camera_pos_norm],
                          sun_vec)

    # elevation is the angle is latitude measured wrt the y-axis of
    # the scene
    sun_elevation = np.rad2deg(np.arcsin(np.dot(sun_scene, [0, 1, 0])))
    # azimuth is the angle in the x-z plane, clockwise from the z-axis
    sun_azimuth = np.rad2deg(np.arctan2(sun_scene[0], sun_scene[2]))

    # now we can set the location of the light, computed to always lie
    # along MSO+x
    sun.azimuth = sun_azimuth
    sun.elevation = sun_elevation

    # set the brightness of the Sun based on the ambient lighting of
    # Mars so there is no washing out
    sun.intensity = 1.0 - mars.property.ambient

    #
    # Render the 3D scene
    #

    mfig.scene.disable_render = False
    # mfig.scene.anti_aliasing_frames = 0 # can uncomment to make
    #                                     # rendering faster and uglier
    mlab.show()

    mode = 'rgba' if transparent_background else 'rgb'
    img = mlab.screenshot(mode=mode, antialiased=True)
    mlab.close(all=True)  # 3D stuff ends here

    #
    # Draw text and labels in matplotlib
    #

    fig, ax = plt.subplots(1, 1,
                           dpi=400*mlab_pix/1000,
                           figsize=(2.5, 2.5))
    ax.imshow(img)

    # put an arrow along the orbit direction
    if show_orbit:
        arrow_width = 5
        arrow_length = 1.5*arrow_width
        # by default, draw the arrow at the closest point on the orbit
        # to the viewer
        arrowidx = np.argmax([np.dot(camera_pos_norm, p) for p in
                              np.transpose(poslist)])
        if view_from_periapsis:
            # draw the arrow 45 degrees after periapsis
            arrowidx = np.argmax(
                [np.dot(
                    (camera_right + camera_pos_norm)/np.sqrt(2),
                    p)
                 for p in np.transpose(poslist)])
        if view_from_orbit_normal:
            # draw the arrow 45 degrees after periapsis
            arrowidx = np.argmax(
                [np.dot(
                    (camera_right-camera_up)/np.sqrt(2.),
                    p)
                 for p in np.transpose(poslist)])

        arrowetlist = etlist[arrowidx] + 5*60*np.array([0, 1])
        arrowstatelist = spice.spkezr('MAVEN', arrowetlist,
                                      'MAVEN_MSO', 'NONE', 'MARS')[0]
        arrowdir = arrowstatelist[1][:3] - arrowstatelist[0][:3]
        arrowdirproj = [np.dot(camera_right, arrowdir),
                        np.dot(camera_up, arrowdir)]
        arrowdirproj = arrowdirproj/np.linalg.norm(arrowdirproj)

        arrowloc = np.transpose(poslist)[arrowidx]
        arrowlocproj = np.array([np.dot(camera_right, arrowloc),
                                 np.dot(camera_up, arrowloc)])
        arrowlocdisp = (arrowlocproj + extent)/extent/2
        arrow = ax.annotate('',
                            xytext=(arrowlocdisp - 0.05*arrowdirproj),
                            xy=(arrowlocdisp + 0.05*arrowdirproj),
                            xycoords='axes fraction',
                            textcoords='axes fraction',
                            arrowprops=dict(facecolor=orbitcolor,
                                            edgecolor='none',
                                            width=0,
                                            headwidth=arrow_width,
                                            headlength=arrow_length))

    # label the poles
    if view_from_periapsis:
        label_poles = True
    if view_from_orbit_normal:
        label_poles = True
    if label_poles is None:
        label_poles = False

    if label_poles:
        # label the north and south pole if they are visible
        def label_pole(loc, lbl):
            polepos = np.matmul(rmat, loc)
            poleposproj = np.array([np.dot(camera_right, polepos),
                                    np.dot(camera_up, polepos)])
            poleposdisp = (poleposproj+extent)/extent/2

            # determine if the north pole is visible
            polevis = (not (np.linalg.norm([poleposproj]) < 1
                            and np.dot(camera_pos, polepos) < 0))
            if polevis:
                polelabel = ax.text(*poleposdisp, lbl,
                                    transform=ax.transAxes,
                                    color='#888888',
                                    ha='center', va='center',
                                    size=4, zorder=1)
                # outline the letter
                polelabel.set_path_effects([
                    path_effects.withStroke(linewidth=0.75, foreground='k')])

        label_pole([0, 0,  1], 'N')
        label_pole([0, 0, -1], 'S')

    if show_orbit:
        # add a mark for periapsis and apoapsis

        rlist = [np.linalg.norm(p) for p in np.transpose(poslist)]

        # find periapsis/apoapsis
        def label_apsis(apsis_fn, label, **kwargs):
            apsisidx = apsis_fn(rlist)
            apsispos = np.transpose(poslist)[apsisidx]
            apsisposproj = np.array([np.dot(camera_right, apsispos),
                                     np.dot(camera_up, apsispos)])
            apsisposdisp = (apsisposproj + extent)/extent/2
            apsisvis = (not (np.linalg.norm([apsisposproj]) < 1
                             and np.dot(camera_pos, apsispos) < 0))

            if apsisvis:
                apsis = mpatches.CirclePolygon(apsisposdisp, 0.015,
                                               resolution=4,
                                               transform=ax.transAxes,
                                               fc=orbitcolor, lw=0, zorder=10)
                ax.add_patch(apsis)
                ax.text(*apsisposdisp, label,
                        transform=ax.transAxes,
                        color='k',
                        ha='center',
                        size=4, zorder=10,
                        **kwargs)

        label_apsis(np.argmin, 'P', va='center_baseline')
        label_apsis(np.argmax, 'A', va='center')

    if show_maven:
        # add a dot for the spacecraft location
        mavenpos = spice.spkezr('MAVEN', myet,
                                'MAVEN_MSO', 'NONE', 'MARS')[0][:3]/mars_radius
        mavenposproj = np.array([np.dot(camera_right, mavenpos),
                                 np.dot(camera_up, mavenpos)])
        mavenposdisp = (mavenposproj + extent)/extent/2
        mavenvis = (not (np.linalg.norm([mavenposproj]) < 1
                         and np.dot(camera_pos, mavenpos) < 0))
        if mavenvis:
            maven = mpatches.Circle(mavenposdisp, 0.012,
                                    transform=ax.transAxes,
                                    fc=orbitcolor,
                                    lw=0, zorder=11)
            ax.add_patch(maven)
            ax.text(*mavenposdisp, 'M',
                    transform=ax.transAxes,
                    color='k', ha='center', va='center_baseline',
                    size=4, zorder=11)

    # suppress all whitespace around the plot
    plt.subplots_adjust(top=1, bottom=0, right=1, left=0,
                        hspace=0, wspace=0)
    plt.margins(0, 0)
    ax.set_axis_off()
    ax.xaxis.set_major_locator(plt.NullLocator())
    ax.yaxis.set_major_locator(plt.NullLocator())

    fig.canvas.draw()

    rgb_array = fig2rgb_array(fig)

    if not show:
        plt.close(fig)

    return_coords = {'extent': extent,
                     'scale': '3395 km',
                     'camera_pos': camera_pos,
                     'camera_pos_norm': camera_pos_norm,
                     'camera_up': camera_up,
                     'camera_right': camera_right,
                     'orbit_coords': poslist}

    return rgb_array, return_coords
예제 #18
0
    def vtk_actors(self):
        if (self.actors is None):
            self.actors = []
            points = _getfem_to_tvtk_points(self.sl.pts())
            (triangles, cv2tr) = self.sl.splxs(2)
            triangles = numpy.array(triangles.transpose(), 'I')
            data = tvtk.PolyData(points=points, polys=triangles)
            if self.scalar_data is not None:
                data.point_data.scalars = numpy.array(self.scalar_data)
            if self.vector_data is not None:
                data.point_data.vectors = numpy.array(self.vector_data)
            if self.glyph_name is not None:
                mask = tvtk.MaskPoints()
                mask.maximum_number_of_points = self.glyph_nb_pts
                mask.random_mode = True
                mask.input = data

                if self.glyph_name == 'default':
                    if self.vector_data is not None:
                        self.glyph_name = 'arrow'
                    else:
                        self.glyph_name = 'ball'

                glyph = tvtk.Glyph3D()
                glyph.scale_mode = 'scale_by_vector'
                glyph.color_mode = 'color_by_scalar'
                #glyph.scale_mode = 'data_scaling_off'
                glyph.vector_mode = 'use_vector'  # or 'use_normal'
                glyph.input = mask.output
                if self.glyph_name == 'arrow':
                    glyph.source = tvtk.ArrowSource().output
                elif self.glyph_name == 'ball':
                    glyph.source = tvtk.SphereSource().output
                elif self.glyph_name == 'cone':
                    glyph.source = tvtk.ConeSource().output
                elif self.glyph_name == 'cylinder':
                    glyph.source = tvtk.CylinderSource().output
                elif self.glyph_name == 'cube':
                    glyph.source = tvtk.CubeSource().output
                else:
                    raise Exception("Unknown glyph name..")
                #glyph.scaling = 1
                #glyph.scale_factor = self.glyph_scale_factor
                data = glyph.output

            if self.show_faces:
                ##                if self.deform is not None:
                ##                    data.point_data.vectors = array(numarray.transpose(self.deform))
                ##                    warper = tvtk.WarpVector(input=data)
                ##                    data = warper.output
                ##                lut = tvtk.LookupTable()
                ##                lut.hue_range = 0.667,0
                ##                c=gf_colormap('tripod')
                ##                lut.number_of_table_values=c.shape[0]
                ##                for i in range(0,c.shape[0]):
                ##                    lut.set_table_value(i,c[i,0],c[i,1],c[i,2],1)

                self.mapper = tvtk.PolyDataMapper(input=data)
                self.mapper.scalar_range = self.scalar_data_range
                self.mapper.scalar_visibility = True
                # Create mesh actor for display
                self.actors += [tvtk.Actor(mapper=self.mapper)]
            if self.show_edges:
                (Pe, E1, E2) = self.sl.edges()
                if Pe.size:
                    E = numpy.array(
                        numpy.concatenate((E1.transpose(), E2.transpose()),
                                          axis=0), 'I')
                    edges = tvtk.PolyData(points=_getfem_to_tvtk_points(Pe),
                                          polys=E)
                    mapper_edges = tvtk.PolyDataMapper(input=edges)
                    actor_edges = tvtk.Actor(mapper=mapper_edges)
                    actor_edges.property.representation = 'wireframe'
                    #actor_edges.property.configure_traits()
                    actor_edges.property.color = self.edges_color
                    actor_edges.property.line_width = self.edges_width
                    actor_edges.property.ambient = 0.5
                    self.actors += [actor_edges]
            if self.sl.nbsplxs(1):
                # plot tubes
                (seg, cv2seg) = self.sl.splxs(1)
                seg = numpy.array(seg.transpose(), 'I')
                data = tvtk.Axes(origin=(0, 0, 0),
                                 scale_factor=0.5,
                                 symmetric=1)
                data = tvtk.PolyData(points=points, lines=seg)
                tube = tvtk.TubeFilter(radius=0.4,
                                       number_of_sides=10,
                                       vary_radius='vary_radius_off',
                                       input=data)
                mapper = tvtk.PolyDataMapper(input=tube.output)
                actor_tubes = tvtk.Actor(mapper=mapper)
                #actor_tubes.property.representation = 'wireframe'
                actor_tubes.property.color = self.tube_color
                #actor_tubes.property.line_width = 8
                #actor_tubes.property.ambient = 0.5

                self.actors += [actor_tubes]

            if self.use_scalar_bar:
                self.scalar_bar = tvtk.ScalarBarActor(
                    title=self.scalar_data_name,
                    orientation='horizontal',
                    width=0.8,
                    height=0.07)
                self.scalar_bar.position_coordinate.coordinate_system = 'normalized_viewport'
                self.scalar_bar.position_coordinate.value = 0.1, 0.01, 0.0
                self.actors += [self.scalar_bar]

            if (self.lookup_table is not None):
                self.set_colormap(self.lookup_table)

        return self.actors
예제 #19
0
 def _get_primitive(self):
     return tvtk.SphereSource(center=self.center,
                              radius=self.radius,
                              theta_resolution=self.theta_res,
                              phi_resolution=self.phi_res)
예제 #20
0
# Copyright (c) 2008, Enthought, Inc.
# License: BSD Style.

from mayavi import mlab

# To access any VTK object, we use 'tvtk', which is a Python wrapping of
# VTK replacing C++ setters and getters by Python properties and
# converting numpy arrays to VTK arrays when setting data.
from tvtk.api import tvtk
from tvtk.common import configure_input_data

v = mlab.figure()

# Create a sphere
# The source generates data points
sphere = tvtk.SphereSource(center=(0, 0, 0), radius=0.5)
# The mapper converts them into position in, 3D with optionally color (if
# scalar information is available).
sphere_mapper = tvtk.PolyDataMapper()
configure_input_data(sphere_mapper, sphere.output)
sphere.update()

# The Property will give the parameters of the material.
p = tvtk.Property(opacity=0.2, color=(1, 0, 0))
# The actor is the actually object in the scene.
sphere_actor = tvtk.Actor(position=(0, 0, 0), mapper=sphere_mapper, property=p)
v.scene.add_actor(sphere_actor)

# Create a cylinder
cylinder = tvtk.CylinderSource(center=(0, 0, 0), radius=0.2, resolution=16)
cylinder_mapper = tvtk.PolyDataMapper()
예제 #21
0
def main():
    parser = argparse.ArgumentParser()

    parser.add_argument('filename', nargs='+',
                        help='name of flydra .hdf5 file',
                        )

    parser.add_argument("--stim-xml",
                        type=str,
                        default=None,
                        help="name of XML file with stimulus info",
                        required=True,
                        )

    parser.add_argument("--align-json",
                        type=str,
                        default=None,
                        help="previously exported json file containing s,R,T",
                        )

    parser.add_argument("--radius", type=float,
                      help="radius of line (in meters)",
                      default=0.002,
                      metavar="RADIUS")

    parser.add_argument("--obj-only", type=str)

    parser.add_argument("--obj-filelist", type=str,
                      help="use object ids from list in text file",
                      )

    parser.add_argument(
        "-r", "--reconstructor", dest="reconstructor_path",
        type=str,
        help=("calibration/reconstructor path (if not specified, "
              "defaults to FILE)"))

    args = parser.parse_args()
    options = args # optparse OptionParser backwards compatibility

    reconstructor_path = args.reconstructor_path
    fps = None

    ca = core_analysis.get_global_CachingAnalyzer()
    by_file = {}

    for h5_filename in args.filename:
        assert(tables.is_hdf5_file(h5_filename))
        obj_ids, use_obj_ids, is_mat_file, data_file, extra = ca.initial_file_load(
            h5_filename)
        this_fps = result_utils.get_fps( data_file, fail_on_error=False )
        if fps is None:
            if this_fps is not None:
                fps = this_fps
        if reconstructor_path is None:
            reconstructor_path = data_file
        by_file[h5_filename] = (use_obj_ids, data_file)
    del h5_filename
    del obj_ids, use_obj_ids, is_mat_file, data_file, extra

    if options.obj_only is not None:
        obj_only = core_analysis.parse_seq(options.obj_only)
    else:
        obj_only = None

    if reconstructor_path is None:
        raise RuntimeError('must specify reconstructor from CLI if not using .h5 files')

    R = reconstruct.Reconstructor(reconstructor_path)

    if fps is None:
        fps = 100.0
        warnings.warn('Setting fps to default value of %f'%fps)
    else:
        fps = 1.0

    if options.stim_xml is None:
        raise ValueError(
            'stim_xml must be specified (how else will you align the data?')

    if 1:
        stim_xml = xml_stimulus.xml_stimulus_from_filename(
            options.stim_xml,
            )
        try:
            fanout = xml_stimulus.xml_fanout_from_filename( options.stim_xml )
        except xml_stimulus.WrongXMLTypeError:
            pass
        else:
            include_obj_ids, exclude_obj_ids = fanout.get_obj_ids_for_timestamp(
                timestamp_string=file_timestamp )
            if include_obj_ids is not None:
                use_obj_ids = include_obj_ids
            if exclude_obj_ids is not None:
                use_obj_ids = list( set(use_obj_ids).difference(
                    exclude_obj_ids ) )
            print('using object ids specified in fanout .xml file')
        if stim_xml.has_reconstructor():
            stim_xml.verify_reconstructor(R)

    x = []
    y = []
    z = []
    speed = []

    if options.obj_filelist is not None:
        obj_filelist=options.obj_filelist
    else:
        obj_filelist=None

    if obj_filelist is not None:
        obj_only = 1

    if obj_only is not None:
        if len(by_file) != 1:
            raise RuntimeError("specifying obj_only can only be done for a single file")
        if obj_filelist is not None:
            data = np.loadtxt(obj_filelist,delimiter=',')
            obj_only = np.array(data[:,0], dtype='int')
            print(obj_only)

        use_obj_ids = numpy.array(obj_only)
        h5_filename = by_file.keys()[0]
        (prev_use_ob_ids, data_file) = by_file[h5_filename]
        by_file[h5_filename] = (use_obj_ids, data_file)

    for h5_filename in by_file:
        (use_obj_ids, data_file) = by_file[h5_filename]
        for obj_id_enum,obj_id in enumerate(use_obj_ids):
            rows = ca.load_data( obj_id, data_file,
                                 use_kalman_smoothing=False,
                                 #dynamic_model_name = dynamic_model_name,
                                 #frames_per_second=fps,
                                 #up_dir=up_dir,
                                )
            verts = numpy.array( [rows['x'], rows['y'], rows['z']] ).T
            if len(verts)>=3:
                verts_central_diff = verts[2:,:] - verts[:-2,:]
                dt = 1.0/fps
                vels = verts_central_diff/(2*dt)
                speeds = numpy.sqrt(numpy.sum(vels**2,axis=1))
                # pad end points
                speeds = numpy.array([speeds[0]] + list(speeds) + [speeds[-1]])
            else:
                speeds = numpy.zeros( (verts.shape[0],) )

            if verts.shape[0] != len(speeds):
                raise ValueError('mismatch length of x data and speeds')
            x.append( verts[:,0] )
            y.append( verts[:,1] )
            z.append( verts[:,2] )
            speed.append(speeds)
        data_file.close()
    del h5_filename, use_obj_ids, data_file

    if 0:
        # debug
        if stim_xml is not None:
            v = None
            for child in stim_xml.root:
                if child.tag == 'cubic_arena':
                    info = stim_xml._get_info_for_cubic_arena(child)
                    v=info['verts4x4']
            if v is not None:
                for vi in v:
                    print('adding',vi)
                    x.append( [vi[0]] )
                    y.append( [vi[1]] )
                    z.append( [vi[2]] )
                    speed.append( [100.0] )

    x = np.concatenate(x)
    y = np.concatenate(y)
    z = np.concatenate(z)
    w = np.ones_like(x)
    speed = np.concatenate(speed)

    # homogeneous coords
    verts = np.array([x,y,z,w])

    #######################################################

    # Create the MayaVi engine and start it.
    e = Engine()
    # start does nothing much but useful if someone is listening to
    # your engine.
    e.start()

    # Create a new scene.
    from tvtk.tools import ivtk
    #viewer = ivtk.IVTK(size=(600,600))
    viewer = IVTKWithCalGUI(size=(800,600))
    viewer.open()
    e.new_scene(viewer)

    viewer.cal_align.set_data(verts,speed,R,args.align_json)

    if 0:
        # Do this if you need to see the MayaVi tree view UI.
        ev = EngineView(engine=e)
        ui = ev.edit_traits()

    # view aligned data
    e.add_source(viewer.cal_align.source)

    v = Vectors()
    v.glyph.scale_mode = 'data_scaling_off'
    v.glyph.color_mode = 'color_by_scalar'
    v.glyph.glyph_source.glyph_position='center'
    v.glyph.glyph_source.glyph_source = tvtk.SphereSource(
        radius=options.radius,
        )
    e.add_module(v)

    if stim_xml is not None:
        if 0:
            stim_xml.draw_in_mayavi_scene(e)
        else:
            actors = stim_xml.get_tvtk_actors()
            viewer.scene.add_actors(actors)

    gui = GUI()
    gui.start_event_loop()
예제 #22
0
    # get scale factor for
    # TODO : get vertical grid type (GEOS5, GEOS5 reduced...) from diagnostics
    atm_thickness = gchemgrid.c_km_geos5_r.max() * 1e3


# vtk atmosphere thickness vs. earth radius: height scale calculation

ratio_earth_atm = 2.0

earth_radius_scaled = ratio_earth_atm * atm_thickness

# vtk file basemap (sphere, continents)
globe_src = tvtk.SphereSource(radius=earth_radius_scaled -
                              1e-3 * earth_radius_scaled,
                              lat_long_tessellation=True,
                              phi_resolution=gchemgrid.c_lat_4x5.size,
                              theta_resolution=gchemgrid.c_lon_4x5.size)
continents_src = tvtk.EarthSource(on_ratio=1, radius=earth_radius_scaled)

writer = tvtk.XMLPolyDataWriter(input=globe_src.output,
                                file_name=os.path.join(run_dir, "vtk",
                                                       "globe.vtp"))
writer.write()
writer = tvtk.XMLPolyDataWriter(input=continents_src.output,
                                file_name=os.path.join(run_dir, "vtk",
                                                       "continents.vtp"))
writer.write()

# vtk meshes
tfield = filter_results[0].values