예제 #1
0
def gtsinside(self,pts,dir=0):
    """_Test whether points are inside the surface.

    pts is a plex-1 Formex.
    dir is the shooting direction.

    Returns a list of point numbers that are inside.
    This is not intended to be used directly. Use inside instead
    """
    import os
    print(os.environ)
    S = self.rollAxes(dir)
    P = pts.rollAxes(dir)
    tmp = utils.tempFile(suffix='.gts').name
    tmp1 = utils.tempFile(suffix='.dta').name
    tmp2 = utils.tempFile(suffix='.out').name
    pf.message("Writing temp file %s" % tmp)
    S.write(tmp,'gts')
    pf.message("Writing temp file %s" % tmp1)
    f = open(tmp1,'w')
    P.coords.tofile(f,sep=' ')
    f.write('\n')
    f.close()
    pf.message("Performing inside testing")
    cmd = "gtsinside %s %s > %s" % (tmp,tmp1,tmp2)
    sta,out = utils.runCommand(cmd)
    os.remove(tmp)
    os.remove(tmp1)
    if sta:
        pf.message("An error occurred during the testing.\nSee file %s for more details." % tmp2)
        return None
    pf.message("Reading results from %s" % tmp2)
    ind = fromfile(tmp2,sep=' ',dtype=Int)
    return ind
예제 #2
0
def workHere():
    """Change the current working directory to the script's location.

    This function is deprecated: use chdir(_file__) instead.
    """
    GD.message("workHere is deprecated: use chdir(_file__) instead")
    chdir(GD.PF.get("curfile", ""))
예제 #3
0
 def printBbox(self):
     """Print the bbox of the current selection."""
     objects = self.check()
     for n,o in zip(self.names,objects):
         GD.message("Object %s has bbox %s" % (n,o.bbox()))
     if len(self.names) > 1:
         GD.message("Overal bbox is %s" % bbox(objects))
예제 #4
0
def create_tetgen_volume():
    """Generate a volume tetraeder mesh inside an stl surface."""
    types = [ 'STL/OFF Files (*.stl *.off)', 'All Files (*)' ]
    fn = askFilename(GD.cfg['workdir'],types)
    if os.path.exists(fn):
        sta,out = utils.runCommand('tetgen -z %s' % fn)
        GD.message(out)
예제 #5
0
    def printSettings(self):
        for i,v in enumerate(self.all):
            pf.message("""
## VIEWPORTS ##
Viewport %s;  Current:%s;  Settings:
%s
""" % (i, v == self.current, v.settings))
예제 #6
0
def read_Formex(fn):
    GD.message("Reading file %s" % fn)
    t = timer.Timer()
    F = Formex.read(fn)
    nelems,nplex = F.f.shape[0:2]
    GD.message("Read %d elems of plexitude %d in %s seconds" % (nelems,nplex, t.seconds()))
    return F
예제 #7
0
    def __init__(self,coords,elems):
        """Create new model data.

        coords is an array with nodal coordinates
        elems is either a single element connectivity array, or a list of such.
        In a simple case, coords and elems can be the arrays obtained by 
        ``coords, elems = F.feModel()``.
        This is however limited to a model where all elements have the same
        number of nodes. Then you can use the list of elems arrays. The 'fe'
        plugin has a helper function to create this list. E.g., if ``FL`` is a
        list of Formices (possibly with different plexitude), then
        ``fe.mergeModels([Fi.feModel() for Fi in FL])``
        will return the (coords,elems) tuple to create the Model.

        The model can have node and element property numbers.
        """
        #Dict.__init__(self)
        if not type(elems) == list:
            elems = [ elems ]
        self.coords = Coords(coords)
        self.elems = [ Connectivity(e) for e in elems ]
        self.meshes = [ Mesh(self.coords,e) for e in self.elems ]
        nnodes = [ m.nnodes() for m in self.meshes ]
        nelems = [ m.nelems() for m in self.meshes ]
        nplex = [ m.nplex() for m in self.meshes ]
        self.cnodes = cumsum([0]+nnodes)
        self.celems = cumsum([0]+nelems)
        pf.message("Number of nodes: %s" % self.coords.shape[0])
        pf.message("Number of elements: %s" % self.celems[-1])
        pf.message("Number of element groups: %s" % len(nelems))
        #pf.message("Number of nodes per group: %s" % nnodes)
        pf.message("Number of elements per group: %s" % nelems)
        pf.message("Plexitude of each group: %s" % nplex)
예제 #8
0
    def pick_parts(self,obj_type,max_objects,store_closest=False):
        """Set the list of actor parts inside the pick_window.

        obj_type can be 'element', 'point' or 'edge'(SurfaceActor only)
        max_objects specifies the maximum number of objects

        The picked object numbers are stored in self.picked.
        If store_closest==True, the closest picked object is stored in as a
        tuple ( [actor,object] ,distance) in self.picked_closest
        """
        self.picked = []
        if max_objects <= 0:
            GD.message("No such objects to be picked!")
            return
        self.camera.loadProjection(pick=self.pick_window)
        self.camera.loadMatrix()
        stackdepth = 2
        selbuf = GL.glSelectBuffer(max_objects*(3+stackdepth))
        GL.glRenderMode(GL.GL_SELECT)
        GL.glInitNames()
        for i,a in enumerate(self.actors):
            GL.glPushName(i)
            a.pickGL(obj_type)  # this will push the number of the part
            GL.glPopName()
        self.picked = []
        libGL.glRenderMode(GL.GL_RENDER)
        if selbuf[0] > 0:
            buf = asarray(selbuf).reshape(-1,3+selbuf[0])
            buf = buf[buf[:,0] > 0]
            self.picked = buf[:,3:]
            if store_closest and len(buf) > 0:
                w = buf[:,1].argmin()
                self.closest_pick = (self.picked[w], buf[w,1])
예제 #9
0
파일: filewrite.py 프로젝트: dladd/pyFormex
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))
예제 #10
0
def checkResultsOnServer(host=None,userdir=None):
    """Get a list of job results from the cluster.

    Specify userdir='bumper/running' to get a list of running jobs.
    """
    global the_host,the_userdir,the_jobnames
    if host is None or userdir is None:
        res = askItems([
            ('host',None,'select',{'choices':['bumpfs','bumpfs2','other']}),
            ('other','',{'text':'Other host name'}),
            ('status',None,'select',{'choices':['results','running','custom']}),
            ('userdir','bumper/results/',{'text':'Custom user directory'}),
            ])
        if not res:
            return
        host = res['host']
        if host == 'other':
            host = res['other']
        status = res['status']
        if status in ['results','running']:
            userdir = 'bumper/%s/' % status
        else:
            userdir = res['userdir']
        
    jobnames = getSubdirs(host,userdir)
    if jobnames:
        the_host = host
        the_userdir = userdir
        the_jobnames = jobnames
    else:
        the_host = None
        the_userdir = None
        the_jobnames = None
    pf.message(the_jobnames)
예제 #11
0
def pick(mode='actor',single=False,func=None,filtr=None):
    """Enter interactive picking mode and return selection.

    See viewport.py for more details.
    This function differs in that it provides default highlighting
    during the picking operation, a button to stop the selection operation

    If no filter is given, the available filters are presented in a combobox.
    """
    if GD.canvas.selection_mode is not None:
        warning("You need to finish the previous picking operation first!")
        return

    pick_buttons = widgets.ButtonBox('Selection:',['Cancel','OK'],[GD.canvas.cancel_selection,GD.canvas.accept_selection])
    GD.GUI.statusbar.addWidget(pick_buttons)
    
    if mode == 'element':
        filters = selection_filters
    else:
        filters = selection_filters[:3]
    filter_combo = widgets.ComboBox('Filter:',filters,set_selection_filter)
    if filtr is not None and filtr in selection_filters:
        i = selection_filters.index(filtr)
        filter_combo.setIndex(i)
    GD.GUI.statusbar.addWidget(filter_combo)
    
    if func is None:
        func = highlight_funcs.get(mode,None)
    GD.message("Select %s %s" % (filtr,mode))
    sel = GD.canvas.pick(mode,single,func,filtr)
    GD.GUI.statusbar.removeWidget(pick_buttons)
    GD.GUI.statusbar.removeWidget(filter_combo)
    return sel
예제 #12
0
파일: calpy_itf.py 프로젝트: dladd/pyFormex
def detect(trypaths=None):
    """Check if we have calpy and if so, add its path to sys.path."""

    global calpy_path

    calpy = utils.checkExternal('calpy')
    if not calpy:
        return

    pf.message("You have calpy version %s" % calpy)
    path = ''
    calpy = calpy.split('-')[0]  # trim the version trailer
    if utils.checkVersion('calpy','0.3.4-rev3',external=True) >= 0:
        sta,out = utils.runCommand('calpy --whereami')
        if not sta:
            path = out
            pf.debug("I found calpy in %s" % path)
    if not path:
        if trypaths is None:
            trypaths = [ '/usr/local/lib', '/usr/local' ]
        for p in trypaths:
            path = '%s/calpy-%s' % (p,calpy)
            if os.path.exists(path):
                pf.debug('path exists: %s' % path)
                break
            else:
                pf.debug('path does not exist: %s' % path)
                path = ''
    if path:
        #path += '/calpy'
        pf.message("I found calpy in '%s'" % path)
        sys.path.append(path)

    calpy_path = path
예제 #13
0
def inputControlLines():
    """Enter three polyline paths in counterclockwise direction."""
    branch = []
    BA = []
    perspective(False)
    for i in range(6):
        pf.message("Input Branch %s" % i)
        if i % 2 == 0:
            coords = None
        else:
            coords = branch[i-1].coords[-1:]

        obj = d2.drawObject2D(mode='polyline',npoints=-1,coords=coords,zvalue=0.)

        obj.specular = 0.
        pf.canvas.removeHighlight()
        ## WHY is bbox='last' or zoomAll needed here
        if obj is not None:
            BA.append(draw(obj,color='blue',flat=True))
            zoomAll()
            branch.append(obj)
        else:
            break

    if len(branch) == 6:
        undraw(BA)
        createBranches(branch)
        zoomAll()
    else:
        warning("Incorrect definition of helper lines")
예제 #14
0
파일: fileMenu.py 프로젝트: dladd/pyFormex
def closeProject(save=None,clear=None):
    """Close the current project, saving it or not.

    Parameters:

    - `save`: None, True or False. Determines whether the project should be
      saved prior to closing it. If None, it will be asked from the user.
      Note that this parameter is only used for named Projects. Temporary
      Projects are never saved implicitely.
    - `clear`: None, True or False.
    """
    if pf.PF.filename is not None:
        if save is None:
            save = draw.ack("Save the current project before closing it?")
        pf.message("Closing project %s (save=%s)" % (pf.PF.filename,save))
        if save:
            saveProject()
            if pf.PF:
                listProject()
                if clear is None:
                    clear = draw.ask("What shall I do with the existing globals?",["Delete","Keep"]) == "Delete"

    if clear:
        pf.PF.clear()

    pf.PF.filename = None
    pf.GUI.setcurproj('None')
    updateSettings({
        'curproj':pf.PF.filename,
        },save=True)
예제 #15
0
파일: fileread.py 프로젝트: dladd/pyFormex
def readMeshFile(fn):
    """Read a nodes/elems model from file.

    Returns a dict:

    - `coords`: a Coords with all nodes
    - `elems`: a list of Connectivities
    - `esets`: a list of element sets
    """
    d = {}
    fil = open(fn,'r')
    for line in fil:
        if line[0] == '#':
            line = line[1:]
        globals().update(getParams(line))
        dfil = open(filename,'r')
        if mode == 'nodes':
            d['coords'] = readNodes(dfil)
        elif mode == 'elems':
            elems = d.setdefault('elems',[])
            e = readElems(dfil,int(nplex)) - int(offset)
            elems.append(e)
        elif mode == 'esets':
            d['esets'] = readEsets(dfil)
        else:
            pf.message("Skipping unrecognized line: %s" % line)
        dfil.close()

    fil.close()
    return d
예제 #16
0
파일: fileMenu.py 프로젝트: dladd/pyFormex
def importProject():
    """Import an existing project.

    Ask the user to select an existing project file, and then import
    all or selected data from it into the current project.
    """
    proj = openProject(exist=True,access='r')
    if proj: # only if non-empty
        keys = utils.sortedKeys(proj)
        res = draw.askItems(
            [   _I('mode',choices=['All','Defined','Undefined','Selected','None'],itemtype='radio'),
                _I('selected',choices=keys,itemtype='list'),
                ],
            caption='Select variables to import',
            )
        if res:
            mode = res['mode'][0]
            if mode == 'A':
                pass
            elif mode == 'D':
                proj = utils.selectDict(proj,pf.PF)
            elif mode == 'U':
                proj = utils.removeDict(proj,pf.PF)
            elif mode == 'S':
                proj = utils.selectDict(proj,res['selected'])
            elif mode == 'N':
                return
            pf.message("Importing symbols: %s" % utils.sortedKeys(proj))
            pf.PF.update(proj)
            listProject()
예제 #17
0
def clip_surface():
    """Clip the stl model."""
    if not check_surface():
        return
    itemlist = [['axis',0],['begin',0.0],['end',1.0],['nodes','any']]
    res = askItems(itemlist,caption='Clipping Parameters')
    if res:
        updateGUI()
        nodes,elems = PF['old_surface'] = PF['surface']
        F = Formex(nodes[elems])
        bb = F.bbox()
        GD.message("Original bbox: %s" % bb) 
        xmi = bb[0][0]
        xma = bb[1][0]
        dx = xma-xmi
        axis = int(res[0][1])
        xc1 = xmi + float(res[1][1]) * dx
        xc2 = xmi + float(res[2][1]) * dx
        nodid = res[3][1]
        #print(nodid)
        clear()
        draw(F,color='yellow')
        w = F.test(nodes='any',dir=axis,min=xc1,max=xc2)
        F = F.clip(w)
        draw(F,color='red')
예제 #18
0
    def write(self,geom,name=None,sep=None):
        """Write any geometry object to the geometry file.

        `geom` is one of the Geometry data types of pyFormex or a list
        or dict of such objects.
        Currently exported geometry objects are
        :class:`Coords`, :class:`Formex`, :class:`Mesh`,
        :class:`PolyLine`, :class:`BezierSpline`.
        The geometry object is written to the file using the specified
        separator, or the default.
        """
        self.checkWritable()
        if isinstance(geom,dict):
            for name in geom:
                self.write(geom[name],name,sep)
        elif isinstance(geom,list):
            if name is None:
                for obj in geom:
                    self.write(obj,None,sep)
            else:
                name = utils.NameSequence(name)
                for obj in geom:
                    self.write(obj,name.next(),sep)
                    
        elif hasattr(geom,'write_geom'):
            geom.write_geom(self,name,sep)
        else:
            try:
                writefunc = getattr(self,'write'+geom.__class__.__name__)
                #print writefunc
                writefunc(geom,name,sep)
            except:
                message("Can not (yet) write objects of type %s to geometry file: skipping" % type(geom))
예제 #19
0
def readSelection(select=True,draw=True,multi=True):
    """Read a Formex (or list) from asked file name(s).

    If select is True (default), this becomes the current selection.
    If select and draw are True (default), the selection is drawn.
    """
    types = utils.fileDescription(['pgf','all'])
    fn = askFilename(GD.cfg['workdir'],types,multi=multi)
    if fn:
        if not multi:
            fn = [ fn ]
        chdir(fn[0])
        res = ODict()
        GD.GUI.setBusy()
        for f in fn:
            res.update(readGeomFile(f))
        GD.GUI.setBusy(False)
        export(res)
        if select:
            oknames = [ k for k in res if isinstance(res[k],Formex) ]
            selection.set(oknames)
            GD.message("Set Formex selection to %s" % oknames)
            if draw:
                selection.draw()
    return fn
예제 #20
0
def readSelection(select=True,draw=True,multi=True):
    """Read a Surface (or list) from asked file name(s).

    If select is True (default), this becomes the current selection.
    If select and draw are True (default), the selection is drawn.
    """
    types = [ 'Surface Files (*.gts *.stl *.off *.neu *.smesh)', 'All Files (*)' ]
    fn = askFilename(GD.cfg['workdir'],types,multi=multi)
    if fn:
        if not multi:
            fn = [ fn ]
        chdir(fn[0])
        names = map(utils.projectName,fn)
        GD.GUI.setBusy()
        surfaces = [ read_Surface(f,False) for f in fn ]
        for i,S in enumerate(surfaces):
            S.setProp(i)
        GD.GUI.setBusy(False)
        export(dict(zip(names,surfaces)))
        if select:
            GD.message("Set selection to %s" % str(names))
            selection.set(names)
            if draw:
                if max([named(s).nfaces() for s in selection]) < 100000 or ack("""
This is a large model and drawing could take quite some time.
You should consider coarsening the model before drawing it.
Shall I proceed with the drawing now?
"""):
                    selection.draw()
    return fn
예제 #21
0
def pause(msg="Use the Step/Continue buttons to proceed"):
    if msg:
        GD.message(msg)
    if allowwait:
        drawblock()    # will need external event to release it
        while (drawlocked):
            sleep(0.5)
            GD.app.processEvents()
예제 #22
0
def printDataSize():
    for s in selection.names:
        S = named(s)
        try:
            size = S.info()
        except:
            size = 'no info available'
        pf.message("* %s (%s): %s" % (s,S.__class__.__name__,size))
예제 #23
0
 def printbbox(self):
     """Print the bbox of the current selection."""
     objects = self.check()
     if objects:
         for n,o in zip(self.names,objects):
             bb = o.bbox()
             pf.message("* %s (%s): bbox [%s, %s]" % (n,o.__class__.__name__,bb[0],bb[1]))
         if len(self.names) > 1:
             pf.message("** Overal bbox: [%s, %s]" % (bb[0],bb[1]))
예제 #24
0
 def selectStepInc(self):
     res = askItems([('Step',self.DB.step,'select',self.DB.res.keys())])
     if res:
         step = int(res['Step'])
         res = askItems([('Increment',None,'select',self.DB.res[step].keys())])
         if res:
             inc = int(res['Increment'])
     GD.message("Step %s; Increment %s;" % (step,inc))
     self.DB.setStepInc(step,inc)
예제 #25
0
def export_webgl():
    F = selection.check(single=True)
    if F:
        types = map(utils.fileDescription,['stl'])
        fn = askNewFilename(pf.cfg['workdir'],types)
        if fn:
            pf.message("Exporting surface model to %s" % fn)
            pf.GUI.setBusy()
            F.webgl(fn)
            pf.GUI.setBusy(False)
예제 #26
0
def runCommand(cmd,RaiseError=True,quiet=False):
    """Run a command and raise error if exited with error."""
    if not quiet:
        pf.message("Running command: %s" % cmd)
    sta,out = commands.getstatusoutput(cmd)
    if sta != 0:
        pf.message(out)
        if RaiseError:
            raise RuntimeError, "Error while executing command:\n  %s" % cmd
    return sta,out
예제 #27
0
def read_Surface(fn,exportName=True):
    GD.message("Reading file %s" % fn)
    t = timer.Timer()
    S = TriSurface.read(fn)
    GD.message("Read surface with %d vertices, %d edges, %d triangles in %s seconds" % (S.ncoords(),S.nedges(),S.nelems(),t.seconds()))
    if exportName:
        name = utils.projectName(fn)
        export({name:S})
        selection.set([name])
    return S
예제 #28
0
def show_volume():
    """Display the volume model."""
    if PF["volume"] is None:
        return
    nodes, elems = PF["volume"]
    F = Formex(nodes[elems], eltype="tet4")
    pf.message("BBOX = %s" % F.bbox())
    clear()
    draw(F, color="random")
    PF["vol_model"] = F
예제 #29
0
def closeProject():
    global the_project,the_project_saved
    if not (the_project_saved or the_project is None):
        GD.message("Closing project %s" % the_project.filename)
        GD .message("Project contents: %s" % the_project.keys())
        the_project.save()
        GD.PF = {}
        GD.PF.update(the_project)
        GD.gui.setcurproj('None')
    the_project = None
예제 #30
0
def show_volume():
    """Display the volume model."""
    if PF['volume'] is None:
        return
    nodes,elems = PF['volume']
    F = Formex(nodes[elems],eltype='tet4')
    GD.message("BBOX = %s" % F.bbox())
    clear()
    draw(F,color='random')
    PF['vol_model'] = F
예제 #31
0
def readInpFile(filename):
    """Read the geometry from an Abaqus/Calculix .inp file

    This is a replacement for the convertInp/readMeshFile combination.
    It uses the ccxinp plugin to provide a direct import of the Finite
    Element meshes from an Abaqus or Calculix input file.
    Currently still experimental and limited in functionality (aimed
    primarily at Calculix). But also many simple meshes from Abaqus can
    already be read.

    Returns an dict.
    """
    from plugins import ccxinp, fe
    ccxinp.skip_unknown_eltype = True
    model = ccxinp.readInput(filename)
    pf.message("Number of parts: %s" % len(model.parts))
    fem = {}
    for part in model.parts:
        try:
            coords = Coords(part['coords'])
            nodid = part['nodid']
            nodpos = inverseUniqueIndex(nodid)
            pf.message("nnodes = %s" % coords.shape[0])
            pf.message("nodid: %s" % nodid)
            pf.message("nodpos: %s" % nodpos)
            for e in part['elems']:
                pf.message("Orig els %s" % e[1])
                pf.message("Trl els %s" % nodpos[e[1]])
            elems = [
                Connectivity(nodpos[e], eltype=t) for (t, e) in part['elems']
            ]
            pf.message('ELEM TYPES: %s' % [e.eltype for e in elems])
            fem[part['name']] = fe.Model(coords, elems)
        except:
            pf.message("Skipping part %s" % part['name'])
    return fem
예제 #32
0
    def read(self, count=-1):
        """Read a pyFormex Geometry File.

        fil is a filename or a file object.
        If the file is in a valid pyFormex geometry file format, geometry
        objects are read from the file and returned in a dictionary.
        The object names are used as keys. If the file does not contain
        object names, they will be autogenerated from the file name.

        A count may be specified to limit the number of objects read.

        If the file format is invalid and no valid geometry could be read,
        None is returned.
        Valid pyFormex geometry file formats are described in the manual.
        """
        eltype = None  # for compatibility with pre 1.1 .formex files
        ndim = 3
        while True:
            objtype = 'Formex'  # the default obj type
            obj = None
            nelems = None
            ncoords = None
            sep = self.sep
            name = None
            normals = None
            color = None
            s = self.fil.readline()

            if len(s) == 0:  # end of file
                break

            if not s.startswith('#'):  # not a header: skip
                continue

            ###
            ###  THIS WILL USE UNDEFINED VALUES FROM A PREVIOUS OBJECT
            ###  THIS SHOULD THEREFORE BE CHANGED !!!!
            ###
            try:
                exec(s[1:].strip())
                print("READ COLOR: %s" % str(color))
            except:
                nelems = ncoords = None

            if nelems is None and ncoords is None:
                # For historical reasons, this is a certain way to test
                # that no geom data block is following
                print("SKIPPING %s" % s)
                continue  # not a legal header: skip

            debug("Reading object of type %s" % objtype, DEBUG.INFO)

            # OK, we have a legal header, try to read data
            if objtype == 'Formex':
                obj = self.readFormex(nelems, nplex, props, eltype, sep)
            elif objtype in ['Mesh', 'TriSurface']:
                obj = self.readMesh(ncoords, nelems, nplex, props, eltype,
                                    normals, sep, objtype)
            elif objtype == 'PolyLine':
                obj = self.readPolyLine(ncoords, closed, sep)
            elif objtype == 'BezierSpline':
                if 'nparts' in s:
                    # THis looks like a version 1.3 BezierSpline
                    obj = self.oldReadBezierSpline(ncoords, nparts, closed,
                                                   sep)
                else:
                    if not 'degree' in s:
                        # compatibility with 1.4  BezierSpline records
                        degree = 3
                    obj = self.readBezierSpline(ncoords, closed, degree, sep)
            elif objtype == 'NurbsCurve':
                obj = self.readNurbsCurve(ncoords, nknots, closed, sep)
            elif objtype in globals() and hasattr(globals()[objtype],
                                                  'read_geom'):
                obj = globals()[objtype].read_geom(self)
            else:
                message(
                    "Can not (yet) read objects of type %s from geometry file: skipping"
                    % objtype)
                continue  # skip to next header

            if obj is not None:
                try:
                    color = checkArray(color, (3, ), 'f')
                    print("SET OBJECT COLOR TO %s" % color)
                    obj.color = color
                except:
                    print("NOT SETTING COLOR %s" % str(color))
                    pass

                if name is None:
                    name = self.objname.next()
                self.results[name] = obj

            if count > 0 and len(self.results) >= count:
                break

        if self.isname:
            self.fil.close()

        return self.results