def viewportLayout(): """Set the viewport layout.""" directions = ['rowwise', 'columnwise'] if pf.GUI.viewports.rowwise: current = directions[0] else: current = directions[1] res = draw.askItems([ _I('Number of viewports', len(pf.GUI.viewports.all)), _I('Viewport layout direction', current, choices=directions), _I('Number of viewports per row/column', pf.GUI.viewports.ncols), ], caption='Config Dialog') if res: pf.debug(res) nvps = res['Number of viewports'] rowwise = res['Viewport layout direction'] == 'rowwise' ncols = res['Number of viewports per row/column'] if rowwise: nrows = None else: nrows = ncols ncols = None pf.GUI.viewports.changeLayout(nvps, ncols, nrows)
def classify(self): """Classify the files in submenus according to keywords.""" kat = ['all','level','topics','techniques'] cat = dict([ (k,set()) for k in kat]) cat['level'] = [ 'beginner', 'normal', 'advanced' ] col = {'all':set()} for f in self.filterFiles(self.getFiles()): col['all'].update([f]) fn = self.fileName(f) d = scriptKeywords(fn) for k,v in d.items(): if not k in kat: GD.debug("Skipping unknown keyword %s in script %s" % (k,fn)) continue if k == 'level': v = [v] else: cat[k].update(v) for i in v: ki = '%s/%s' % (k,i) if not ki in col.keys(): col[ki] = set() col[ki].update([f]) sortSets(cat) sortSets(col) return kat,cat,col
def __init__(self): """Initialize an empty canvas with default settings.""" self.actors = ActorList(self) self.highlights = ActorList(self) self.annotations = ActorList(self) self.decorations = ActorList(self) self.triade = None self.background = None self.bbox = None self.resetLighting() self.setBbox() self.settings = CanvasSettings() self.mode2D = False self.rendermode = pf.cfg['render/mode'] self.lighting = pf.cfg['render/lighting'] if self.lighting not in [True,False]: self.lighting = self.rendermode.startswith('smooth') self.polygonfill = False self.avgnormals = False self.alphablend = False self.dynamouse = True # dynamic mouse action works on mouse move self.dynamic = None # what action on mouse move self.camera = None self.view_angles = camera.view_angles self.cursor = None self.focus = False pf.debug("Canvas Setting:\n%s"% self.settings)
def startGui(args=[]): """Start the gui""" if GD.GUI is None: GD.debug("Starting the pyFormex GUI") from gui import gui gui.startGUI(args) gui.runGUI()
def __init__(self, vshader=None, fshader=None, attributes=None, uniforms=None): _vertexshader, _fragmentshader = defaultShaders() if vshader is None: vshader = _vertexshader pf.debug("Using vertex shader %s" % vshader, pf.DEBUG.OPENGL) with open(vshader) as f: VertexShader = f.read() if fshader is None: fshader = _fragmentshader pf.debug("Using fragment shader %s" % fshader, pf.DEBUG.OPENGL) with open(fshader) as f: FragmentShader = f.read() if attributes is None: attributes = Shader.attributes if uniforms is None: uniforms = Shader.uniforms vertex_shader = shaders.compileShader(VertexShader, GL.GL_VERTEX_SHADER) fragment_shader = shaders.compileShader(FragmentShader, GL.GL_FRAGMENT_SHADER) self.shader = shaders.compileProgram(vertex_shader, fragment_shader) self.attribute = self.locations(GL.glGetAttribLocation, attributes) self.uniform = self.locations(GL.glGetUniformLocation, uniforms) self.picking = 0 # Default render mode
def start(self, *args, **kargs): """Start repeated execution""" timer = None if self.duration >= 0: timer = threading.Timer(self.duration, self.timeOut) timer.start() self.exitcode = 0 count = 0 while not self.exitcode: pf.debug("Loop Exitcode %s, Count: %s" % (self.exitcode, count), pf.DEBUG.SCRIPT) pf.app.processEvents() if callable(self.func): self.exitcode = self.func(*args, **kargs) if self.exitcode: break count += 1 if self.maxcount >= 0 and count >= self.maxcount: self.exitcode = 3 break if self.sleep > 0: time.sleep(self.sleep) pf.debug( "Exit Repeater with Exitcode %s, Count: %s" % (self.exitcode, count), pf.DEBUG.SCRIPT)
def changeMode(self, canvas): """Modify the actor according to the specified mode""" pf.debug("GEOMACTOR.changeMode", pf.DEBUG.DRAW) self.drawable = [] self._prepareNormals(canvas) # ndim >= 2 if (self.eltype is not None and self.eltype.ndim >= 2) or (self.eltype is None and self.object.nplex() >= 3): if self.mode: rendermode = self.mode else: rendermode = canvas.rendermode #print("RENDERMODE",rendermode) if rendermode == 'wireframe': # Draw the colored edges self._addEdges() else: # Draw the colored faces self._addFaces() # Overlay the black edges (or not) if rendermode.endswith('wire'): self._addWires() # ndim < 2 else: # Draw the colored faces self._addFaces() #### CHILDREN #### for child in self.children: child.changeMode(canvas) pf.debug( "GEOMACTOR.changeMode create %s drawables" % len(self.drawable), pf.DEBUG.DRAW)
def setToolbarPlacement(store=None): """Ask placement of toolbars. Items in list should be existing toolbar widgets. """ if store is None: store = GD.cfg toolbar = [ GD.gui.modebar, GD.gui.viewbar ] setting = ['gui/modebar', 'gui/viewbar' ] options = [ None, 'default', 'left', 'right', 'top', 'bottom' ] label = [ str(tb.windowTitle()) for tb in toolbar ] current = [ store[s] for s in setting ] itemlist = [(l, options[1], 'select', options) for (l,c) in zip(label,setting)] itemlist.append(('Store these settings as defaults', False)) res = widgets.InputDialog(itemlist,'Config Dialog',GD.gui).getResult() if res: GD.debug(res) if res['Store these settings as defaults']: # The following does not work for our Config class! # store.update(res) # Therefore, we set the items individually for s,l in zip(setting,label): val = res[l] if val == "None": val = None store[s] = val GD.debug(store)
def __init__(self,filename,size): """Initialize a FontTexture""" pf.debug("Creating FontTexture(%s) in size %s" % (filename,size),pf.DEBUG.FONT) # Load font and check it is monospace face = ft.Face(str(filename)) face.set_char_size(int(size*64)) if not face.is_fixed_width: raise RuntimeError("Font is not monospace") # Determine largest glyph size width, height, ascender, descender = 0, 0, 0, 0 for c in range(32,128): face.load_char( chr(c), ft.FT_LOAD_RENDER | ft.FT_LOAD_FORCE_AUTOHINT ) bitmap = face.glyph.bitmap width = max( width, bitmap.width ) ascender = max( ascender, face.glyph.bitmap_top ) descender = max( descender, bitmap.rows-face.glyph.bitmap_top ) height = ascender+descender # Generate texture data self.width, self.height = width,height image = np.zeros((height*6, width*16), dtype=np.ubyte) for j in range(6): for i in range(16): face.load_char(chr(32+j*16+i), ft.FT_LOAD_RENDER | ft.FT_LOAD_FORCE_AUTOHINT ) bitmap = face.glyph.bitmap x = i*width + face.glyph.bitmap_left y = j*height + ascender - face.glyph.bitmap_top image[y:y+bitmap.rows,x:x+bitmap.width].flat = bitmap.buffer #print(image.shape,image.dtype) Texture.__init__(self,image,format=GL.GL_ALPHA,texformat=GL.GL_ALPHA)
def flyAlong(path="flypath", upvector=[0.0, 1.0, 0.0], sleeptime=None): """Fly through the current scene along the flypath. - `flypath`: a PolyLine or plex-2 Formex. """ from plugins.curve import PolyLine if type(path) is str: path = named(path) if not path: warning("You have to define a flypath first!") return if isinstance(path, PolyLine): path = path.toFormex() if path.nplex() != 2: warning("The flypath should be a plex-2 Formex!") for eye, center in path: pf.debug("Eye: %s; Center: %s" % (eye, center)) pf.canvas.camera.lookAt(eye, center, upvector) pf.canvas.display() pf.canvas.update() image.saveNext() if sleeptime is None: sleeptime = pf.cfg["draw/flywait"] sleeptime = float(sleeptime) if sleeptime > 0.0: sleep(sleeptime) pf.canvas.camera.setCenter(*center) pf.canvas.camera.setDist(coords.length(center - eye)) pf.canvas.update()
def load(appname, refresh=False, strict=False): """Load the named app If refresh is True, the module will be reloaded if it was already loaded before. On succes, returns the loaded module, else returns None. In the latter case, if the config variable apptraceback is True, the traceback is store in a module variable _traceback. """ global _traceback pf.debug("Loading %s with refresh=%s" % (appname, refresh), pf.DEBUG.APPS) print("Loading application %s " % appname) try: _traceback = '' __import__(appname) app = sys.modules[appname] if refresh: reload(app) if strict: if not hasattr(app, 'run') or not callable(app.run): return None return app except: import traceback _traceback = traceback.format_exc() return None
def pause(timeout=None, msg=None): """Pause the execution until an external event occurs or timeout. When the pause statement is executed, execution of the pyformex script is suspended until some external event forces it to proceed again. Clicking the PLAY, STEP or CONTINUE button will produce such an event. - `timeout`: float: if specified, the pause will only last for this many seconds. It can still be interrupted by the STEP buttons. - `msg`: string: a message to write to the board to explain the user about the pause """ from pyformex.gui.drawlock import Repeater def _continue_(): return not pf.GUI.drawlock.locked if msg is None and timeout is None: msg = "Use the Play/Step/Continue button to proceed" pf.debug("Pause (%s): %s" % (timeout, msg), pf.DEBUG.SCRIPT) if msg: print(msg) pf.GUI.enableButtons(pf.GUI.actions, ['Step', 'Continue'], True) pf.GUI.drawlock.release() if pf.GUI.drawlock.allowed: pf.GUI.drawlock.locked = True if timeout is None: timeout = widgets.input_timeout R = Repeater(_continue_, timeout, sleep=0.1) R.start() pf.GUI.drawlock.release()
def refLookup(key): """Lookup a key in the reference configuration.""" try: return pyformex.refcfg[key] except: pyformex.debug("!There is no key '%s' in the reference config!"%key) return None
def draw_parts(x,e,mode,color=None,alpha=1.0): """Draw a collection of faces. (x,e) are one of: - x is a (nelems,nfaces,nplex,3) shaped coordinates and e is None, - x is a (ncoords,3) shaped coordinates and e is a (nelems,nfaces,nplex) connectivity array. Each of the nfaces sets of nplex points defines a polygon. If color is given it is an (nel,3) array of RGB values. This function will multiplex the colors, so that n faces are drawn in the same color. This is e.g. convenient when drawing faces of a solid element. """ if e is None: nfaces,nplex = x.shape[1:3] x = x.reshape(-1,nplex,3) else: nfaces,nplex = e.shape[1:3] e = e.reshape(-1,nplex) if color is not None: if color.ndim < 3: GD.debug("COLOR SHAPE BEFORE MULTIPLEXING %s" % str(color.shape)) color = color_multiplex(color,nfaces) GD.debug("COLOR SHAPE AFTER MULTIPLEXING %s" % str(color.shape)) drawPolygons(x,e,mode,color,alpha)
def drawFaces(x,e,faces,mode,color=None,alpha=1.0): """Draw the faces of a geometry. This function draws the faces of a geometry collection, usually of a higher dimensionality (i.c. a volume). The faces are identified by a constant indices into all element vertices. The geometry is specified by x or (x,e) The faces are specified by a list of lists. Each list defines a single face of the solid, in local vertex numbers (0..nplex-1). The faces are sorted and collected according to their plexitude before drawing them. """ GD.debug("drawFaces") # We may have faces with different plexitudes! for fac in olist.collectOnLength(faces).itervalues(): fa = asarray(fac) nplex = fa.shape[1] if e is None: coords = x[:,fa,:] elems = None else: coords = x elems = e[:,fa] GD.debug("COORDS SHAPE: %s" % str(coords.shape)) if elems is not None: GD.debug("ELEMS SHAPE: %s" % str(elems.shape)) if color is not None and color.ndim==3: GD.debug("COLOR SHAPE BEFORE EXTRACTING: %s" % str(color.shape)) # select the colors of the matching points color = color[:,fa,:] color = color.reshape((-1,)+color.shape[-2:]) GD.debug("COLOR SHAPE AFTER EXTRACTING: %s" % str(color.shape)) draw_parts(coords,elems,mode,color,alpha)
def setToolbarPlacement(store=None): """Ask placement of toolbars. Items in list should be existing toolbar widgets. """ if store is None: store = GD.cfg toolbar = GD.GUI.toolbardefs label = [i[0] for i in toolbar] setting = ["gui/%s" % i[1] for i in toolbar] options = [None, "default", "left", "right", "top", "bottom"] current = [store[s] for s in setting] itemlist = [(l, options[1], "select", options) for (l, c) in zip(label, setting)] itemlist.append(("Store these settings as defaults", False)) res = widgets.InputDialog(itemlist, "Config Dialog", GD.GUI).getResult() if res: GD.debug(res) if res["Store these settings as defaults"]: # The following does not work for our Config class! # store.update(res) # Therefore, we set the items individually for s, l in zip(setting, label): val = res[l] if val == "None": val = None store[s] = val GD.debug(store)
def remove(self, data, key=-1): """Remove data from the collection.""" if isinstance(data, Collection): if data.obj_type == self.obj_type: for k in data.d: self.remove(data.d[k], k) return else: raise ValueError( "Cannot remove Collections with different object type") data = np.asarray(data) if data.ndim == 2: for key in np.unique(data[:, 0]): self.remove(data[data[:, 0] == key, 1], key) else: key = int(key) if key in self.d: data = np.setdiff1d(self.d[key], np.unique(data)) if data.size > 0: self.d[key] = data else: del self.d[key] else: pf.debug( "Not removing from non-existing selection for actor %s" % key, pf.DEBUG.DRAW)
def save(self,quiet=False): """Save the project to file.""" if 'w' not in self.access: pf.debug("Not saving because Project file opened readonly",pf.DEBUG.PROJECT) return if not quiet: print("Project variables changed: %s" % self.hits) if self.filename is None: import tempfile fd,fn = tempfile.mkstemp(prefix='pyformex_',suffix='.pyf') self.filename = fn else: if not quiet: print("Saving project %s with mode %s and compression %s" % (self.filename,self.mode,self.gzip)) #print(" Contents: %s" % self.keys()) f = open(self.filename,'w'+self.mode) # write header f.write("%s\n" % self.header_data()) f.flush() if self.mode == 'b': # When using binary, can as well use highest protocol protocol = cPickle.HIGHEST_PROTOCOL else: protocol = 0 if self.gzip: pyf = gzip.GzipFile(mode='w'+self.mode,compresslevel=self.gzip,fileobj=f) cPickle.dump(self,pyf,protocol) pyf.close() else: cPickle.dump(self,f,protocol) f.close() self.hits = 0
def startGui(args=[]): """Start the gui""" if pf.GUI is None: pf.debug("Starting the pyFormex GUI") from gui import guimain if guimain.startGUI(args) == 0: guimain.runGUI()
def createMovie(encoder='ffmpeg'): """Create a movie from a saved sequence of images. encoder is one of: 'ffmpeg, mencoder, convert' """ if not multisave: pf.warning('You need to start multisave mode first!') return names,format,quality,window,border,hotkey,autosave,rootcrop = multisave glob = names.glob() ## if glob.split('.')[-1] != 'jpg': ## pf.warning("Currently you need to save in 'jpg' format to create movies") ## return if encoder == 'convert': cmd = "convert -delay 1 -colors 256 %s output.gif" % names.glob() elif encoder == 'mencoder': cmd = "mencoder -ovc lavc -fps 5 -o output.avi %s" % names.glob() elif encoder == 'mencoder1': cmd = "mencoder \"mf://%s\" -mf fps=10 -o output1.avi -ovc lavc -lavcopts vcodec=msmpeg4v2:vbitrate=800" % names.glob() else: cmd = "ffmpeg -qscale 1 -r 1 -i %s output.mp4" % names.glob() pf.debug(cmd) utils.runCommand(cmd)
def start_selection(self,mode,filtr): """Start an interactive picking mode. If selection mode was already started, mode is disregarded and this can be used to change the filter method. """ if self.selection_mode is None: GD.debug("START SELECTION MODE: %s" % mode) self.setMouse(LEFT,self.mouse_pick) self.setMouse(LEFT,self.mouse_pick,SHIFT) self.setMouse(LEFT,self.mouse_pick,CTRL) self.setMouse(RIGHT,self.emit_done) self.setMouse(RIGHT,self.emit_cancel,SHIFT) self.connect(self,DONE,self.accept_selection) self.connect(self,CANCEL,self.cancel_selection) #self.setCursorShape('pick') self.selection_mode = mode self.selection_front = None if filtr == 'none': filtr = None GD.debug("SET SELECTION FILTER: %s" % filtr) self.selection_filter = filtr if filtr is None: self.selection_front = None self.selection.clear() self.selection.setType(self.selection_mode)
def closeEvent(self,event): """Override the close event handler. We override the default close event handler for the main window, to allow the user to cancel the exit. """ # # DEV: things going wrong during the event handler are hard to debug! # You can add those things to a function and add the function to a # menu for testing. At the end of the file helpMenu.py there is an # example (commented out). # pf.GUI.cleanup() if pf.options.gui: script.force_finish() if exitDialog(): self.drawlock.free() dooze = pf.cfg['gui/dooze'] if dooze > 0: print("Exiting in %s seconds" % dooze) draw.sleep(dooze) # force reset redirect sys.stderr.flush() sys.stdout.flush() sys.stderr = sys.__stderr__ sys.stdout = sys.__stdout__ pf.debug("Executing registered exit functions",pf.DEBUG.GUI) for f in self.on_exit: pf.debug(f,pf.DEBUG.GUI) f() self.writeSettings() event.accept() else: event.ignore()
def viewportSettings(): """Interactively set the viewport settings.""" mode = GD.canvas.rendermode modes = canvas.Canvas.rendermodes s = GD.canvas.settings if s.bgcolor2 is None: s.bgcolor2 = s.bgcolor itemlist = [('rendermode', mode, 'select', modes), ('linewidth', s.linewidth, 'float'), ('bgcolor', s.bgcolor, 'color'), ('bgcolor2', s.bgcolor2, 'color'), ('fgcolor', s.fgcolor, 'color'), ('slcolor', s.slcolor, 'color'), ('Store these settings as defaults', False), ] res = widgets.InputDialog(itemlist,'Config Dialog').getResult() if res: GD.debug(res) GD.canvas.updateSettings(res) GD.canvas.setRenderMode(res['rendermode']) #GD.canvas.clear() GD.canvas.redrawAll() GD.canvas.update() if res['Store these settings as defaults']: GD.cfg.update(GD.canvas.settings.__dict__,name='canvas')
def draw(self,*args,**kargs): clear() GD.debug("Drawing SELECTION: %s" % self.names) self._actors = draw(self.names,clear=False,shrink=self.shrink,*args,**kargs) for i,a in enumerate(self.annotations): if a[1]: self.drawAnnotation(i)
def runGUI(): """Go into interactive mode""" egg = pf.cfg.get('gui/easter_egg',None) pf.debug('EGG: %s' % str(egg),pf.DEBUG.INFO) if egg: pf.debug('EGG') if type(egg) is str: pye = egg.endswith('pye') egg = open(egg).read() else: pye = True egg = ''.join(egg) draw.playScript(egg,pye=True) if os.path.isdir(pf.cfg['workdir']): # Make the workdir the current dir os.chdir(pf.cfg['workdir']) pf.debug("Setting workdir to %s" % pf.cfg['workdir'],pf.DEBUG.INFO) else: # Save the current dir as workdir prefMenu.updateSettings({'workdir':os.getcwd(),'_save_':True}) pf.interactive = True pf.debug("Start main loop",pf.DEBUG.INFO) #utils.procInfo('runGUI') #from multiprocessing import Process #p = Process(target=pf.app.exec_) #p.start() #res = p.join() res = pf.app.exec_() pf.debug("Exit main loop with value %s" % res,pf.DEBUG.INFO) return res
def runGUI(): """Go into interactive mode""" egg = pf.cfg.get('gui/easter_egg',None) pf.debug('EGG: %s' % str(egg)) if egg: pf.debug('EGG') if type(egg) is str: pye = egg.endswith('pye') egg = file(egg).read() else: pye = True egg = ''.join(egg) draw.playScript(egg,pye=True) if os.path.isdir(pf.cfg['workdir']): # Make the workdir the current dir os.chdir(pf.cfg['workdir']) pf.debug("Setting workdir to %s" % pf.cfg['workdir']) else: # Save the current dir as workdir prefMenu.updateSettings({'workdir':os.getcwd(),'Save changes':True}) pf.interactive = True pf.debug("Start main loop") #utils.procInfo('runGUI') #from multiprocessing import Process #p = Process(target=pf.app.exec_) #p.start() #res = p.join() res = pf.app.exec_() pf.debug("Exit main loop with value %s" % res) return res
def spawn(cmd): """Spawn a child process.""" cmd = cmd.split() pid = os.spawnvp(os.P_NOWAIT, cmd[0], cmd) pf.debug("Spawned child process %s for command '%s'" % (pid, cmd), pf.DEBUG.INFO) return pid
def flyAlong(path='flypath',upvector=[0.,1.,0.],sleeptime=None): """Fly through the scene along the flypath.""" if type(path) is str: path = named(path) if not path: warning("You have to define a flypath first!") return if path.nplex() != 2: warning("The flypath should be a plex-2 Formex!") for eye,center in path: GD.debug("Eye: %s; Center: %s" % (eye,center)) GD.canvas.camera.lookAt(eye,center,upvector) GD.canvas.display() GD.canvas.update() image.saveNext() if sleeptime is None: sleeptime = GD.cfg['draw/flywait'] sleeptime = float(sleeptime) if sleeptime > 0.0: sleep(sleeptime) GD.canvas.camera.setCenter(*center) GD.canvas.camera.setDist(coords.length(center-eye)) GD.canvas.update()
def filterWarning(message, module='', cat='U', action='ignore'): import warnings pf.debug( "Filter Warning '%s' from module '%s' cat '%s'" % (message, module, cat), pf.DEBUG.WARNING) category = _warn_category.get(cat, Warning) warnings.filterwarnings(action, message, category, module)
def startGui(args=[]): """Start the gui""" if pf.GUI is None: pf.debug("Starting the pyFormex GUI", pf.DEBUG.GUI) from pyformex.gui import guimain if guimain.startGUI(args) == 0: guimain.runGUI()
def viewportSettings(): """Interactively set the viewport settings.""" mode = pf.canvas.rendermode modes = canvas.Canvas.rendermodes s = pf.canvas.settings if s.bgcolor2 is None: s.bgcolor2 = s.bgcolor itemlist = [I('rendermode', mode, choices=modes), I('linewidth', s.linewidth, itemtype='float'), I('bgcolor', s.bgcolor, itemtype='color'), I('bgcolor2', s.bgcolor2, itemtype='color'), I('fgcolor', s.fgcolor, itemtype='color'), I('slcolor', s.slcolor, itemtype='color'), I('Store these settings as defaults', False), ] res = widgets.InputDialog(itemlist,'Config Dialog').getResult() if res: pf.debug(res) pf.canvas.setRenderMode(res['rendermode']) pf.canvas.settings.update(res,strict=False) #pf.canvas.clear() pf.canvas.redrawAll() pf.canvas.update() if res['Store these settings as defaults']: pf.cfg.update(pf.canvas.settings.__dict__,name='canvas')
def draw(self,**kargs): clear() pf.debug("Drawing SELECTION: %s" % self.names,pf.DEBUG.DRAW) self._actors = draw(self.names,clear=False,shrink=self.shrink,wait=False,**kargs) for f in self.annotations: pf.debug("Drawing ANNOTATION: %s" % f,pf.DEBUG.DRAW) self.drawAnnotation(f)
def raiseExit(): print "EEEEEEEEEEEEXXXXXXXXXXXXXXXXIIIIIIIIIIIIIIIITTTTTTTTTTTTTTTTTTT" pf.debug("RAISED EXIT") print scriptlock if pf.GUI: pf.GUI.drawlock.release() raise _Exit,"EXIT REQUESTED FROM SCRIPT"
def cleanup(self): """Cleanup the GUI (restore default state).""" GD.debug('GUI cleanup') self.drawlock.release() GD.canvas.cancel_selection() draw.clear_canvas() self.setBusy(False)
def __init__(self, filename=None, access='wr', convert=True, signature=_signature_, compression=5, binary=True, data={}, **kargs): """Create a new project.""" if 'create' in kargs: utils.warn( "The create=True argument should be replaced with access='w'") if 'legacy' in kargs: utils.warn("The legacy=True argument has become superfluous") self.filename = filename self.access = access self.signature = str(signature) self.gzip = compression if compression in range(1, 10) else 0 self.mode = 'b' if binary or compression > 0 else '' TrackedDict.__init__(self) if filename and os.path.exists(filename) and 'r' in self.access: # read existing contents self.load(convert) self.hits = 0 if data: self.update(data) if filename and access == 'w': # destroy existing contents self.save() pf.debug("INITIAL hits = %s" % self.hits, pf.DEBUG.PROJECT)
def runGUI(): """Go into interactive mode""" GD.debug("Start main loop") res = GD.app.exec_() GD.debug("Exit main loop") return res
def savePreferences(): """Save the preferences. The name of the preferences file was set in GD.preffile. If a local preferences file was read, it will be saved there. Otherwise, it will be saved as the user preferences, possibly creating that file. If GD.preffile is None, preferences are not saved. """ f = GD.preffile if not f: return del GD.cfg["__ref__"] # Dangerous to set permanently! del GD.cfg["input/timeout"] GD.debug("!!!Saving config:\n%s" % GD.cfg) try: fil = file(f, "w") fil.write("%s" % GD.cfg) fil.close() res = "Saved" except: res = "Could not save" GD.debug("%s preferences to file %s" % (res, f))
def initialize(): """Initialize the image module.""" global image_formats_qt, image_formats_qtr, image_formats_gl2ps, image_formats_fromeps, gl2ps, _producer, _gl2ps_types # Find interesting supporting software utils.hasExternal("ImageMagick") # Set some globals GD.debug("LOADING IMAGE FORMATS") image_formats_qt = map(str, QtGui.QImageWriter.supportedImageFormats()) image_formats_qtr = map(str, QtGui.QImageReader.supportedImageFormats()) if GD.cfg.get("imagesfromeps", False): GD.image_formats_qt = [] if utils.hasModule("gl2ps"): import gl2ps _producer = GD.Version + " (http://pyformex.berlios.de)" _gl2ps_types = {"ps": gl2ps.GL2PS_PS, "eps": gl2ps.GL2PS_EPS, "tex": gl2ps.GL2PS_TEX, "pdf": gl2ps.GL2PS_PDF} if utils.checkVersion("gl2ps", "1.03") >= 0: _gl2ps_types.update({"svg": gl2ps.GL2PS_SVG, "pgf": gl2ps.GL2PS_PGF}) image_formats_gl2ps = _gl2ps_types.keys() image_formats_fromeps = ["ppm", "png", "jpeg", "rast", "tiff", "xwd", "y4m"] if GD.options.debug: print "Qt image types for saving: ", image_formats_qt print "Qt image types for input: ", image_formats_qtr print "gl2ps image types:", image_formats_gl2ps print "image types converted from EPS:", image_formats_fromeps
def saneColorSet(color=None,colormap=None,shape=(1,),canvas=None): """Return a sane set of colors. A sane set of colors is one that guarantees correct use by the draw functions. This means either - no color (None) - a single color - at least as many colors as the shape argument specifies - a color index and a color map with enough colors to satisfy the index. The return value is a tuple color,colormap. colormap will be None, unless color is an integer array, meaning a color index. """ if isInt(shape): # make sure we get a tuple shape = (shape,) color = saneColor(color) if color is not None: pf.debug("SANECOLORSET: color %s, shape %s" % (color.shape,shape),pf.DEBUG.DRAW) if color.dtype.kind == 'i': ncolors = color.max()+1 if colormap is None: if canvas: colormap = canvas.settings.colormap else: colormap = pf.canvas.settings.colormap #cfg['canvas/colormap'] colormap = saneColor(colormap) colormap = saneColorArray(colormap,(ncolors,)) else: color = saneColorArray(color,shape) colormap = None pf.debug("SANECOLORSET RESULT: %s" % str(color.shape),pf.DEBUG.DRAW) return color,colormap
def system(cmd): pf.debug("COMMAND: %s" % cmd) import subprocess P = subprocess.Popen(cmd,shell=True,stdout=subprocess.PIPE, stderr=subprocess.PIPE) # or .STDOUT to redirect sta = P.wait() # wait for the process to finish out = P.communicate()[0] # get the stdout return sta,out
def drawEdges(x,e,edges,color=None): """Draw the edges of a geometry. This function draws the edges of a geometry collection, usually of a higher dimensionality (i.c. a surface or a volume). The edges are identified by a constant indices into all element vertices. The geometry is specified by x or (x,e) The edges are specified by a list of lists. Each list defines a single edge of the solid, in local vertex numbers (0..nplex-1). """ GD.debug("drawEdges") fa = asarray(edges) if e is None: coords = x[:,fa,:] elems = None else: coords = x elems = e[:,fa] GD.debug("COORDS SHAPE: %s" % str(coords.shape)) if elems is not None: GD.debug("ELEMS SHAPE: %s" % str(elems.shape)) if color is not None and color.ndim==3: GD.debug("COLOR SHAPE BEFORE EXTRACTING: %s" % str(color.shape)) # select the colors of the matching points color = color[:,fa,:]#.reshape((-1,)+color.shape[-2:]) color = color.reshape((-1,)+color.shape[-2:]) GD.debug("COLOR SHAPE AFTER EXTRACTING: %s" % str(color.shape)) draw_parts(coords,elems,'wireframe',color,1.0)
def killProcesses(pids,signal): """Send the specified signal to the processes in list""" for pid in pids: try: os.kill(pid,signal) except: pf.debug("Error in killing of process '%s'" % pid)
def setLighting(): mat_items = [ {'name':a,'text':a,'value':getattr(pf.canvas,a),'itemtype':'slider','min':0,'max':100,'scale':0.01,'func':set_mat_value} for a in [ 'ambient', 'specular', 'emission'] ] + [ {'name':a,'text':a,'value':getattr(pf.canvas,a),'itemtype':'slider','min':0,'max':128,'scale':1.,'func':set_mat_value} for a in ['shininess'] ] enabled = [ pf.cfg['render/light%s'%light] is not None and pf.cfg['render/light%s'%light]['enabled'] for light in range(8) ] pf.debug("ENABLED LIGHTS") #items = [ ('material',mat_items) ] + [ ('light%s'%light, createLightDialogItems(light)) for light in range(8) if enabled[light]] choices = pf.canvas.light_model.keys() # DO NOT ALLOW THE LIGHT MODEL TO BE CHANGED choices = [ 'ambient and diffuse' ] items = [ {'name':'lightmodel','value':pf.canvas.lightmodel,'choices':choices,'tooltip':"""The light model defines which light components are set by the color setting functions. The default light model is 'ambient and diffuse'. The other modes are experimentally. Use them only if you know what you are doing."""}, ('material',mat_items) ] + [ ('light%s'%light, createLightDialogItems(light)) for light in range(8) if enabled[light]] #print items dia = None def close(): dia.close() def accept(save=False): dia.acceptData() res = dia.results pf.debug(res) pf.cfg['render/lightmodel'] = res['render/lightmodel'] pf.canvas.resetLighting() pf.app.processEvents() mt = utils.subDict(res,'render/material/') l0 = utils.subDict(res,'render/light0/') res = dict([ i for i in res.items() if not (i[0].startswith('render/material/') or i[0].startswith('render/light0/'))]) res['_save_'] = save res['render/material'] = mt res['render/light0'] =l0 updateSettings(res) def acceptAndSave(): accept(save=True) def addLight(): accept(save=False) dia.close() def createDialog(): dia = widgets.NewInputDialog( caption='pyFormex Settings', store=pf.cfg, items=items, prefix='render/', autoprefix=True, actions=[ ('Close',close), ('Accept and Save',acceptAndSave), ('Apply',accept), ] ) return dia dia = createDialog() dia.show()
def __init__(self): """Initialize an empty canvas with default settings.""" self.actors = ActorList(self,'actor') self.highlights = ActorList(self,'highlight') self.annotations = ActorList(self,'annotation') self.decorations = ActorList(self,'decoration') self.triade = None self.bbox = None self.resetLighting() self.resetLights() self.setBbox() self.settings = CanvasSettings() self.mode2D = False self.rendermode = 'wireframe' self.polygonfill = False self.lighting = True self.avgnormals = False self.alphablend = False self.dynamouse = True # dynamic mouse action works on mouse move self.dynamic = None # what action on mouse move self.camera = None self.view_angles = camera.view_angles self.cursor = None self.focus = False GD.debug("Canvas Setting:\n%s"% self.settings)
def saveWarningFilter(message, module='', category=UserWarning): cat = inverseDict(_warn_category).get(category, 'U') oldfilters = pf.prefcfg['warnings/filters'] newfilters = oldfilters + [(str(message), '', cat)] pf.prefcfg.update({'filters': newfilters}, name='warnings') pf.debug("Future warning filters: %s" % pf.prefcfg['warnings/filters'], pf.DEBUG.WARNING)
def __init__(self,func,duration=-1,maxcount=-1,sleep=0): """Create a new repeater""" pf.debug("REPEAT: %s, %s" % (duration, maxcount), pf.DEBUG.SCRIPT) self.exitcode = False self.func = func self.duration = duration self.maxcount = maxcount self.sleep = sleep
def refLookup(key): """Lookup a key in the reference configuration.""" try: return pf.refcfg[key] except: pf.debug("!There is no key '%s' in the reference config!" % key, pf.DEBUG.CONFIG) return None
def glSettings(settings): pf.debug("GL SETTINGS: %s" % settings, pf.DEBUG.DRAW) glShadeModel(settings.get('Shading', None)) glCulling(settings.get('Culling', None)) glLighting(settings.get('Lighting', None)) glLineSmooth(onOff(settings.get('Line Smoothing', None))) glPolygonFillMode(settings.get('Polygon Fill', None)) glPolygonMode(settings.get('Polygon Mode', None)) pf.canvas.update()
def cleanup(self): """Cleanup the GUI (restore default state).""" pf.debug('GUI cleanup',pf.DEBUG.GUI) self.drawlock.release() pf.canvas.cancel_selection() pf.canvas.cancel_draw() draw.clear_canvas() #draw.wakeup() self.setBusy(False)
def __init__(self, f, try_resolve=True): """Initialize the Unpickler""" pickle.Unpickler.__init__(self, f) if try_resolve: self.find_class = find_class else: pf.debug( "NOT TRYING TO RESOLVE RELOCATIONS: YOU MAY GET INTO TROUBLE", pf.DEBUG.PROJECT)
def accept(save=False): dia.acceptData() res = dia.results res['_save_'] = save if res['_addhost_']: res['jobs/hosts'] = pf.cfg['jobs/hosts'] + [res['_addhost_']] res['jobs/host'] = res['_addhost_'] pf.debug(res) updateSettings(res)
def scriptLock(id): global _run_mode if id == '__auto/script__': pf.scriptMode = 'script' elif id == '__auto/app__': pf.scriptMode = 'app' pf.debug("Setting script lock %s" % id, pf.DEBUG.SCRIPT) pf.scriptlock |= {id}
def closeGui(): """Close the GUI. Calling this function from a script closes the GUI and terminates pyFormex. """ pf.debug("Closing the GUI: currently, this will also terminate pyformex.", pf.DEBUG.GUI) pf.GUI.close()
def draw(self,**kargs): clear() pf.debug("Drawing SELECTION: %s" % self.names, pf.DEBUG.DRAW) pf.GUI.setBusy(True) self._actors = draw(self.names,clear=False,shrink=self.shrink,wait=False,**kargs) for f in self.annotations: pf.debug("Drawing ANNOTATION: %s" % f, pf.DEBUG.DRAW) self.drawAnnotation(f) pf.GUI.setBusy(False)
def filterWarnings(): pf.debug("Current warning filters: %s" % pf.cfg['warnings/filters'], pf.DEBUG.WARNING) try: for w in pf.cfg['warnings/filters']: utils.filterWarning(*w) except: pf.debug( "Error while processing warning filters: %s" % pf.cfg['warnings/filters'], pf.DEBUG.WARNING)
def pickle_load(f, try_resolve=True): """Load data from pickle file f.""" pi = cPickle.Unpickler(f) if try_resolve: pi.find_global = find_global else: pf.debug("NOT TRYING TO RESOLVE RELOCATIONS: YOU MAY GET INTO TROUBLE", pf.DEBUG.PROJECT) return pi.load()
def Unpickler(f, try_resolve=True): """Create an Unpickler object""" unpickler = pickle.Unpickler(f) if try_resolve: unpickler.find_global = find_class else: pf.debug( "NOT TRYING TO RESOLVE RELOCATIONS: YOU MAY GET INTO TROUBLE", pf.DEBUG.PROJECT) return unpickler
def _classify(self, nmax=20): """Classify, symlink and reload the scripts""" pf.debug("Classifying scripts", pf.DEBUG.APPS) if self.dir: f = os.path.join(self.dir, catname) all_apps, kat, cat, col = classify(self.dir, self.pkg, nmax) s = "all_apps = %r\nkat = %r\ncat = %r\ncol = %r\n" % ( all_apps, kat, cat, col) open(f, 'w').writelines(s) print("Created catalog %s" % f) self.reload()
def quit(): """Quit the pyFormex program This is a hard exit from pyFormex. It is normally not called directly, but results from an exit(True) call. """ if pf.app and pf.app_started: # quit the QT app pf.debug("draw.exit called while no script running", pf.DEBUG.SCRIPT) pf.app.quit() # closes the GUI and exits pyformex else: # the QT app didn't even start sys.exit(0) # use Python to exit pyformex