diff --git a/Packages/DV3D/Application.py b/Packages/DV3D/Application.py index 8608e86f3f..97988f94fa 100644 --- a/Packages/DV3D/Application.py +++ b/Packages/DV3D/Application.py @@ -93,3 +93,7 @@ def hideWidgets(self): def showWidgets(self): self.plot.showWidgets() +if __name__ == '__main__': + + from DistributedPointCollections import kill_all_zombies + kill_all_zombies() \ No newline at end of file diff --git a/Packages/DV3D/StructuredDataset.py b/Packages/DV3D/StructuredDataset.py index 62ee9e5b74..1e4c1db6f6 100644 --- a/Packages/DV3D/StructuredDataset.py +++ b/Packages/DV3D/StructuredDataset.py @@ -715,7 +715,10 @@ def getTransVarDataCube( self, varName, transVar, decimation, **args ): if decimation: decimationFactor = decimation[0]+1 args1 = {} - order = 'xyt' if ( timeBounds == None) else 'xyz' if levaxis else 'xy' + if ( timeBounds == None): + order = 'xyt' if timeaxis is not None else 'xy' + else: + order = 'xyz' if levaxis is not None else 'xy' try: nts = self.timeRange[1] if ( timeIndex <> None ) and useTimeIndex: @@ -756,7 +759,8 @@ def getTransVarDataCube( self, varName, transVar, decimation, **args ): try: rv = transVar( **args1 ) except Exception, err: - print>>sys.stderr, "Error Reading Variable", str(err) + print>>sys.stderr, "Error Reading Variable, args = ", str(args1) + traceback.print_exc() return CDMSDataset.NullVariable memoryLogger.log("Create Mask") diff --git a/Packages/DV3D/StructuredGridPlot.py b/Packages/DV3D/StructuredGridPlot.py index 89e7254595..de7f1e14a8 100644 --- a/Packages/DV3D/StructuredGridPlot.py +++ b/Packages/DV3D/StructuredGridPlot.py @@ -64,8 +64,17 @@ def processVerticalScalingCommand( self, args, config_function ): if args and args[0] == "StartConfig": ispec = self.inputSpecs[ 0 ] wbounds = ispec.getDataBounds() + self.zscaleBoxWidget = vtk.vtkBoxWidget() + self.zscaleBoxWidget.SetInteractor( self.renderWindowInteractor ) + self.zscaleBoxWidget.SetPlaceFactor(1.0) + self.zscaleBoxWidget.HandlesOff() + self.zscaleBoxWidget.SetEnabled(1) + oprop = self.zscaleBoxWidget.GetOutlineProperty() + oprop.SetColor( 0.0, 0.0, 0.0 ) + oprop.SetLineWidth( 2.0 ) self.zscaleBoxWidget.On() self.zscaleBoxWidget.PlaceWidget(wbounds) +# print " >>>>>>>>>>>>>>>>>>>>> Place box widget: ", str( wbounds ) elif args and args[0] == "Init": self.parameter_initializing = True ispec = self.inputSpecs[ 0 ] @@ -80,21 +89,15 @@ def processVerticalScalingCommand( self, args, config_function ): # verticalScale.setValues( [ zsval ] ) self.setZScale( zsval ) verticalScale.setValue( 'count', 1 ) - self.zscaleBoxWidget = vtk.vtkBoxWidget() - self.zscaleBoxWidget.SetInteractor( self.renderWindowInteractor ) - self.zscaleBoxWidget.SetPlaceFactor(1.0) - self.zscaleBoxWidget.HandlesOff() - oprop = self.zscaleBoxWidget.GetOutlineProperty() - oprop.SetColor( 0.0, 0.0, 0.0 ) - oprop.SetLineWidth( 2.0 ) self.parameter_initializing = False elif args and args[0] == "EndConfig": vscale = verticalScale.getValues() self.setZScale( vscale ) self.zscaleBoxWidget.Off() + self.zscaleBoxWidget.SetEnabled(0) + self.zscaleBoxWidget = None self.processConfigParameterChange( verticalScale ) elif args and args[0] == "InitConfig": - self.zscaleBoxWidget.SetEnabled(1) self.updateTextDisplay( config_function.label ) bbar = self.getInteractionButtons() self.skipIndex = 2 diff --git a/Packages/vcs/Lib/Canvas.py b/Packages/vcs/Lib/Canvas.py index fe66db3570..7612ab8149 100644 --- a/Packages/vcs/Lib/Canvas.py +++ b/Packages/vcs/Lib/Canvas.py @@ -73,6 +73,7 @@ import vcsaddons import vcs.manageElements import configurator +from projection import round_projections class SIGNAL(object): @@ -1978,9 +1979,9 @@ def continents(self, *args, **parms): # # ############################################################################# def createline(self,name=None, source='default', ltype=None, - width=None, color=None, priority=1, + width=None, color=None, priority=None, viewport=None, worldcoordinate=None, - x=None, y=None, projection='default'): + x=None, y=None, projection=None): return vcs.createline(name,source,ltype,width,color,priority,viewport,worldcoordinate,x,y,projection) createline.__doc__ = vcs.manageElements.createline.__doc__ @@ -2229,7 +2230,7 @@ def drawfillarea(self, name=None, style=1, index=1, color=241, # # ############################################################################# def createtexttable(self,name=None, source='default', font=None, - spacing=None, expansion=None, color=None, priority=1, + spacing=None, expansion=None, color=None, priority=None, viewport=None, worldcoordinate=None, x=None, y=None): return vcs.createtexttable(name,source,font,spacing,expansion,color,priority, @@ -2263,7 +2264,7 @@ def gettextorientation(self,To_name_src='default'): # Text Combined functions for VCS. # # # ############################################################################# - def createtextcombined(self,Tt_name=None, Tt_source='default', To_name=None, To_source='default', font=None, spacing=None, expansion=None, color=None, priority=1, viewport=None, worldcoordinate=None, x=None, y=None, height=None, angle=None, path=None, halign=None, valign=None, projection=None): + def createtextcombined(self,Tt_name=None, Tt_source='default', To_name=None, To_source='default', font=None, spacing=None, expansion=None, color=None, priority=None, viewport=None, worldcoordinate=None, x=None, y=None, height=None, angle=None, path=None, halign=None, valign=None, projection=None): return vcs.createtextcombined(Tt_name, Tt_source, To_name, To_source, font, spacing, expansion, color, priority, viewport, worldcoordinate, x, y, height, angle, path, halign, valign, projection) @@ -2678,7 +2679,6 @@ def __plot (self, arglist, keyargs): # copy_tmpl=self.createtemplate(source=arglist[2]) check_mthd = vcs.getgraphicsmethod(arglist[3],arglist[4]) check_tmpl = vcs.gettemplate(arglist[2]) - # By defalut do the ratio thing for lat/lon and linear projection # but it can be overwritten by keyword Doratio = keyargs.get("ratio",None) @@ -3482,10 +3482,11 @@ def set_convert_labels(copy_mthd,test=0): elif tp=="default": tp="boxfill" gm=vcs.elements[tp][arglist[4]] + if hasattr(gm,"priority") and gm.priority==0: + return p=self.getprojection(gm.projection) - if p.type in ["polar (non gctp)","polar stereographic"] and (doratio=="0" or doratio[:4]=="auto"): + if p.type in round_projections and (doratio=="0" or doratio[:4]=="auto"): doratio="1t" - for keyarg in keyargs.keys(): if not keyarg in self.__class__._plot_keywords_+self.backend._plot_keywords: warnings.warn('Unrecognized vcs plot keyword: %s, assuming backend (%s) keyword'%(keyarg,self.backend.type)) @@ -3519,6 +3520,7 @@ def set_convert_labels(copy_mthd,test=0): # Now creates a copy of the primitives, in case it's used on other canvases with diferent ratios if arglist[3]=='text': nms = arglist[4].split(":::") + P=self.gettext(nms[0],nms[1]) p = self.createtext(Tt_source=nms[0],To_source=nms[1]) elif arglist[3]=='marker': p = self.createmarker(source=arglist[4]) @@ -3532,7 +3534,7 @@ def set_convert_labels(copy_mthd,test=0): t.data.y2 = p.viewport[3] proj = self.getprojection(p.projection) - if proj.type in ["polar (non gctp)","polar stereographic"]: + if proj.type in round_projections and (doratio=="0" or doratio[:4]=="auto"): doratio="1t" if proj.type=='linear' and doratio[:4]=='auto': @@ -3551,7 +3553,7 @@ def set_convert_labels(copy_mthd,test=0): else: arglist[4]=p.name else: - if arglist[3]=='text': + if arglist[3]=='text' and keyargs.get("donotstoredisplay",False) is True: sp = p.name.split(":::") del(vcs.elements["texttable"][sp[0]]) del(vcs.elements["textorientation"][sp[1]]) @@ -3577,7 +3579,7 @@ def set_convert_labels(copy_mthd,test=0): tp="textcombined" gm=vcs.elements[tp][arglist[4]] p=self.getprojection(gm.projection) - if p.type in ["polar (non gctp)","polar stereographic"]: + if p.type in round_projections: doratio="1t" if p.type == 'linear': if gm.g_name =='Gfm': diff --git a/Packages/vcs/Lib/VTKPlots.py b/Packages/vcs/Lib/VTKPlots.py index db9db2313d..35f73a33ad 100644 --- a/Packages/vcs/Lib/VTKPlots.py +++ b/Packages/vcs/Lib/VTKPlots.py @@ -189,6 +189,9 @@ def configureEvent(self,obj,ev): self.oldCursor = cursor return + if self.get3DPlot() is not None: + return + sz = self.renWin.GetSize() if self._lastSize == sz: # We really only care about resize event @@ -431,13 +434,13 @@ def plot(self,data1,data2,template,gtype,gname,bg,*args,**kargs): returned.update(self.plot3D(data1,data2,tpl,gm,ren,**kargs)) elif gtype in ["text"]: if tt.priority!=0: - if not (None,None,None) in self._renderers.keys(): - ren = self.createRenderer() - self.renWin.AddRenderer(ren) - self.setLayer(ren,1) - self._renderers[(None,None,None)]=ren - else: - ren = self._renderers[(None,None,None)] + #if not (None,None,None) in self._renderers.keys(): + ren = self.createRenderer() + self.renWin.AddRenderer(ren) + self.setLayer(ren,1) + # self._renderers[(None,None,None)]=ren + #else: + # ren = self._renderers[(None,None,None)] returned["vtk_backend_text_actors"] = vcs2vtk.genTextActor(ren,to=to,tt=tt) self.setLayer(ren,tt.priority) elif gtype=="line": @@ -445,28 +448,22 @@ def plot(self,data1,data2,template,gtype,gname,bg,*args,**kargs): actors = vcs2vtk.prepLine(self.renWin,gm) returned["vtk_backend_line_actors"]=actors for act,geo in actors: - ren = self.fitToViewport(act,gm.viewport,wc=gm.worldcoordinate,geo=geo) - ren.AddActor(act) - self.setLayer(ren,gm.priority) + ren = self.fitToViewport(act,gm.viewport,wc=gm.worldcoordinate,geo=geo,priority=gm.priority) elif gtype=="marker": if gm.priority!=0: actors = vcs2vtk.prepMarker(self.renWin,gm) returned["vtk_backend_marker_actors"]=actors for g,gs,pd,act,geo in actors: - ren = self.fitToViewport(act,gm.viewport,wc=gm.worldcoordinate,geo=geo) - ren.AddActor(act) + ren = self.fitToViewport(act,gm.viewport,wc=gm.worldcoordinate,geo=geo,priority=gm.priority) if pd is None and act.GetUserTransform(): vcs2vtk.scaleMarkerGlyph(g, gs, pd, act) - self.setLayer(ren,gm.priority) elif gtype=="fillarea": if gm.priority!=0: actors = vcs2vtk.prepFillarea(self.renWin,gm) returned["vtk_backend_fillarea_actors"]=actors for act,geo in actors: - ren = self.fitToViewport(act,gm.viewport,wc=gm.worldcoordinate,geo=geo) - ren.AddActor(act) - self.setLayer(ren,gm.priority) + ren = self.fitToViewport(act,gm.viewport,wc=gm.worldcoordinate,geo=geo,priority=gm.priority) elif gtype=="1d": #self.renWin.AddRenderer(ren) returned.update(self.plot1D(data1,data2,tpl,gm)) @@ -584,11 +581,10 @@ def plot1D(self,data1,data2,tmpl,gm): return {} def setLayer(self,renderer,priority): - n = self.numberOfPlotCalls + (priority-1)*10000 + 1 + n = self.numberOfPlotCalls + (priority-1)*200 + 1 nMax = max(self.renWin.GetNumberOfLayers(),n+1) self.renWin.SetNumberOfLayers(nMax) renderer.SetLayer(n) - pass def plot3D(self,data1,data2,tmpl,gm,ren,**kargs): from DV3D.Application import DV3DApp @@ -698,11 +694,7 @@ def plotVector(self,data1,data2,tmpl,gm,vtk_backend_grid=None,vtk_backend_geo=No act.GetProperty().SetColor(r/100.,g/100.,b/100.) x1,x2,y1,y2 = vcs.utils.getworldcoordinates(gm,data1.getAxis(-1),data1.getAxis(-2)) act = vcs2vtk.doWrap(act,[x1,x2,y1,y2],wrap) - ren = self.fitToViewport(act,[tmpl.data.x1,tmpl.data.x2,tmpl.data.y1,tmpl.data.y2],[x1,x2,y1,y2]) - if tmpl.data.priority!=0: - ren.AddActor(act) - self.setLayer(ren,tmpl.data.priority) - ren.AddActor(act) + ren = self.fitToViewport(act,[tmpl.data.x1,tmpl.data.x2,tmpl.data.y1,tmpl.data.y2],[x1,x2,y1,y2],priority=tmpl.data.priority) returned.update(self.renderTemplate(tmpl,data1,gm,taxis,zaxis)) if self.canvas._continents is None: continents = False @@ -1165,10 +1157,8 @@ def plot2D(self,data1,data2,tmpl,gm,vtk_backend_grid=None,vtk_backend_geo=None): pass # create a new renderer for this mapper # (we need one for each mapper because of cmaera flips) - ren = self.fitToViewport(act,[tmpl.data.x1,tmpl.data.x2,tmpl.data.y1,tmpl.data.y2],wc=[x1,x2,y1,y2],geo=geo) - if tmpl.data.priority>0: - ren.AddActor(act) - self.setLayer(ren,tmpl.data.priority) + ren = self.fitToViewport(act,[tmpl.data.x1,tmpl.data.x2,tmpl.data.y1,tmpl.data.y2], + wc=[x1,x2,y1,y2],geo=geo,priority=tmpl.data.priority) returned["vtk_backend_actors"] = actors if isinstance(gm,meshfill.Gfm): @@ -1221,13 +1211,8 @@ def plotContinents(self,x1,x2,y1,y2,projection,wrap,tmpl): else: geo=None - ren = self.fitToViewport(contActor,[tmpl.data.x1,tmpl.data.x2,tmpl.data.y1,tmpl.data.y2],wc=[x1,x2,y1,y2],geo=geo) - if tmpl.data.priority!=0: - self.setLayer(ren,tmpl.data.priority) - ren.AddActor(contActor) - col = ren.GetActors() - col.InitTraversal() - n=col.GetNextActor() + ren = self.fitToViewport(contActor,[tmpl.data.x1,tmpl.data.x2,tmpl.data.y1,tmpl.data.y2], + wc=[x1,x2,y1,y2],geo=geo,priority=tmpl.data.priority) return {} def renderTemplate(self,tmpl,data,gm,taxis,zaxis): @@ -1409,9 +1394,9 @@ def put_img_on_canvas(self,filename,zoom=1,xOffset=0,yOffset=0,*args,**kargs): def hideGUI(self): plot = self.get3DPlot() - if plot: plot.hideWidgets() - - if self.bg is False: + if plot: + plot.hideWidgets() + elif self.bg is False: from vtk_ui.manager import get_manager manager = get_manager(self.renWin.GetInteractor()) if manager: @@ -1419,13 +1404,11 @@ def hideGUI(self): def showGUI(self): plot = self.get3DPlot() - - if plot: plot.showWidgets() - - if self.bg is False: + if plot: + plot.showWidgets() + elif self.bg is False: from vtk_ui.manager import get_manager manager = get_manager(self.renWin.GetInteractor()) - if manager: # Set the UI renderer's layer on top of what's there right now layer = self.renWin.GetNumberOfLayers() + 1 @@ -1621,8 +1604,10 @@ def scaleLogo(self): self.setLayer(self.logoRenderer,1) self.renWin.AddRenderer(self.logoRenderer) - def fitToViewport(self,Actor,vp,wc=None,geo=None): + def fitToViewport(self,Actor,vp,wc=None,geo=None,priority=None): ## Data range in World Coordinates + if priority==0: + return None vp=tuple(vp) if wc is None: Xrg = list(Actor.GetXRange()) @@ -1630,66 +1615,98 @@ def fitToViewport(self,Actor,vp,wc=None,geo=None): else: Xrg=[float(wc[0]),float(wc[1])] Yrg=[float(wc[2]),float(wc[3])] - if Yrg[0]>Yrg[1]: - #Yrg=[Yrg[1],Yrg[0]] - #T.RotateY(180) - Yrg=[Yrg[1],Yrg[0]] - flipY = True - else: - flipY = False - if Xrg[0]>Xrg[1]: - Xrg=[Xrg[1],Xrg[0]] - flipX=True - else: - flipX=False - - if geo is not None: - pt = vtk.vtkPoints() - pt.SetNumberOfPoints(1) - Xrg2 = [1.e20,-1.e20] - Yrg2 = [1.e20,-1.e20] - Npts=50. - for x in numpy.arange(Xrg[0],Xrg[1],(Xrg[1]-Xrg[0])/Npts): - for y in numpy.arange(Yrg[0],Yrg[1],(Yrg[1]-Yrg[0])/Npts): - pt.SetPoint(0,x,y,0) - pts = vtk.vtkPoints() - geo.TransformPoints(pt,pts) - b = pts.GetBounds() - xm,xM,ym,yM=b[:4] - if xm!=-numpy.inf: - Xrg2[0]=min(Xrg2[0],xm) - if xM!=numpy.inf: - Xrg2[1]=max(Xrg2[1],xM) - if ym!=-numpy.inf: - Yrg2[0]=min(Yrg2[0],ym) - if yM!=numpy.inf: - Yrg2[1]=max(Yrg2[1],yM) - Xrg=Xrg2 - Yrg=Yrg2 - sc = self.renWin.GetSize() - wRatio = float(sc[0])/float(sc[1]) - dRatio = (Xrg[1]-Xrg[0])/(Yrg[1]-Yrg[0]) - vRatio = float(vp[1]-vp[0])/float(vp[3]-vp[2]) + wc_used = (float(Xrg[0]),float(Xrg[1]),float(Yrg[0]),float(Yrg[1])) + sc = self.renWin.GetSize() - if wRatio>1.: #landscape orientated window - yScale = 1. - xScale = vRatio*wRatio/dRatio - else: - xScale = 1. - yScale = dRatio/(vRatio*wRatio) - ## Ok now we know scaling and vp, let's see if we did this already. - if (vp,xScale,yScale) in self._renderers.keys(): + # Ok at this point this is all the info we need + # we can determine if it's a unique renderer or not + # let's see if we did this already. + if (vp,wc_used,sc,priority) in self._renderers.keys(): #yep already have one, we will use this Renderer - Renderer = self._renderers[(vp,xScale,yScale)] + Renderer,xScale,yScale = self._renderers[(vp,wc_used,sc,priority)] didRenderer = True else: Renderer = self.createRenderer() self.renWin.AddRenderer(Renderer) - self._renderers[(vp,xScale,yScale)]=Renderer Renderer.SetViewport(vp[0],vp[2],vp[1],vp[3]) didRenderer = False + if Yrg[0]>Yrg[1]: + #Yrg=[Yrg[1],Yrg[0]] + #T.RotateY(180) + Yrg=[Yrg[1],Yrg[0]] + flipY = True + else: + flipY = False + if Xrg[0]>Xrg[1]: + Xrg=[Xrg[1],Xrg[0]] + flipX=True + else: + flipX=False + + if geo is not None: + pt = vtk.vtkPoints() + Xrg2 = [1.e20,-1.e20] + Yrg2 = [1.e20,-1.e20] + if geo.GetDestinationProjection().GetName() in ["aeqd",]: + ## These need more precision to compute actual range + Npts=250 + else: + Npts=50 + NGridCover=0 + pt.SetNumberOfPoints(Npts*Npts) + for x in numpy.arange(Xrg[0],Xrg[1],(Xrg[1]-Xrg[0])/Npts): + for y in numpy.arange(Yrg[0],Yrg[1],(Yrg[1]-Yrg[0])/Npts): + pt.InsertPoint(NGridCover,x,y,0) + NGridCover+=1 + pts = vtk.vtkPoints() + #pts.SetNumberOfPoints(Npts*Npts) + geo.TransformPoints(pt,pts) + b = pts.GetBounds() + xm,xM,ym,yM=b[:4] + if xm!=-numpy.inf: + Xrg2[0]=min(Xrg2[0],xm) + if xM!=numpy.inf: + Xrg2[1]=max(Xrg2[1],xM) + if ym!=-numpy.inf: + Yrg2[0]=min(Yrg2[0],ym) + if yM!=numpy.inf: + Yrg2[1]=max(Yrg2[1],yM) + Xrg=Xrg2 + Yrg=Yrg2 + wRatio = float(sc[0])/float(sc[1]) + dRatio = (Xrg[1]-Xrg[0])/(Yrg[1]-Yrg[0]) + vRatio = float(vp[1]-vp[0])/float(vp[3]-vp[2]) + + + if wRatio>1.: #landscape orientated window + yScale = 1. + xScale = vRatio*wRatio/dRatio + else: + xScale = 1. + yScale = dRatio/(vRatio*wRatio) + self.setLayer(Renderer,priority) + self._renderers[(vp,wc_used,sc,priority)] = Renderer,xScale,yScale + + xc = xScale*float(Xrg[1]+Xrg[0])/2. + yc = yScale*float(Yrg[1]+Yrg[0])/2. + xd = xScale*float(Xrg[1]-Xrg[0])/2. + yd = yScale*float(Yrg[1]-Yrg[0])/2. + cam = Renderer.GetActiveCamera() + cam.ParallelProjectionOn() + cam.SetParallelScale(yd) + cd = cam.GetDistance() + cam.SetPosition(xc,yc,cd) + cam.SetFocalPoint(xc,yc,0.) + if geo is None: + if flipY: + cam.Elevation(180.) + cam.Roll(180.) + pass + if flipX: + cam.Azimuth(180.) + T = vtk.vtkTransform() T.Scale(xScale,yScale,1.) @@ -1733,24 +1750,7 @@ def fitToViewport(self,Actor,vp,wc=None,geo=None): plane.SetNormal(outNormal[0], outNormal[1], outNormal[2]) plane = planeCollection.GetNextItem() - if not didRenderer: - xc = xScale*float(Xrg[1]+Xrg[0])/2. - yc = yScale*float(Yrg[1]+Yrg[0])/2. - xd = xScale*float(Xrg[1]-Xrg[0])/2. - yd = yScale*float(Yrg[1]-Yrg[0])/2. - cam = Renderer.GetActiveCamera() - cam.ParallelProjectionOn() - cam.SetParallelScale(yd) - cd = cam.GetDistance() - cam.SetPosition(xc,yc,cd) - cam.SetFocalPoint(xc,yc,0.) - if geo is None: - if flipY: - cam.Elevation(180.) - cam.Roll(180.) - pass - if flipX: - cam.Azimuth(180.) + Renderer.AddActor(Actor) return Renderer def update_input(self,vtkobjects,array1,array2=None,update=True): diff --git a/Packages/vcs/Lib/manageElements.py b/Packages/vcs/Lib/manageElements.py index fbc2ee31e8..bdf0883c43 100644 --- a/Packages/vcs/Lib/manageElements.py +++ b/Packages/vcs/Lib/manageElements.py @@ -1021,9 +1021,9 @@ def getscatter(GSp_name_src='default'): getscatter.__doc__ = getscatter.__doc__ % (plot_keywords_doc,graphics_method_core,axesconvert, get_GM_input, scatter_output) def createline(name=None, source='default', ltype=None, - width=None, color=None, priority=1, + width=None, color=None, priority=None, viewport=None, worldcoordinate=None, - x=None, y=None, projection='default'): + x=None, y=None, projection=None): """ Function: createline # Construct a new line secondary method @@ -1071,7 +1071,8 @@ def createline(name=None, source='default', ltype=None, ln.x = x if (y is not None): ln.y = y - ln.projection=projection + if (projection is not None): + ln.projection=projection return ln def getline(name='default', ltype=None, width=None, color=None, @@ -1133,7 +1134,7 @@ def getline(name='default', ltype=None, width=None, color=None, return ln def createmarker(name=None, source='default', mtype=None, - size=None, color=None,priority=1, + size=None, color=None,priority=None, viewport=None, worldcoordinate=None, x=None, y=None,projection=None): """ @@ -1244,7 +1245,7 @@ def getmarker(name='default', mtype=None, size=None, color=None, return mrk def createfillarea(name=None, source='default', style=None, - index=None, color=None, priority=1, + index=None, color=None, priority=None, viewport=None, worldcoordinate=None, x=None, y=None): """ @@ -1353,7 +1354,7 @@ def getfillarea(name='default', style=None, return fa def createtexttable(name=None, source='default', font=None, - spacing=None, expansion=None, color=None, priority=1, + spacing=None, expansion=None, color=None, priority=None, viewport=None, worldcoordinate=None, x=None, y=None): """ @@ -1507,7 +1508,7 @@ def gettextorientation(To_name_src='default'): raise ValueError,"The textorientation '%s' does not exists" % To_name_src return vcs.elements["textorientation"][To_name_src] -def createtextcombined(Tt_name=None, Tt_source='default', To_name=None, To_source='default', font=None, spacing=None, expansion=None, color=None, priority=1, viewport=None, worldcoordinate=None, x=None, y=None, height=None, angle=None, path=None, halign=None, valign=None, projection=None): +def createtextcombined(Tt_name=None, Tt_source='default', To_name=None, To_source='default', font=None, spacing=None, expansion=None, color=None, priority=None, viewport=None, worldcoordinate=None, x=None, y=None, height=None, angle=None, path=None, halign=None, valign=None, projection=None): """ Function: createtext or createtextcombined # Construct a new text combined secondary method diff --git a/Packages/vcs/Lib/projection.py b/Packages/vcs/Lib/projection.py index 88c3661e7a..69c9b2c6a3 100644 --- a/Packages/vcs/Lib/projection.py +++ b/Packages/vcs/Lib/projection.py @@ -22,6 +22,10 @@ import vcs import copy +#projection that seems to be doing a circle +# We will probably to add some more in it as we find more that fit this +round_projections = ['polar (non gctp)','stereographic', + 'orthographic',"ortho",] def process_src(nm,code): try: gm = Proj(nm) diff --git a/Packages/vcs/Lib/template.py b/Packages/vcs/Lib/template.py index 60316aab33..7d7b4c4657 100644 --- a/Packages/vcs/Lib/template.py +++ b/Packages/vcs/Lib/template.py @@ -35,6 +35,7 @@ from types import * import inspect import cdutil +from projection import round_projections ## Following for class properties def _getgen(self,name): @@ -944,9 +945,35 @@ def drawTicks(self,slab,gm,x,axis,number,vp,wc,bg=0,X=None,Y=None,**kargs): # the following to make sure we have a unique name, # i put them together assuming it would be faster ticks=x.createline(source=obj.line) - tt=x.createtext(Tt_source=objlabl.texttable,To_source=objlabl.textorientation) + ticks.projection = gm.projection ticks.priority=obj.priority + tt=x.createtext(Tt_source=objlabl.texttable,To_source=objlabl.textorientation) + tt.projection = gm.projection tt.priority=objlabl.priority + if vcs.elements["projection"][gm.projection].type!="linear": + ticks.viewport=vp + ticks.worldcoordinate=wc + tt.worldcoordinate=wc + if axis=="y": + tt.viewport=[objlabl.x,self.data.x2,self.data.y1,self.data.y2] + if vcs.elements["projection"][tt.projection].type in round_projections: + tt.priority=0 + else: + if vcs.elements["projection"][tt.projection].type in round_projections: + xmn,xmx=vcs.minmax(self.data.x1,self.data.x2) + ymn,ymx=vcs.minmax(self.data.y1,self.data.y2) + xwiden = .02 + ywiden = .02 + xmn -= xwiden + xmx += xwiden + ymn -= ywiden + ymx += ywiden + vp = [max(0.,xmn),min(xmx,1.),max(0,ymn),min(ymx,1.)] + tt.viewport=vp + pass + else: + tt.viewport=[self.data.x1,self.data.x2,objlabl.y,self.data.y2] + # initialize the list of values tstring=[] xs=[] @@ -960,46 +987,75 @@ def drawTicks(self,slab,gm,x,axis,number,vp,wc,bg=0,X=None,Y=None,**kargs): if isinstance(loc,str): loc = vcs.elements["list"].get(loc,{}) # set the x/y/text values + xmn,xmx = vcs.minmax(wc[0],wc[1]) + ymn,ymx = vcs.minmax(wc[2],wc[3]) for l in loc.keys(): if axis=='x': - mn,mx = vcs.minmax(wc[0],wc[1]) - if mn<=l<=mx: - xs.append([(l-wc[0])/dx+vp[0],(l-wc[0])/dx+vp[0]]) - ys.append([obj.y1,obj.y2]) - txs.append((l-wc[0])/dx+vp[0]) - tys.append(objlabl.y) - tstring.append(loc[l]) + if xmn<=l<=xmx: + if vcs.elements["projection"][gm.projection].type=="linear": + xs.append([(l-wc[0])/dx+vp[0],(l-wc[0])/dx+vp[0]]) + ys.append([obj.y1,obj.y2]) + txs.append((l-wc[0])/dx+vp[0]) + tys.append(objlabl.y) + else: + xs.append([l,l]) + end = wc[2]+(wc[3]-wc[2])*(obj.y2-obj.y1)/(self.data._y2-self._data.y1) + ys.append([wc[2],end]) + txs.append(l) + tys.append(wc[3]) + tstring.append(loc[l]) elif axis=='y': - mn,mx = vcs.minmax(wc[2],wc[3]) - if mn<=l<=mx: - ys.append([(l-wc[2])/dy+vp[2],(l-wc[2])/dy+vp[2]]) - xs.append([obj.x1,obj.x2]) - tys.append((l-wc[2])/dy+vp[2]) - txs.append(objlabl.x) - tstring.append(loc[l]) + if ymn<=l<=ymx: + if vcs.elements["projection"][gm.projection].type=="linear": + ys.append([(l-wc[2])/dy+vp[2],(l-wc[2])/dy+vp[2]]) + xs.append([obj.x1,obj.x2]) + tys.append((l-wc[2])/dy+vp[2]) + txs.append(objlabl.x) + else: + ys.append([l,l]) + end = wc[0]+(wc[1]-wc[0])*(obj._x2-obj._x1)/(self._data._x2-self._data.x1) + if vcs.elements["projection"][gm.projection].type!="linear" and end<-180.: + end=wc[0] + xs.append([wc[0],end]) + tys.append(l) + txs.append(wc[0]) + tstring.append(loc[l]) # now does the mini ticks if getattr(gm,axis+'mtics'+number)!='': obj=getattr(self,axis+'mintic'+number) - for l in getattr(gm,axis+'mtics'+number).keys(): - a=getattr(gm,axis+'mtics'+number)[l] - if axis=='x': - mn,mx = vcs.minmax(wc[0],wc[1]) - if mn<=l<=mx: - xs.append([(l-wc[0])/dx+vp[0],(l-wc[0])/dx+vp[0]]) - ys.append([obj.y1,obj.y2]) - tstring.append(a) - elif axis=='y': - mn,mx = vcs.minmax(wc[2],wc[3]) - if mn<=l<=mx: - ys.append([(l-wc[2])/dy+vp[2],(l-wc[2])/dy+vp[2]]) - xs.append([obj.x1,obj.x2]) - tstring.append(a) + if obj.priority>0: + ynum = getattr(self._data,"_y%i" % number) + xnum = getattr(self._data,"_x%i" % number) + for l in getattr(gm,axis+'mtics'+number).keys(): + a=getattr(gm,axis+'mtics'+number)[l] + if axis=='x': + if xmn<=l<=xmx: + if vcs.elements["projection"][gm.projection].type=="linear": + xs.append([(l-wc[0])/dx+vp[0],(l-wc[0])/dx+vp[0]]) + ys.append([obj.y1,obj.y2]) + tstring.append(a) + else: + xs.append([l,l]) + ys.append([wc[2], + wc[2]+(wc[3]-wc[2])*(obj._y-ynum)/(self._data._y2-self._data._y1)]) + tstring.append(a) + elif axis=='y': + if ymn<=l<=ymx: + if vcs.elements["projection"][gm.projection].type=="linear": + ys.append([(l-wc[2])/dy+vp[2],(l-wc[2])/dy+vp[2]]) + xs.append([obj.x1,obj.x2]) + tstring.append(a) + else: + ys.append([l,l]) + xs.append([wc[0], + wc[0]+(wc[1]-wc[0])*(obj._x-xnum)/(self._data._x2-self._data._x1)]) + tstring.append(a) if txs!=[]: tt.string=tstring tt.x=txs tt.y=tys - displays.append(x.text(tt,bg=bg,**kargs)) + displays.append(x.text(tt,bg=bg,ratio="none",**kargs)) if xs!=[]: ticks._x=xs ticks._y=ys @@ -1263,15 +1319,19 @@ def plot(self,x,slab,gm,bg=0,min=None,max=None,X=None,Y=None,**kargs): dp.backend["vtk_backend_template_attribute"] = "dataname" displays.append(dp) sp = tt.name.split(":::") - del(vcs.elements["texttable"][sp[0]]) - del(vcs.elements["textorientation"][sp[1]]) - del(vcs.elements["textcombined"][tt.name]) + if kargs.get("donotstoredisplay",True): + del(vcs.elements["texttable"][sp[0]]) + del(vcs.elements["textorientation"][sp[1]]) + del(vcs.elements["textcombined"][tt.name]) kargs["donotstoredisplay"]=True if not isinstance(gm,vcs.taylor.Gtd): nms = ["x","y","z","t"] for i,ax in enumerate(slab.getAxisList()[::-1]): + if nms[i] in ["x","y"] and hasattr(gm,"projection") and \ + vcs.elements["projection"][gm.projection].type in round_projections: + continue nm=nms[i]+"name" sub = getattr(self,nm) tt=x.createtext(None,sub.texttable,None,sub.textorientation) @@ -1305,78 +1365,41 @@ def plot(self,x,slab,gm,bg=0,min=None,max=None,X=None,Y=None,**kargs): displays+=self.drawTicks(slab,gm,x,axis='y',number='1',vp=vp,wc=wc,bg=bg,X=X,Y=Y,**kargs) displays+=self.drawTicks(slab,gm,x,axis='y',number='2',vp=vp,wc=wc,bg=bg,X=X,Y=Y,**kargs) + if X is None: + X=slab.getAxis(-1) + if Y is None: + Y=slab.getAxis(-2) + displays = [] + wc2 = vcs.utils.getworldcoordinates(gm,X,Y) # Do the boxes and lines - b=self.box1 - if b.priority!=0: - l=x.createline(source=b.line) - l._x=[b._x1,b._x2,b._x2,b._x1,b._x1] - l._y=[b._y1,b._y1,b._y2,b._y2,b._y1] - l._priority=b._priority - displays.append(x.line(l,bg=bg,**kargs)) - del(vcs.elements["line"][l.name]) - - b=self.box2 - if b.priority!=0: - l=x.createline(source=b.line) - l._x=[b._x1,b._x2,b._x2,b._x1,b._x1] - l._y=[b._y1,b._y1,b._y2,b._y2,b._y1] - l._priority=b.priority - displays.append(x.line(l,bg=bg,**kargs)) - del(vcs.elements["line"][l.name]) - - b=self.box3 - if b.priority!=0: - l=x.createline(source=b.line) - l._x=[b._x1,b._x2,b._x2,b._x1,b._x1] - l._y=[b._y1,b._y1,b._y2,b._y2,b._y1] - l._priority=b._priority - displays.append(x.line(l,bg=bg,**kargs)) - del(vcs.elements["line"][l.name]) - - b=self.box4 - if b.priority!=0: - l=x.createline(source=b.line) - l._x=[b._x1,b._x2,b._x2,b._x1,b._x1] - l._y=[b._y1,b._y1,b._y2,b._y2,b._y1] - l._priority=b._priority - displays.append(x.line(l,bg=bg,**kargs)) - del(vcs.elements["line"][l.name]) - - b=self.line1 - if b.priority!=0: - l=x.createline(source=b.line) - l._x=[b._x1,b._x2] - l._y=[b._y1,b._y2] - l._priority=b.priority - displays.append(x.line(l,bg=bg,**kargs)) - del(vcs.elements["line"][l.name]) - - b=self.line2 - if b.priority!=0: - l=x.createline(source=b.line) - l._x=[b._x1,b._x2] - l._y=[b._y1,b._y2] - l._priority=b._priority - displays.append(x.line(l,bg=bg,**kargs)) - del(vcs.elements["line"][l.name]) - - b=self.line3 - if b.priority!=0: - l=x.createline(source=b.line) - l._x=[b._x1,b._x2] - l._y=[b._y1,b._y2] - l._priority=b._priority - displays.append(x.line(l,bg=bg,**kargs)) - del(vcs.elements["line"][l.name]) - - b=self.line4 - if b.priority!=0: - l=x.createline(source=b.line) - l._x=[b._x1,b._x2] - l._y=[b._y1,b._y2] - l._priority=b._priority - displays.append(x.line(l,bg=bg,**kargs)) - del(vcs.elements["line"][l.name]) + for tp in ["box","line"]: + for num in ["1","2"]: + e = getattr(self,tp+num) + if e.priority!=0: + l=x.createline(source=e.line) + if hasattr(gm,"projection"): + l.projection=gm.projection + if vcs.elements["projection"][l.projection].type!="linear": + l.worldcoordinate=wc2 + l.viewport=[e._x1,e._x2,e._y1,e._y2] + dx = (e._x2-e._x1)/(self.data.x2-self.data.x1)*(wc2[1]-wc2[0]) + dy = (e._y2-e._y1)/(self.data.y2-self.data.y1)*(wc2[3]-wc2[2]) + if tp == "line": + l._x = [wc2[0],wc2[0]+dx] + l._y = [wc2[2],wc2[2]+dy] + elif tp=="box" and vcs.elements["projection"][l.projection].type in round_projections: + l._x = [[-180.,180],[-180.,180]] + l._y = [wc2[3],wc2[3]],[wc2[2],wc2[2]] + else: + l._x = [wc2[0],wc2[0]+dx,wc2[0]+dx,wc2[0],wc2[0]] + l._y = [wc2[2],wc2[2],wc2[3],wc2[3],wc2[2]] + else: + l._x = [e._x1,e._x2,e._x2,e._x1,e._x1] + l._y = [e._y1,e._y1,e._y2,e._y2,e._y1] + l._priority=e._priority + displays.append(x.plot(l,bg=bg,ratio="none",**kargs)) + del(vcs.elements["line"][l.name]) + #x.mode=m # I think i have to use dict here because it's a valid value # (obviously since i got it from the object itself and didn't touch it diff --git a/Packages/vcs/Lib/utils.py b/Packages/vcs/Lib/utils.py index bfa487bc7f..fe80f9648e 100644 --- a/Packages/vcs/Lib/utils.py +++ b/Packages/vcs/Lib/utils.py @@ -1516,32 +1516,35 @@ def getworldcoordinates(gm,X,Y): """Given a graphics method and two axes figures out correct world coordinates""" # compute the spanning in x and y, and adjust for the viewport wc=[0,1,0,1] - if gm.datawc_x1 > 9.E19 : - try: - i=0 - try: - while X[:][i].count()==0: - i+=1 - except: - pass - wc[0]=X[:][i] - except: - wc[0]=X[:].min() - else: - wc[0] = gm.datawc_x1 - if gm.datawc_x2 > 9.E19 : - try: - i=-1 - try: - while X[:][i].count()==0: - i-=1 - except: - pass - wc[1]=X[:][i] - except: - wc[1]=X[:].max() - else: - wc[1] = gm.datawc_x2 + try: + if gm.datawc_x1 > 9.E19 : + try: + i=0 + try: + while X[:][i].count()==0: + i+=1 + except: + pass + wc[0]=X[:][i] + except: + wc[0]=X[:].min() + else: + wc[0] = gm.datawc_x1 + if gm.datawc_x2 > 9.E19 : + try: + i=-1 + try: + while X[:][i].count()==0: + i-=1 + except: + pass + wc[1]=X[:][i] + except: + wc[1]=X[:].max() + else: + wc[1] = gm.datawc_x2 + except: + return wc if (((not isinstance(X,cdms2.axis.TransientAxis) and isinstance(Y,cdms2.axis.TransientAxis)) or not vcs.utils.monotonic(X[:])) and numpy.allclose([gm.datawc_x1,gm.datawc_x2],1.e20))\ or (hasattr(gm,"projection") and vcs.elements["projection"][gm.projection].type!="linear") : wc[0]=X[:].min() diff --git a/Packages/vcs/Lib/vcs2vtk.py b/Packages/vcs/Lib/vcs2vtk.py index 2e3457ed75..f4ba888387 100644 --- a/Packages/vcs/Lib/vcs2vtk.py +++ b/Packages/vcs/Lib/vcs2vtk.py @@ -10,6 +10,7 @@ import cdms2 import warnings import cdtime +from projection import round_projections f = open(os.path.join(vcs.prefix,"share","vcs","wmo_symbols.json")) wmo = json.load(f) @@ -868,13 +869,36 @@ def genTextActor(renderer,string=None,x=None,y=None,to='default',tt='default',cm sz = renderer.GetRenderWindow().GetSize() actors=[] + pts = vtk.vtkPoints() + geo = None + if vcs.elements["projection"][tt.projection].type!="linear": + # Need to figure out new WC + Npts = 20 + for i in range(Npts+1): + X = tt.worldcoordinate[0]+float(i)/Npts*(tt.worldcoordinate[1]-tt.worldcoordinate[0]) + for j in range(Npts+1): + Y = tt.worldcoordinate[2]+float(j)/Npts*(tt.worldcoordinate[3]-tt.worldcoordinate[2]) + pts.InsertNextPoint(X,Y,0.) + geo,pts = project(pts,tt.projection,tt.worldcoordinate,geo=None) + wc = pts.GetBounds()[:4] + #renderer.SetViewport(tt.viewport[0],tt.viewport[2],tt.viewport[1],tt.viewport[3]) + renderer.SetWorldPoint(wc) + + for i in range(n): t = vtk.vtkTextActor() p=t.GetTextProperty() prepTextProperty(p,sz,to,tt,cmap) - t.SetInput(string[i]) - X,Y = world2Renderer(renderer,x[i],y[i],tt.viewport,tt.worldcoordinate) + pts = vtk.vtkPoints() + pts.InsertNextPoint(x[i],y[i],0.) + if geo is not None: + geo,pts = project(pts,tt.projection,tt.worldcoordinate,geo=geo) + X,Y,tz=pts.GetPoint(0) + X,Y = world2Renderer(renderer,X,Y,tt.viewport,wc) + else: + X,Y = world2Renderer(renderer,x[i],y[i],tt.viewport,tt.worldcoordinate) t.SetPosition(X,Y) + t.SetInput(string[i]) #T=vtk.vtkTransform() #T.Scale(1.,sz[1]/606.,1.) #T.RotateY(to.angle) @@ -1186,9 +1210,9 @@ def prepMarker(renWin,marker,cmap=None): while len(a)