using System.Collections.Generic; using global::System.Numerics; namespace Pilz.S3DFileParser { public class Object3D { public List Meshes { get; private set; } = new List(); public Dictionary Materials { get; private set; } = new Dictionary(); public Shading Shading { get; set; } = new Shading(); public void ScaleModel(float factor) { foreach (Mesh m in Meshes) { foreach (Vertex v in m.Vertices) { v.X *= factor; v.Y *= factor; v.Z *= factor; } } } public void OffsetModel(Vector3 off) { foreach (Mesh m in Meshes) { foreach (Vertex v in m.Vertices) { v.X += off.X; v.Y += off.Y; v.Z += off.Z; } } } public ModelBoundaries GetBoundaries() { float? maxX = default; float? maxY = default; float? maxZ = default; float? minX = default; float? minY = default; float? minZ = default; foreach (Mesh m in Meshes) { foreach (Vertex vert in m.Vertices) { if (maxX is null || vert.X > maxX) maxX = (float?)vert.X; if (maxY is null || vert.Y > maxY) maxY = (float?)vert.Y; if (maxZ is null || vert.Z > maxZ) maxZ = (float?)vert.Z; if (minX is null || vert.X < minX) minX = (float?)vert.X; if (minY is null || vert.Y < minY) minY = (float?)vert.Y; if (minZ is null || vert.Z < minZ) minZ = (float?)vert.Z; } } if (maxX is null) maxX = 0; if (maxY is null) maxY = 0; if (maxZ is null) maxZ = 0; if (minX is null) minX = 0; if (minY is null) minY = 0; if (minZ is null) minZ = 0; return new ModelBoundaries(new Vector3((float)maxX, (float)maxY, (float)maxZ), new Vector3((float)minX, (float)minY, (float)minZ)); } public void SetNullVertices() { var newVert = new Vertex() { X = 0d, Y = 0d, Z = 0d }; int nullCounter; foreach (Mesh m in Meshes) { nullCounter = 0; foreach (Face f in m.Faces) { foreach (Point p in f.Points) { if (p.Vertex is null) { p.Vertex = newVert; nullCounter += 1; } } } if (nullCounter > 0) { m.Vertices.Add(newVert); } } } public void SetNullUVs() { var newUV = new UV() { U = 0f, V = 0f }; int nullCounter; foreach (Mesh m in Meshes) { nullCounter = 0; foreach (Face f in m.Faces) { foreach (Point p in f.Points) { if (p.UV is null) { p.UV = newUV; nullCounter += 1; } } } if (nullCounter > 0) { m.UVs.Add(newUV); } } } public void SetNullNormals() { var newNormal = new Normal() { X = 0f, Y = 0f, Z = 1f }; int nullCounter; foreach (Mesh m in Meshes) { nullCounter = 0; foreach (Face f in m.Faces) { foreach (Point p in f.Points) { if (p.Normal is null) { p.Normal = newNormal; nullCounter += 1; } } } if (nullCounter > 0) { m.Normals.Add(newNormal); } } } public void RemoveUnusedMaterials() { // Dim usedMats As New List(Of Material) // Dim unusedMats As New List(Of String) // For Each f As Face In Faces // If Not usedMats.Contains(f.Material) Then // usedMats.Add(f.Material) // End If // Next // For Each kvp As KeyValuePair(Of String, Material) In Materials // If Not usedMats.Contains(kvp.Value) Then // unusedMats.Add(kvp.Key) // End If // Next // For Each k As String In unusedMats // Materials.Remove(k) // Next } public Object3D ToOneMesh() { var newObject3D = new Object3D(); var newMesh = new Mesh(); foreach (KeyValuePair mat in Materials) newObject3D.Materials.Add(mat.Key, mat.Value); foreach (Mesh m in Meshes) { foreach (Vertex v in m.Vertices) newMesh.Vertices.Add(v); foreach (VertexColor vc in m.VertexColors) newMesh.VertexColors.Add(vc); foreach (Normal n in m.Normals) newMesh.Normals.Add(n); foreach (UV uv in m.UVs) newMesh.UVs.Add(uv); foreach (Face f in m.Faces) newMesh.Faces.Add(f); } newObject3D.Meshes.Add(newMesh); return newObject3D; } public void CenterModel() { Mesh.CenterModel(Meshes); } public static void CenterModel(IEnumerable objs) { var meshes = new List(); foreach (Object3D obj in objs) meshes.AddRange(obj.Meshes); Mesh.CenterModel(meshes); } } }