Skip to content

Commit

Permalink
initial fixup
Browse files Browse the repository at this point in the history
  • Loading branch information
sowa705 committed Dec 8, 2024
1 parent 504ee4c commit 81a0c8c
Show file tree
Hide file tree
Showing 6 changed files with 103 additions and 54 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
**/.idea/shelf/*
**/.idea/dictionaries
**/.idea/httpRequests/
.idea/

# Sensitive or high-churn files
**/.idea/**/dataSources/
Expand Down
32 changes: 31 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,33 @@
# MeshSimplifier

Fork of the UnityMeshSimplifier Library adapted for modern .NET 9+ projects
Trimmed down fork of the [UnityMeshSimplifier](https://github.com/Whinarn/UnityMeshSimplifier) Library adapted for modern non-Unity .NET 9+ projects

## Basic usage

```csharp
using MeshSimplifier;

// load your 3D model into a Mesh object
Mesh mesh = new Mesh();
mesh.vertices = ...;
mesh.triangles = ...;
mesh.submeshes = [new SubMesh(0,mesh.triangles.Length)];

MeshSimplifier simplifier = new MeshSimplifier();

simplifier.Initialize(mesh);
simplifier.SimplifyMesh(0.5f);

var optimizedMesh = simplifier.ToMesh();
```

## Removed features

- Unity integration
- BlendShapes
- BoneWeights (may be re-added in the future)
- 3D and 4D UVs (may be re-added in the future)

## License

This project is licensed as MIT as stated in LICENSE.md, huge thanks to the UnityMeshSimplifer contributors and Fast Quadric Mesh Simplification team
37 changes: 34 additions & 3 deletions src/Mesh.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,32 +2,63 @@

namespace MeshSimplifier;

public class SubMesh
{
public int startIndex;
public int indexCount;

public SubMesh(int subMeshOffset, int length)
{
startIndex = subMeshOffset;
indexCount = length;
}
}

public class Mesh
{
public Vector3[] vertices;
public Vector3[] normals;
public Vector4[] tangents;
public Vector2[] uvs;
public Vector2[][] textureCoordinates;
public Vector4[] colors;
public int[] triangles;
public SubMesh[] subMeshes;

public int subMeshCount;
public int subMeshCount => subMeshes.Length;
public int vertexCount => vertices.Length;

public int[] GetTriangles(int submeshIndex)
{
return [];
if (submeshIndex >= subMeshes.Length)
{
throw new ArgumentException("Submesh index out of range");
}
var subMesh = subMeshes[submeshIndex];
return triangles.Skip(subMesh.startIndex).Take(subMesh.indexCount).ToArray();
}

public void GetUVs(int channel, List<Vector4> uvList)
{
throw new NotImplementedException();
}

public void GetUVs(int channel, List<Vector3> uvList)
{
throw new NotImplementedException();
}

public void GetUVs(int channel, List<Vector2> uvList)
{
if (channel>=textureCoordinates.Length)
{
throw new ArgumentException("Channel index out of range");
}

if (textureCoordinates[channel] is null)
{
throw new ArgumentException("Channel is null");
}

uvList.AddRange(textureCoordinates[channel]);
}
}
23 changes: 22 additions & 1 deletion src/MeshSimplifier.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ public sealed class MeshSimplifier
private const double DenomEpilson = 0.00000001;
private static readonly int UVChannelCount = 1;

private SimplificationOptions simplificationOptions = SimplificationOptions.Default;
private SimplificationOptions simplificationOptions = new();
private bool verbose = false;

private int subMeshCount = 0;
Expand Down Expand Up @@ -1924,6 +1924,27 @@ public void SimplifyMesh(float quality)
}
}

public Mesh ToMesh()
{
var mesh = new Mesh();
mesh.vertices = Vertices.ToArray();
mesh.triangles = this.triangles.Data.SelectMany(x=>(new int[] { x.v0, x.v1, x.v2 })).ToArray();
mesh.textureCoordinates = [this.UV1.ToArray()];
mesh.colors = this.Colors.ToArray();
mesh.normals = this.Normals.ToArray();
mesh.tangents = this.Tangents.ToArray();

var allSubMeshes = GetAllSubMeshTriangles();
var submeshes = new SubMesh[subMeshOffsets.Length];
for (int i = 0; i < subMeshOffsets.Length; i++)
{
submeshes[i] = new SubMesh(subMeshOffsets[i], allSubMeshes[i].Length);
}

mesh.subMeshes = submeshes;
return mesh;
}

/// <summary>
/// Simplifies the mesh without losing too much quality.
/// </summary>
Expand Down
22 changes: 0 additions & 22 deletions src/MeshUtils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,6 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/

#if UNITY_2018_2_OR_NEWER
#define UNITY_8UV_SUPPORT
#endif

using System;
using System.Collections.Generic;
using System.Numerics;
Expand All @@ -42,24 +38,6 @@ public static class MeshUtils
/// </summary>
public static readonly int UVChannelCount = 4;

/// <summary>
/// Returns the UV sets for a specific mesh.
/// </summary>
/// <param name="mesh">The mesh.</param>
/// <returns>The UV sets.</returns>
public static IList<Vector4>[] GetMeshUVs(Mesh mesh)
{
if (mesh == null)
throw new ArgumentNullException(nameof(mesh));

var uvs = new IList<Vector4>[UVChannelCount];
for (int channel = 0; channel < UVChannelCount; channel++)
{
uvs[channel] = GetMeshUVs(mesh, channel);
}
return uvs;
}

/// <summary>
/// Returns the 2D UV list for a specific mesh and UV channel.
/// </summary>
Expand Down
42 changes: 15 additions & 27 deletions src/SimplificationOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,76 +34,64 @@ namespace MeshSimplifier
[StructLayout(LayoutKind.Auto)]
public struct SimplificationOptions
{
/// <summary>
/// The default simplification options.
/// </summary>
public static readonly SimplificationOptions Default = new SimplificationOptions
{
PreserveBorderEdges = false,
PreserveUVSeamEdges = false,
PreserveUVFoldoverEdges = false,
PreserveSurfaceCurvature = false,
EnableSmartLink = true,
VertexLinkDistance = double.Epsilon,
MaxIterationCount = 100,
Agressiveness = 7.0,
ManualUVComponentCount = false,
UVComponentCount = 2
};

/// <summary>
/// If the border edges should be preserved.
/// Default value: false
/// </summary>
public bool PreserveBorderEdges;
public bool PreserveBorderEdges = false;
/// <summary>
/// If the UV seam edges should be preserved.
/// Default value: false
/// </summary>
public bool PreserveUVSeamEdges;
public bool PreserveUVSeamEdges = false;
/// <summary>
/// If the UV foldover edges should be preserved.
/// Default value: false
/// </summary>
public bool PreserveUVFoldoverEdges;
public bool PreserveUVFoldoverEdges = false;
/// <summary>
/// If the discrete curvature of the mesh surface be taken into account during simplification. Taking surface curvature into account can result in good quality mesh simplification, but it can slow the simplification process significantly.
/// Default value: false
/// </summary>
public bool PreserveSurfaceCurvature;
public bool PreserveSurfaceCurvature = false;
/// <summary>
/// If a feature for smarter vertex linking should be enabled, reducing artifacts in the
/// decimated result at the cost of a slightly more expensive initialization by treating vertices at
/// the same position as the same vertex while separating the attributes.
/// Default value: true
/// </summary>
public bool EnableSmartLink;
public bool EnableSmartLink = true;
/// <summary>
/// The maximum distance between two vertices in order to link them.
/// Note that this value is only used if EnableSmartLink is true.
/// Default value: double.Epsilon
/// </summary>
public double VertexLinkDistance;
public double VertexLinkDistance = double.Epsilon;
/// <summary>
/// The maximum iteration count. Higher number is more expensive but can bring you closer to your target quality.
/// Sometimes a lower maximum count might be desired in order to lower the performance cost.
/// Default value: 100
/// </summary>
public int MaxIterationCount;
public int MaxIterationCount = 100;
/// <summary>
/// The agressiveness of the mesh simplification. Higher number equals higher quality, but more expensive to run.
/// Default value: 7.0
/// </summary>
public double Agressiveness;
public double Agressiveness = 7.0;
/// <summary>
/// If a manual UV component count should be used (set by UVComponentCount), instead of the automatic detection.
/// Default value: false
/// </summary>
public bool ManualUVComponentCount;
public bool ManualUVComponentCount = false;

/// <summary>
/// The UV component count. The same UV component count will be used on all UV channels.
/// Default value: 2
/// </summary>
public int UVComponentCount;
public int UVComponentCount = 2;

public SimplificationOptions()
{
}
}
}

0 comments on commit 81a0c8c

Please sign in to comment.