""" A collection of support methods for connecting VisAD to Jython. The emphasis is on display-side methods and classes. All display-dependent functions (methods) are available as either static functions (where one of the parameter is the 'display') or as an instance function (for a previously-created 'display'). See the '_vdisp' class. """ try: #try/except done to remove these lines from documentation only from visad import ScalarMap, Display, DataReferenceImpl, RealTupleType,\ Gridded2DSet, Gridded3DSet, DisplayImpl, RealType, RealTuple, \ VisADLineArray, VisADQuadArray, VisADTriangleArray, SetType, \ VisADGeometryArray, ConstantMap, Integer1DSet, FunctionType, \ ScalarMap, Display, Integer1DSet, FieldImpl, CellImpl, \ DisplayListener, DisplayEvent, GraphicsModeControl, \ MouseHelper, UnionSet from types import StringType from visad.ss import BasicSSCell from visad.java2d import DisplayImplJ2D, DisplayRendererJ2D from java.lang import Double # define private fields for certains types and scalar mappings __py_shapes = None except: pass # Super class for displays - this contains all the # useful instance methods for the displays. (Note # the 'static' methods usually use these.) This # class should _only_ be instantiated indirectly using # the makeDisplay(), makeDisplay2D(), or makeDisplay3D() # methods!! class _vdisp: instance = 0 # make sure we use unique names for each instance def __init__(self): instance =+ 1 self.text_type = RealType.getRealType("py_text_type_"+str(instance)) self.shape_type = RealType.getRealType("py_shape_type_"+str(instance)) self.pcMatrix = None self.text_map = ScalarMap(self.text_type, Display.Text) self.addMap(self.text_map) self.shape_map = ScalarMap(self.shape_type, Display.Shape) self.addMap(self.shape_map) self.my_frame = None def addMaps(self, maps): """ Add list/tuple mappings to the . These determine what scalars will appear along what axes. See makeMaps, below. """ for map in maps: self.addMap(map) def addShape(self, type, scale=.1, color=None, index=None, autoScale=1): """ Add a shape for this display. Parameters: of shape ('cross','triangle','square', 'solid_square','solid_triangle', or a VisADGeometryArray. = relative size for the shape. = color name (e.g., "green") = the index of the shape to replace with this one. If autoScale is true, the shape will be scaled. Returns an index to this shape. (For use with moveShape.) """ return (self.shapes.addShape(type, scale, color, index, autoScale)) def moveShape(self, index, coord): """ Move the shape pointed to by , to the which is a list of values in the same order as returned by getDisplayMaps. """ self.shapes.moveShape(index, coord) def drawString(self, string, point, color=None, center=0, font="futural", start=[0.,0.,0.], base=[.1,0.,0.], up=[0.,.1,0.],size=None ): """ Draw a string of characters on this display. is the string of characters. is the starting location for the string drawing, expressed as a list/tuple of 2 or 3 values (x,y,z). is the color (e.g., "red" or java.awt.Color; default = white).
if true will center the string. defiles the HersheyFont name to use. defines the relative location of the starting point (x,y,z; default = 0,0,0). defines the direction that the base of the string should point (x,y,z; default= along x-axis). defines the direction of the vertical stroke for each character (default = along y-axis). is the relative size. Returns the index to the shape of the text (useful for moving). """ textfs = textShape(string, center, font, start, base, up, size) i = self.shapes.addShape(textfs, color=color, index=None) self.shapes.moveShape(i, point) return i def addTitle(self, string, center=1, font="timesrb", color=None, size=None, offset=.1, index=None): """ Put a title onto this display. The title is centered just above the VisAD 'box'. Use 'offset' to move it up/down. Set the text color with 'color', and if this is a replacement for a previous title, then 'index' is the value previously returned. Return the shape index for later adjustments... """ ts = textShape(string,center,font,start=[1.,2.+offset,0], size=size) return self.shapes.addShape(ts, color=color, index=index, autoScale=0) def saveDisplay(self,filename, display_wait=1, file_write_wait=1): """ Save the display as a JPEG, given the filename to use. This will wait for the display to be 'done'. """ from visad.util import Util Util.captureDisplay(self, filename, display_wait, file_write_wait) def addData(self, name, data, constantMaps=None, renderer=None, ref=None, zlayer=None): """ Add VisAD to the display . Use a reference . If there are ConstantMaps, also add them. If there is a non-default Renderer, use it as well. You can supply a pre-defined DataReference as . Finally, if nothing is mapped to Display.ZAxis, data objects with the highest will appear on top in the display. Returns the DataReference """ if zlayer is not None: zmap = [ConstantMap(zlayer, Display.ZAxis)] if constantMaps is not None: constantMaps = constantMaps + zmap else: constantMaps = zmap if ref is None: ref = DataReferenceImpl(name) if renderer is None: self.addReference(ref, constantMaps) else: self.addReferences(renderer, ref, constantMaps) if data is not None: ref.setData(data) else: print "added Data is None" return ref def toggle(self, ref, on): rendVector = self.getRendererVector() for i in range(rendVector.size()): ren = rendVector.elementAt(i) links = ren.getLinks() for j in range(len(links)): if (links[j].getThingReference() == ref): links[j].getRenderer().toggle(on) def setPointSize(self, size): """ Set the size of points (1,2,3...) to use in this display. """ self.getGraphicsModeControl().setPointSize(size) def setAspectRatio(self, ratio): """ Set the aspect for this display. The ratio is expressed as the fractional value for: width/height. """ x = 1. y = 1. if ratio > 1: x = 1. y = 1. / ratio else: y = 1. x = 1. * ratio self.setAspects(x, y, 1.) def setAspects(self, x, y, z): """ Set the relative sizes of each axis in this display. """ self.getProjectionControl().setAspectCartesian( (x, y, z)) def rotateBox(self, azimuth, declination): """ Rotate the 3D display box to the azimuth angle (0-360) and declination angle (all in degrees). Code from Unidata. """ zangle = 180 - azimuth aziMat = self.make_matrix(0, 0, zangle, 1, 0, 0, 0) pc = self.getProjectionControl() comb = self.multiply_matrix(aziMat, pc.getMatrix()) decMat = self.make_matrix(declination, 0, 0, 1, 0, 0, 0) comb2 = self.multiply_matrix(decMat,comb) pc.setMatrix(comb2) def maximizeBox(self, clip=1): """ Set the size of the VisAD 'box' for the to 95%. If is true, the display will be clipped at the border of the box; otherwise, data displays may spill over. """ self.setBoxSize(.95, clip) def setBoxSize(self, percent=.70, clip=1, showBox=1, snap=0): """ Set the size of the VisAD 'box' for the as a percentage (fraction). The default is .70 (70%). If is true, the display will be clipped at the border of the box; otherwise, data displays may spill over. If is true, the wire-frame will be shown; otherwise, it will be turned off. If is true, the box will be reoriented to an upright position. """ pc=self.getProjectionControl() if (not snap) or (self.pcMatrix == None): self.pcMatrix=pc.getMatrix() if len(self.pcMatrix) > 10: self.pcMatrix[0]=percent self.pcMatrix[5]=percent self.pcMatrix[10]=percent else: self.pcMatrix[0]=percent/.64 self.pcMatrix[3]=-percent/.64 pc.setMatrix(self.pcMatrix) dr = self.getDisplayRenderer(); if __ok3d: try: if isinstance(dr, DisplayRendererJ3D): dr.setClip(0, clip, 1., 0.0, 0.0, -1.); dr.setClip(1, clip, -1., 0.0, 0.0, -1.); dr.setClip(2, clip, 0.0, 1., 0.0, -1.); dr.setClip(3, clip, 0.0, -1., 0.0, -1.); #dr.setClip(4, 1, 0.0, 0.0, 1., -1.); #dr.setClip(5, 1, 0.0, 0.0, -1., -1.); elif isinstance(dr, DisplayRendererJ2D): if clip: dr.setClip(-1., 1., -1., 1.) else: dr.unsetClip() except: pass dr.setBoxOn(showBox) def makeCube(self): """ Turn the VisAD box for this display into a cube with no perspective (no 'vanishing point'. Useful for aligning vertically-stacked data. """ self.getGraphicsModeControl().setProjectionPolicy(0) def setBackgroundColor(self,c): """ Set the background color to 'color' (which may be a java.awt.Color, or a string with the name in it (like 'green') """ r,g,b = _color2rgb(c) self.getDisplayRenderer().getRendererControl().setBackgroundColor(r,g,b) def setForegroundColor(self,c): """ Set the foreground color to 'color' (which may be a java.awt.Color, or a string with the name in it (like 'green') """ r,g,b = _color2rgb(c) self.getDisplayRenderer().getRendererControl().setForegroundColor(r,g,b) def setBoxOn(self,on): """ Turn the wire frame box on or off. """ self.getDisplayRenderer().getRendererControl().setBoxOn(on) def setCursorColor(self,c): """ Set the cursor color to 'color' (which may be a java.awt.Color, or a string with the name in it (like 'green') """ r,g,b = _color2rgb(c) self.getDisplayRenderer().getRendererControl().setCursorColor(r,g,b) def setBoxColor(self,c): """ Set the box color to 'color' (which may be a java.awt.Color, or a string with the name in it (like 'green') """ r,g,b = _color2rgb(c) self.getDisplayRenderer().getRendererControl().setBoxColor(r,g,b) def zoomBox(self, factor): """ Zoom the display by 'factor' (1.0 does nothing...). Related: setBoxSize(). """ mouseBehavior = self.getMouseBehavior() pc = self.getProjectionControl() currentMatrix = pc.getMatrix() scaleMatrix = mouseBehavior.make_matrix( 0, 0, 0, factor, 0, 0, 0) scaleMatrix = mouseBehavior.multiply_matrix( scaleMatrix, currentMatrix); try: pc.setMatrix(scaleMatrix) except: pass def setPointMode(size, on): """ Turn on (on=true) point mode for some renderings; otherwise these objects may be shown as lines or texture maps. """ self.getGraphicsModControl().setPointSize(size) self.getGraphicsModControl().setPointMode(on) def showAxesScales(self, on): """ Turn on the axes labels for this display if 'on' is true """ self.getGraphicsModeControl().setScaleEnable(on) def enableRubberBandBoxZoomer(self,useKey,callback=None,color=None,x=None,y=None): """ Method to attach a Rubber Band Box zoomer to this display. Once attached, it is there foreever! The useKey parameter can be 0 (no key), 1(CTRL), 2(SHIFT) """ rrbz = RubberBandZoomer(self,useKey,1,callback,color,x,y) return rrbz.ref def enableRubberBandBox(self,useKey,callback=None,color=None,x=None,y=None): """ Method to attach a Rubber Band Box to this display. Once attached, it is there forever! The useKey parameter can be 0 (no key), 1(CTRL), 2(SHIFT) """ rrbz = RubberBandZoomer(self,useKey,0,callback,color,x,y) return rrbz.ref def getDisplayScalarMaps(self, includeShapes=0): """ Return a list of the scalarmaps mappings for this display. The list elements are ordered: x,y,z,display. If is true, then mappings for Shape will be appended. The may be a Display, or the name of a 'plot()' window. """ return (getDisplayScalarMaps(self,includeShapes)) def getDisplayScalarMapLists(self, includeShapes=0): """ Return a list of the scalarmaps mappings for this display. The list elements are ordered: x,y,z,display. If is true, then mappings for Shape will be appended. The may be a Display, or the name of a 'plot()' window. Note: this is identical to getDisplayScalarMaps except that the return type is a list of lists since there may more than one ScalarMap to x, y or z. """ return (getDisplayScalarMapLists(self,includeShapes)) def getDisplayMaps(self, includeShapes=0): """ Return a list of the type mappings for the . The list elements are ordered: x,y,z,display. If is true, then mappings for Shape will be appended. The may be a Display, or the name of a 'plot()' window. """ return (getDisplayMaps(self,includeShapes)) def moveLine(self, lref, points): """ move the referenced line to the new points """ type = lref.getType() lref.setData(makeLine(type,points)) def drawLine(self, points, color=None, mathtype=None, style=None, width=None): """ Draw lines on this display. is a 2 or 3 dimensional, list/tuple of points to connect as a line, ordered as given in the . Default is whatever is mapped to the x,y (and maybe z) axis. is the line color ("red" or java.awt.Color; default=white),