def _loadAnalyzeFile(filename, name, imgObj, task): with f: filename = Future.get(filename) name = name or self.mgr.getUniqueObjName( splitPathExt(filename)[1]) img = imgObj or nibabel.load(filename) dat = dat = np.asanyarray(img.dataobj) hdr = dict(img.get_header()) hdr['filename'] = filename pixdim = hdr['pixdim'] interval = float(pixdim[4]) if interval == 0.0 and len( img.shape) == 4 and img.shape[-1] > 1: interval = 1.0 spacing = vec3(pixdim[1], pixdim[2], pixdim[3]) dat = eidolon.transposeRowsColsNP( dat) # transpose from row-column to column-row obj = self.createObjectFromArray(name, dat, interval, 0, vec3(), rotator(), spacing, task=task) obj.source = hdr f.setObject(obj)
def testXis2(self): '''Test the xi values of corners of a SharedImage, calls getPlaneXi().''' si = SharedImage('', vec3(1, -2, 3), rotator(0.1, -0.2, 0.3), (10, 10), (0.678, 0.789)) corners = si.getCorners() self.assertEqual(vec3(), si.getPlaneXi(corners[0])) self.assertEqual(vec3(1, 1), si.getPlaneXi(corners[-1])) self.assertEqual(vec3(0.5, 0.5), si.getPlaneXi(si.center))
def testFromTo2(self): for i in range(100): x, y, z = randnums(3, -5, 5) v = vec3(x, y, z) r = rotator(v, -v) self.assertEqual(r, rotator( vec3(1, 0, 0).cross(v), 0)) # TODO: wanted to actually test 180 degree rotators
def testXis1(self): '''Test the xi values of points on the plane of a SharedImage, calls SharedImage.getPlaneXi().''' si = SharedImage('', vec3(), rotator(), (10, 10)) self.assertEqual(vec3(), si.getPlaneXi(vec3())) self.assertEqual(vec3(1, 1), si.getPlaneXi(vec3(10, -10))) self.assertEqual(vec3(0.5, 0.5), si.getPlaneXi(vec3(5, -5))) self.assertEqual(vec3(0.5, 0.5), si.getPlaneXi(vec3(5, -5)))
def importImages(x4, plugin): ''' Import images from the X4DF object `x4', returning a list of ImageSceneObject instances. The `plugin' must be an ImageScenePlugin instance used to create the objects. ''' arrs = {a.name: a for a in x4.arrays} results = [] for im in x4.images: name, timescheme, trans, imagedata, _ = im images = [] filenames = [] tstart, tstep = timescheme or (0, 0) trans = trans or idTransform for i, imgdat in enumerate(imagedata): src, timestep, imgtrans, _ = imgdat arr = arrs[src].data imgtrans = imgtrans or trans filenames.append(arrs[src].filename) if timestep is None: offset, interval = tstart, tstep else: offset, interval = tstart + i * tstep, 0 arr = reverseAxes( arr ) # array is stored in inverse index order from what is expected pos = vec3(*imgtrans.position) rot = rotator(*imgtrans.rmatrix.flatten()) spacing = vec3(*imgtrans.scale) * vec3( arr.shape[1], arr.shape[0], arr.shape[2] if len(arr.shape) > 2 else 0).inv() obj = plugin.createObjectFromArray('tmp', arr, interval, offset, pos, rot, spacing) images += obj.images results.append( eidolon.ImageSceneObject(name, None, images, filenames=list(filter(bool, filenames)))) return results
def loadPolydataNodes(self, filename): '''Fast load for node data from a polydata .vtk file, this ignores everything but the nodes.''' with open(filename) as o: header = [ o.readline(), o.readline(), o.readline(), o.readline(), o.readline() ] assert header[2].strip().lower() == 'ascii', repr(header) assert header[3].strip().lower() == 'dataset polydata', repr( header) nodes = eidolon.Vec3Matrix('nodes', 0) nodes.reserveRows(int(header[-1].split()[1]) / 3) vals = [] for line in o: vals += line.split( ) # add numbers to accumulated list, this allows nodes to be split between lines safely while len( vals ) >= 3: # read a node if there's 3+ values, if the # of values isn't a multiple of 3 retain the last 1 or 2 in vals nodes.append( vec3(float(vals.pop(0)), float(vals.pop(0)), float(vals.pop(0)))) return nodes, header
def testIdent1(self): '''Test the default rotator which should represent the identity transformation.''' for i in range(100): x, y, z = randnums(3, -5, 5) v = vec3(x, y, z) r = rotator() self.assertEqual(r * v, v)
def testInv1(self): for i in range(100): x, y, z = randnums(3, -5, 5) v = vec3(x, y, z) y, p, r = randnums(3, -math.pi * 2, math.pi * 2) r1 = rotator(y, p, r) self.assertEqual(r1 * (r1 / v), v)
def testMatrix2(self): for i in range(100): a = randangle() r = rotator(vec3(1, 0, 0), a) eqas_(listSum(r.toMatrix()), (1, 0, 0, 0, 0, math.cos(a), -math.sin(a), 0, 0, math.sin(a), math.cos(a), 0, 0, 0, 0, 1))
def testMembers(self): '''Test members assigned to a vec3 are returned correctly.''' x, y, z = randnums(3, -5, 5) v = vec3(x, y, z) self.assertEqual(v.x(), x) self.assertEqual(v.y(), y) self.assertEqual(v.z(), z) self.assertAlmostEqual(v.len(), math.sqrt(x * x + y * y + z * z))
def testMatrix1(self): for i in range(100): a = randangle() m = [ math.cos(a), 0, math.sin(a), 0, 1, 0, -math.sin(a), 0, math.cos(a) ] r = rotator(*m) self.assertEqual(r, rotator(vec3(0, 1, 0), a))
def testInf(self): '''Test +inf and -inf as vector component values.''' v = vec3(float('+inf'), float('-inf')) self.assertEqual(v.x(), float('+inf')) self.assertEqual(v.y(), float('-inf')) self.assertEqual(-v.x(), float('-inf')) self.assertEqual(-v.y(), float('+inf')) self.assertEqual(v.x(), 1e400) self.assertEqual(v.y(), -1e400) self.assertEqual(v.len(), float('+inf'))
def loadImageStackObject(self,name,filenames,pos=vec3(),rot=rotator(),spacing=(1.0,1.0),imgsep=1.0,sortIndex=None,regex=None,reverse=False,task=None): ''' Loads a stack of images (or a sequence of stacks), ordered bottom up, into a ImageSceneObject. If `sortIndex' is not None, this is the sorting index in the file names used to sort the stack. The start position `pos' is intepreted as the top left position of the bottom-most image. If `filenames' is a list of filenames only, the series is not timed, however if it's a list of lists of filenames then each sublist is (optionally) sorted and then loaded into a time series object. ''' isTimed=eidolon.isIterable(filenames[0]) and not isinstance(filenames[0],str) if isTimed: if sortIndex!=None: filenames=[sortFilenameList(fn,sortIndex,regex) for fn in filenames] if reverse: for f in filenames: f.reverse() positions=[pos+(rot*vec3(0,0,imgsep*i)) for i in range(len(filenames[0]))] imagesteps=[loadImageStack(fn,self.mgr.scene.loadImageFile,positions,rot,spacing,task) for fn in filenames] for i,imgs in enumerate(imagesteps): for img in imgs: img.timestep=i images=listSum(imagesteps) filenames=listSum(filenames) else: if sortIndex!=None: filenames=sortFilenameList(filenames,sortIndex,regex) if reverse: filenames.reverse() positions=[pos+(rot*vec3(0,0,imgsep*i)) for i in range(len(filenames))] images=loadImageStack(filenames,self.mgr.scene.loadImageFile,positions,rot,spacing,task) return self.createSceneObject(name,images,filenames,isTimed)
def getTransformFromInfo(offcenter, angulation, sliceorient, spacing, dimensions): ''' Returns a (vec3,rotator) pair for the position and orientation of an image given the ParRec parameters for offcenter position, angulation in degrees, slice orientation value from SliceOrientations, pixel spacing, and image dimensions. ''' cy, cz, cx = offcenter theta, phi, rho = map(math.radians, angulation) refmat = np.array([[-1, 0, 0], [0, 0, 1], [0, -1, 0]]) AFRtoLPS = np.array([[0, 0, 1], [1, 0, 0], [0, 1, 0]]) torient = np.eye(3) # get the slice orientation transform matrix if sliceorient == SliceOrientations.Transverse: torient = np.array([[0, 1, 0], [-1, 0, 0], [0, 0, -1]]) elif sliceorient == SliceOrientations.Sagittal: torient = np.array([[-1, 0, 0], [0, 0, -1], [0, 1, 0]]) elif sliceorient == SliceOrientations.Coronal: torient = np.array([[0, 0, -1], [1, 0, 0], [0, 1, 0]]) # convert angulation values to rotation matrices tap = np.array([[1, 0, 0], [0, math.cos(theta), -math.sin(theta)], [0, math.sin(theta), math.cos(theta)]]) tfh = np.array([[math.cos(phi), 0, math.sin(phi)], [0, 1, 0], [-math.sin(phi), 0, math.cos(phi)]]) trl = np.array([[math.cos(rho), -math.sin(rho), 0], [math.sin(rho), math.cos(rho), 0], [0, 0, 1]]) # compose transformations and convert to a rotator object dirmat = AFRtoLPS.dot(trl).dot(tap).dot(tfh).dot(refmat).dot(torient) rot = rotator(*dirmat.flat) # Since rotation is defined at the center of the image, need to add a rotated mid vector to the # position which is instead defined at the top left corner. midoffset = ((spacing * vec3(1, -1, 1)) * (dimensions - vec3(1))) * 0.5 - spacing * vec3(0.5, -0.5, 0) pos = vec3(cx, cy, cz) - (rot * midoffset) return pos, rot
def testXis3(self): '''Test the xi values of points on the plane of a SharedImage, calls SharedImage.getPlaneXi().''' pos = vec3(5, -6, 7) si = SharedImage('', pos, rotator(), (10, 10)) self.assertEqual(vec3(), si.getPlaneXi(pos)) self.assertEqual(vec3(1, 1), si.getPlaneXi(pos + vec3(10, -10))) self.assertEqual(vec3(0.5, 0.5, 5), si.getPlaneXi(pos + vec3(5, -5, 5)))
def setUp(self): self.tempdir = tempfile.mkdtemp() self.plugin = eidolon.getSceneMgr().getPlugin('Nifti') self.vfunc = lambda x, y, z, t: (x + 1) * 1000 + (y + 1) * 100 + ( z + 1) * 10 + t + 1 self.volarr = np.fromfunction(self.vfunc, (21, 33, 46, 17)) self.vpos = vec3(-10, 20, -15) self.vrot = rotator(0.1, -0.2, 0.13) self.vol = self.plugin.createObjectFromArray('TestVolume', self.volarr, pos=self.vpos, rot=self.vrot)
def testXis4(self): '''Test the xi values of points on the plane of a SharedImage, calls SharedImage.getPlaneXi().''' pos = vec3(5, -6, 7) dim = (0.678, 0.789) si = SharedImage('', pos, rotator(), (10, 10), dim) self.assertEqual(vec3(), si.getPlaneXi(pos)) self.assertEqual(vec3(1, 1), si.getPlaneXi(pos + vec3(10 * dim[0], -10 * dim[1]))) self.assertEqual(vec3(0.5, 0.5, 5), si.getPlaneXi(pos + vec3(5 * dim[0], -5 * dim[1], 5)))
def convertImage(obj, plugin, arrayformat=ASCII, dataFormat='f4', filenamePrefix=None): ''' Convert the ImageSceneObject `obj' into a x4df structure. The arrays are all formatted the same using `arrayformat' and are stored in files whose names begin with `filenamePrefix' if this is given, otherwise they are stored in the XML document. If the format is binary and `filenamePrefix' is not given, the name of `obj' is used instead. The `plugin' value should be an ImageScenePlugin instance used to generate an object array from obj, typically this is `obj.plugin' but doesn't have to be. The return value is a single x4df object containing a single mesh. ''' if len(obj.getOrientMap()) > 1: raise NotImplementedError( 'Cannot yet convert image objects which are not single 2D planes or 3D volumes' ) start, step = obj.getTimestepScheme() tscheme = (start, step) if start != 0 or step != 0 else None if arrayformat in (BINARY, BINARY_GZ): filenamePrefix = filenamePrefix or obj.getName() filename = '%s.dat' % filenamePrefix if filenamePrefix else None imgarrmap = plugin.getImageObjectArray(obj) imgarr = reverseAxes(imgarrmap['array']) pos = imgarrmap['pos'] shape = imgarr.shape spacing = imgarrmap['spacing'] * vec3(shape[1], shape[0], shape[2]) rot = imgarrmap['rot'] trans = x4df.transform(np.asarray(list(pos)), np.asarray(rot.toMatrix())[:3, :3].flatten(), np.asarray(list(spacing))) x4 = x4df.dataset([], [], [], []) im = x4df.image(obj.getName(), tscheme, trans, [], []) x4.images.append(im) imd = x4df.imagedata('image', None, None, []) im.imagedata.append(imd) x4.arrays.append( x4df.array('image', ' '.join(map(str, imgarr.shape)), None, dataFormat, arrayformat, None, filename, imgarr)) return x4
def _split(s=None, l=None, t=None): if t == None or len(t) == 0: return None global matrixCounter matrixCounter += 1 if mtype: # if there's a matrix type, convert each element of t accordingly tokens = t[0].strip().split() if mtype == vec3: mat = [ vec3(float(a), float(b), float(c)) for a, b, c in eidolon.group(tokens, 3) ] else: mat = list(map(mtype, tokens)) else: # otherwise assume the elements in t are converted already and just make a list of these mat = list(t) return eidolon.listToMatrix(mat, 'mat' + str(matrixCounter))
# Eidolon is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program (LICENSE.txt). If not, see <http://www.gnu.org/licenses/> import sys sys.path.append(scriptdir+'..') from eidolon import MeshSceneObject,ElemType,vec3,color,ReprType,frange,PyDataSet mat=mgr.getMaterial('Rainbow') mat.setSpectrumValue(1,0.005,color(0.0,1.0,1.0,1.0)) trinodes=[vec3(0,0,0),vec3(1,0,0),vec3(0.5,0,1),vec3(1.1,0,0),vec3(2.1,0,0),vec3(1.6,0,1)] triinds=[(0,1,2),(3,4,5)] trifield=[1,2,3,4,5,6] trielemfield=[-1,2] quadnodes=[vec3(2.2,0,0),vec3(3.2,0,0),vec3(2.2,0,1),vec3(3.2,0,1),vec3(3.3,0,0),vec3(4.3,0,0),vec3(3.3,0,1),vec3(4.3,0,1)] quadinds=[(6,7,8,9),(10,11,12,13)] quadfield=[1,2,3,4,5,6,7,8] quadelemfield=[-1,2] quadfieldtopo=[(0,1,2,3),(4,5,6,7)] # need a separate topology for quad field since the quad topo doesn't start indexing from 0 nodes=trinodes+quadnodes nodefield=list(frange(len(nodes))) inds=[
# it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # Eidolon is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program (LICENSE.txt). If not, see <http://www.gnu.org/licenses/> from eidolon import vec3, ElemType, PyDataSet, ReprType, MeshSceneObject # construct a dataset with a single triangle by defining 3 vertices, an index matrix with 1 element, and a field assigning a value to each vertex nodes = [vec3(0, 0, 0), vec3(1, 0, 0), vec3(0.5, 0, 0.866)] # 3 vertices of triangle inds = [(0, 1, 2)] # single element in index matrix field = [0.0, 1.0, 2.0] ds = PyDataSet('TriDS', nodes, [('triind', ElemType._Tri1NL, inds)], [('vals', field, 'triind')]) # create the scene object which contains the dataset obj = MeshSceneObject('Tri', ds) mgr.addSceneObject(obj) # create a visual representation of the triangle, "volume" in this value referring to a 3D representation rep = obj.createRepr(ReprType._volume, 0) mgr.addSceneObjectRepr(rep) rep.applyMaterial('Rainbow', field='vals')
for i, elem in enumerate(elems): elemvals = [nodefield[e] for e in elem] if nodefield.m() == 1: result[i] = avg(elemvals) else: result[i] = tuple(map(avg, zip(*elemvals))) return result w, h, d = 4, 4, 16 nodes, inds = eidolon.generateHexBox(w - 2, h - 2, d - 2) # twist cube around origin in XZ plane nodes = [ vec3(0, (1 - n.z()) * halfpi, n.x() + 1).fromPolar() + vec3(0, n.y(), 0) for n in nodes ] bottomnodes = list(range(0, w * h)) # indices of nodes at the bottom of the cube topnodes = list(range(len(nodes) - w * h, len(nodes))) # indices of nodes at the top of the cube tinds = [] # convert hex to tets, warning: index() relies on float precision hx = ElemType.Hex1NL.xis tx = eidolon.divideHextoTet(1) for hexind in inds: for tet in tx: tinds.append([hexind[hx.index(t)] for t in tet])
# The following code will recreate the data loaded in tutorial5.py thus is an example of algorithmic mesh generation nodes, inds = generateHexBox( 1, 1, 1) # Generate a box in the unit cube comprised of 8 hexahedra nodes = listToMatrix( nodes, 'Nodes' ) # use this helper function to convert Python lists to *Matrix types (Vec3Matrix in this case) inds = listToMatrix( inds, 'LinHex', ElemType._Hex1NL) # convert here as well specifying a matrix type Hex1NL # construct a list of PyDataset objects which contain the node, topology, and field information for each timestep dds = [] for i in xrange(10): n1 = nodes.clone() # clone the nodes n1.mul(vec3(1 + i * 0.1, 1, 1)) # scale the nodes in the X direction field = [n1.getAt(j).lenSq() for j in xrange(n1.n()) ] # generate a field defined as the squared length of each node fieldmat = listToMatrix( field, 'LenSq' ) # convert field, the matrix for each timestep has the same name "LenSq" dds.append(PyDataSet( 'ds%i' % i, n1, [inds], [fieldmat ])) # create the dataset, each shares the matrix `inds' which is safe obj = MeshSceneObject( 'LinBox', dds ) # create the MeshSceneObject, note that this object's "plugin" attribute is None here mgr.addSceneObject( obj
# with this program (LICENSE.txt). If not, see <http://www.gnu.org/licenses/> import sys sys.path.append(scriptdir+'..') from eidolon import ReprType,ImageSceneObject,vec3 from TestUtils import generateTimeSphereImages step=0.1 images=generateTimeSphereImages(step) obj=ImageSceneObject('Sphere',[],images) mgr.addSceneObject(obj) rep=obj.createRepr(ReprType._imgtimestack) mgr.addSceneObjectRepr(rep) rep.setPosition(vec3(5,-10,-4)) rep.setRotation(0.1,0.2,-0.12) rep1=obj.createRepr(ReprType._imgtimevolume) mgr.addSceneObjectRepr(rep1) rep1.setPosition(vec3(61,6,8)) rep1.setRotation(-0.1,-0.13,0.22) obj1 = SlicePlugin.createSlicePlane(vec3(49.5,-25.0,24.5),vec3(-0.128762689557,-0.782178248535,0.60960426286)) mgr.addSceneObject(obj1) rep2 = obj1.createRepr(ReprType._line) mgr.addSceneObjectRepr(rep2) mgr.showHandle(rep2,True) obj1.setApplyToRepr(rep)
ParserElement.setDefaultWhitespaceChars( ' \t') # \n and \r are significant in this grammar # regular expressions for integer and float, including sign and power components intregex = r"[+-]?(([1-9]\d*)|0)" floatregex = r"[+-]?((\d+(:?\.\d*)?)|(:?\.\d+))(:?[eE][+-]?\d+)?" # base types ident = Word( alphas + "_", alphanums + "_%$&*@#~" ) # no clear definition of an identifier, there may be other accepted characters nls = Suppress(OneOrMore(lineEnd)) fnum = Regex(floatregex).setParseAction(lambda s, l, t: float(t[0])) intnum = Regex(intregex).setParseAction(lambda s, l, t: int(t[0])) vec = (fnum * 3).setParseAction(lambda s, l, t: vec3(t[0], t[1], t[2])) # base matrices intnums = Regex(r"(%s[ \n\r\t]+)+" % intregex).setParseAction(toMatrix(int)) nums = Regex(r"(%s[ \n\r\t]+)+" % floatregex).setParseAction(toMatrix(float)) vecs = Regex(r"(%s[ \n\r\t]+)+" % floatregex).setParseAction(toMatrix(vec3)) metadata = Optional( Suppress( ZeroOrMore(nls) + Keyword('METADATA') + lineEnd + OneOrMore(CharsNotIn('\r\n') + lineEnd) + lineEnd)) # dataset spatialvalue = (Keyword('DIMENSIONS') | Keyword('ORIGIN') | Keyword('SPACING') | Keyword('ASPECT_RATIO')) + vec + nls spatialvalues = ZeroOrMore(spatialvalue).setParseAction(lambda s, l, t: dict(
# # This file is part of Eidolon. # # Eidolon is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # Eidolon is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program (LICENSE.txt). If not, see <http://www.gnu.org/licenses/> from eidolon import vec3, PyDataSet, MeshSceneObject, ReprType nodes=[vec3(0,0,0),vec3(2,0,0),vec3(5,0,0),vec3(10,0,0)] field=[0.0,1.0,2.0,3.0] ds=PyDataSet('PtDS',nodes,[],[('vals',field)]) obj=MeshSceneObject('Pts',ds) mgr.addSceneObject(obj) rep=obj.createRepr(ReprType._glyph,glyphname='sphere', sfield= 'vals',glyphscale=(1,1,1)) mgr.addSceneObjectRepr(rep) rep.applyMaterial('Rainbow',field='vals') mgr.setCameraSeeAll()
# # You should have received a copy of the GNU General Public License along # with this program (LICENSE.txt). If not, see <http://www.gnu.org/licenses/> import sys, math sys.path.append(scriptdir + '..') from eidolon import MeshSceneObject, ElemType, ReprType, vec3, frange from TestUtils import generateTestMeshDS dds = [] for i in frange(0, 1, 0.05): i = math.sin(i * math.pi * 2) ds = generateTestMeshDS(ElemType._Tri1NL, 5) nodes = ds.getNodes() nodes.mul(vec3(2.0 + i, 1.0, 2.0 - i)) dist = ds.getDataField('dist') for n in range(dist.n()): dist.setAt(nodes.getAt(n).distTo(vec3(0.25)), n) dds.append(ds) obj = MeshSceneObject('Sphere', dds) mgr.addSceneObject(obj) obj.setTimestepList(list(frange(0, 1, 0.05))) rep = obj.createRepr(ReprType._volume, 0) mgr.addSceneObjectRepr(rep) mgr.setCameraSeeAll()
# Eidolon is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # Eidolon is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program (LICENSE.txt). If not, see <http://www.gnu.org/licenses/> from eidolon import ReprType,vec3, rotator,generateArrow,halfpi, MeshSceneObject,TriDataSet,AxesType pos=vec3(-10,20,-15) rot=rotator(0.1,-0.2,0.13) w,h,d=31,42,53 nodesz,indsz=generateArrow(5) nodesz=[(n+vec3.Z())*vec3(w,d,h)*vec3(0.1,0.1,0.5) for n in nodesz] nodesx=[rotator(vec3(0,1,0),halfpi)*n for n in nodesz] nodesy=[rotator(vec3(1,0,0),-halfpi)*n for n in nodesz] nodes=[(rot*n)+pos for n in (nodesx+nodesy+nodesz)] nlen=len(nodesz) indices=indsz+[(i+nlen,j+nlen,k+nlen) for i,j,k in indsz]+[(i+nlen*2,j+nlen*2,k+nlen*2) for i,j,k in indsz] field=[2.0]*nlen+[1.0]*nlen+[0.0]*nlen axes=MeshSceneObject('Axes',TriDataSet('tris',nodes,indices,[('col',field)])) mgr.addSceneObject(axes)
# Eidolon Biomedical Framework # Copyright (C) 2016-7 Eric Kerfoot, King's College London, all rights reserved # # This file is part of Eidolon. # # Eidolon is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # Eidolon is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program (LICENSE.txt). If not, see <http://www.gnu.org/licenses/> from eidolon import ReprType, generateSphereImageStack, ImageSceneObject, vec3 images = generateSphereImageStack(50, 50, 50, vec3(0.5, 0.5, 1), vec3(0.45, 0.45, 0.9)) obj = ImageSceneObject('Sphere', [], images) mgr.addSceneObject(obj) rep = obj.createRepr(ReprType._imgvolume) mgr.addSceneObjectRepr(rep) mgr.setCameraSeeAll()
from eidolon import MeshSceneObject, ElemType, vec3, listToMatrix, ReprType from TestUtils import generateTestMeshDS ds = generateTestMeshDS(ElemType._Tri1NL, 4) nodes = ds.getNodes() dirs = listToMatrix([tuple(nodes.getAt(i)) for i in range(nodes.n())], 'dirs') ds.setDataField(dirs) obj = MeshSceneObject('Sphere', ds) mgr.addSceneObject(obj) rep = obj.createRepr(ReprType._point) mgr.addSceneObjectRepr(rep) rep.applyMaterial('Rainbow', field='dist') rep.setScale(vec3(1.5)) rep1 = obj.createRepr(ReprType._glyph, glyphname='sphere', sfield='dist', glyphscale=(0.015, 0.015, 0.015)) mgr.addSceneObjectRepr(rep1) rep1.applyMaterial('Rainbow', field='dist') rep2 = obj.createRepr(ReprType._glyph, dfield='dirs', glyphname='arrow', glyphscale=(0.025, 0.025, 0.035)) mgr.addSceneObjectRepr(rep2) rep2.setScale(vec3(0.75)) rep2.applyMaterial('Rainbow', field='dirs', valfunc='Average')