import Pmw, AppShell, math, time, string, marshal from toolbarbutton import ToolBarButton import tkFileDialog from tkSimpleDialog import Dialog import mesh from Tkinter import FALSE,TRUE, Frame,X, LEFT,YES,BOTH,ALL,Widget,CURRENT, Label,W, Entry, E, StringVar, END, Checkbutton, Radiobutton, IntVar, DISABLED, NORMAL #from cursornames import TLC,TRC, BLC, BRC, TS, RS, LS, BS from tkMessageBox import showerror, _show, QUESTION,YESNOCANCEL import types import visualmesh import os import profile import load_mesh.loadASCII from alpha_shape.alpha_shape import AlphaError # CONSTANTS VERT_SELECT_ADDING_SEG_COLOR = 'orange' SELECT_COLOR = 'red' SEG_COLOUR = 'blue' TRIANGLE_COLOUR = 'green' APPLICATION_NAME = 'Pmesh' SET_COLOUR = 'red' DEFAULT_ATTRIBUTE = 'elevation' #for alpha shapes NO_SELECTION = 0 AUTO = 1 SET_ALPHA = 2 class Draw(AppShell.AppShell): usecommandarea = 1 appname = APPLICATION_NAME frameWidth = 840 frameHeight = 600 def createButtons(self): """ Add buttons to the bottom of the GUI """ self.buttonAdd('Postscript', helpMessage='Save current drawing (as PostScript)', statusMessage='', command=self.ipostscript) self.buttonAdd('Clear', helpMessage='Delete the mesh', statusMessage='', command=self.clearMesh) self.buttonAdd('Close', helpMessage='Close Screen', statusMessage='', command=self.close) def createBase(self): """ Create the GUI framework. Set up the GUI """ self.toolbar = self.createcomponent('toolbar', (), None, Frame, (self.interior(),), background="gray90") self.toolbar.pack(fill=X) self.scrolledcanvas = self.createcomponent('ScrolledCanvas', (), None, Pmw.ScrolledCanvas, (self.interior(),) ,borderframe = 1 ,labelpos = 'n' ) self.scrolledcanvas.configure(hscrollmode = 'dynamic') self.scrolledcanvas.configure(vscrollmode = 'dynamic') self.scrolledcanvas.pack(side=LEFT, expand=YES, fill=BOTH) self.canvas = self.scrolledcanvas.component('canvas') self.canvas.configure( background="white" ) self.canvas.pack(side=LEFT, expand=YES, fill=BOTH) Widget.bind(self.canvas, "", self.mouseDown) Widget.bind(self.canvas, "", self.rightMouseUp) Widget.bind(self.canvas, "",self.DeleteSelectedMeshObject) # "" didn't work.. #Widget.bind(self.canvas, "", self.DeleteSelectedMeshObject) #self.root.bind("", self.setRegular) #self.root.bind("", self.setRegular) self.scrolledcanvas.resizescrollregion() # def setRegular(self, event): # if event.type == '2' and event.keysym == 'Shift_L': # self.regular = TRUE # else: # self.regular = FALSE def createMenus(self): """ Add menus to the top of the GUI """ self.menuBar.deletemenuitems('File',0) self.menuBar.addmenuitem('File', 'command', 'New mesh', label='New', command=self.clearMesh) self.menuBar.addmenuitem('File', 'command', 'Open mesh', label='Open...', command=self.importFile) self.menuBar.addmenuitem('File', 'command', 'Save mesh', label='Save', command=self.saveDrawing) self.menuBar.addmenuitem('File', 'command', 'Save mesh', label='SaveAs...', command=self.saveAsDrawing) self.menuBar.addmenuitem('File', 'separator') self.menuBar.addmenuitem('File', 'command', 'Add ungenerated file from arcGIS', label='Add ungenerated file...', command=self.ImportUngenerate) self.menuBar.addmenuitem('File', 'command', 'Export ASCII obj', label='Export ASCII obj', command=self.exportObj) self.menuBar.addmenuitem('File', 'command', 'Export ASCII segment outline', label='Export ASCII segment outline...', command=self.exportASCIIsegmentoutlinefile) self.menuBar.addmenuitem('File', 'command', 'Export ASCII xya file', label='Export ASCII xya file...', command=self.exportPointsFile) self.menuBar.addmenuitem('File', 'command', 'add Segments to connect all vertices' , label='join vertices', command=self.joinVertices) self.menuBar.addmenuitem('File', 'command', 'add Segments to form alpha shape' , label='Auto segment', command=self.auto_segment) self.menuBar.addmenuitem('File', 'command', 'modify the alpha boundary by applying filters', label='filter alpha boundary', command=self.auto_segmentFilter) self.menuBar.addmenuitem('File', 'command', 'Normalise mesh', label='Normalise mesh', command=self.normaliseMesh) self.menuBar.addmenuitem('File', 'command', 'Normalise mesh for glutobj', label='Normalise mesh for glutobj', command=self.normalise4ObjMesh) self.menuBar.addmenuitem('File', 'separator') self.menuBar.addmenuitem('File', 'command', '', label='Print geo reference', command=self.printGeoReference) self.menuBar.addmenuitem('File', 'separator') self.menuBar.addmenuitem('File', 'command', 'Exit program', label='Exit', command=self.quit) def createTools(self): """ Add buttons to the top of the GUI """ self.mouseDownFunc = {} self.modeClass = {} ToolBarButton(self, self.toolbar, 'sep', 'sep.gif', width=10, state='disabled') for key, balloon, mouseDownFunc, Mode in [ ('pointer','Edit drawing eventually. Right now this does nothing', self.drag, None) ,('vertex', 'Vertex mode', self.drawVertex, mesh.Vertex) ,('segment', 'Segment mode',self.selectSegmentPoint, mesh.Segment) ,('hole', 'hole mode',self.drawHole, mesh.Hole) ,('region', 'region mode',self.drawRegion, mesh.Region) ]: t = ToolBarButton(self, self.toolbar, key, '%s.gif' % key, command=self.selectFunc, balloonhelp=balloon, statushelp='') t.cycle("DrawMode") if key == 'pointer': #FIXME- this is specified in line 1062 as well # self.selectFunc('pointer') self.curFunc = self.drawVertex t.setInitialSunkenButton("DrawMode") self.modeClass[key] = Mode # for actions that occur when the mouse goes down self.mouseDownFunc[key] = mouseDownFunc def createZooms(self): """ Add zoom buttons to the top of the GUI """ ToolBarButton(self, self.toolbar, 'sep', 'sep.gif', width=10, state='disabled') zoom = '0.5' ToolBarButton(self, self.toolbar, zoom, 'zoom%s.gif' % zoom, command=self.selectZoom, balloonhelp='*%s zoom' % zoom, statushelp='') ToolBarButton(self, self.toolbar,'1.0', 'zoomToMesh.gif', command=self.ResizeToFitWrapper, balloonhelp='Zooms to mesh size', statushelp='') zoom = '2' ToolBarButton(self, self.toolbar, zoom, 'zoom%s.gif' % zoom, command=self.selectZoom, balloonhelp='*%s zoom' % zoom, statushelp='') def createEdits(self): """ Add Edit buttons to the top of the GUI """ ToolBarButton(self, self.toolbar, 'sep', 'sep.gif', width=10, state='disabled') for key, func, balloon in [ ('addVertex', self.windowAddVertex, 'add Vertex'), ('edit', self.windowEdit, 'edit selected object'), ('default', self.windowDefault, 'set default value for selected mode'), ('joinVer', self.joinVerticesButton, 'add Segments to connect all vertices'), # ('autoSegHull', self.auto_segmentHullButton, 'add Segments to form alpha shape, using Hull'), # ('autoSeg', self.auto_segmentButton, 'add Segments to form alpha shape'), ('autoSegGiveAlpha', self.auto_segmentGiveAlphaButton, 'add Segments to form alpha shape, specify alpha'), ('meshGen', self.windowMeshGen, 'Generate Mesh')]: ToolBarButton(self, self.toolbar, key, '%s.gif' % key, command=func, balloonhelp=balloon, statushelp='' ) def createSetTools(self): """ Add set tool buttons to the top of the GUI """ ToolBarButton(self, self.toolbar, 'sep', 'sep.gif', width=10, state='disabled') for key, func, balloon in [ ('threshold', self.threshold, 'threshold the set'), ('Courant_threshold', self.Courant_threshold, 'Courant_threshold the set'), ('gradient_threshold', self.gradient_threshold, 'gradient_threshold the set'), ('smooth', self.smooth_polySet, 'smooth the polygons'), ('polyset', self.triangles_to_polySet, 'make a poly set out of selected triangles')]: #('refineSet', self.refineSet, 'Refine the set')]: ToolBarButton(self, self.toolbar, key, '%s.gif' %key, command=func, balloonhelp=balloon, statushelp='' ) def createSetIcons(self): """ Add Edit buttons to the top of the GUI """ ToolBarButton(self, self.toolbar, 'sep', 'sep.gif', width=10, state='disabled') for key, func, balloon in [ ('selectAllTriangles', self.selectAllTriangles, 'select all'), ('none', self.clearSelection, 'clear selection')]: ToolBarButton(self, self.toolbar, key, '%s.gif' %key, command=func, balloonhelp=balloon, statushelp='' ) def createVisualiseIcons(self): """ Add Edit buttons to the top of the GUI """ ToolBarButton(self, self.toolbar, 'sep', 'sep.gif', width=10, state='disabled') for key, func, balloon in [ ('visualise', self.visualise, 'Visualise mesh triangles'), ('unvisualise', self.unvisualise, 'Do not visualise mesh triangles (for large meshes)')]: ToolBarButton(self, self.toolbar, key, '%s.gif' %key, command=func, balloonhelp=balloon, statushelp='' ) def refineSet(self,parent): self.mesh.refineSet(self.selSet) self.visualiseMesh(self.mesh) def setStructureNumber(self,parent): dialog = setStructureNumberDialog(self.canvas) if dialog.numberOK: self.structureSize = dialog.number def erode(self, parent): #Not implimented self.canvas.delete(ALL) self.mesh.erode(self.selSet,structureSize=self.structureSize) self.visualiseMesh(self.mesh) def dilate(self, parent): #Not implimented self.canvas.delete(ALL) self.mesh.dilate(self.selSet,structureSize=self.structureSize) self.visualiseMesh(self.mesh) def general_threshold(self,parent,function,function_description): """ add a vertex using a window and entering x y values. the parent attribute isn't used by this function. need to userstand toolbarbutton.py to know how to get rid of it. """ if self.selSet == 'None': self.selectAllTriangles(parent) dialog = GeneralThresholdDialog(self.canvas,self.mesh.attributeTitles,function_description) if dialog.minmaxValuesOk: self.canvas.delete(ALL) min = dialog.min max = dialog.max attribute_name = dialog.attribute_name self.mesh.general_threshold(self.selSet,min=min,max=max,attribute_name = attribute_name,function=function) self.visualiseMesh(self.mesh) def threshold(self, parent): """ add a vertex using a window and entering x y values. the parent attribute isn't used by this function. need to userstand toolbarbutton.py to know how to get rid of it. """ function = self.mesh.av_att function_description = 'average attribute of triangle' self.general_threshold(parent,function,function_description) def Courant_threshold(self, parent): """ add a vertex using a window and entering x y values. the parent attribute isn't used by this function. need to userstand toolbarbutton.py to know how to get rid of it. """ function = self.mesh.Courant_ratio function_description = 'average attribute/area of triangle' self.general_threshold(parent,function,function_description) def gradient_threshold(self, parent): """ add a vertex using a window and entering x y values. the parent attribute isn't used by this function. need to userstand toolbarbutton.py to know how to get rid of it. """ function = self.mesh.Gradient function_description = 'average gradient of triangle' self.general_threshold(parent,function,function_description) def smooth_polySet(self,parent): dialog = SmoothDialog(self.canvas) if dialog.valueOK: min_radius = dialog.min_radius self._smooth_polySet(min_radius) def _smooth_polySet(self,min_radius): userVertices,userSegments,alphaSegments = \ self.mesh.smooth_polySet(min_radius=min_radius) self.mesh.userVertices=[] self.mesh.userSegments=[] self.mesh.alphaSegments=[] self.canvas.delete(ALL) event = None print 'len(userVertices.keys())' print len(userVertices.keys()) print 'len(userSegments.keys())' print len(userSegments.keys()) print 'len(alphaSegments.keys())' print len(alphaSegments.keys()) ####### point_keys = {} for vert in userVertices.keys(): assert not point_keys.has_key((vert.x,vert.y)) point_keys[(vert.x,vert.y)]=vert assert len(point_keys.keys())==len(userVertices.keys()) ####### for v in userVertices.keys(): x = v.x*self.SCALE y = v.y*self.SCALE userVertices[(v.x,v.y)]=self.drawVertex(x,y,event) for line in userSegments.keys(): v0 = userVertices[line[0]] v1 = userVertices[line[1]] segment = self.drawSegment(v0,v1) segment.set_tag(userSegments[line].tag) for line in alphaSegments.keys(): v0 = userVertices[line[0]] v1 = userVertices[line[1]] segment = self.drawSegment(v0,v1) segment.set_tag(alphaSegments[line].tag) self.visualiseMesh(self.mesh) def triangles_to_polySet(self,parent): userVertices,userSegments,alphaSegments = \ self.mesh.triangles_to_polySet(self.selSet) self.mesh.userVertices=[] self.canvas.delete(ALL) event = None print 'len(userVertices.keys())' print len(userVertices.keys()) print 'len(userSegments.keys())' print len(userSegments.keys()) print 'len(alphaSegments.keys())' print len(alphaSegments.keys()) ####### point_keys = {} for vert in userVertices.keys(): assert not point_keys.has_key((vert.x,vert.y)) point_keys[(vert.x,vert.y)]=vert assert len(point_keys.keys())==len(userVertices.keys()) ####### for v in userVertices.keys(): if userVertices[v] is True: x = v.x*self.SCALE y = v.y*self.SCALE userVertices[(v.x,v.y)]=self.drawVertex(x,y,event) for line in userSegments.keys(): v0 = userVertices[line[0]] v1 = userVertices[line[1]] segment = self.drawSegment(v0,v1) segment.set_tag(userSegments[line].tag) for line in alphaSegments.keys(): v0 = userVertices[line[0]] v1 = userVertices[line[1]] segment = self.drawSegment(v0,v1) segment.set_tag(alphaSegments[line].tag) self.visualiseMesh(self.mesh) #self.smooth_polySet(parent) def selectTriangles(self,setName): """ """ self.canvas.delete(ALL) self.selSet = setName self.visualiseMesh(self.mesh) def selectAllTriangles(self,parent): """ selected all triangles in the mesh """ self.canvas.delete(ALL) self.selSet = self.mesh.selectAllTriangles() self.visualiseMesh(self.mesh) def clearSelection(self,parent): #FIXME looks like self.clearSelections - change name (Peter) """ """ self.canvas.delete(ALL) self.selSet = self.mesh.clearSelection() self.visualiseMesh(self.mesh) def visualise(self,parent): self.canvas.delete(ALL) self.Visualise = True self.visualiseMesh(self.mesh) def unvisualise(self,parent): self.canvas.delete(ALL) self.Visualise = False self.visualiseMesh(self.mesh) def createMesh(self): """ Build the data structures for storing the mesh objects """ self.mesh = mesh.Mesh() self.Vertices = visualmesh.vPoints(mesh.Vertex) self.Segments = visualmesh.vSegments(mesh.Segment) self.Holes = visualmesh.vPoints(mesh.Hole) self.Regions = visualmesh.vRegions(mesh.Region) self.UserMesh = visualmesh.vMesh([self.Vertices,self.Segments,self.Holes,self.Regions]) self.Triangles = visualmesh.vTriangles(mesh.Triangle) self.selSet='None' def deleteMesh(self): """ Delete the data structures for storing the mesh objects """ self.mesh = None self.Vertices = None self.Segments = None self.Triangles = None def addCylinders(self): """ Automatically add some verts and segs to the mesh.Used in Debugging center and radius """ from coordinate_transforms.geo_reference import Geo_reference,DEFAULT_ZONE offset_x = 30 offset_y = 40 x_origin = 10-offset_x y_origin = 20-offset_y r = 10 pi = math.pi num_of_cuts = 100 cuts = [] factor = 2* math.pi/num_of_cuts for cut in range(num_of_cuts): cuts.append(cut*factor) for radius in cuts: x = x_origin + r * math.cos(radius) y = y_origin + r * math.sin(radius) v = self.drawVertex(x,y,None) if not radius == 0.0: # FIXME self.drawSegment(v,v_old) else: v_first = v v_old = v self.drawSegment(v,v_first) region = self.drawRegion(x_origin, y_origin, 0) region.setTag("setheight5") x_origin = 30-offset_x y_origin = 30-offset_y r = 5 pi = math.pi num_of_cuts = 100 cuts = [] factor = 2* math.pi/num_of_cuts for cut in range(num_of_cuts): cuts.append(cut*factor) for radius in cuts: x = x_origin + r * math.cos(radius) y = y_origin + r * math.sin(radius) v = self.drawVertex(x,y,None) if not radius == 0.0: # FIXME self.drawSegment(v,v_old) else: v_first = v v_old = v self.drawSegment(v,v_first) region = self.drawRegion(x_origin, y_origin, 0) region.setTag("setheight10") self.mesh.geo_reference = Geo_reference(zone=DEFAULT_ZONE, xllcorner=offset_x, yllcorner=offset_y) #Since the new vertex may be off screen self.scrolledcanvas.resizescrollregion() def selectFunc(self, tag): """ Change the current mode class When changing from one mode to another """ self.mouseDownCurFunc = self.mouseDownFunc[tag] self.curModeClass = self.modeClass[tag] self.clearSelections() self.canvas.config(cursor='arrow') # I can make it arrow, but it will change back to pointer, after # adding an object # if self.curFunc == self.func['pointer']: # self.canvas.config(cursor='arrow') # else: # self.canvas.config(cursor='crosshair') def clearSelections(self): """ deselect objects that have been selected """ if self.selMeshObject: self.deselectMeshObject(self.selMeshObject, self.selMeshTag) if self.selVertex: self.deselectVertex(self.selVertex, self.selVertexTag) def selectZoom(self, tag): """ Zoom in or out of the current mesh view """ fraction = string.atof(tag) self.SCALE *= fraction self.scrolledcanvas.scale(ALL, 0, 0, fraction, fraction) # Redraw all of the vertices, holes and regions, #so the squares representing vertices # don't get bigger vertices = self.mesh.getUserVertices() holes = self.mesh.getHoles() regions = self.mesh.getRegions() MeshObjects = vertices + holes + regions # make a list of tags to delete guiIDs = [getattr(MeshObjects[i],'guiID') for i in xrange(len(MeshObjects))] apply(self.canvas.delete, guiIDs) for obj in MeshObjects: if self.selVertex == obj: obj.draw(self.canvas,obj.guiID, scale =self.SCALE ,colour= VERT_SELECT_ADDING_SEG_COLOR) elif self.selMeshObject == obj: obj.draw(self.canvas,obj.guiID, scale =self.SCALE ,colour= SELECT_COLOR) else: obj.draw(self.canvas,obj.guiID, scale =self.SCALE ) top, bottom = self.scrolledcanvas.xview() xcenter = (top + bottom)/2 xdiff = xcenter - top xcnew = xcenter - xdiff/fraction top, bottom = self.scrolledcanvas.yview() ycenter = (top + bottom)/2 ydiff = ycenter - top ycnew = ycenter - ydiff/fraction self.scrolledcanvas.resizescrollregion() # update so the moveto calls will work... self.scrolledcanvas.update() # but calling update now does make things jerky self.canvas.xview_moveto(xcnew) self.canvas.yview_moveto(ycnew) def windowAddVertex (self, parent): """ add a vertex using a window and entering x y values. the parent attribute isn't used by this function. need to userstand toolbarbutton.py to know how to get rid of it. """ dialog = AddVertexDialog(self.canvas) if dialog.xyValuesOk: print dialog.x print dialog.y self.drawVertex(dialog.x*self.SCALE,dialog.y*self.SCALE,None) #Since the new vertex may be off screen self.ResizeToFit() else: print "bad values" def windowDefault (self, parent): """ the parent attribute isn't used by this function. need to userstand toolbarbutton.py to know how to get rid of it. """ # self.UserMesh is a vMesh instance self.UserMesh.defaultWindow(self.canvas, self.curModeClass) def windowEdit (self, parent): """ the parent attribute isn't used by this function. need to userstand toolbarbutton.py to know how to get rid of it. """ if self.selMeshObject: self.UserMeshChanged = self.UserMesh.editWindow(self.canvas, self.selMeshObject, self.UserMeshChanged) def auto_segmentButton (self, parent): self.auto_segment() def auto_segmentGiveAlphaButton (self, parent): dialog = auto_segmentDialog(self.canvas, self.meshLastAlpha) if dialog.use_optimum.get() == SET_ALPHA: if dialog.alphaValueOk: self.auto_segment(alpha = dialog.alpha, raw_boundary=dialog.raw_boundary.get(), remove_holes=dialog.remove_holes.get(), smooth_indents=dialog.smooth_indents.get(), expand_pinch=dialog.expand_pinch.get()) else: showerror('pMesh', 'Bad alpha value.') else: self.auto_segment(raw_boundary=dialog.raw_boundary.get(), remove_holes=dialog.remove_holes.get(), smooth_indents=dialog.smooth_indents.get(), expand_pinch=dialog.expand_pinch.get()) def auto_segment (self, alpha = None, raw_boundary=True, remove_holes=False, smooth_indents=False, expand_pinch=False ): """ add Segments to bound all vertices """ if len(self.mesh.getUserVertices()) >= 3: try: newsegs, ObjectsToVisuallyDelete, self.meshLastAlpha = \ self.mesh.auto_segment(alpha=alpha, remove_holes=remove_holes, smooth_indents=smooth_indents, expand_pinch=expand_pinch) except AlphaError: showerror('pMesh', 'Unable to auto_segment.') else: for drawOb in ObjectsToVisuallyDelete: self.UserMesh.unvisualise(drawOb, self.canvas) for segment in newsegs: self.serial +=1 self.uniqueID = 'M*%d' % self.serial self.Segments.visualise(segment, self.uniqueID, self.canvas, self.SCALE) else: showerror('pMesh', 'Three or more vetices are needed to be able to auto_segment.') def auto_segmentFilter (self): dialog = auto_segmentFilterDialog(self.canvas) newsegs, ObjectsToVisuallyDelete, self.meshLastAlpha = \ self.mesh.auto_segmentFilter(raw_boundary=dialog.raw_boundary.get(), remove_holes=dialog.remove_holes.get(), smooth_indents=dialog.smooth_indents.get(), expand_pinch=dialog.expand_pinch.get()) #print "newsegs",newsegs #print "ObjectsToVisuallyDelete",ObjectsToVisuallyDelete for drawOb in ObjectsToVisuallyDelete: self.UserMesh.unvisualise(drawOb, self.canvas) for segment in newsegs: self.serial +=1 self.uniqueID = 'M*%d' % self.serial self.Segments.visualise(segment, self.uniqueID, self.canvas, self.SCALE) def joinVerticesButton (self, parent): self.joinVertices() def joinVertices (self): """ add Segments to connect all vertices the parent attribute isn't used by this function. need to userstand toolbarbutton.py to know how to get rid of it. """ if len(self.mesh.getUserVertices()) >= 3: newsegs = self.mesh.joinVertices() for segment in newsegs: self.serial +=1 self.uniqueID = 'M*%d' % self.serial self.Segments.visualise(segment, self.uniqueID, self.canvas, self.SCALE) else: showerror('pMesh', 'Three or more vetices are needed to be able to join vertices.') def windowMeshGen (self, parent): """ The parent attribute isn't used by this function. need to understand toolbarbutton.py to know how to get rid of it. """ # Put exceptions round things. #catch failure in self.mesh.generateMesh dialog = MeshGenDialog(self.canvas, self.MeshMinAngle, self.MeshMaxArea, self.MeshnumTriangles, self.MeshMaxAreaLast) if dialog.ValuesOk: print dialog.minAngle print dialog.maxArea self.clearSelections() self.canvas.delete(ALL) if dialog.goodMaxArea == True: self.MeshMinAngle = dialog.minAngle self.MeshMaxArea = dialog.maxArea self.MeshMaxAreaLast = True self.mesh = self.MeshGenAreaAngle (dialog.minAngle, dialog.maxArea, self.mesh) elif dialog.goodNumTriangles == True: self.MeshMinAngle = dialog.minAngle self.MeshnumTriangles = dialog.numTriangles self.MeshMaxAreaLast = False self.mesh = self.MeshGenAreaNumTriangles (dialog.minAngle, dialog.numTriangles, self.mesh) else: pass print "userMeshChanged = False" self.UserMeshChanged = False self.visualiseMesh(self.mesh) print "Mesh Generation finished" def MeshGenAreaAngle (self, minAngle, maxArea, mesh): """ Generate a mesh, given a minAngle and max area """ tempMesh = mesh try: tempMesh.generateMesh(mode = "pzq"+str(minAngle) +"a"+str(maxArea) +"a") #So areas for regions will be used except AttributeError : # can't catch PyEval_RestoreThread # This doesn't catch tempMesh.generateMesh failing tempMesh = mesh return tempMesh def MeshGenAreaNumTriangles (self, minAngle, numTriangles, mesh): """ Generate a mesh, given a minAngle and rough # of triangles """ #get big triangles #calc area #calc max triangle area # tempMesh = mesh try: tempMesh.generateMesh("pzq1") except AttributeError : # can't catch PyEval_RestoreThread # This doesn't catch tempMesh.generateMesh failing pass meshArea = 0 for triangle in tempMesh.getTriangulation(): meshArea += triangle.calcArea() print "meshArea: ", meshArea maxArea = meshArea/numTriangles return self.MeshGenAreaAngle (minAngle, maxArea, self.mesh) def mouseDown(self, event): """ On a mouse down event, depending on the current state, either add a vertex or a seg etc """ self.curObject = None self.lastx = self.startx = self.canvas.canvasx(event.x) #The screen canvas has y 'flipped'. -1* unflips it self.lasty = self.starty = -1*self.canvas.canvasy(event.y) print "----------------------" self.mouseDownCurFunc( self.lastx, self.lasty,event) #!!! remove the event? # do last def rightMouseUp(self, event): """ On a right mouse button up event select the nearest object. """ found=False if event.widget.find_withtag(CURRENT): # if there's a widget with a tag [tag,string] = self.canvas.gettags(CURRENT) # get a list of them print "tag",tag #tags ('M*1008', 'current') if tag[:2] == 'M*': #!!! this can be removed when there are # only mesh objects on screen #key, value = string.split(tag, '*') objectID = tag print "Found!! objectID:", objectID meshObjects = self.getAllUserMeshObjects() # It may be a triangle, which is ignored if meshObjects.hasKey(objectID): selMeshObject = meshObjects.getMeshObject(objectID) found = True print "Found! selMeshObject", selMeshObject #Only select one object at a time if self.selMeshObject: self.deselectMeshObject(self.selMeshObject, self.selMeshTag) self.selectMeshObject(selMeshObject,objectID) def getAllUserMeshObjects(self): return self.UserMesh def DeleteSelectedMeshObject(self, event): """ if an object is selected, delete it. """ if self.selMeshObject: #an object is selected #first deselect the vertex, for selecting a segment if self.selVertex: self.deselectVertex(self.selVertex, self.selVertexTag) ObjectsToVisuallyDelete = self.mesh.deleteMeshObject (self.selMeshObject) for drawOb in ObjectsToVisuallyDelete: self.UserMesh.unvisualise(drawOb, self.canvas) self.selMeshObject = None self.selMeshTag = None def selectMeshObject(self, meshObject, objectID): """ selected a mesh object. """ self.canvas.delete(objectID) self.selMeshObject = meshObject self.selMeshTag = objectID meshObject.draw(self.canvas,objectID, scale =self.SCALE ,colour = SELECT_COLOR) def deselectMeshObject(self, meshObject, objectID): """ deselected a mesh object. """ self.canvas.delete(objectID) self.selMeshObject = None self.selMeshTag = None if isinstance(meshObject, mesh.Segment): meshObject.draw(self.canvas,objectID, scale =self.SCALE ,colour = SEG_COLOUR) else: meshObject.draw(self.canvas,objectID, scale =self.SCALE ) def drag(self,x,y,event): """ Hack function. called when in select and left mouse goes down """ pass def drawEastingNorthingVertex(self,x,y,event): """ draw a vertex object, plus add it to the mesh data structure event isn't used """ self.serial +=1 self.uniqueID = 'M*%d' % self.serial #x_scaled = self.SCALE*x #y_scaled = -1*self.SCALE*y #print "x y:", x,y vert = self.Vertices.draw(x-self.mesh.geo_reference.get_xllcorner, y-self.mesh.geo_reference.get_yllcorner, self.mesh, self.uniqueID, self.SCALE, self.canvas, event) #FIXME why is event passed on. self.UserMeshChanged = True return vert def drawVertex(self,x,y,event): """ draw a vertex object, plus add it to the mesh data structure event isn't used """ self.serial +=1 self.uniqueID = 'M*%d' % self.serial #x_scaled = self.SCALE*x #y_scaled = -1*self.SCALE*y #print "x y:", x,y vert = self.Vertices.draw(x,y,self.mesh,self.uniqueID,self.SCALE,self.canvas,event) self.UserMeshChanged = True return vert def drawHole(self,x,y,event): """ draw a hole object, plus add it to the mesh data structure event isn't used """ self.serial +=1 self.uniqueID = 'M*%d' % self.serial self.userMeshChanged = True hole = self.Holes.draw(x,y,self.mesh,self.uniqueID,self.SCALE,self.canvas,event) return hole def drawRegion(self,x,y,event): """ draw a region object, plus add it to the mesh data structure event isn't used """ self.serial +=1 self.uniqueID = 'M*%d' % self.serial region = self.Regions.draw(x,y,self.mesh,self.uniqueID,self.SCALE,self.canvas,event) return region def selectSegmentPoint(self,x,y, event): """ logic when selecting a vertex object to add a segment """ found=False if event.widget.find_withtag(CURRENT): # if there's a widget with a tag [tag,string] = self.canvas.gettags(CURRENT) # get a list of them print "tag",tag #tags ('M*1008', 'current') objectID = tag #print "Found!! objectID:", objectID if self.Vertices.hasKey(objectID): #isinstance(self.meshObjects[objectID],mesh.Vertex): vertex = self.Vertices.getMeshObject(objectID) found = True print "Found! vertex", vertex if found and self.selVertex == vertex: print "The selected vertex has already been selected" #The selected vertex has already been selected # therefore deselect it self.deselectVertex(self.selVertex, self.selVertexTag) found = False if found: #A vertex has been selected! if self.selVertex: if self.mesh.isUserSegmentNew(self.selVertex,vertex): #vertex is the 2nd vertex self.drawSegment(vertex,self.selVertex) self.deselectVertex(self.selVertex, self.selVertexTag) self.selectVertex(vertex,objectID) else: print "vertex is the 1st vertex" #vertex is the 1st vertex self.selectVertex(vertex,objectID) else: print " There are no widgets. This happen's too much" def selectVertex(self, vertex,objectID): """ select a vertex object when adding a segment """ self.canvas.delete(objectID) self.selVertex = vertex self.selVertexTag = objectID vertex.draw(self.canvas,objectID, scale =self.SCALE ,colour = VERT_SELECT_ADDING_SEG_COLOR) def deselectVertex(self, vertex,objectID): """ deselect a vertex object when adding a segment """ self.canvas.delete(objectID) self.selVertex = None self.selVertexTag = None vertex.draw(self.canvas,objectID, scale =self.SCALE ) def drawSegment(self,v1,v2): """ Create a seg object, draw it and add it to the mesh data structure """ self.serial +=1 self.uniqueID = 'M*%d' % self.serial self.userMeshChanged = True seg = self.Segments.draw(v1,v2,self.mesh,self.uniqueID,self.SCALE,self.canvas,None) return seg def printGeoReference(self): try: print "geo reference", self.mesh.geo_reference except: print "no geo reference" def visualiseMesh(self,mesh): """ visualise vertices, segments, triangulation, holes """ if self.Visualise: for triangle in mesh.getTriangulation(): self.serial +=1 self.uniqueID = 'M*%d' % self.serial self.Triangles.visualise(triangle, self.uniqueID, self.canvas, self.SCALE) if self.Visualise: Triangles = mesh.sets[mesh.setID[self.selSet]] for triangle in Triangles: triangle.draw(self.canvas,1, scale = self.SCALE, colour = SET_COLOUR) for segment in mesh.getUserSegments(): self.serial +=1 self.uniqueID = 'M*%d' % self.serial self.Segments.visualise(segment, self.uniqueID, self.canvas, self.SCALE) for vertex in mesh.getUserVertices(): self.serial +=1 self.uniqueID = 'M*%d' % self.serial self.Vertices.visualise(vertex, self.uniqueID, self.canvas, self.SCALE) for hole in mesh.getHoles(): self.serial +=1 self.uniqueID = 'M*%d' % self.serial self.Holes.visualise(hole, self.uniqueID, self.canvas, self.SCALE) for region in mesh.getRegions(): self.serial +=1 self.uniqueID = 'M*%d' % self.serial self.Regions.visualise(region, self.uniqueID, self.canvas, self.SCALE) def normalise4ObjMesh(self): if self.mesh: self.clearSelections() self.canvas.delete(ALL) self.mesh.normaliseMesh(400,-200,20) self.visualiseMesh(self.mesh) self.ResizeToFit() self.ResizeToFit() def normaliseMesh(self): if self.mesh: self.clearSelections() self.canvas.delete(ALL) self.mesh.normaliseMesh(1,0,1) self.visualiseMesh(self.mesh) self.ResizeToFit() self.ResizeToFit() def clearMesh(self): """Clear the current mesh object, and the canvas """ self.clearSelections() self.canvas.delete(ALL) self.deleteMesh() self.initData() self.createMesh() def exportObj(self): fileType = "obj" fileTypeDesc = "obj mesh" ofile = tkFileDialog.asksaveasfilename(filetypes=[(fileTypeDesc, fileType), ("All Files", "*")]) if ofile: addOn = "." + fileType jumpback = - len(addOn) if ofile[jumpback:] != addOn: ofile = ofile + addOn try: self.mesh.exportASCIIobj(ofile) except IOError: showerror('Export ASCII file', 'Can not write to file.') except RuntimeError: showerror('Export ASCII file', 'No triangulation to export.') def ImportUngenerate(self): ofile = tkFileDialog.askopenfilename(initialdir=self.currentPath, filetypes=[ ("ungenerated polygon information", "txt"), ("All Files", "*")]) if ofile == "": # The user cancelled the loading action return try: self.clearSelections() self.canvas.delete(ALL) dict = mesh.importUngenerateFile(ofile) self.mesh.addVertsSegs(dict) except SyntaxError: #this is assuming that the SyntaxError is thrown in #loadxyafile showerror('File error', ofile + ' is not in the correct format.') except IOError: #!!! this error type can not be thrown? showerror('File error', 'file ' + ofile + ' could not be found.') except RuntimeError: showerror('File error', 'file ' + ofile + ' has an unknown file type.') self.visualiseMesh(self.mesh) self.ResizeToFit() def exportASCIIsegmentoutlinefile(self): ofile = tkFileDialog.asksaveasfilename(initialdir=self.currentPath, filetypes=[("mesh", "*.tsh *.msh"), ("All Files", "*")]) if ofile: # .tsh is the default file format if (ofile[-4:] == ".tsh" or ofile[-4:] == ".msh"): self.currentFilePathName = ofile else: self.currentFilePathName = ofile + ".tsh" try: self.mesh.exportASCIIsegmentoutlinefile(ofile) except IOError: #FIXME should this function be throwing any errors? showerror('Export ASCII file', 'Can not write to file.') def exportPointsFile(self): ofile = tkFileDialog.asksaveasfilename(initialdir=self.currentPath, filetypes=[("point files", "*.xya *.pts"), ("All Files", "*")]) if ofile: # .xya is the default file format if (ofile[-4:] == ".xya" or ofile[-4:] == ".pts"): self.currentFilePathName = ofile else: self.currentFilePathName = ofile + ".xya" try: self.mesh.exportPointsFile(ofile) except IOError: showerror('Export ASCII file', 'Can not write to file.') def importFile(self): """ import mesh data from a variety of formats (currently 2!) """ print "self.currentPath",self.currentPath ofile = tkFileDialog.askopenfilename(initialdir=self.currentPath, filetypes=[ ("text Mesh", "*.tsh *.msh"), ("points", "*.xya *.pts"), ("All Files", "*")]) if ofile == "": # The user cancelled the loading action return try: newmesh = mesh.importMeshFromFile(ofile) self.currentPath, dummy = os.path.split(ofile) #print "be good self.currentPath",self.currentPath self.currentFilePathName = ofile self.clearMesh() self.mesh = newmesh #FIXME - to speed things up, don't visualise the mesh # use ResizeToFitWrapper self.visualiseMesh(self.mesh) self.ResizeToFit() except IOError: #!!! this error type can not be thrown? showerror('File error', 'file ' + ofile + ' could not be loaded.') except RuntimeError: showerror('File error', 'file ' + ofile + ' has an unknown file type.') # Could not get the file name to showup in the title #appname = ofile + " - " + APPLICATION_NAME #print "appname",appname except load_mesh.loadASCII.TitleAmountError: showerror('File error', 'file ' + ofile + ' has a bad title line (first line).') def ResizeToFitWrapper(self, Parent): """ The parent attribute isn't used by this function. need to understand toolbarbutton.py to know how to get rid of it. """ self.ResizeToFit() def ResizeToFit(self): """Visualise the mesh so it fits in the window""" if self.mesh.getUserVertices() == []: return #There are no vertices! # Resize the window self.scrolledcanvas.resizescrollregion() # I need this so the xview values are correct self.scrolledcanvas.update() xtop, xbottom = self.scrolledcanvas.xview() ytop, ybottom = self.scrolledcanvas.yview() xdiff = xbottom-xtop ydiff = ybottom-ytop if xdiff == 1 and xdiff == 1: #The mesh might be too small. #Make it too large, then resize #!!! Recursive hack. Should be a better way fraction = 50 self.SCALE *= fraction self.scrolledcanvas.scale(ALL, 0, 0, fraction, fraction) self.ResizeToFit() else: # without 0.99 some of the mesh may be off screen fraction = 0.99*min(xdiff,ydiff) self.selectZoom(fraction) def saveDrawing(self): """ Save the current drawing """ #print "dsg!!! self.currentFilePathName ",self.currentFilePathName if (self.currentFilePathName[-4:] != ".tsh" or self.currentFilePathName[-4:] != ".msh"): # force user to choose a name self.saveAsDrawing() else: self.exportASCIItriangulationfile(self.currentFilePathName) def saveAsDrawing(self): """ Save the current drawing, prompting for a file name """ ofile = tkFileDialog.asksaveasfilename(initialdir=self.currentPath, filetypes=[("mesh", "*.tsh *.msh"), ("All Files", "*")]) if ofile: # .tsh is the default file format if (ofile[-4:] == ".tsh" or ofile[-4:] == ".msh"): self.currentFilePathName = ofile else: self.currentFilePathName = ofile + ".tsh" self.exportASCIItriangulationfile(self.currentFilePathName) def exportASCIItriangulationfile(self,currentFilePathName): """ Have a warning prompt when saving a mesh where the generated mesh is different from the user mesh - eg boundary tags that aren't carried thru. Warning ~"Mesh not generated after changes. Generate mesh? " - cancel, don't gen, don't save. Yes - generate mesh, go to save screen. No - goto save screen. To implement this need to know when the user has done a change, and the mesh hasn't been generated. If there is no generated mesh do not prompt. """ #print "self.UserMeshChanged",self.UserMeshChanged #print "self.mesh.isTriangulation()",self.mesh.isTriangulation() if (self.UserMeshChanged) and self.mesh.isTriangulation(): m = _show("Warning", "A triangulation has not been generated, after mesh changes. Generate triangulation before saving?", icon=QUESTION, type=YESNOCANCEL) if m == "no": self.mesh.export_mesh_file(currentFilePathName) self.UserMeshChanged = False elif m == "cancel": pass elif m == "yes": self.windowMeshGen(None) self.mesh.export_mesh_file(currentFilePathName) else: self.mesh.export_mesh_file(currentFilePathName) self.UserMeshChanged = False def initData(self): """ Initialise various lists and flags """ self.serial = 1000 self.currentFilePathName = 'untitled' # these are attributes I've added self.SCALE = 1 self.selVertex = None #The last vertex selected, in draw seg mode self.selVertexTag = None # The selected vertex drawn object tag self.mesh = None self.MeshMinAngle = 20 self.MeshMaxArea = 200 self.MeshnumTriangles = 20 self.MeshMaxAreaLast = False self.selMeshObject = None # The mesh object selected in the current mode self.selMeshTag = None mesh.Segment.set_default_tag("") self.UserMeshChanged = False self.meshLastAlpha = None self.Visualise = True #Is the mesh shown or not? def ipostscript(self): """ Print the canvas as a postscript file """ ofile = tkFileDialog.asksaveasfilename(initialdir=self.currentPath, filetypes=[("postscript", "ps"), ("All Files", "*")]) if ofile: if ofile[-3:] != ".ps": ofile = ofile + ".ps" postscript = self.canvas.postscript() fd = open(ofile, 'w') fd.write(postscript) fd.close() def close(self): self.quit() def createInterface(self): """ Call all functions that create the GUI interface """ self.initData() self.createMesh() AppShell.AppShell.createInterface(self) self.createButtons() self.createMenus() self.createBase() self.createTools() self.createZooms() self.createEdits() self.createSetTools() self.createSetIcons() self.createVisualiseIcons() #self.addCylinders() # !!!DSG start pmesh with a triangle self.selectFunc('pointer') self.currentPath = os.getcwd() def loadtestmesh(self,ofile): """ debugging script to test loading a file """ fd = open(ofile) a = mesh.Vertex (-10.0, 0.0) d = mesh.Vertex (0.0, 4.0) f = mesh.Vertex (4.0,0.0) g = mesh.Vertex (-5.0,5.0) s1 = mesh.Segment(a,d) s2 = mesh.Segment(d,f) s3 = mesh.Segment(a,f) r1 = mesh.Region(0.3, 0.3) m = mesh.Mesh(userVertices=[a,d,f,g], userSegments=[s1,s2,s3], regions=[r1] ) fd.close() print 'returning m' return oadtestmesh(ofile) class AddVertexDialog(Dialog): """ Dialog box for adding a vertex by entering co-ordindates """ def body(self, master): """ GUI description """ self.title("Add New Vertex") Label(master, text='X position:').grid(row=0, sticky=W) Label(master, text='Y position:').grid(row=1, sticky=W) self.xstr = Entry(master, width = 16, name ="entry") self.ystr = Entry(master, width = 16) self.xstr.grid(row=0, column=1, sticky=W) self.ystr.grid(row=1, column=1, sticky=W) self.xstr.focus_force() self.x = 0 self.y = 0 self.xyValuesOk = False def apply(self): """ check entered values """ try: self.x = float(self.xstr.get()) self.y = float(self.ystr.get()) self.xyValuesOk = True except ValueError: showerror('Bad Vertex values', 'X Y values are not numbers.') class auto_segmentDialog(Dialog): """ Dialog box for adding segments """ def __init__(self, parent, alpha): self.alpha = alpha Dialog.__init__(self, parent) def body(self, master): """ GUI description """ self.title("Automatically Add Segments") self.use_optimum = IntVar() self.use_optimum.set(AUTO) # should initialise the radio buttons. # It doesn't #self.use_optimum.set(NO_SELECTION) self.ck = Radiobutton(master, value = AUTO, variable=self.use_optimum) self.ck.grid(row=1, column=0) Label(master, text='Use optimum alpha').grid(row=1, column=1, sticky=W) self.ck2 = Radiobutton(master, value = SET_ALPHA, variable=self.use_optimum) self.ck2.grid(row=2, column=0) Label(master, text='alpha:').grid(row=2, column=1, sticky=W) if (self.alpha): alphaVar = StringVar() alphaVar.set(self.alpha) self.alpha_str = Entry(master, textvariable = alphaVar, width = 16, name ="entry") else: self.alpha_str = Entry(master, width = 16, name ="entry") self.alpha_str.grid(row=2, column=3, sticky=W) #boundary type buttons self.raw_boundary = IntVar() self.remove_holes = IntVar() self.smooth_indents = IntVar() self.expand_pinch = IntVar() self.ck3 = Checkbutton(master, state=NORMAL, variable=self.raw_boundary) self.ck3.grid(row=3, column=0) Label(master, text='Raw boundary').grid(row=3, column=1, sticky=W) # self.ck4 = Checkbutton(master, state=NORMAL, variable=self.remove_holes) self.ck4.grid(row=4, column=0) Label(master, text='Remove small holes').grid(row=4,column=1, sticky=W) # self.ck5 = Checkbutton(master,state=NORMAL, variable=self.smooth_indents) self.ck5.grid(row=5, column=0) Label(master, text='Remove sharp indents').grid(row=5, column=1, sticky=W) # self.ck6 = Checkbutton(master,state=NORMAL, variable=self.expand_pinch) self.ck6.grid(row=6, column=0) Label(master, text='Remove pinch off').grid(row=6, column=1, sticky=W) self.alpha = 0 self.alphaValueOk = False def apply(self): """ check entered values """ try: self.alpha = float(self.alpha_str.get()) self.alphaValueOk = True except ValueError: pass #showerror('Bad Alpha value', # 'Alpha is negative.') class auto_segmentFilterDialog(Dialog): """ Dialog box for adding segments """ def __init__(self, parent): Dialog.__init__(self, parent) def body(self, master): """ GUI description """ self.title("Automatically Add Segments") self.use_optimum = IntVar() self.use_optimum.set(AUTO) # should initialise the radio buttons. # It doesn't self.boundary_type = IntVar() #boundary type buttons self.raw_boundary = IntVar() self.remove_holes = IntVar() self.smooth_indents = IntVar() self.expand_pinch = IntVar() self.ck3 = Checkbutton(master, state=NORMAL, variable=self.raw_boundary) self.ck3.grid(row=3, column=0) Label(master, text='Raw boundary').grid(row=3, column=1, sticky=W) # self.ck4 = Checkbutton(master, state=NORMAL, variable=self.remove_holes) self.ck4.grid(row=4, column=0) Label(master, text='Remove small holes').grid(row=4,column=1, sticky=W) # self.ck5 = Checkbutton(master,state=NORMAL, variable=self.smooth_indents) self.ck5.grid(row=5, column=0) Label(master, text='Remove sharp indents').grid(row=5, column=1, sticky=W) # self.ck6 = Checkbutton(master,state=NORMAL, variable=self.expand_pinch) self.ck6.grid(row=6, column=0) Label(master, text='Remove pinch off').grid(row=6, column=1, sticky=W) class MeshGenDialog(Dialog): """ Dialog box for generating a mesh """ # initial values, hard coded. # should be values associated with the current mesh lastMinAngle = 20 lastMaxArea = 100 def __init__(self, parent, minAngle, maxArea, numTriangles, MeshMaxAreaLast): self.minAngle = minAngle self.maxArea = maxArea self.numTriangles = numTriangles self.MeshMaxAreaLast = MeshMaxAreaLast Dialog.__init__(self, parent) def body(self, master): """ GUI description """ self.title("Generate Mesh") Label(master, text='Minimum Angle(0 - 40):').grid(row=0, sticky=W) Label(master, text='Angles>33 may not converge').grid(row=1, sticky=W) Label(master, text='Maximum Area:').grid(row=2, sticky=W) Label(master, text='OR # of triangles:').grid(row=3, sticky=W) minAngleVar = StringVar() minAngleVar.set(self.minAngle) self.minAnglestr = Entry(master, width = 16, textvariable = minAngleVar, takefocus=1) if (self.MeshMaxAreaLast): maxAreaVar = StringVar() maxAreaVar.set(self.maxArea) self.maxAreastr = Entry(master, textvariable = maxAreaVar, width = 16) self.numTrianglesstr = Entry(master, width = 16) else: self.maxAreastr = Entry(master, width = 16) self.maxAreastr.focus_force() numTrianglesVar = StringVar() numTrianglesVar.set(self.numTriangles) self.numTrianglesstr = Entry(master, textvariable = numTrianglesVar, width = 16) self.minAnglestr.grid(row=0, column=1, sticky=W) self.maxAreastr.grid(row=2, column=1, sticky=W) self.numTrianglesstr.grid(row=3, column=1, sticky=W) self.numTriangles = 0 self.minAngle = 0 self.maxArea = 0 self.ValuesOk = False def apply(self): """ check entered values """ self.goodMaxArea = self.goodNumTriangles = True self.ValuesOk = True try: self.minAngle = float(self.minAnglestr.get()) MeshGenDialog.lastMinAngle =self.minAngle except ValueError: self.ValuesOk = False showerror('Bad mesh generation values', ' Values are not numbers.') try: self.maxArea = float(self.maxAreastr.get()) MeshGenDialog.lastMaxArea =self.maxArea except ValueError: self.goodMaxArea = False try: self.numTriangles = int(self.numTrianglesstr.get()) MeshGenDialog.lastNumTriangles =self.numTriangles except ValueError: self.goodNumTriangles= False if self.goodMaxArea == False and self.goodNumTriangles == False: self.ValuesOk = False showerror('Bad mesh generation values', 'Values are not numbers.') if self.goodMaxArea == True and self.goodNumTriangles == True: self.ValuesOk = False showerror('Bad mesh generation values', 'Give a maximum area OR number of triangles, not both.') try: # value checking if self.minAngle <0.0 or self.minAngle >40.0: raise IOError if self.goodMaxArea == True and self.maxArea <0.0: raise IOError if self.goodNumTriangles == True and self.numTriangles <=0: raise IOError except IOError: self.ValuesOk = False showerror('Bad mesh generation values', 'Values are out of range.') class GeneralThresholdDialog(Dialog): """ Dialog box for thresholding a set by entering minimum and maximum values """ def __init__(self, parent, attribute_titles, function_description): self.attribute_titles=attribute_titles self.function_description=function_description Dialog.__init__(self, parent) def body(self, master): """ GUI description """ self.title("Threshold selected set") blurb1 = 'Threshold selected set between minimum' blurb2 = 'and maximum ' + self.function_description Label(master,text=blurb1).grid(row=0, sticky=W) Label(master,text=blurb2).grid(row=1, sticky=W) Label(master, text='minimum attribute:').grid(row=2, sticky=W) Label(master, text='maximum attribute:').grid(row=3, sticky=W) Label(master, text='attribute name').grid(row=4, sticky=W) nameVar = StringVar() nameVar.set('elevation') self.minstr = Entry(master, width = 16, name ="entry") self.maxstr = Entry(master, width = 16) self.attstr = Entry(master, width = 16,textvariable = nameVar) self.minstr.grid(row=2, column=1, sticky=W) self.maxstr.grid(row=3, column=1, sticky=W) self.attstr.grid(row=4, column=1, sticky=W) self.minstr.focus_force() self.min = 0 self.max = 0 self.attribute_name = 'elevation' self.minmaxValuesOk = False def apply(self): self.minmaxValuesOk = True try: self.min = float(self.minstr.get()) self.max = float(self.maxstr.get()) except ValueError: self.minmaxValuesOk = False showerror('Bad mesh generation values', ' Values are not numbers.') try: self.attribute_titles.index(self.attstr.get())#dodgey. self.attribute_name = self.attstr.get() except ValueError: self.attribute_name = None showerror('Bad attribute name', 'Using h = 1') class ThresholdDialog(Dialog): """ Dialog box for thresholding a set by entering minimum and maximum values """ def __init__(self, parent, attribute_titles): self.attribute_titles=attribute_titles Dialog.__init__(self, parent) def body(self, master): """ GUI description """ self.title("Threshold selected set") Label(master, text='minimum attribute:').grid(row=0, sticky=W) Label(master, text='maximum attribute:').grid(row=1, sticky=W) Label(master, text='attribute name').grid(row=2, sticky=W) nameVar = StringVar() nameVar.set('elevation') self.minstr = Entry(master, width = 16, name ="entry") self.maxstr = Entry(master, width = 16) self.attstr = Entry(master, width = 16,textvariable = nameVar) self.minstr.grid(row=0, column=1, sticky=W) self.maxstr.grid(row=1, column=1, sticky=W) self.attstr.grid(row=2, column=1, sticky=W) self.minstr.focus_force() self.min = 0 self.max = 0 self.attribute_name = 'elevation' self.minmaxValuesOk = False def apply(self): self.minmaxValuesOk = True try: self.min = float(self.minstr.get()) self.max = float(self.maxstr.get()) except ValueError: self.minmaxValuesOk = False showerror('Bad mesh generation values', ' Values are not numbers.') try: self.attribute_titles.index(self.attstr.get())#dodgey. self.attribute_name = self.attstr.get() except ValueError: self.minmaxValuesOk = False showerror('Bad attribute name', ' Attribute not in mesh.') class Courant_ThresholdDialog(Dialog): """ Dialog box for thresholding a set by entering minimum and maximum values """ def __init__(self, parent, attribute_titles): self.attribute_titles=attribute_titles Dialog.__init__(self, parent) def body(self, master): """ GUI description """ self.title("Courant_Threshold selected set") Label(master, text='minimum attribute:').grid(row=0, sticky=W) Label(master, text='maximum attribute:').grid(row=1, sticky=W) Label(master, text='attribute name').grid(row=2, sticky=W) nameVar = StringVar() nameVar.set('elevation') self.minstr = Entry(master, width = 16, name ="entry") self.maxstr = Entry(master, width = 16) self.attstr = Entry(master, width = 16,textvariable = nameVar) self.minstr.grid(row=0, column=1, sticky=W) self.maxstr.grid(row=1, column=1, sticky=W) self.attstr.grid(row=2, column=1, sticky=W) self.minstr.focus_force() self.min = 0 self.max = 0 self.attribute_name = 'elevation' self.minmaxValuesOk = False def apply(self): self.minmaxValuesOk = True try: self.min = float(self.minstr.get()) self.max = float(self.maxstr.get()) except ValueError: self.minmaxValuesOk = False showerror('Bad mesh generation values', ' Values are not numbers.') try: self.attribute_titles.index(self.attstr.get())#dodgey. self.attribute_name = self.attstr.get() except ValueError: self.minmaxValuesOk = False showerror('Bad attribute name', ' Attribute not in mesh.') class SmoothDialog(Dialog): """ Dialog box for setting the number of triangles used to make up dilation or erosion """ def body(self, master): """ GUI description """ self.title("Enter the minimum radius to remove") Label(master, text='radius:').grid(row=0, sticky=W) self.min_radius = Entry(master, width = 16, name ="entry") self.min_radius.grid(row=0, column=1, sticky=W) self.min_radius.focus_force() self.min = 2. self.valueOK = False def apply(self): self.valueOK = True try: self.min = float(self.min_radius.get()) self.min_radius = self.min except ValueError: self.valueOK = False showerror('Bad Number', ' Value not a number') class setStructureNumberDialog(Dialog): """ Dialog box for setting the number of triangles used to make up dilation or erosion """ def body(self, master): """ GUI description """ self.title("Set number of elements effected by morphing sets") Label(master, text='number:').grid(row=0, sticky=W) self.number = Entry(master, width = 16, name ="entry") self.number.grid(row=0, column=1, sticky=W) self.number.focus_force() self.number = 0 self.numberOk = False def apply(self): self.numberOk = True try: self.number = int(self.number.get()) except ValueError: self.numberOK = False showerror('Bad mesh generation values', ' Values are not numbers.') if __name__ == '__main__': draw = Draw() draw.run() #profile.run('draw.run()', 'pmeshprof')