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]
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
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
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
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
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
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'
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]
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)
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
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'
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,
# 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)
#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()
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()
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
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
def _get_primitive(self): return tvtk.SphereSource(center=self.center, radius=self.radius, theta_resolution=self.theta_res, phi_resolution=self.phi_res)
# 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()
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()
# 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