/// <summary> /// Generate a HalfEdgeMesh from an existing MeshGeometry3D Object. /// </summary> /// <param name="meshGeometry">The existing MeshGeometry3D Object.</param> /// <param name="calculateNormals">Calculate Vertex Normals or not.</param> /// <returns>The generated HalfEdgeMesh.</returns> public static HalfEdgeMesh GenerateFromMeshGeometry3D(MeshGeometry3D meshGeometry, bool calculateNormals = false) { var vertices = meshGeometry.Positions.Select(p => new Vertex((float)p.X, (float)p.Y, (float)p.Z)).ToList(); var triangles = new List <Triangle>(); for (int i = 0; i < meshGeometry.TriangleIndices.Count; i += 3) { triangles.Add(new Triangle(meshGeometry.TriangleIndices.ElementAt(i), meshGeometry.TriangleIndices.ElementAt(i + 1), meshGeometry.TriangleIndices.ElementAt(i + 2))); } var mesh = new HalfEdgeMesh(); mesh.AddVertices(vertices); mesh.AddTriangles(triangles); if (calculateNormals) { mesh.CalculateVertexNormals(); } return(mesh); }
/// <summary> /// Generate a HalfEdgeMesh of a Sphere. /// </summary> /// <param name="center">The Center of the Sphere.</param> /// <param name="radius">The Radius of the Sphere.</param> /// <param name="numSides">Number of Sides of the Sphere (multiply by 4 for one Ring).</param> /// <param name="sides">Which Sides of the Sphere should be generated.</param> /// <param name="calculateNormals">Calculate Vertex Normals or not.</param> /// <returns>The generated HalfEdgeMesh.</returns> public static HalfEdgeMesh GenerateSphere(Vector center, float radius = 1, int numSides = 8, CubeSides sides = CubeSides.All, bool calculateNormals = false) { var shiftVector = Vector.One * 0.5f; var mesh = new HalfEdgeMesh(); var sideLength = 1f / numSides; var verticesPerSide = numSides + 1; var vertices = new List <Vertex>(); var bottomVertices = new List <Vertex>(verticesPerSide * verticesPerSide); var topVertices = new List <Vertex>(verticesPerSide * verticesPerSide); var frontVertices = new List <Vertex>(verticesPerSide * verticesPerSide); var backVertices = new List <Vertex>(verticesPerSide * verticesPerSide); var leftVertices = new List <Vertex>(verticesPerSide * verticesPerSide); var rightVertices = new List <Vertex>(verticesPerSide * verticesPerSide); var idx = 0; for (int z = 0; z <= numSides; z++) { for (int y = 0; y <= numSides; y++) { for (int x = 0; x <= numSides; x++) { if (z == 0 || z == numSides || x == 0 || x == numSides || y == 0 || y == numSides) { var vertex = new Vertex(x * sideLength - 0.5f, y * sideLength - 0.5f, z * sideLength - 0.5f) { Index = idx, }; if (x == 0 && sides.HasFlag(CubeSides.NegativeZ)) { bottomVertices.Add(vertex); } else if (x == numSides && sides.HasFlag(CubeSides.PositiveZ)) { topVertices.Add(vertex); } if (y == 0 && sides.HasFlag(CubeSides.NegativeY)) { frontVertices.Add(vertex); } else if (y == numSides && sides.HasFlag(CubeSides.PositiveY)) { backVertices.Add(vertex); } if (z == 0 && sides.HasFlag(CubeSides.NegativeX)) { leftVertices.Add(vertex); } else if (z == numSides && sides.HasFlag(CubeSides.PositiveX)) { rightVertices.Add(vertex); } vertices.Add(vertex); idx++; } else { x += numSides - 2; } } } } foreach (var vertex in vertices) { var vertexVector = (Vector)vertex; vertexVector.Normalize(); vertex.Position = vertexVector * radius + center; } mesh.AddVertices(vertices); var triangles = new List <Triangle>(); for (int i = 0; i < numSides * numSides; i++) { idx = i + i / numSides; var nextIdx = idx + 1; var nextRowIdx = nextIdx + numSides; var nextRowNextIdx = nextRowIdx + 1; if (sides.HasFlag(CubeSides.NegativeZ)) { mesh.AddTriangle(new Triangle(bottomVertices[idx].Index, bottomVertices[nextRowNextIdx].Index, bottomVertices[nextIdx].Index)); mesh.AddTriangle(new Triangle(bottomVertices[idx].Index, bottomVertices[nextRowIdx].Index, bottomVertices[nextRowNextIdx].Index)); } if (sides.HasFlag(CubeSides.PositiveZ)) { mesh.AddTriangle(new Triangle(topVertices[idx].Index, topVertices[nextIdx].Index, topVertices[nextRowNextIdx].Index)); mesh.AddTriangle(new Triangle(topVertices[idx].Index, topVertices[nextRowNextIdx].Index, topVertices[nextRowIdx].Index)); } if (sides.HasFlag(CubeSides.NegativeY)) { mesh.AddTriangle(new Triangle(frontVertices[idx].Index, frontVertices[nextIdx].Index, frontVertices[nextRowNextIdx].Index)); mesh.AddTriangle(new Triangle(frontVertices[idx].Index, frontVertices[nextRowNextIdx].Index, frontVertices[nextRowIdx].Index)); } if (sides.HasFlag(CubeSides.PositiveY)) { mesh.AddTriangle(new Triangle(backVertices[idx].Index, backVertices[nextRowNextIdx].Index, backVertices[nextIdx].Index)); mesh.AddTriangle(new Triangle(backVertices[idx].Index, backVertices[nextRowIdx].Index, backVertices[nextRowNextIdx].Index)); } if (sides.HasFlag(CubeSides.NegativeX)) { mesh.AddTriangle(new Triangle(leftVertices[idx].Index, leftVertices[nextRowNextIdx].Index, leftVertices[nextIdx].Index)); mesh.AddTriangle(new Triangle(leftVertices[idx].Index, leftVertices[nextRowIdx].Index, leftVertices[nextRowNextIdx].Index)); } if (sides.HasFlag(CubeSides.PositiveX)) { mesh.AddTriangle(new Triangle(rightVertices[idx].Index, rightVertices[nextIdx].Index, rightVertices[nextRowNextIdx].Index)); mesh.AddTriangle(new Triangle(rightVertices[idx].Index, rightVertices[nextRowNextIdx].Index, rightVertices[nextRowIdx].Index)); } } if (calculateNormals) { mesh.CalculateVertexNormals(); } return(mesh); }