# File io/MeshIO.rb, line 166
  def MeshIO.readMesh(baseName)
    eleLines = IO.readlines("#{baseName}.ele")
    nodeLines = IO.readlines("#{baseName}.node")
    bdryLines = IO.readlines("#{baseName}.bdry")
    edgeLines = IO.readlines("#{baseName}.edge")

    ## split bdryLines into bfLines, bvLines, bsbLines
    bfLines = []
    bvLines = []
    bsbLines = []
    nbsb = -1
    nbv = -1
    bdryLines.each do |bline|
      if (bline =~ /--- ([0-9]*)/)
        nbv = ($1).to_i
      elsif (bline =~ /=== ([0-9]*)/)
        nbsb = ($1).to_i
      end
    end

    bvLines = bdryLines.slice(0...nbv)
    bsbLines = bdryLines.slice((nbv+1)..(3*nbsb+nbv))
    bfLines = bdryLines.slice((3*nbsb+nbv+2)..-1)


    pts = []    ## array from nindex to GeometricPoints
    dpts = []   ## array from nindex to LinearData
    vts = []    ## array from nindex to BezierVertex
    bvts = []   ## array from bvindex to BezierVertex
    bsbs = []   ## array from bsbindex to BoundaryBSplines
    bfaces = [] ## array from bfindex to Cell
    edges = []  ## array from eindex to BezierEdge

    mesh = QuadraticBezierMesh.new
    bmesh = BoundaryComplex.new

    nodeLines.each_index do |nindex|
      ptLine = nodeLines[nindex].split(" ")
      pts[nindex] = GeometricPoint.new(ptLine.slice(1..2).collect {|s| s.to_f})
      dArray = ptLine.slice(3..-1).collect {|s| s.to_f}

      ## zero out any data channels we don't want read in
      dpts[nindex] = LinearData.new(dArray)
    end

    bvLines.each_index do |bvindex|
      bvline = bvLines[bvindex].split(" ")
      nindex= bvline[1].to_i
      bvts[bvindex] = bmesh.addVertex(pts[nindex])

      v0 = getVertex(nindex,vts,pts,dpts,mesh)
      v0.bdry = VertexBoundary.new(bvts[bvindex])
    end

    for b in (0...(bsbLines.length/3))
      bsbline = (bsbLines[3*b]).split(" ")
      dline = (bsbLines[3*b + 1]).split(" ")
      kline = (bsbLines[3*b + 2]).split(" ")

      bsbindex = bsbline[0].to_i
      bv0 = bvts[bsbline[1].to_i]
      bv1 = bvts[bsbline[2].to_i]
      closed = (bsbline[3].to_i == 1)
      fixed = bsbline[4].to_i
      color = bsbline[5].to_i
      
      ## rest might not be there, backwards compatibility
      if bsbline.length > 6
        rest = bsbline[6].to_f
      else
        rest = 1.0
      end

      d = []
      for di in 0...(dline.length/2)
        d[di] = GeometricPoint.new([dline[2*di].to_f,dline[2*di+1].to_f])
      end

      k = kline.collect! {|kv| kv.to_f}
      
      d = d.slice(1..-2) if closed

      spline = QBSpline.new(d,closed,k)

      bsb = bmesh.addEdge(bv0,bv1,spline)
      bsb.fixed = fixed
      bsb.color = color
      bsb.rest = rest

      bsbs[bsbindex] = bsb
    end
    bfLines.each_index do |bfindex|
      bfline = bfLines[bfindex].split(" ")
      angle = bfline[1].to_f
      color = bfline[2].to_i

      eds = (bfline.slice(3..(-1))).collect {|bsbindex| bsbs[bsbindex.to_i]}

      bf = bmesh.addFace(eds,nil,angle)
      bf.data.color = color
      bfaces[bfindex] = bf
    end
    
    edgeLines.each_index do |eindex|
      edgeLine = edgeLines[eindex].split(" ")

      v0i = edgeLine[1].to_i
      mi = edgeLine[2].to_i
      v1i = edgeLine[3].to_i

      v0 = MeshIO.getVertex(v0i,vts,pts,dpts,mesh)

      cp = pts[mi]
      dp = dpts[mi]
      v1 = MeshIO.getVertex(v1i,vts,pts,dpts,mesh)
      
      e = mesh.addEdge(v0,v1,[cp],dp)

      if (edgeLine[4].to_i != -1)
        bsb = bsbs[edgeLine[4].to_i]
        u0 = edgeLine[5].to_f
        u1 = edgeLine[6].to_f
        e.bdry = EdgeBoundary.new(bsb,u0,u1)
        v0.bdry = VertexBoundary.new(bsb,u0) if (v0.bdry == nil)
        v1.bdry = VertexBoundary.new(bsb,u1) if (v1.bdry == nil)
      end
      edges[eindex] = e
    end

    eleLines.each do |eleLine|
      elLine = eleLine.split(" ")
      eds = (elLine.slice(1..3)).collect! {|eindex| edges[eindex.to_i] }

      inverted = (elLine[4].to_i == 1)
      bfnum = elLine[5].to_i

      tri = mesh.addTriangle(eds[0],eds[1],eds[2],[],2,nil,inverted)
      tri.bdry = bfaces[bfnum]
    end
    
    mesh.rebuildAll
    return [mesh,bmesh]
  end