예제 #1
0
    def displayCylinder(self, name):
        # If it is already there, remove it
        self.undisplayCylinder(name)
        self.displayed[name] = None
        t = self.cylinders[name]['type']
        p = self.cylinders[name]['position']
        v = self.cylinders[name]['vector']
        r = self.cylinders[name]['diameter'] / 2.0
        pEnd = p[0] + v[0] * self.cylinders[name]['length'], p[
            1] + v[1] * self.cylinders[name]['length'], p[
                2] + v[2] * self.cylinders[name]['length']
        #print "New cylinder mesh at %.2f, %.2f, %.2f,  radius=%.2f" % (p[0], p[1], p[2], r)
        newCyl = self.a.toAObject(
            aims.SurfaceGenerator.cylinder(aims.Point3df(p[0], p[1], p[2]),
                                           aims.Point3df(pEnd), r, r, 24, True,
                                           True))

        # Couleur automatique par catégorie
        if t not in self.typeColors:
            self.currentColorHue = (self.currentColorHue + 40) % 256
            self.typeColors[t] = QtGui.QColor.fromHsv(self.currentColorHue,
                                                      245, 220, 255)
        color = self.typeColors[t]
        self.a.setMaterial(newCyl,
                           diffuse=[
                               color.redF(),
                               color.greenF(),
                               color.blueF(),
                               color.alphaF()
                           ])
        self.a.addObjects(newCyl, self.wins)
        self.displayed[name] = {'mesh': newCyl, 'type': t}
예제 #2
0
def peaks_as_spheres(path_peaks_volume, path_spheres, radius=2):
    """
    Represent peaks as spheres centered on peaks location and of radius radius
    :param path_peaks_volume: path of the boolean volume with peaks
    :param path_spheres: path of the mesh (spheres) representing the peaks
    :param radius: radius (in mm) of the spheres used for display
    :return:
    """
    volume = aims.read(path_peaks_volume)
    data = np.array(volume)[..., 0]

    voxel_size = volume.header()['voxel_size'] + [1]
    scaling = aims.AffineTransformation3d()
    scaling.fromMatrix(np.diag(voxel_size))
    peaks_vol_coord = np.transpose(np.vstack(np.where(data != 0)))
    centers = [aims.Point3df(p) for p in peaks_vol_coord]
    print(len(centers))

    for i, center in enumerate(centers):
        center = scaling.transform(center)
        sphere = aims.SurfaceGenerator.sphere(center, radius,300)
        if i == 0:
            spheres = sphere
        else:
            aims.SurfaceManip.meshMerge(spheres, sphere)
    aims.write(spheres, path_spheres)
예제 #3
0
def vertices_and_faces_to_mesh(vertices, faces, header=None):
    '''
    Create an aims 2D or 3D mesh using precomputed vertices and faces. Vertices and faces are assumed to be compatible
    :param vertices: ndarray (N,d)
    :param faces: ndarray (N1,d1)
    :param header: a dictionnary like structure
    :return: AimsTimeSurface
    '''
    # determine the mesh type based on polygon type (does not work for quads polygon !)
    poly_type = faces.shape[-1]
    mesh = aims.TimeSurface(dim=poly_type)
    v = mesh.vertex()
    p = mesh.polygon()

    v.assign([aims.Point3df(x) for x in vertices])
    p.assign([aims.AimsVector(x, dtype='U32', dim=poly_type) for x in faces])
    # recompute normals, not mandatory but to have coherent mesh
    #rem does not work for 2D meshes normals need to be added manually (works like a texture)
    mesh.updateNormals()
    if header is not None:
        #fill the mesh empty header of the mesh with values in header
        h = mesh.header()
        for k in header.keys():
            h[k] = header[k]
    return mesh
예제 #4
0
def mesh_from_arrays(coord, triangles, path=None):
    """ Create a mesh object from two arrays

    fixme:  intent should be set !
    """
    carray = gifti.GiftiDataArray().from_array(coord.astype(np.float32),
                                               "NIFTI_INTENT_POINTSET",
                                               encoding='B64BIN')
    #endian="LittleEndian")
    tarray = gifti.GiftiDataArray().from_array(triangles.astype(np.int32),
                                               "NIFTI_INTENT_TRIANGLE",
                                               encoding='B64BIN')
    #endian="LittleEndian")
    img = gifti.GiftiImage(darrays=[carray, tarray])
    if path is not None:
        try:
            from soma import aims
            mesh = aims.AimsTimeSurface(3)
            mesh.vertex().assign([aims.Point3df(x) for x in coord])
            mesh.polygon().assign(
                [aims.AimsVector_U32_3(x) for x in triangles])
            aims.write(mesh, path)
        except:
            print("soma writing failed")
            gifti.write(img, path)
    return img
예제 #5
0
    def activateVirtualLed(self, x, y, globx, globy):

        print 'coucou', x, y

        w = self.view().aWindow()
        obj = w.objectAtCursorPosition(x, y)
        if obj is not None:
            print 'object:', obj, obj.name()
            poly = w.polygonAtCursorPosition(x, y, obj)
            mesh = anatomistControl.cpp.AObjectConverter.aims(obj)

            if poly == 0xffffff or poly < 0 or poly >= len(mesh.polygon()):
                return
            #print 'polygon:', poly

            #print 'mesh:', mesh
            ppoly = mesh.polygon()[poly]
            vert = mesh.vertex()

            #print 'poly:', poly, ppoly
            pos = aims.Point3df()
            pos = w.positionFromCursor(x, y)
            #print 'pos:', pos
            v = ppoly[np.argmin([(vert[p] - pos).norm() for p in ppoly])]
            print 'vertex:', v, vert[v]
예제 #6
0
    def clickHandler(self, eventName, params):

        #   pdb.set_trace()
        coords = params['position'][:3]
        #coords = self.a.linkCursorLastClickedPosition().items()
        if self.mesh is not None:
            #self.updateMeshTexture(coords)

            win = params['window']
            pos2d = aims.Point3df()
            win.view().cursorFromPosition(coords, pos2d)
            x, y = pos2d[:2]
            obj = win.objectAtCursorPosition(x, y)
            MeshObj = [iterobj for iterobj in obj if iterobj == self.mesh]

            if len(MeshObj) > 0:  #obj == self.currentObj:

                if self.aimsMesh is None:
                    self.aimsMesh = self.a.toAimsObject(self.mesh)

                poly = win.polygonAtCursorPosition(x, y, self.currentObj)
                if poly != 0xffffff and poly >= 0 and poly < len(
                        self.aimsMesh.polygon()):
                    ppoly = self.aimsMesh.polygon()[poly]
                    vert = self.aimsMesh.vertex()
                    v = ppoly[np.argmin([(vert[p] - coords).norm()
                                         for p in ppoly])]
                    self.updateMeshTexture(v, self.aimsMesh)

        self.dispCoords(coords)
        self.coords[self.currentElec] = coords
        #j'en suis la
        intermediaire = self.texture2[0].arraydata()
        intermediaire[np.where(intermediaire >= 15)] = 0
        self.VertexLed.append()
def index_to_sphere(mesh, index, radius=R, nb_vertices=V):
    """
    Create a sphere of center the index th vertices of a mesh and of radius radius
    :param mesh:
    :param index:
    :param radius:
    :param nb_vertices:
    :return:
    """
    vertices = np.array(mesh.vertex())
    center = vertices[index]
    sphere = aims.SurfaceGenerator.sphere(aims.Point3df(center), radius, int(nb_vertices))
    return sphere
예제 #8
0
def vertices_and_faces_to_mesh(vertices, faces):
    '''
	Create an aims 3D mesh using precomputed vertices and faces. Vertices and faces are assumed to be compatible
	:param vertices: ndarray
	:param faces: ndarray
	:return: aims mesh
	'''
    #determine the mesh type based on polygon type (does not work for quads polygon !)
    poly_type = faces.shape[-1]
    mesh = aims.TimeSurface(dim=poly_type)
    v = mesh.vertex()
    p = mesh.polygon()

    v.assign([aims.Point3df(x) for x in vertices])

    p.assign([aims.AimsVector(x, dtype='U32', dim=poly_type) for x in faces])
    #recompute normals, not mandatory but to have coherent mesh
    mesh.updateNormals()
    return mesh
예제 #9
0
def vertices_and_faces_to_mesh(vertices, faces):
    """
    Create an aims 2D or 3D mesh using precomputed vertices and faces. Vertices and faces are assumed to be compatible
    Note this should note be used as default aims.TimeSurface() function does exactly the same things but I did not know it
    at the time
    :param vertices: ndarray
    :param faces: ndarray
    :return: AimsTimeSurface
    """
    # determine the mesh type based on polygon type (does not work for quads polygon !)
    poly_type = faces.shape[-1]
    mesh = aims.TimeSurface(dim=poly_type)
    v = mesh.vertex()
    p = mesh.polygon()
    v.assign([aims.Point3df(x) for x in vertices])
    p.assign([aims.AimsVector(x, dtype="U32", dim=poly_type) for x in faces])
    # recompute normals, not mandatory but to have coherent mesh
    # rem does not work for 2D meshes normals need to be added manually (works like a texture)
    mesh.updateNormals()
    return mesh
예제 #10
0
 def printElec(self):
     diameter = 1
     listPlots = []
     for eleckeys, elec in self.approxElec.items():
         name = eleckeys
         for plot in elec.keys():
             #tu parcours approxElec pour générer les maillage
             mesh = self.a.toAObject(
                 aims.SurfaceGenerator.sphere(
                     aims.Point3df(elec[plot][0], elec[plot][1],
                                   elec[plot][2]), diameter, 64))
             mesh.setName(name + str(plot + 1))
             listPlots.append(mesh)
             self.a.setMaterial(
                 mesh, diffuse=(0.0, 0.9, 0.1, 1.0)
             )  #[color.redF(), color.greenF(), color.blueF(), color.alphaF()]
             self.a.assignReferential(self.locaData.preReferential(), mesh)
             self.a.addObjects(mesh, self.locaData.wins[0])
             #self.locaData.DeetoEstimated = approxElec
         meshes = {name: listPlots}
         self.dicMeshes.update(meshes)
예제 #11
0
    def displayCylinder(self, name):
        # If it is already there, remove it
        self.undisplayCylinder(name)
        self.displayed[name] = None
        t = self.cylinders[name]['type']
        p = self.cylinders[name]['position']
        v = self.cylinders[name]['vector']
        r = self.cylinders[name]['diameter'] / 2.0
        newCyl = None

        if self.dispMode == 'off':
            self.displayed[name] = {'mesh': None, 'type': t}
            return
        if self.dispMode not in ['real', 'sphere', 'bipole']:
            print "Unknown dispMode %s for electrode !  Using 'real'..." % repr(
                self.dispMode)
            self.dispMode = 'real'

        if self.dispMode == 'real':
            pEnd = p[0] + v[0] * self.cylinders[name]['length'], p[
                1] + v[1] * self.cylinders[name]['length'], p[
                    2] + v[2] * self.cylinders[name]['length']
            newCyl = self.a.toAObject(
                aims.SurfaceGenerator.cylinder(aims.Point3df(p[0], p[1], p[2]),
                                               aims.Point3df(pEnd), r, r, 24,
                                               True, True))
            self.a.releaseObject(newCyl)
        elif self.dispMode == 'sphere':
            diam = 2.0
            if self.dispParams.has_key('diameter'):
                diam = float(self.dispParams['diameter'])
            if t == 'Plot':  # Ignore the other parts
                pCenter = (p[0] + v[0] * self.cylinders[name]['length'] / 2.0,
                           p[1] + v[1] * self.cylinders[name]['length'] / 2.0,
                           p[2] + v[2] * self.cylinders[name]['length'] / 2.0)
                newCyl = self.a.toAObject(
                    aims.SurfaceGenerator.sphere(
                        aims.Point3df(pCenter[0], pCenter[1], pCenter[2]),
                        diam, 32))
                self.a.releaseObject(newCyl)
                #newCyl = self.a.toAObject(aims.SurfaceGenerator.cube(aims.Point3df(pCenter[0], pCenter[1], pCenter[2]), 2.0))
        elif self.dispMode == 'bipole':
            #pCenter = (p[0] + v[0]*self.cylinders[name]['length']/2.0, p[1] + v[1]*self.cylinders[name]['length']/2.0, p[2] + v[2]*self.cylinders[name]['length']/2.0)
            #to change one day
            newCyl = self.a.toAObject(
                aims.SurfaceGenerator.ellipse(aims.Point3df(p[0], p[1], p[2]),
                                              2.5, 1.5, 50))
            self.a.releaseObject(newCyl)
            #aims.SurfaceGenerator.ellipse()

        # Automatic color for an unknown type
        if t not in self.typeColors:
            self.currentColorHue = (self.currentColorHue + 40) % 256
            self.typeColors[t] = QtGui.QColor.fromHsv(self.currentColorHue,
                                                      245, 220, 255)
        color = self.typeColors[t]
        if newCyl is not None:
            self.a.setMaterial(newCyl,
                               diffuse=[
                                   color.redF(),
                                   color.greenF(),
                                   color.blueF(),
                                   color.alphaF()
                               ])
        self.displayed[name] = {'mesh': newCyl, 'type': t}
예제 #12
0
import os
from soma import aims
import numpy
PRD = os.environ['PRD']
os.chdir(os.path.join(PRD, 'surface'))
mesh = aims.AimsTimeSurface(3)
# a mesh has a header
mesh.header()['cortex_high'] = 'cortex_high'
vert = mesh.vertex()
poly = mesh.polygon()
c = numpy.loadtxt('lh_vertices_high.txt')
vert.assign([aims.Point3df(x) for x in c])
pol = numpy.loadtxt('lh_triangles_high.txt')
poly.assign([aims.AimsVector(x, dtype='U32', dim=3) for x in pol])
# write result
aims.write(mesh, 'lh_mesh_high.mesh')
예제 #13
0
def execution( self, context ):
    if loadmat is None:
        return self.matlabExecution( context )

    # scipy / numpy / pyaims execution
    aim = self.source_volume
    amat = self.read
    bim = self.registered_volume
    if self.registered_volume is not None:
        bmatname = self.registered_volume.fullName() + '.mat'
        bmat = self.central_to_registered
        if bmat is None:
            context.write( 'No destination transformation - ' \
                           'taking its origin translation' )
            # bim = None
    else:
        bmat = None
        context.write( 'No destination volume - going only to central ref' )

    aattrs = aimsGlobals.aimsVolumeAttributes( aim )
    # context.write( 'aatrs: ', aattrs )
    if bim:
        battrs = aimsGlobals.aimsVolumeAttributes( bim )
        # context.write( 'battrs: ', battrs )

    dim1 = aattrs[ 'volume_dimension' ][:3]
    vox1 = aattrs[ 'voxel_size' ][:3]
    t1 = aims.Motion( aattrs[ 'transformations' ][0] )
    s2m = aims.Motion( aattrs[ 'storage_to_memory' ] )
    mvox1 = aims.Motion()
    mvox1.rotation().setValue( vox1[0], 0, 0 )
    mvox1.rotation().setValue( vox1[1], 1, 1 )
    mvox1.rotation().setValue( vox1[2], 2, 2 )
    tn = t1 * s2m * mvox1
    origin1 = tn.inverse().transform( aims.Point3df( 0, 0, 0 ) )
    origin1 += aims.Point3df( 1, 1, 1 ) # add 1 to matlab coords
    if bim:
        dim2 = battrs[ 'volume_dimension' ][:3]
        vox2 = battrs[ 'voxel_size' ][:3]
        t2 = aims.Motion( battrs[ 'transformations' ][0] )
        s2m2 = aims.Motion( battrs[ 'storage_to_memory' ] )
        mvox2 = aims.Motion()
        mvox2.rotation().setValue( vox2[0], 0, 0 )
        mvox2.rotation().setValue( vox2[1], 1, 1 )
        mvox2.rotation().setValue( vox2[2], 2, 2 )
        tn = t2 * s2m2 * mvox2
        origin2 = tn.inverse().transform( aims.Point3df( 0, 0, 0 ) )
        origin2 += aims.Point3df( 1, 1, 1 ) # add 1 to matlab coords
    else:
        dim2 = [ 0, 0, 0 ]
        vox2 = [ 1, 1, 1 ]
        origin2 = [ 0, 0, 0 ]

    # context.write( 'dim1:', str( dim1 ) )
    # context.write( 'vox1:', str( vox1 ) )
    # context.write( 'origin1:', str( origin1 ) )
    # context.write( 'dim2', str( dim2 ) )
    # context.write( 'vox2:', str( vox2 ) )
    # context.write( 'origin2:', str( origin2 ) )

    # create matlab script

    DIM1 = numpy.transpose( numpy.mat( dim1 ) )
    VOX1 = numpy.transpose( numpy.mat( vox1 ) )
    ORIGIN1 = numpy.transpose( numpy.mat( origin1 ) )
    DIM2 = numpy.transpose( numpy.mat( dim2 ) )
    VOX2 = numpy.transpose( numpy.mat( vox2 ) )
    ORIGIN2 = numpy.transpose( numpy.mat( origin2 ) )
    trans1 = self.write.fullPath()

    if os.path.exists( amat.fullPath() ):
        a = loadmat( amat.fullPath() )
        aM = numpy.mat( a[ 'M' ] ).astype( numpy.double )
        aM = aM * numpy.mat( numpy.diag( [ 1./vox1[0], 1./vox1[1], 1./vox1[2],
          1. ] ) )
    else:
        aM = numpy.mat( numpy.diag( [ 1., 1., 1., 1., ] ) )
        aM[ 0:3, 3 ] = - numpy.multiply( ORIGIN1, VOX1 )

    ainv = numpy.linalg.inv( aM )
    o1 = ainv[:, 3 ]
    # Y and Z axis are flipped
    o1[ 1:3 ] = -o1[ 1:3 ] + numpy.multiply( ( DIM1[1:3] - 1 ), VOX1[1:3] )

    if bmat:
        if os.path.exists( bmat.fullPath() ):
            b = loadmat( bmat.fullPath() );
            bM = numpy.mat( b[ 'M' ] ).astype( numpy.double )
            bM = bM * numpy.mat( numpy.diag( [ 1./vox2[0], 1./vox2[1], 1./vox2[2],
              1. ] ) )
        else:
            bM = numpy.mat( numpy.diag( [ 1., 1., 1., 1. ] ) )
            bM[ 0:3, 3 ] = - numpy.multiply( ORIGIN2, VOX2 )
    else:
        bM =  numpy.mat( numpy.diag( [ 1., 1., 1., 1. ] ) )
    bM[ 0:3, 3 ] = - numpy.multiply( ORIGIN2, VOX2 )
    binv = numpy.linalg.inv( bM )
    o2 = binv[:, 3 ]
    # Y and Z axis are flipped
    o2[ 1:3 ] = -o2[ 1:3, 0 ] + numpy.multiply( ( DIM2[1:3] - 1 ), VOX2[1:3] )

    # flip Y and Z axis to go to Aims/Anatomist world
    aflip = numpy.mat( numpy.diag( [ 1., -1., -1., 1. ] ) )
    aflip[ 1:3, 3 ] = numpy.multiply( ( DIM1[1:3] - 1 ), VOX1[1:3] )
    aM = aM * aflip
    # verify origin still transforms to 0
    # aM * o1
    bflip = numpy.mat( numpy.diag( [ 1., -1., -1., 1. ] ) )
    bflip[ 1:3, 3 ] = numpy.multiply( ( DIM2[1:3] - 1 ), VOX2[1:3] )
    bM = bM * bflip
    # verify origin still transforms to 0
    # bM * o2

    M = numpy.linalg.inv(bM) * aM

    # M * o1 - o2

    T = numpy.array( numpy.transpose( M[ 0:3, 3 ] ) )[ 0,: ]

    context.write( 'writing ', trans1 )
    fid = open( trans1, 'w' )

    Mt = numpy.array( numpy.transpose( M[0:3, 0:3] ) )
    print('%f %f %f' % tuple( T ), file=fid)
    print('%f %f %f' % tuple( Mt[ 0,: ] ), file=fid)
    print('%f %f %f' % tuple( Mt[ 1,: ] ), file=fid)
    print('%f %f %f' % tuple( Mt[ 2,: ] ), file=fid)
    fid.close()
예제 #14
0
 def applyMatrix(self, x, y, z, matrix):
   return matrix.transform( aims.Point3df(x,y,z) ).items()