Exemplo n.º 1
0
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(),
	}
}
Exemplo n.º 2
0
func NewEdge(v1, v2 *Vertex) *Edge {
	a := gomesh.MakeVertexPair(v1, v2)
	return &Edge{
		VertexPair: a,
	}
}
Exemplo n.º 3
0
Arquivo: io.go Projeto: nat-n/shapeset
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
}