Exemple #1
0
def write_stl_asc(fn,x):
    """Write a collection of triangles to an ascii .stl file.

    Parameters:

    - `fn`: file name, by preference ending with '.stl' or '.stla'
    - `x`: (ntriangles,3,3) shaped array with the vertices of the
      triangles
    """
    if not x.shape[1:] == (4,3):
        raise ValueError,"Expected an (ntri,4,3) array, got %s" % x.shape

    pf.message("Writing ascii STL %s" % fn)
    with open(fn,'wb') as fil:

        fil.write("solid  Created by %s\n" % pf.fullVersion())
        for e in x:
            fil.write("  facet normal %s %s %s\n" % tuple(e[0]))
            fil.write("    outer loop\n")
            for p in e[1:]:
                fil.write("      vertex %s %s %s\n" % tuple(p))
            fil.write("    endloop\n")
            fil.write("  endfacet\n")
        fil.write("endsolid\n")
    pf.message("Finished writing ascii STL, %s bytes" % utils.fileSize(fn))
Exemple #2
0
    def start_js(self,name):
        """Export the start of the js file.

        Parameters:

        - `name`: string: the name of the model that will be shown
          by default when displaying the webgl html page

        This function should only be executed once, before any
        other export functions. It is called automatically by
        the first call to exportScene.
        """
        jsname = utils.changeExt(self.name, '.js')
        print("Exporting WebGL script to %s" % os.path.abspath(jsname))
        if self.urlprefix:
            jsurl = self.urlprefix + jsname
            print("Include it in the .html page as '%s'" % jsurl)
        else:
            jsurl = jsname
        self.scripts.append(jsurl)

        self.jsfile = open(jsname, 'w')
        s = "// Script generated by %s\n" % pf.fullVersion()
        if self.jsheader:
            s += str(self.jsheader)
        s += """
var the_renderer;
var the_controls;

window.onload = function() {
show%s();
}
"""% name
        self.jsfile.write(s)
Exemple #3
0
def detectedSoftware(all=True):
    """Return a dict with all detected helper software"""
    if all:
        checkAllModules()
        checkAllExternals()

    system, host, release, version, arch = os.uname()
    soft = {
        'System':
        OrderedDict([
            ('pyFormex_version', the_version['pyformex']),
            ('pyFormex_installtype', pf.installtype),
            ('pyFormex_fullversion', pf.fullVersion()),
            ('pyFormex_libraries', ', '.join(Libraries())),
            ('pyFormex_shaders', ', '.join(Shaders())),
            ('Python_version', the_version['python']),
            ('Python_fullversion', sys.version.replace('\n', ' ')),
            ('System', system),
            ('Host', host),
            ('Release', release),
            ('Version', version),
            ('Arch', arch),
        ]),
        'Modules':
        the_version,
        'Externals':
        the_external,
    }
    return soft
Exemple #4
0
def processReportOptions():
    """Process the reporting options

    Returns True if at least one reporting option was found,
    otherwise False.
    """
    ret = False

    if pf.options.docmodule is not None:
        for a in pf.options.docmodule:
            doc_module(a)
        # This is an all_exclusive option !!
        # So we immediately return
        return True

    if pf.options.experimental:
        sys.path.insert(1, os.path.join(pf.pyformexdir, 'experimental'))
        pf.options.whereami = True

    if pf.options.whereami:
        print(pf.fullVersion())
        print("pyFormex executable: %s" % pf.executable)
        print("pyFormex installation (%s): %s " %
              (pf.installtype, pf.pyformexdir))
        print("Python sys.path: %s" % sys.path)
        ret = True

    if pf.options.detect:
        print("Detecting installed helper software")
        print(software.reportSoftware())
        ret = True

    if pf.options.listmodules is not None:
        if not pf.options.listmodules:
            # Set default subpackages
            pf.options.listmodules = [
                'core', 'lib', 'plugins', 'gui', 'opengl'
            ]
        list_modules(pf.options.listmodules)
        ret = True

    if pf.options.pytest is not None:
        run_pytest(pf.options.pytest)
        ret = True

    if pf.options.doctest is not None:
        for a in pf.options.doctest:
            doctest_module(a)
        ret = True

    if pf.options.remove:
        remove_pyFormex(pf.pyformexdir, pf.executable)
        # After this option, we can not continue,
        # so this should be the last option processed
        ret = True

    return ret
Exemple #5
0
def openProject(fn=None,exist=False,access=['wr','rw','w','r'],default=None):
    """Open a (new or old) Project file.

    A dialog is presented to ask the user for a Project file name and the
    access modalities. The parameters help in setting sensible defaults
    for the user and in delimiting his options.
    Depending on he results of the dialog, either a new project is created or
    an old one is opened, or nothing is done.
    If a project is opened, it is returned, else the return value is None.

    Parameters:

    - `fn`: filename: if specified, the Project file dialog will start with
      the specified file, otherwise it will start in the current directory.
    - `exist`: boolean: if False (default), the user can create new project
      files as well as open existing ones. Use exist=True or
      :func:`openExistingProject` to only accept existing project files.
    - `access`: a list of :class:`Project` access modes to be presented to
      the user.
    - `default`: the access mode that is presented as default to the user.
      If not specified, the first option of `access` will be the default.
    """
    if type(access) == str:
        access = [access]
    cur = fn if fn else '.'
    typ = utils.fileDescription(['pyf','all'])
    res = widgets.ProjectSelection(cur,typ,exist=exist,access=access,default=default,convert=True).getResult()
    if not res:
        return

    fn = res.fn
    if not fn.endswith('.pyf'):
        fn += '.pyf'
    access = res.acc
    compression = res.cpr
    convert = res.cvt
    signature = pf.fullVersion()

    # OK, we have all data, now create/open the project
    pf.message("Opening project %s" % fn)
    pf.GUI.setBusy() # loading  may take a while
    try:
        proj = project.Project(fn,access=access,convert=convert,signature=signature,compression=compression)
        if proj.signature != signature:
            pf.warning("The project was written with %s, while you are now running %s. If the latter is the newer one, this should probably not cause any problems. Saving is always done in the current format of the running version. Save your project and this message will be avoided on the next reopening." % (proj.signature,signature))
    except:
        proj = None
        raise
    finally:
        pf.GUI.setBusy(False)

    proj.hits = 0
    pf.debug("START COUNTING HITS",pf.DEBUG.PROJECT)
    return proj
Exemple #6
0
def openProject(fn=None,exist=False,access=['wr', 'rw', 'w', 'r'],default=None):
    """Open a (new or old) Project file.

    A dialog is presented to ask the user for a Project file name and the
    access modalities. The parameters help in setting sensible defaults
    for the user and in delimiting his options.
    Depending on he results of the dialog, either a new project is created or
    an old one is opened, or nothing is done.
    If a project is opened, it is returned, else the return value is None.

    Parameters:

    - `fn`: filename: if specified, the Project file dialog will start with
      the specified file, otherwise it will start in the current directory.
    - `exist`: boolean: if False (default), the user can create new project
      files as well as open existing ones. Use exist=True or
      :func:`openExistingProject` to only accept existing project files.
    - `access`: a list of :class:`Project` access modes to be presented to
      the user.
    - `default`: the access mode that is presented as default to the user.
      If not specified, the first option of `access` will be the default.
    """
    if isinstance(access, str):
        access = [access]
    cur = fn if fn else '.'
    res = widgets.ProjectSelection(cur, ['pyf', 'all'], exist=exist, access=access, default=default, convert=True).getResults()
    if not res:
        return

    fn = res.fn
    if not fn.endswith('.pyf'):
        fn += '.pyf'
    access = res.acc
    compression = res.cpr
    convert = res.cvt
    signature = pf.fullVersion()

    # OK, we have all data, now create/open the project
    print("Opening project %s" % fn)
    pf.GUI.setBusy() # loading  may take a while
    try:
        proj = project.Project(fn, access=access, convert=convert, signature=signature, compression=compression)
        if proj.signature != signature:
            pf.warning("The project was written with %s, while you are now running %s. If the latter is the newer one, this should probably not cause any problems. Saving is always done in the current format of the running version. Save your project and this message will be avoided on the next reopening." % (proj.signature, signature))
    except:
        proj = None
        raise
    finally:
        pf.GUI.setBusy(False)

    proj.hits = 0
    pf.debug("START COUNTING HITS", pf.DEBUG.PROJECT)
    return proj
Exemple #7
0
def write_stl_bin(fn, x, color=None):
    """Write a binary stl.

    Parameters:

    - `x`: (ntri,4,3) float array describin ntri triangles.
      The first item of each triangle is the normal, the other
      three are the vertices.
    - `color`: (4,) int array with values in the range 0..255. These are
      the red, green, blue and alpha components of the color. This is a
      single color for all the triangles, and will be stored in the header
      of the STL file.
    """
    x = checkArray(x, shape=(-1, 4, 3), kind='f')
    if color is not None:
        #color = checkArray(color, shape=(4,), kind='i').astype(np.uint8)
        color = checkArray(color, shape=(4, ), kind='u',
                           allow='i').astype(np.uint8)

    def addTriangle(i):
        x[i].tofile(fil)
        fil.write('\x00\x00')

    print("Writing binary STL %s" % fn)
    ver = pf.fullVersion()
    if len(ver) > 50:
        ver = ver[:50]
    if color is None:
        color = ''
    else:
        color = "COLOR=%4s" % color.tostring()
        print("Adding %s to the header" % color)

    with open(fn, 'wb') as fil:
        head = "%-50s%-30s" % (ver, color)
        fil.write(head)
        ntri = x.shape[0]
        print("Number of triangles: %s" % ntri)
        np.array(ntri).astype(np.int32).tofile(fil)
        x = x.astype(np.float32)
        [addTriangle(i) for i in range(ntri)]
    print("Finished writing binary STL, %s bytes" % utils.fileSize(fn))
Exemple #8
0
def write_stl_bin(fn,x,color=None):
    """Write a binary stl.

    Parameters:

    - `x`: (ntri,4,3) float array describin ntri triangles.
      The first item of each triangle is the normal, the other
      three are the vertices.
    - `color`: (4,) int array with values in the range 0..255. These are
      the red, green, blue and alpha components of the color. This is a
      single color for all the triangles, and will be stored in the header
      of the STL file.
    """
    x = checkArray(x,shape=(-1,4,3),kind='f')
    if color is not None:
        color = checkArray(color,shape=(4,),kind='i').astype(np.uint8)

    def addTriangle(i):
        x[i].tofile(fil)
        fil.write('\x00\x00')

    pf.message("Writing binary STL %s" % fn)
    ver = pf.fullVersion()
    if len(ver) > 50:
        ver = ver[:50]
    if color is None:
        color = ''
    else:
        color = "COLOR=%4s" % color.tostring()
        pf.message("Adding %s to the header" % color)

    with open(fn,'wb') as fil:
        head = "%-50s%-30s" % (ver,color)
        fil.write(head)
        ntri = x.shape[0]
        pf.message("Number of triangles: %s" % ntri)
        np.array(ntri).astype(np.int32).tofile(fil)
        x = x.astype(np.float32)
        [ addTriangle(i) for i in range(ntri) ]
    pf.message("Finished writing binary STL, %s bytes" % utils.fileSize(fn))
Exemple #9
0
def reportDetected():
    notfound = '** Not Found **'
    s = "%s\n" % pf.fullVersion()
    s += "\nInstall type: %s\n" % pf.installtype
    s += "\npyFormex C libraries: %s\n" % Libraries()
    s += "\nPython version: %s\n" % sys.version
    s += "\nOperating system: %s\n" % sys.platform
    s += "\nDetected Python Modules:\n"
    the_version.sort(sorted(the_version.keys()))
    for k in the_version:
        v = the_version[k]
        if not v:
            v = notfound
        s += "%s (%s)\n" % (k, v)
    s += "\nDetected External Programs:\n"
    the_external.sort(sorted(the_external.keys()))
    for k in the_external:
        v = the_external[k]
        if not v:
            v = notfound
        s += "%s (%s)\n" % (k, v)
    return s
Exemple #10
0
def reportDetected():
    notfound = '** Not Found **'
    s = "%s\n" % pf.fullVersion()
    s += "\nInstall type: %s\n" % pf.installtype
    s += "\npyFormex C libraries: %s\n" % Libraries()
    s += "\nPython version: %s\n" % sys.version
    s += "\nOperating system: %s\n" % sys.platform
    s += "\nDetected Python Modules:\n"
    the_version.sort(sorted(the_version.keys()))
    for k in the_version:
        v = the_version[k]
        if not v:
            v = notfound
        s += "%s (%s)\n" % ( k,v)
    s += "\nDetected External Programs:\n"
    the_external.sort(sorted(the_external.keys()))
    for k in the_external:
        v = the_external[k]
        if not v:
            v = notfound
        s += "%s (%s)\n" % ( k,v)
    return s
Exemple #11
0
def createWebglHtml(name,scripts=[],bgcolor='white',body='',
                    description='WebGL model', keywords="pyFormex, WebGL",
                    author='', title='pyFormex WebGL model',header=''):
    """Create a html file for a WebGL model.

    Returns the absolute pathname to the created HTML file.
    """
    s = """<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="generator" content="%s">
""" % pf.fullVersion()
    if description:
        s += '<meta name="description" content="%s">\n' % description
    if keywords:
        s += '<meta name="keywords" content="%s">\n' % keywords
    if author:
        s += '<meta name="author" content="%s">\n' % author
    s += "<title>%s</title>\n" % title
    if header:
        s += header

    for scr in scripts:
        s += '<script type="text/javascript" src="%s"></script>\n' % scr

    s += """
</head>
<body bgcolor='%s'>
%s
</body>
</html>
""" % (colors.WEBcolor(bgcolor),body)

    with open(name, 'w') as htmlfile:
        htmlfile.write(s)
    return os.path.abspath(name)
Exemple #12
0
def createMultiWebGL():
    """Creates a multimodel WebGL from single WebGL models"""
    from pyformex.gui.draw import askFilename, askNewFilename, ack, showHTML
    models = askFilename(filter=['html','js'],multi=True)
    if not models:
        return
    combined = askNewFilename(filter=['html','js'],caption="Enter name of the combined model")
    if not combined:
        return
    fout = open(utils.changeExt(combined,'js'),'w')

    print("""// Script generated by %s
var the_renderer;
var the_menu;
window.onload = function() {
show%s()
}
""" % (pf.fullVersion(),utils.projectName(models[0])),file=fout)

    body = createdBy()
    body += "<div style='position:absolute;top:150px;left:10px;'>"
    for model in models:
        name = utils.projectName(model)
        body += "<button onclick='show%s()'>Show %s</button><br />" % (name,name)
        print('',file=fout)
        print("show%s = function() {" % name,file=fout)
        fn = utils.changeExt(model,'js')
        f = open(fn,'r')
        s = f.readlines()
        f.close()
        while len(s) > 0:
            line = s.pop(0)
            if line.startswith("window.onload = function"):
                break
        line = s.pop(0)
        if line.startswith("var r = new X.renderer3D"):
            print("""if (the_menu != null) the_menu.destroy();
if (the_renderer != null) the_renderer.destroy();
the_renderer = new X.renderer3D();
var r = the_renderer;
""",file=fout)
        else:
            raise ValueError("Invalid WebGL script %s" % fn)

        while len(s) > 0:
            line = s.pop(0)
            print(line,file=fout)
            if line.startswith("var gui = new dat.GUI"):
                print("the_menu = gui;",file=fout)
    fout.close()
    body += "</div>"

    fn = createWebglHtml(
        utils.changeExt(combined,'html'),
        scripts=[
            pf.cfg['webgl/script'],
            pf.cfg['webgl/guiscript'],
            utils.changeExt(combined,'js')
            ],
        body=body
        )

    if ack("Show the scene in your browser?"):
        showHTML(fn)
Exemple #13
0
def startGUI(args):
    """Create the QT4 application and GUI.

    A (possibly empty) list of command line options should be provided.
    QT4 wil remove the recognized QT4 and X11 options.
    """
    # This seems to be the only way to make sure the numeric conversion is
    # always correct
    #
    QtCore.QLocale.setDefault(QtCore.QLocale.c())
    #
    #pf.options.debug = -1
    pf.debug("Arguments passed to the QApplication: %s" % args,pf.DEBUG.INFO)
    pf.app = Application(args)
    #
    pf.debug("Arguments left after constructing the QApplication: %s" % args,pf.DEBUG.INFO)
    pf.debug("Arguments left after constructing the QApplication: %s" % '\n'.join(pf.app.arguments()),pf.DEBUG.INFO)
    #pf.options.debug = 0
    # As far as I have been testing this, the args passed to the Qt application are
    # NOT acknowledged and neither are they removed!!


    pf.debug("Setting application attributes",pf.DEBUG.INFO)
    pf.app.setOrganizationName("pyformex.org")
    pf.app.setOrganizationDomain("pyformex.org")
    pf.app.setApplicationName("pyFormex")
    pf.app.setApplicationVersion(pf.__version__)
    ## pf.settings = QtCore.QSettings("pyformex.org", "pyFormex")
    ## pf.settings.setValue("testje","testvalue")

    # Quit application if last window closed
    pf.app.lastWindowClosed.connect(pf.app.quit)

    # Check if we have DRI
    pf.debug("Setting OpenGL format",pf.DEBUG.OPENGL)
    dri = hasDRI()

    # Check for existing pyFormex processes
    pf.debug("Checking for running pyFormex",pf.DEBUG.INFO)
    if pf.X11:
        windowname,running = findOldProcesses()
    else:
        windowname,running = "UNKOWN",[]
    pf.debug("%s,%s" % (windowname,running),pf.DEBUG.INFO)


    while len(running) > 0:
        if len(running) >= 16:
            print("Too many open pyFormex windows --- bailing out")
            return -1

        pids = [ i[2] for i in running if i[2] is not None ]
        warning = """..

pyFormex is already running on this screen
------------------------------------------
A main pyFormex window already exists on your screen.

If you really intended to start another instance of pyFormex, you
can just continue now.

The window might however be a leftover from a previously crashed pyFormex
session, in which case you might not even see the window anymore, nor be able
to shut down that running process. In that case, you would better bail out now
and try to fix the problem by killing the related process(es).

If you think you have already killed those processes, you may check it by
rerunning the tests.
"""
        actions = ['Really Continue','Rerun the tests','Bail out and fix the problem']
        if pids:
            warning += """

I have identified the process(es) by their PID as::

%s

If you trust me enough, you can also have me kill this processes for you.
""" % pids
            actions[2:2] = ['Kill the running processes']

        if dri:
            answer = draw.ask(warning,actions)
        else:
            warning += """
I have detected that the Direct Rendering Infrastructure
is not activated on your system. Continuing with a second
instance of pyFormex may crash your XWindow system.
You should seriously consider to bail out now!!!
"""
            answer = draw.warning(warning,actions)


        if answer == 'Really Continue':
            break # OK, Go ahead

        elif answer == 'Rerun the tests':
            windowname,running = findOldProcesses() # try again

        elif answer == 'Kill the running processes':
            killProcesses(pids)
            windowname,running = findOldProcesses() # try again

        else:
            return -1 # I'm out of here!


    # Load the splash image
    pf.debug("Loading the splash image",pf.DEBUG.GUI)
    splash = None
    if os.path.exists(pf.cfg['gui/splash']):
        pf.debug('Loading splash %s' % pf.cfg['gui/splash'],pf.DEBUG.GUI)
        splashimage = QtGui.QPixmap(pf.cfg['gui/splash'])
        splash = QtGui.QSplashScreen(splashimage)
        splash.setWindowFlags(QtCore.Qt.WindowStaysOnTopHint|QtCore.Qt.SplashScreen)
        splash.setFont(QtGui.QFont("Helvetica",20))
        splash.showMessage(pf.Version,QtCore.Qt.AlignHCenter|QtCore.Qt.AlignTop,QtCore.Qt.red)
        splash.show()

    # create GUI, show it, run it

    pf.debug("Creating the GUI",pf.DEBUG.GUI)
    desktop = pf.app.desktop()
    pf.maxsize = Size(desktop.availableGeometry())
    size = pf.cfg.get('gui/size',(800,600))
    pos = pf.cfg.get('gui/pos',(0,0))
    bdsize = pf.cfg.get('gui/bdsize',(800,600))
    size = MinSize(size,pf.maxsize)

    # Create the GUI
    pf.GUI = Gui(windowname,
                 pf.cfg.get('gui/size',(800,600)),
                 pf.cfg.get('gui/pos',(0,0)),
                 pf.cfg.get('gui/bdsize',(800,600)),
                 )


    # set the appearance
    pf.debug("Setting Appearence",pf.DEBUG.GUI)
    pf.GUI.setAppearence()


    # setup the message board
    pf.board = pf.GUI.board
    pf.board.write("""%s   (C) Benedict Verhegghe

pyFormex comes with ABSOLUTELY NO WARRANTY. This is free software, and you are welcome to redistribute it under the conditions of the GNU General Public License, version 3 or later. See Help->License or the file COPYING for details.
""" % pf.fullVersion())

    # Set interaction functions


    def show_warning(message,category,filename,lineno,file=None,line=None):
        """Replace the default warnings.showwarning

        We display the warnings using our interactive warning widget.
        This feature can be turned off by setting
        cfg['warnings/popup'] = False
        """
        full_message = warnings.formatwarning(message,category,filename,lineno,line)
        pf.message(full_message)
        res,check = draw.showMessage(full_message,level='warning',check="Do not show this warning anymore in future sessions")
        if check[0]:
            utils.filterWarning(str(message))
            utils.saveWarningFilter(str(message))

    if pf.cfg['warnings/popup']:
        warnings.showwarning = show_warning


    pf.message = draw.message
    pf.warning = draw.warning
    pf.error = draw.error


    # setup the canvas
    pf.debug("Setting the canvas",pf.DEBUG.GUI)
    pf.GUI.processEvents()
    pf.GUI.viewports.changeLayout(1)
    pf.GUI.viewports.setCurrent(0)
    #pf.canvas = pf.GUI.viewports.current
    pf.canvas.setRenderMode(pf.cfg['draw/rendermode'])

    #
    # PYSIDE: raises (intercepted) exception on startup
    #
    draw.reset()

    # setup the status bar
    pf.debug("Setup status bar",pf.DEBUG.GUI)
    pf.GUI.addInputBox()
    pf.GUI.toggleInputBox(False)
    pf.GUI.addCoordsTracker()
    pf.GUI.toggleCoordsTracker(pf.cfg.get('gui/coordsbox',False))
    pf.debug("Using window name %s" % pf.GUI.windowTitle(),pf.DEBUG.GUI)

    # Script menu
    pf.GUI.scriptmenu = appMenu.createAppMenu(mode='script',parent=pf.GUI.menu,before='help')

    # App menu
    pf.GUI.appmenu = appMenu.createAppMenu(parent=pf.GUI.menu,before='help')


    # BV: removed, because they are in the script/app menus,
    # and the file menu is alredy very loaded

    ## # Link History Menus also in the File menu
    ## parent = pf.GUI.menu.item('file')
    ## before = parent.item('---1')
    ## if pf.GUI.apphistory:
    ##     parent.insert_menu(pf.GUI.apphistory,before)

    ## if pf.GUI.scripthistory:
    ##     parent.insert_menu(pf.GUI.scripthistory,before)

    # Create databases
    createDatabases()

    # Plugin menus
    import plugins
    filemenu = pf.GUI.menu.item('file')
    pf.gui.plugin_menu = plugins.create_plugin_menu(filemenu,before='---1')
    # Load configured plugins, ignore if not found
    plugins.loadConfiguredPlugins()

    # show current application/file
    appname = pf.cfg['curfile']
    pf.GUI.setcurfile(appname)

    # Last minute menu modifications can go here

    # cleanup
    pf.GUI.setBusy(False)         # HERE
    pf.GUI.addStatusBarButtons()

    if splash is not None:
        # remove the splash window
        splash.finish(pf.GUI)

    pf.GUI.setBusy(False)        # OR HERE

    pf.debug("Showing the GUI",pf.DEBUG.GUI)
    pf.GUI.show()

    # redirect standard output to board
    # TODO: this should disappear when we have buffered stdout
    # and moved this up into GUI init
    pf.GUI.board.redirect(pf.cfg['gui/redirect'])


    pf.GUI.update()

    if pf.cfg['gui/fortune']:
        sta,out = utils.runCommand(pf.cfg['fortune'])
        if sta == 0:
            draw.showInfo(out)

    #pf.app.setQuitOnLastWindowClosed(False)
    pf.app_started = True
    pf.GUI.processEvents()

    # load last project
    #
    #  TODO
    if pf.cfg['openlastproj']:
        fn = pf.cfg['curproj']
        if fn:
            try:
                proj = fileMenu.readProjectFile(fn)
                fileMenu.setProject(proj)
            except:
                # Avoid crashes from a faulty project file
                # TODO: should we push this up to fileMenu.readProjectFile ?
                #
                pf.message("Could not load the current project %s" % fn)
    #
    return 0
Exemple #14
0
def parseArguments(args):
    """Process command line arguments

    Parameters:

    - args: a list of command line arguments.

    The arguments of the pyFormex command line can be splitted in
    options and remaining arguments. This function will split the
    options from the other arguments and store them in the variable
    pf.options for access throughout pyFormex. The remaining arguments
    are stored in pf.options.args
    """
    import argparse
    parser = argparse.ArgumentParser(
        prog=pf.__prog__,
        #        usage = "%(prog)s [<options>] [ [ scriptname [scriptargs] ] ...]",
        description=pf.Description,
        epilog="More info on http://pyformex.org",
        #        formatter = optparse.TitledHelpFormatter(),
    )
    MO = parser.add_argument  # create a shorthand notation
    MO("--version", action='version', version=pf.fullVersion())
    MO(
        "--gui",
        action="store_true",
        dest="gui",
        default=None,
        help=
        "Start the GUI (this is the default when no scriptname argument is given)",
    )
    MO(
        "--nogui",
        action="store_false",
        dest="gui",
        default=None,
        help=
        "Do not start the GUI (this is the default when a scriptname argument is given)",
    )
    MO(
        "--nocanvas",
        action="store_false",
        dest="canvas",
        default=True,
        help=
        "Do not add an OpenGL canvas to the GUI (this is for development purposes only!)",
    )
    MO(
        "--interactive",
        action="store_true",
        dest="interactive",
        default=False,
        help=
        "Go into interactive mode after processing the command line parameters. This is implied by the --gui option.",
    )
    MO(
        "--uselib",
        action="store_true",
        dest="uselib",
        default=None,
        help="Use the pyFormex C lib if available. This is the default.",
    )
    MO(
        "--nouselib",
        action="store_false",
        dest="uselib",
        default=None,
        help="Do not use the pyFormex C-lib.",
    )
    MO(
        "--config",
        action="store",
        dest="config",
        default=None,
        help=
        "Use file CONFIG for settings. This file is loaded in addition to the normal configuration files and overwrites their settings. Any changes will be saved to this file.",
    )
    MO(
        "--nodefaultconfig",
        action="store_true",
        dest="nodefaultconfig",
        default=False,
        help=
        "Skip the default site and user config files. This option can only be used in conjunction with the --config option.",
    )
    MO(
        "--redirect",
        action="store_true",
        dest="redirect",
        default=None,
        help=
        "Redirect standard output to the message board (ignored with --nogui)",
    )
    MO(
        "--noredirect",
        action="store_false",
        dest="redirect",
        help="Do not redirect standard output to the message board.",
    )
    MO(
        "--debug",
        action="store",
        dest="debug",
        default='',
        help=
        "Display debugging information to sys.stdout. The value is a comma-separated list of (case-insensitive) strings corresponding with the attributes of the DebugLevels class. The individual values are OR-ed together to produce a final debug value. The special value 'all' can be used to switch on all debug info.",
    )
    MO(
        "--debuglevel",
        action="store",
        dest="debuglevel",
        type=int,
        default=0,
        help=
        "Display debugging info to sys.stdout. The value is an int with the bits of the requested debug levels set. A value of -1 switches on all debug info. If this option is used, it overrides the --debug option.",
    )
    MO(
        "--mesa",
        action="store_true",
        dest="mesa",
        default=False,
        help=
        "Force the use of software 3D rendering through the mesa libs. The default is to use hardware accelerated rendering whenever possible. This flag can be useful when running pyFormex remotely on another host. The hardware accelerated version will not work over remote X.",
    )
    MO(
        "--dri",
        action="store_true",
        dest="dri",
        default=None,
        help=
        "Use Direct Rendering Infrastructure. By default, direct rendering will be used if available.",
    )
    MO(
        "--nodri",
        action="store_false",
        dest="dri",
        default=None,
        help=
        "Do not use the Direct Rendering Infrastructure. This may be used to turn off the direc rendering, e.g. to allow better capturing of images and movies.",
    )
    MO(
        "--opengl",
        action="store",
        dest="opengl",
        default='2.0',
        help=
        "Force the use of a specific OpenGL version. The version should be specified as a string 'a.b'. The default is 2.0",
    )
    MO(
        "--shader",
        action="store",
        dest="shader",
        default='',
        help=
        "Force the use of an alternate GPU shader for the OpenGL rendering. If the default selected shader does not work well for your hardware, you can use this option to try one of the alternate shaders. See 'pyformex --detect' for a list of the available shaders.",
    )
    MO(
        "--newviewports",
        action="store_true",
        dest="newviewports",
        default=False,
        help=
        "Use the new multiple viewport canvas implementation. This is an experimental feature only intended for developers.",
    )
    MO(
        "--testcamera",
        action="store_true",
        dest="testcamera",
        default=False,
        help="Print camera settings whenever they change.",
    )
    MO(
        "--memtrack",
        action="store_true",
        dest="memtrack",
        default=False,
        help="Track memory for leaks. This is only for developers.",
    )
    MO(
        "--fastnurbs",
        action="store_true",
        dest="fastnurbs",
        default=False,
        help="Test C library nurbs drawing: only for developers!",
    )
    MO(
        "--pyside",
        action="store_true",
        dest="pyside",
        default=None,
        help="Use the PySide bindings for QT4 libraries",
    )
    MO(
        "--pyqt4",
        action="store_false",
        dest="pyside",
        default=None,
        help="Use the PyQt4 bindings for QT4 libraries",
    )
    MO(
        "--unicode",
        action="store_true",
        dest="unicode",
        default=False,
        help="Allow unicode filenames. Beware: this is experimental!",
    )
    MO(
        "--experimental",
        action="store_true",
        dest="experimental",
        default=False,
        help=
        "Allow the pyformex/experimental modules to be loaded. Beware: this should only be used if you know what you are doing!",
    )
    MO(
        "--listfiles",
        action="store_true",
        dest="listfiles",
        default=False,
        help="List the pyFormex Python source files and exit.",
    )
    MO(
        "--listmodules",
        action="store",
        dest="listmodules",
        default=None,
        metavar='PKG',
        nargs='*',
        help=
        "List the Python modules in the specified pyFormex subpackage and exit. Specify 'core' to just list the modules in the pyFormex top level. Specify 'all' to list all modules. The default is to list the modules in core, lib, plugins, gui, opengl.",
    )
    MO(
        "--search",
        action="store_true",
        dest="search",
        default=False,
        help=
        "Search the pyformex source for a specified pattern and exit. This can optionally be followed by -- followed by options for the grep command and/or '-a' to search all files in the extended search path. The final argument is the pattern to search. '-e' before the pattern will interprete this as an extended regular expression. '-l' option only lists the names of the matching files.",
    )
    MO(
        "--remove",
        action="store_true",
        dest="remove",
        default=False,
        help=
        "Remove the pyFormex installation and exit. This option only works when pyFormex was installed from a tarball release using the supplied install procedure. If you install from a distribution package (e.g. Debian), you should use your distribution's package tools to remove pyFormex. If you run pyFormex directly from SVN sources, you should just remove the whole checked out source tree.",
    )
    MO(
        "--whereami",
        action="store_true",
        dest="whereami",
        default=False,
        help="Show where the pyformex package is installed and exit.",
    )
    MO(
        "--detect",
        action="store_true",
        dest="detect",
        default=False,
        help="Show detected helper software and exit.",
    )
    MO(
        "--doctest",
        action="store",
        dest="doctest",
        default=None,
        metavar='MODULE',
        nargs='*',
        help=
        "Run the docstring tests for the specified pyFormex modules and exit. MODULE name is specified in Python syntax, relative to pyformex package (e.g. coords, plugins.curve).",
    )
    MO(
        "--pytest",
        action="store",
        dest="pytest",
        default=None,
        metavar='MODULE',
        nargs='*',
        help=
        "Run the pytest tests for the specified pyFormex modules and exit. MODULE name is specified in Python syntax, relative to pyformex package (e.g. coords, plugins.curve).",
    )
    MO(
        "--docmodule",
        action="store",
        dest="docmodule",
        default=None,
        metavar='MODULE',
        nargs='*',
        help=
        "Print the autogenerated documentation for module MODULE and exit. This is mostly useful during the generation of the pyFormex reference manual, as the produced result still needs to be run through the Sphinx documentation generator. MODULE is the name of a pyFormex module (Python syntax).",
    )
    MO(
        '-c',
        "--script",
        action="store",
        dest="script",
        default=None,
        metavar='SCRIPT',
        help=
        "A pyFormex script to be executed at startup. It is executed before any specified script files. This is mostly used in --nogui mode, when the script to execute is very short.",
    )
    MO(
        "args",
        action="store",
        nargs='*',
        metavar='FILE',
        help=
        "pyFormex script files to be executed on startup. The files should have a .py extension. Their contents will be executed as a pyFormex script. While mostly used with the --nogui option, this will also work in GUI mode.",
    )

    pf.options = parser.parse_args(args)
    # TODO: maybe store pf.parser instead ??
    pf.print_help = parser.print_help

    # Set debug level
    if pf.options.debug and not pf.options.debuglevel:
        pf.options.debuglevel = pf.debugLevel(pf.options.debug.split(','))

    # Check for invalid options
    if pf.options.nodefaultconfig and not pf.options.config:
        print(
            "\nInvalid options: --nodefaultconfig but no --config option\nDo pyformex --help for help on options.\n"
        )
        sys.exit()

    pf.debug("Options: %s" % pf.options, pf.DEBUG.ALL)
Exemple #15
0
def run(argv=[]):
    """This is a fairly generic main() function.

    It is responsible for reading the configuration file(s),
    processing the command line options and starting the application.
    The basic configuration file is 'pyformexrc' located in the pyformex
    directory. It should always be present and be left unchanged.
    You can copy this file to another location if you want to make changes.
    By default, pyformex will try to read the following extra configuration
    files (in this order:
        default settings:     <pyformexdir>/pyformexrc
        system-wide settings: /etc/pyformexrc
        user settings:        $HOME/.pyformex/pyformexrc
        local settings        $PWD/.pyformexrc
    Also, an extra config file can be specified in the command line.
    Config file settings always override previous ones.
    On exit, the preferences that were changed are written to the last
    read config file. Changed settings are those that differ from the settings
    in all but the last one.
    """
    # Create a config instance
    pf.cfg = Config()
    # Fill in the pyformexdir and homedir variables
    # (use a read, not an update)
    if os.name == 'posix':
        homedir = os.environ['HOME']
    elif os.name == 'nt':
        homedir = os.environ['HOMEDRIVE'] + os.environ['HOMEPATH']
    pf.cfg.read("pyformexdir = '%s'\n" % pyformexdir)
    pf.cfg.read("homedir = '%s'\n" % homedir)

    # Read the defaults (before the options)
    defaults = os.path.join(pyformexdir, "pyformexrc")
    pf.cfg.read(defaults)

    # Process options
    import optparse
    from optparse import make_option as MO
    parser = optparse.OptionParser(
        # THE Qapp options are removed, because it does not seem to work !!!
        # SEE the comments in the gui.startGUI function
        usage="usage: %prog [<options>] [ [ scriptname [scriptargs] ] ...]",
        version=pf.fullVersion(),
        description=pf.Description,
        formatter=optparse.TitledHelpFormatter(),
        option_list=[
            MO(
                "--gui",
                action="store_true",
                dest="gui",
                default=None,
                help=
                "Start the GUI (this is the default when no scriptname argument is given)",
            ),
            MO(
                "--nogui",
                action="store_false",
                dest="gui",
                default=None,
                help=
                "Do not start the GUI (this is the default when a scriptname argument is given)",
            ),
            MO(
                "--interactive",
                action="store_true",
                dest="interactive",
                default=False,
                help=
                "Go into interactive mode after processing the command line parameters. This is implied by the --gui option.",
            ),
            MO(
                "--dri",
                action="store_true",
                dest="dri",
                default=None,
                help=
                "Use Direct Rendering Infrastructure. By default, direct rendering will be used if available.",
            ),
            MO(
                "--nodri",
                action="store_false",
                dest="dri",
                default=None,
                help=
                "Do not use the Direct Rendering Infrastructure. This may be used to turn off the direc rendering, e.g. to allow better capturing of images and movies.",
            ),
            MO(
                "--uselib",
                action="store_true",
                dest="uselib",
                default=None,
                help=
                "Use the pyFormex C lib if available. This is the default.",
            ),
            MO(
                "--nouselib",
                action="store_false",
                dest="uselib",
                default=None,
                help="Do not use the pyFormex C-lib.",
            ),
            MO(
                "--commands",
                action="store_true",
                dest="commands",
                default=False,
                help=
                "Use the commands module to execute external commands. Default is to use the subprocess module.",
            ),
            MO(
                "--config",
                action="store",
                dest="config",
                default=None,
                help="Use file CONFIG for settings",
            ),
            MO(
                "--nodefaultconfig",
                action="store_true",
                dest="nodefaultconfig",
                default=False,
                help=
                "Skip the default site and user config files. This option can only be used in conjunction with the --config option.",
            ),
            MO(
                "--redirect",
                action="store_true",
                dest="redirect",
                default=None,
                help=
                "Redirect standard output to the message board (ignored with --nogui)",
            ),
            MO(
                "--noredirect",
                action="store_false",
                dest="redirect",
                help="Do not redirect standard output to the message board.",
            ),
            MO(
                "--debug",
                action="store",
                dest="debug",
                default='',
                help=
                "Display debugging information to sys.stdout. The value is a comma-separated list of (case-insensitive) strings corresponding with the attributes of the DebugLevels class. The individual values are OR-ed together to produce a final debug value. The special value 'all' can be used to switch on all debug info.",
            ),
            MO(
                "--debuglevel",
                action="store",
                dest="debuglevel",
                type="int",
                default=0,
                help=
                "Display debugging info to sys.stdout. The value is an int with the bits of the requested debug levels set. A value of -1 switches on all debug info. If this option is used, it overrides the --debug option.",
            ),
            MO(
                "--newviewports",
                action="store_true",
                dest="newviewports",
                default=False,
                help=
                "Use the new multiple viewport canvas implementation. This is an experimental feature only intended for developers.",
            ),
            MO(
                "--testmodule",
                action="store",
                dest="testmodule",
                default=None,
                help=
                "Run the docstring tests for module TESTMODULE. TESTMODULE is the name of the module, using . as path separator.",
            ),
            MO(
                "--testcamera",
                action="store_true",
                dest="testcamera",
                default=False,
                help="Print camera settings whenever they change.",
            ),
            MO(
                "--testexecutor",
                action="store_true",
                dest="executor",
                default=False,
                help="Test alternate executor: only for developers!",
            ),
            MO(
                "--memtrack",
                action="store_true",
                dest="memtrack",
                default=False,
                help="Track memory for leaks. This is only for developers.",
            ),
            MO(
                "--fastnurbs",
                action="store_true",
                dest="fastnurbs",
                default=False,
                help="Test C library nurbs drawing: only for developers!",
            ),
            MO(
                "--pyside",
                action="store_true",
                dest="pyside",
                default=None,
                help="Use the PySide bindings for QT4 libraries",
            ),
            MO(
                "--pyqt4",
                action="store_false",
                dest="pyside",
                default=None,
                help="Use the PyQt4 bindings for QT4 libraries",
            ),
            MO(
                "--opengl2",
                action="store_true",
                dest="opengl2",
                default=False,
                help=
                "Use the new OpenGL rendering engine. This is an experimental feature only intended for developers.",
            ),
            MO(
                "--listfiles",
                action="store_true",
                dest="listfiles",
                default=False,
                help="List the pyformex Python source files.",
            ),
            MO(
                "--search",
                action="store_true",
                dest="search",
                default=False,
                help=
                "Search the pyformex source for a specified pattern and exit. This can optionally be followed by -- followed by options for the grep command and/or '-a' to search all files in the extended search path. The final argument is the pattern to search. '-e' before the pattern will interprete this as an extended regular expression. '-l' option only lists the names of the matching files.",
            ),
            MO(
                "--remove",
                action="store_true",
                dest="remove",
                default=False,
                help=
                "Remove the pyFormex installation and exit. This option only works when pyFormex was installed from a tarball release using the supplied install procedure. If you install from a distribution package (e.g. Debian), you should use your distribution's package tools to remove pyFormex. If you run pyFormex directly from SVN sources, you should just remove the whole checked out source tree.",
            ),
            MO(
                "--whereami",
                action="store_true",
                dest="whereami",
                default=False,
                help="Show where the pyformex package is installed and exit",
            ),
            MO(
                "--detect",
                action="store_true",
                dest="detect",
                default=False,
                help="Show detected helper software and exit",
            ),
        ])
    pf.options, args = parser.parse_args(argv)
    pf.print_help = parser.print_help

    # Set debug level
    if pf.options.debug and not pf.options.debuglevel:
        pf.options.debuglevel = pf.debugLevel(pf.options.debug.split(','))

    # process options
    if pf.options.nodefaultconfig and not pf.options.config:
        print(
            "\nInvalid options: --nodefaultconfig but no --config option\nDo pyformex --help for help on options.\n"
        )
        sys.exit()

    pf.debug("Options: %s" % pf.options, pf.DEBUG.ALL)

    ########## Process special options which will not start pyFormex #######

    if pf.options.testmodule:
        for a in pf.options.testmodule.split(','):
            test_module(a)
        return

    if pf.options.remove:
        remove_pyFormex(pyformexdir, pf.bindir)
        return

    if pf.options.whereami:  # or pf.options.detect :
        pf.options.debuglevel |= pf.DEBUG.INFO

    pf.debug("pyformex script started from %s" % pf.bindir, pf.DEBUG.INFO)
    pf.debug("I found pyFormex installed in %s " % pyformexdir, pf.DEBUG.INFO)
    pf.debug("Current Python sys.path: %s" % sys.path, pf.DEBUG.INFO)

    if pf.options.detect:
        print("Detecting installed helper software")
        utils.checkExternal()
        print(utils.reportDetected())

    if pf.options.whereami or pf.options.detect:
        return

    ########### Read the config files  ####################

    # These values should not be changed
    pf.cfg.userprefs = os.path.join(pf.cfg.userconfdir, 'pyformexrc')

    # Set the config files
    if pf.options.nodefaultconfig:
        sysprefs = []
        userprefs = []
    else:
        sysprefs = [pf.cfg.siteprefs]
        userprefs = [pf.cfg.userprefs]
        if os.path.exists(pf.cfg.localprefs):
            userprefs.append(pf.cfg.localprefs)

    if pf.options.config:
        userprefs.append(pf.options.config)

    if len(userprefs) == 0:
        # We should always have a place to store the user preferences
        userprefs = [pf.cfg.userprefs]

    pf.preffile = os.path.abspath(userprefs[-1])  # Settings will be saved here

    # Read all but the last as reference
    for f in filter(os.path.exists, sysprefs + userprefs[:-1]):
        pf.debug("Reading config file %s" % f, pf.DEBUG.CONFIG)
        pf.cfg.read(f)

    pf.refcfg = pf.cfg
    pf.debug("=" * 60, pf.DEBUG.CONFIG)
    pf.debug("RefConfig: %s" % pf.refcfg, pf.DEBUG.CONFIG)

    # Use the last as place to save preferences
    pf.prefcfg = Config(default=refLookup)
    if os.path.exists(pf.preffile):
        pf.debug("Reading config file %s" % pf.preffile, pf.DEBUG.CONFIG)
        pf.prefcfg.read(pf.preffile)
    pf.debug("=" * 60, pf.DEBUG.CONFIG)
    pf.debug("Config: %s" % pf.prefcfg, pf.DEBUG.CONFIG)

    # Fix incompatible changes in configuration
    apply_config_changes(pf.prefcfg)

    # Create an empty one for the session settings
    pf.cfg = Config(default=prefLookup)

    ####################################################################
    ## Post config initialization ##

    # process non-starting options dependent on config

    if pf.options.search or pf.options.listfiles:
        if len(args) > 0:
            opts = [a for a in args if a.startswith('-')]
            args = [a for a in args if not a in opts]
            if '-a' in opts:
                opts.remove('-a')
                extended = True
            else:
                extended = False
            if len(args) > 1:
                files = args[1:]
            else:
                files = utils.sourceFiles(relative=True, extended=extended)
            if pf.options.listfiles:
                print('\n'.join(files))
            else:
                cmd = "grep %s '%s' %s" % (' '.join(opts), args[0], ''.join(
                    [" '%s'" % f for f in files]))
                #print(cmd)
                os.system(cmd)
        return

    # process other options dependent on config
    if pf.options.pyside is None:
        pf.options.pyside = pf.cfg['gui/bindings'].lower() == 'pyside'

    # process options that override the config
    if pf.options.redirect is not None:
        pf.cfg['gui/redirect'] = pf.options.redirect
    delattr(pf.options, 'redirect')  # avoid abuse
    #print "REDIRECT",pf.cfg['gui/redirect']

    ###################################################################

    # This should probably be changed to options overriding config
    # Set option from config if it was not explicitely given
    if pf.options.uselib is None:
        pf.options.uselib = pf.cfg['uselib']

    # Set default --nogui if first remaining argument is a pyformex script.
    if pf.options.gui is None:
        pf.options.gui = not (len(args) > 0 and utils.is_pyFormex(args[0]))

    if pf.options.gui:
        pf.options.interactive = True

    #  If we run from an source version, we should set the proper revision
    #  number and run the svnclean procedure.

    if pf.installtype in 'SG':
        svnclean = os.path.join(pyformexdir, 'svnclean')
        if os.path.exists(svnclean):
            try:
                utils.system(svnclean)
            except:
                print("Error while executing %s, we ignore it and continue" %
                      svnclean)

    ###### We have the config and options all set up ############
    filterWarnings()

    def _format_warning(message, category, filename, lineno, line=None):
        """Replace the default warnings.formatwarning

        This allows the warnings being called using a simple mnemonic
        string. The full message is then found from the message module.
        """
        import messages
        message = messages.getMessage(message)
        message = """..

pyFormex Warning
================
%s

`Called from:` %s `line:` %s
""" % (message, filename, lineno)
        if line:
            message += "%s\n" % line
        return message

    if pf.cfg['warnings/nice']:
        import warnings
        warnings.formatwarning = _format_warning

    utils.checkModule('numpy', fatal=True)

    # Make sure pf.PF is a Project
    from project import Project
    pf.PF = Project()

    utils.setSaneLocale()

    # Set application paths
    pf.debug("Loading AppDirs", pf.DEBUG.INFO)
    import apps
    apps.setAppDirs()

    # Start the GUI if needed
    # Importing the gui should be done after the config is set !!
    if pf.options.gui:
        from gui import guimain
        pf.debug("GUI version", pf.DEBUG.INFO)
        res = guimain.startGUI(args)
        if res != 0:
            print("Could not start the pyFormex GUI: %s" % res)
            return res  # EXIT

    # Display the startup warnings and messages
    if startup_warnings:
        if pf.cfg['startup_warnings']:
            pf.warning(startup_warnings)
        else:
            print(startup_warnings)
    if startup_messages:
        print(startup_messages)

    if pf.options.debuglevel & pf.DEBUG.INFO:
        # NOTE: inside an if to avoid computing the report when not printed
        pf.debug(utils.reportDetected(), pf.DEBUG.INFO)

    #
    # Qt4 may have changed the locale.
    # Since a LC_NUMERIC setting other than C may cause lots of troubles
    # with reading and writing files (formats become incompatible!)
    # we put it back to a sane setting
    #
    utils.setSaneLocale()

    # Initialize the libraries
    #import lib
    #lib.init_libs(pf.options.uselib,pf.options.gui)

    # Prepend the autorun script
    ar = pf.cfg.get('autorun', '')
    if ar and os.path.exists(ar):
        args[0:0] = [ar]

    # remaining args are interpreted as scripts and their parameters
    res = 0
    if args:
        pf.debug("Remaining args: %s" % args, pf.DEBUG.INFO)
        from script import processArgs
        res = processArgs(args)

        if res:
            if pf.options.gui:
                pf.message("There was an error while executing a script")
            else:
                return res  # EXIT

    else:
        pf.debug("stdin is a tty: %s" % sys.stdin.isatty(), pf.DEBUG.INFO)
        # Play script from stdin
        # Can we check for interactive session: stdin connected to terminal?
        #from script import playScript
        #playScript(sys.stdin)

    # after processing all args, go into interactive mode
    if pf.options.gui and pf.app:
        res = guimain.runGUI()

    ## elif pf.options.interactive:
    ##     print("Enter your script and end with CTRL-D")
    ##     from script import playScript
    ##     playScript(sys.stdin)

    #Save the preferences that have changed
    savePreferences()

    # Exit
    return res
Exemple #16
0
    def export(self,
               name=None,
               title=None,
               description=None,
               keywords=None,
               author=None,
               createdby=False):
        """Export the WebGL scene.

        Parameters:

        - `name`: a string that will be used for the filenames of the
          HTML, JS and STL files.
        - `title`: an optional title to be set in the .html file. If not
          specified, the `name` is used.

        You can also set the meta tags 'description', 'keywords' and
        'author' to be included in the .html file. The first two have
        defaults if not specified.

        Returns the name of the exported htmlfile.
        """
        if name is None:
            name = self.name
        if title is None:
            title = '%s WebGL example, created by pyFormex' % name
        if description is None:
            description = title
        if keywords is None:
            keywords = "pyFormex, WebGL, XTK, HTML, JavaScript"

        s = """// Script generated by %s

window.onload = function() {
var r = new X.renderer3D();
r.init();

""" % pf.fullVersion()
        s += '\n'.join([self.format_object(o) for o in self])
        if self.gui:
            s += self.format_gui()
        if self._camera:
            if 'position' in self._camera:
                s += "r.camera.position = %s;\n" % list(self._camera.position)
            if 'focus' in self._camera:
                s += "r.camera.focus = %s;\n" % list(self._camera.focus)
            if 'up' in self._camera:
                s += "r.camera.up = %s;\n" % list(self._camera.up)
        s += """
r.render();
};
"""
        jsname = utils.changeExt(name, '.js')
        with open(jsname, 'w') as jsfile:
            jsfile.write(s)
        print("Exported WebGL script to %s" % os.path.abspath(jsname))

        # TODO: setting DOCTYTPE makes browser initial view not good
        # s = """<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
        s = """<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="generator" content="%s">
<meta name="description" content="%s">
<meta name="keywords" content="%s">
""" % (pf.fullVersion(), description, keywords)
        if author:
            s += '<meta name="author" content="%s">\n' % author
        s += "<title>%s</title>\n" % title

        if self.gui:
            self.scripts.append(pf.cfg['webgl/guiscript'])
        self.scripts.append(jsname)

        for scr in self.scripts:
            s += '<script type="text/javascript" src="%s"></script>\n' % scr

        s += """
</head>
<body>"""
        if createdby:
            if type(createdby) is int:
                width = ' width="%s%%"' % createdby
            else:
                width = ''
            s += """<div id='pyformex' style='position:absolute;top:10px;left:10px;'>
<a href='http://pyformex.org' target=_blank><img src='http://pyformex.org/images/pyformex_createdby.png' border=0%s></a>
</div>""" % width
        s += """</body>
</html>
"""
        htmlname = utils.changeExt(jsname, '.html')
        with open(htmlname, 'w') as htmlfile:
            htmlfile.write(s)
        print("Exported WebGL model to %s" % os.path.abspath(htmlname))

        return htmlname
Exemple #17
0
##

"""project.py

Functions for managing a project in pyFormex.
"""
from __future__ import print_function

import pyformex as pf
from track import TrackedDict
from pyformex import utils
import os,sys
import cPickle
import gzip

_signature_ = pf.fullVersion()

module_relocations = {
    'plugins.mesh' : 'mesh',
    'plugins.surface' : 'plugins.trisurface',
}

class_relocations = {
    'coords.BoundVectors' : 'plugins.alt.BoundVectors',
    'coords.CoordinateSystem' : 'coordsys.CoordinateSystem',
    'elements.Element':'elements.ElementType',
}

def find_global(module,name):
    """Override the import path of some classes"""
    pf.debug("I want to import %s from %s" % (name,module),pf.DEBUG.PROJECT)
Exemple #18
0
##  along with this program.  If not, see http://www.gnu.org/licenses/.
##
"""project.py

Functions for managing a project in pyFormex.
"""
from __future__ import print_function

import pyformex as pf
from track import TrackedDict
from pyformex import utils
import os, sys
import cPickle
import gzip

_signature_ = pf.fullVersion()

module_relocations = {
    'plugins.mesh': 'mesh',
    'plugins.surface': 'plugins.trisurface',
}

class_relocations = {
    'coords.BoundVectors': 'plugins.alt.BoundVectors',
    'coords.CoordinateSystem': 'coordsys.CoordinateSystem',
    'elements.Element': 'elements.ElementType',
}


def find_global(module, name):
    """Override the import path of some classes"""
Exemple #19
0
    def export(self,name=None,title=None,description=None,keywords=None,author=None,createdby=False):
        """Export the WebGL scene.

        Parameters:

        - `name`: a string that will be used for the filenames of the
          HTML, JS and STL files.
        - `title`: an optional title to be set in the .html file. If not
          specified, the `name` is used.

        You can also set the meta tags 'description', 'keywords' and
        'author' to be included in the .html file. The first two have
        defaults if not specified.

        Returns the name of the exported htmlfile.
        """
        if name is None:
            name = self.name
        if title is None:
            title = '%s WebGL example, created by pyFormex' % name
        if description is None:
            description = title
        if keywords is None:
            keywords = "pyFormex, WebGL, XTK, HTML, JavaScript"

        s = """// Script generated by %s

window.onload = function() {
var r = new X.renderer3D();
r.init();

""" % pf.fullVersion()
        s += '\n'.join([self.format_object(o) for o in self ])
        if self.gui:
            s += self.format_gui()
        if self._camera:
            if 'position' in self._camera:
                s +=  "r.camera.position = %s;\n" % list(self._camera.position)
            if 'focus' in self._camera:
                s +=  "r.camera.focus = %s;\n" % list(self._camera.focus)
            if 'up' in self._camera:
                s +=  "r.camera.up = %s;\n" % list(self._camera.up)
        s += """
r.render();
};
"""
        jsname = utils.changeExt(name,'.js')
        with open(jsname,'w') as jsfile:
            jsfile.write(s)
        print("Exported WebGL script to %s" % os.path.abspath(jsname))

        # TODO: setting DOCTYTPE makes browser initial view not good
        # s = """<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
        s = """<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="generator" content="%s">
<meta name="description" content="%s">
<meta name="keywords" content="%s">
""" % (pf.fullVersion(),description,keywords)
        if author:
            s += '<meta name="author" content="%s">\n' % author
        s += "<title>%s</title>\n" % title

        if self.gui:
            self.scripts.append(pf.cfg['webgl/guiscript'])
        self.scripts.append(jsname)

        for scr in self.scripts:
            s += '<script type="text/javascript" src="%s"></script>\n' % scr

        s += """
</head>
<body>"""
        if createdby:
            if type(createdby) is int:
                width = ' width="%s%%"' % createdby
            else:
                width = ''
            s += """<div id='pyformex' style='position:absolute;top:10px;left:10px;'>
<a href='http://pyformex.org' target=_blank><img src='http://pyformex.org/images/pyformex_createdby.png' border=0%s></a>
</div>""" % width
        s += """</body>
</html>
"""
        htmlname = utils.changeExt(jsname,'.html')
        with open(htmlname,'w') as htmlfile:
            htmlfile.write(s)
        print("Exported WebGL model to %s" % os.path.abspath(htmlname))

        return htmlname