/// <summary> /// Implementation currently ignores texture coordinates and normals. /// </summary> /// <typeparam name="TV"></typeparam> /// <typeparam name="TE"></typeparam> /// <typeparam name="TF"></typeparam> /// <param name="path"></param> /// <param name="mesh"></param> /// <param name="setPosition"></param> public static void ReadFromObj <TV, TE, TF>(string path, HeMesh <TV, TE, TF> mesh, Action <TV, Vec3d> setPosition) where TV : HeMesh <TV, TE, TF> .Vertex where TE : HeMesh <TV, TE, TF> .Halfedge where TF : HeMesh <TV, TE, TF> .Face { var verts = mesh.Vertices; var faces = mesh.Faces; var face = new List <int>(); using (var reader = new StreamReader(path)) { string line; while ((line = reader.ReadLine()) != null) { // skip empty lines and comments if (line.Length == 0 || line[0] == '#') { continue; } // check the first character var segments = line.Split(ObjUtil.Separators, StringSplitOptions.RemoveEmptyEntries); switch (segments[0]) { case "v": { // parse vertex double x = double.Parse(segments[1]); double y = double.Parse(segments[2]); double z = double.Parse(segments[3]); var v = mesh.AddVertex(); setPosition(v, new Vec3d(x, y, z)); break; } case "f": { // parse face for (int i = 1; i < segments.Length; i++) { var ids = segments[i].Split(ObjUtil.FaceSeparators); face.Add(int.Parse(ids[0]) - 1); } mesh.AddFace(face); face.Clear(); break; } } } } }
/// <summary> /// Reads this buffer to the given mesh. /// </summary> public void ReadTo <V, E, F>(HeMesh <V, E, F> mesh, Action <V, VA> setVertexAttributes = null, Action <E, EA> setHedgeAttributes = null, Action <F, FA> setFaceAttributes = null) where V : HeMesh <V, E, F> .Vertex where E : HeMesh <V, E, F> .Halfedge where F : HeMesh <V, E, F> .Face { var verts = mesh.Vertices; var hedges = mesh.Halfedges; var faces = mesh.Faces; int nv = verts.Count; int nhe = hedges.Count; int nf = faces.Count; // add new vertices for (int i = 0; i < _vertexRefs.Length; i++) { mesh.AddVertex(); } // add new halfedges for (int i = 0; i < _hedgeRefs.Length; i += 2) { mesh.AddEdge(); } // add new faces for (int i = 0; i < _faceRefs.Length; i++) { mesh.AddFace(); } // link up vertices for (int i = 0; i < _vertexRefs.Length; i++) { var v = verts[i + nv]; var first = _vertexRefs[i]; if (first != -1) { v.First = hedges[first + nhe]; } } // link up halfedges for (int i = 0; i < _hedgeRefs.Length; i++) { var he = hedges[i + nhe]; var refs = _hedgeRefs[i]; var prev = refs[0]; if (prev != -1) { he.Previous = hedges[prev + nhe]; } he.Next = hedges[refs[1] + nhe]; he.Start = verts[refs[2] + nv]; var face = refs[3]; if (face != -1) { he.Face = faces[face + nf]; } } // link up faces for (int i = 0; i < _faceRefs.Length; i++) { var f = faces[i + nf]; var first = _faceRefs[i]; if (first != -1) { f.First = hedges[first + nhe]; } } // TODO validate topology? // set vertex attributes if (setVertexAttributes != null) { for (int i = 0; i < _vertexAttributes.Length; i++) { setVertexAttributes(verts[i + nv], _vertexAttributes[i]); } } // set vertex attributes if (setHedgeAttributes != null) { for (int i = 0; i < _hedgeAttributes.Length; i++) { setHedgeAttributes(hedges[i + nhe], _hedgeAttributes[i]); } } // set vertex attributes if (setFaceAttributes != null) { for (int i = 0; i < _faceAttributes.Length; i++) { setFaceAttributes(faces[i + nf], _faceAttributes[i]); } } }