export mesh files

Questions about BrainVisa usage and installation

Moderators: denghien, riviere

Post Reply
neurolab
Posts: 15
Joined: Wed Feb 16, 2005 2:30 pm

export mesh files

Post by neurolab »

hi,

we're interested in viewing mesh files with applications other than Brain VISA, for example:

-3D studio,
-Blender,
-Analyze
-Amira...

Is there any process in BrainVisa to export that kind of files to standard formats (.3ds, .dxf, .obj)?

Is it possible to obtain any technical information about the mesh file format?

Thanks in advance.
User avatar
Yann Cointepas
Posts: 316
Joined: Tue Jan 20, 2004 2:56 pm
Location: Neurospin, Saint Aubin, France
Contact:

Post by Yann Cointepas »

There is not yet many supported format for mesh. I made a *.pov writer long ago that can be used with AimsFileConvert:

Code: Select all

AimsFileConvert: -i file.mesh -o file.pov
We would like to have a read/write converter in a format supported by blender but we do not have much time to develop it. Someone here say he was interessed by writing a VRML converter. Wait and see...

You can find technical documentation about our formats on the "help pages" link of our site: http://brainvisa.info/doc/html/en/index.html
Karpati
Posts: 5
Joined: Tue Jan 18, 2005 7:09 pm
Location: Hungary
Contact:

Post by Karpati »

See the 3D Object Converter:

http://web.axelero.hu/karpo/
User avatar
Yann Cointepas
Posts: 316
Joined: Tue Jan 20, 2004 2:56 pm
Location: Neurospin, Saint Aubin, France
Contact:

Post by Yann Cointepas »

Thanks for the information Karpati.

In the meantime, I wrote two Python scripts to import/export BrainVISA meshes in Blender.

mesh_export.py:

Code: Select all

#!BPY

"""
Name: 'BrainVISA mesh (.mesh)...'
Blender: 232
Group: 'Export'
Tooltip: 'Export selected mesh to BrainVISA mesh Format (.mesh)'
"""

__author__ = "Yann Cointepas"
__url__ = ("BrainVISA project, http://brainvisa.info",)
__version__ = "1.0"

__bpydoc__ = """\
This script exports meshes to BrainVISA mesh file format.

Usage:<br>
	Select meshes to be exported and run this script from "File->Export" menu.
"""


import Blender
import sys
from struct import pack

def packString( s ):
  return pack( '>L', len( s ) ) + s
  

def write(filename):
  file = open( filename, 'wb' )

  objects = Blender.Object.GetSelected()
  objname = objects[0].name
  meshname = objects[0].data.name
  mesh = Blender.NMesh.GetRaw(meshname)
  obj = Blender.Object.Get(objname)

  # Get polygon dimension
  polygonDimension = len( mesh.faces[0].v )
  
  file.write( 'binarABCD' ) # big-endian binary format
  file.write( packString( 'VOID' ) )
  file.write( pack( '>L', polygonDimension ) )
  file.write( pack( '>L', 1 ) ) # One time step
  
  # The single time step
  file.write( pack( '>L', 0 ) ) # instant
  # write vertices
  file.write( pack( '>L', len( mesh.verts ) ) )
  for v in mesh.verts:
    file.write( ''.join( [pack('>f',i) for i in v.co] ))
  # write normals
  file.write( pack( '>L', len( mesh.verts ) ) )
  for v in mesh.verts:
    file.write( ''.join( [pack('>f',i) for i in v.no] ))
  # No texture allowed
  file.write( pack( '>L', 0 ) )
  # Write polygons
  file.write( pack( '>L', len( mesh.faces ) ) )
  for f in mesh.faces:
    if len( f.v ) != polygonDimension:
      raise RuntimeError( 'BrainVISA mesh format does not support meshes with several polygon dimensions (e.g. triangles and squares)' )
    file.write( ''.join( [pack('>L',v.index) for v in f.v] ) )
  file.close()

  Blender.Window.DrawProgressBar(1.0, '')  # clear progressbar

def fs_callback(filename):
	# if not filename.endswith('.mesh'): filename += '.mesh'
	write(filename)

Blender.Window.FileSelector(fs_callback, "Export BrainVISA mesh")
mesh_import.py:

Code: Select all

#!BPY

"""
Name: 'BrainVISA mesh (.mesh)...'
Blender: 232
Group: 'Import'
Tooltip: 'Import BrainVISA mesh File Format (.mesh)'
"""

__author__ = "Yann Cointepas"
__url__ = ("BrainVISA project, http://brainvisa.info",)
__version__ = "1.0"

__bpydoc__ = """\
This script imports BrainVISA mesh File format files to Blender.

Usage:<br>
	Execute this script from the "File->Import" menu and choose a mesh file to
open.

Notes:<br>
	If the mesh file contains several time steps, only the first one is imported.
"""


import struct
import Blender
from Blender import NMesh

def readAndUnpack( format, file ):
  return struct.unpack( format, file.read( struct.calcsize( format ) ) )

class BinaryItemReader:
  def __init__( self, bigEndian=True ):
    if bigEndian:
      self._endianess = '>'
    else:
      self._endianess = '<'
    
  def read( self, format, file ):
    result = ()
    format = format.split( 's' )
    if format:
      if format[0]:
        result = readAndUnpack( self._endianess + format[0], file )
      else:
        result = ()
      for f in format[ 1: ]:
        size = readAndUnpack( self._endianess + 'L', file )[0]
        result = result + ( file.read( size ), )
        result = result + readAndUnpack( self._endianess + f, file )
    return result
        
class MeshReader:
  def __init__( self, fileName ):
    self._file = None
    self._file = open( fileName, 'rb' )
    if self._file.read( 5 ) == 'binar':
      self._itemReader = BinaryItemReader( self._file.read( 4 ) == 'ABCD' )
    else:
      raise RuntimeError( 'Ascii mesh format not implemented' )
    void, self._polygonDimension, timeStepCount = self._itemReader.read( 'sLL', self._file )
    if timeStepCount == 0:
      raise RuntimeError( 'No mesh in this file' )
    instant = self._itemReader.read( 'L', self._file )[0]

    self.verticesCount = self._itemReader.read( 'L', self._file )[0]
    self._verticesRead = False
    self.normalsCount = None
    self._normalsRead = False
    self.facesCount = None
    self._facesRead = False
  
  def vertices( self ):
    if self._verticesRead:
      raise RuntimeError( 'Vertices can be read only once' )
    for i in xrange( self.verticesCount ):
      yield self._itemReader.read( 'fff', self._file )
    self._verticesRead = True
    self.normalsCount = self._itemReader.read( 'L', self._file )[0]
    
  def normals( self ):
    if not self._verticesRead:
      if self.verticesCount == 0:
        self._verticesRead = True
      else:
        raise RuntimeError( 'Vertices must be read before normals' )
    if self._normalsRead:
      raise RuntimeError( 'Normals can be read only once' )
    for i in xrange( self.normalsCount ):
      yield self._itemReader.read( 'fff', self._file )
    self._normalsRead = True
    textureCount = self._itemReader.read( 'L', self._file )[0]
    if textureCount != 0:
      raise RuntimeError( 'Texture in mesh file not supported' )
    self.facesCount = self._itemReader.read( 'L', self._file )[0]

  def faces( self ):
    if not self._verticesRead:
      if self.verticesCount == 0:
        self._verticesRead = True
      else:
        raise RuntimeError( 'Vertices must be read before faces' )
    if not self._normalsRead:
      if self.normalsCount == 0:
        self._normalsRead = True
        textureCount = self._itemReader.read( 'L', self._file )[0]
        if textureCount != 0:
          raise RuntimeError( 'Texture in mesh file not supported' )
        self.facesCount = self._itemReader.read( 'L', self._file )[0]
      else:
        raise RuntimeError( 'Normals must be read before faces' )
    if self._facesRead:
      raise RuntimeError( 'Faces can be read only once' )
    format = 'L' * self._polygonDimension
    for i in xrange( self.facesCount ):
      yield self._itemReader.read( format, self._file )
    self._facesRead = True
    self._file.close()
    self._file = None

  def __del__( self ):
    if self._file is not None:
      self._file.close()
  
  
def read(filename):
  reader = MeshReader( filename )
  mesh = NMesh.New()
  print reader.verticesCount, 'vertices'
  for x, y, z in reader.vertices():
    mesh.verts.append( NMesh.Vert( x, y, z ) )
  count = 0
  print reader.normalsCount, 'normals'
  for x, y, z in reader.normals():
    mesh.verts[ count ].no[ 0 ] = x
    mesh.verts[ count ].no[ 1 ] = y
    mesh.verts[ count ].no[ 2 ] = z
    count += 1
  print reader.facesCount, 'faces'
  for f in reader.faces():
    face = NMesh.Face( [mesh.verts[i] for i in f] )
    face.smooth = True
    mesh.faces.append( face )
  
  object = Blender.Object.New( 'Mesh' )  
  object.name = Blender.sys.splitext(Blender.sys.basename(filename))[0]
  Blender.Scene.getCurrent().link( object )
  object.link( mesh )
  mesh.update( reader.normalsCount == 0 )
  
  Blender.Window.DrawProgressBar(1.0, '')  # clear progressbar

def fs_callback(filename):
  read(filename)

Blender.Window.FileSelector(fs_callback, "Import Mesh")
Post Reply