Files
Pilz/Pilz.Simple3DFileParser/Model/Object3D.cs
2020-09-24 11:21:53 +02:00

217 lines
6.5 KiB
C#

using System.Collections.Generic;
using global::System.Numerics;
namespace Pilz.S3DFileParser
{
public class Object3D
{
public List<Mesh> Meshes { get; private set; } = new List<Mesh>();
public Dictionary<string, Material> Materials { get; private set; } = new Dictionary<string, Material>();
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<string, Material> 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<Object3D> objs)
{
var meshes = new List<Mesh>();
foreach (Object3D obj in objs)
meshes.AddRange(obj.Meshes);
Mesh.CenterModel(meshes);
}
}
}