func WrapMesh(m *gomesh.Mesh) *Mesh { m.ReindexVerticesAndFaces() // also wrap vertices; i.e. replaces mesh.Vertex with shapeset.vertex for i := 0; i < m.Vertices.Len(); i++ { if v, ok := m.Vertices.Get(i)[0].(*gomesh.Vertex); ok { m.Vertices.Update(i, &Vertex{Vertex: *v}) } } // also wrap faces and update them to reference outer vertex object for i := 0; i < m.Faces.Len(); i++ { if fx, ok := m.Faces.Get(i)[0].(*gomesh.Face); ok { f := &Face{Face: *fx} f.SetA(m.Vertices.Get(f.GetA().GetLocationInMesh(m))[0]) f.SetB(m.Vertices.Get(f.GetB().GetLocationInMesh(m))[0]) f.SetC(m.Vertices.Get(f.GetC().GetLocationInMesh(m))[0]) m.Faces.Update(i, f) f.GetA().AddFace(f) f.GetB().AddFace(f) f.GetC().AddFace(f) } } // iterate faces, build set of edges vert_pairs := make(map[gomesh.VertexPair]*Edge) m.Faces.EachWithIndex(func(i int, f gomesh.FaceI) { pairs := [3]gomesh.VertexPair{ gomesh.MakeVertexPair(f.GetA(), f.GetB()), gomesh.MakeVertexPair(f.GetB(), f.GetC()), gomesh.MakeVertexPair(f.GetC(), f.GetA()), } for i, pair := range pairs { var e *Edge if e1, exists := vert_pairs[pair]; !exists { e = &Edge{VertexPair: pair} e.V1.(*Vertex).AddEdge(e) e.V2.(*Vertex).AddEdge(e) vert_pairs[pair] = e } else { e = e1 } e.AddFace(f.(*Face)) f.(*Face).Edges[i] = e } }) return &Mesh{ Mesh: *m, Borders: make(map[BorderId]*Border), BoundingBox: m.BoundingBox(), } }
func NewEdge(v1, v2 *Vertex) *Edge { a := gomesh.MakeVertexPair(v1, v2) return &Edge{ VertexPair: a, } }
func Load(ss_reader *io.Reader) (ss *ShapeSet, err error) { // Parse json from reader and load with temporary types parsed_data := new(shapeSetParseSchema) err = json.NewDecoder(*ss_reader).Decode(parsed_data) if err != nil { err = errors.New("Could not parse json from ss_reader") return } // for building up partial border info from meshes border_tracker := make(map[BorderId]map[MeshId][]*Vertex) meshesBuffer := make([]*Mesh, 0) for _, mesh_data := range parsed_data.Meshes { var verts, norms []float64 var faces []int mesh_name := mesh_data.Name m := NewMesh(mesh_name) // load vertices from parsed data verts, err = parseCSFloats(mesh_data.Verts) vertexBuffer := make([]gomesh.VertexI, 0, len(verts)/3) if err != nil { err = errors.New("Could not parse vertices for: " + mesh_name) return } for i := 0; i < len(verts); i += 3 { vertexBuffer = append(vertexBuffer, &Vertex{Vertex: gomesh.Vertex{ Vec3: geom.Vec3{verts[i], verts[i+1], verts[i+2]}, Meshes: make(map[gomesh.Mesh]int), }}) } // Vertex normals are optional if len(mesh_data.Norms) > 0 { norms, err = parseCSFloats(mesh_data.Norms) if err != nil { err = errors.New("Could not parse normals for: " + mesh_name) return } if len(norms) != 0 && len(norms) != len(verts) { err = errors.New("Malformed Mesh (vertices/normals mismatch): " + mesh_name) return } for i := 0; i < len(norms); i += 3 { vertexBuffer[i/3].SetNormal(&geom.Vec3{norms[i], norms[i+1], norms[i+2]}) } } edges := make(map[gomesh.VertexPair]*Edge) // load faces from parsed data faces, err = parseCSInts(mesh_data.Faces) faceBuffer := make([]gomesh.FaceI, 0, len(faces)/3) if err != nil { err = errors.New("Could not parse faces for: " + mesh_name) return } for i := 0; i < len(faces); i += 3 { // create new face from vertex triple vA := vertexBuffer[faces[i]] vB := vertexBuffer[faces[i+1]] vC := vertexBuffer[faces[i+2]] new_face := &Face{Face: gomesh.Face{Vertices: [3]gomesh.VertexI{vA, vB, vC}}} // reference face from vertices vA.AddFace(new_face) vB.AddFace(new_face) vC.AddFace(new_face) faceBuffer = append(faceBuffer, new_face) // find/create edges of new_face e0 := gomesh.MakeVertexPair(vA, vB) e1 := gomesh.MakeVertexPair(vB, vC) e2 := gomesh.MakeVertexPair(vC, vA) newPairs := [3]gomesh.VertexPair{e0, e1, e2} for i, vp := range newPairs { var f_edge *Edge if e, exists := edges[vp]; exists { f_edge = e } else { f_edge = &Edge{VertexPair: vp} f_edge.Vertex1().AddEdge(f_edge) f_edge.Vertex2().AddEdge(f_edge) edges[vp] = f_edge } f_edge.AddFace(new_face) new_face.Edges[i] = f_edge } } for border_id, border_indices := range mesh_data.Borders { var vert_indices []int vert_indices, err = parseCSInts(border_indices) if err != nil { err = errors.New( "Could not parse border for mesh " + m.GetName() + " indices for border " + border_id + ", in mesh " + mesh_name) return } bverts := make([]*Vertex, 0) for _, vi := range vert_indices { bverts = append(bverts, vertexBuffer[vi].(*Vertex)) } bid, err := BorderIdFromString(border_id) if err != nil { panic(err.Error()) } mid := MeshIdFromString(mesh_name) if _, exists := border_tracker[bid]; !exists { border_tracker[bid] = make(map[MeshId][]*Vertex) } border_tracker[bid][mid] = bverts } m.Vertices.Append(vertexBuffer...) m.Faces.Append(faceBuffer...) m.ReindexVerticesAndFaces() m.BoundingBox = m.Mesh.BoundingBox() meshesBuffer = append(meshesBuffer, m) } // Create ShapeSet ss = New(parsed_data.Name, parsed_data.Shapes, meshesBuffer) // merge border vertices for border_id, mesh_borders := range border_tracker { mesh_ids := ByMeshIdPrecedence{} for mesh_id, _ := range mesh_borders { mesh_ids = append(mesh_ids, mesh_id) } sort.Sort(mesh_ids) first_mesh_vertices := mesh_borders[mesh_ids[0]] for _, mesh_id := range mesh_ids[1:] { secondary_mesh_vertices := mesh_borders[mesh_id] for i := 0; i < len(first_mesh_vertices); i++ { gomesh.MergeSharedVertices( first_mesh_vertices[i], secondary_mesh_vertices[i]) } } _, err = ss.BordersIndex.LoadBorder( border_id, []MeshId(mesh_ids), first_mesh_vertices, ) if err != nil { return } } ss.BordersIndex.indexBorderEdges() return }