-
Notifications
You must be signed in to change notification settings - Fork 69
/
Copy pathMRMeshFixer.cs
82 lines (74 loc) · 3.54 KB
/
MRMeshFixer.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text;
namespace MR
{
public partial class DotNet
{
[StructLayout(LayoutKind.Sequential)]
public struct MultipleEdge
{
VertId v0;
VertId v1;
}
[DllImport("MRMeshC", CharSet = CharSet.Ansi)]
private static extern IntPtr mrFindHoleComplicatingFaces(IntPtr mesh);
[DllImport("MRMeshC", CharSet = CharSet.Ansi)]
private static extern IntPtr mrFindDegenerateFaces(ref MRMeshPart mp, float criticalAspectRatio, IntPtr cb, ref IntPtr errorStr);
[DllImport("MRMeshC", CharSet = CharSet.Ansi)]
private static extern IntPtr mrFindShortEdges(ref MRMeshPart mp, float criticalLength, IntPtr cb, ref IntPtr errorStr);
[DllImport("MRMeshC", CharSet = CharSet.Ansi)]
unsafe private static extern void fixMultipleEdges(IntPtr mesh, MultipleEdge* multipleEdges, ulong multipleEdgesNum);
[DllImport("MRMeshC", CharSet = CharSet.Ansi)]
private static extern void findAndFixMultipleEdges(IntPtr mesh);
[DllImport("MRMeshC", CharSet = CharSet.Ansi)]
private static extern IntPtr mrStringData(IntPtr str);
/// returns all faces that complicate one of mesh holes;
/// hole is complicated if it passes via one vertex more than once;
/// deleting such faces simplifies the holes and makes them easier to fill
public static BitSet FindHoleComplicatingFaces(Mesh mesh)
{
return new BitSet(mrFindHoleComplicatingFaces(mesh.mesh_));
}
/// finds faces having aspect ratio >= criticalAspectRatio
public static FaceBitSet FindDegenerateFaces(MeshPart meshPart, float criticalAspectRatio)
{
IntPtr errorString = new IntPtr();
IntPtr res = mrFindDegenerateFaces(ref meshPart.mrMeshPart, criticalAspectRatio, IntPtr.Zero, ref errorString);
if (errorString != IntPtr.Zero)
{
var errData = mrStringData(errorString);
string errorMessage = MarshalNativeUtf8ToManagedString(errData);
throw new Exception(errorMessage);
}
return new FaceBitSet(res);
}
/// finds edges having length <= criticalLength
public static UndirectedEdgeBitSet FindShortEdges(MeshPart meshPart, float criticalLength)
{
IntPtr errorString = new IntPtr();
IntPtr res = mrFindShortEdges(ref meshPart.mrMeshPart, criticalLength, IntPtr.Zero, ref errorString);
if (errorString != IntPtr.Zero)
{
var errData = mrStringData(errorString);
string errorMessage = MarshalNativeUtf8ToManagedString(errData);
throw new Exception(errorMessage);
}
return new UndirectedEdgeBitSet(res);
}
/// resolves given multiple edges, but splitting all but one edge in each group
unsafe public static void FixMultipleEdges(ref Mesh mesh, List<MultipleEdge> multipleEdges)
{
MultipleEdge* multipleEdgesPtr = stackalloc MultipleEdge[multipleEdges.Count];
for (int i = 0; i < multipleEdges.Count; i++)
multipleEdgesPtr[i] = multipleEdges[i];
fixMultipleEdges(mesh.mesh_, multipleEdgesPtr, (ulong)multipleEdges.Count);
}
/// finds and resolves multiple edges
public static void FixMultipleEdges(ref Mesh mesh)
{
findAndFixMultipleEdges(mesh.mesh_);
}
}
}