forked from gradientspace/geometry3Sharp
-
Notifications
You must be signed in to change notification settings - Fork 32
/
MeshIterativeSmooth.cs
83 lines (59 loc) · 2.24 KB
/
MeshIterativeSmooth.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
83
using System;
using System.Collections.Generic;
namespace g3
{
public class MeshIterativeSmooth
{
public DMesh3 Mesh;
public int[] Vertices;
public double Alpha = 0.25f;
public int Rounds = 10;
public enum SmoothTypes {
Uniform, Cotan, MeanValue
};
public SmoothTypes SmoothType = SmoothTypes.Uniform;
// reproject smoothed position to new location
public Func<Vector3d, Vector3f, int, Vector3d> ProjectF;
Vector3d[] SmoothedPostions;
public MeshIterativeSmooth(DMesh3 mesh, int[] vertices, bool bOwnVertices = false)
{
Mesh = mesh;
Vertices = (bOwnVertices) ? vertices : (int[])vertices.Clone();
SmoothedPostions = new Vector3d[Vertices.Length];
ProjectF = null;
}
public virtual ValidationStatus Validate()
{
return ValidationStatus.Ok;
}
public virtual bool Smooth()
{
int NV = Vertices.Length;
double a = MathUtil.Clamp(Alpha, 0, 1);
double num_rounds = MathUtil.Clamp(Rounds, 0, 10000);
Func<DMesh3, int, double, Vector3d> smoothFunc = MeshUtil.UniformSmooth;
if (SmoothType == SmoothTypes.MeanValue)
smoothFunc = MeshUtil.MeanValueSmooth;
else if (SmoothType == SmoothTypes.Cotan)
smoothFunc = MeshUtil.CotanSmooth;
Action<int> smooth = (i) => {
int vID = Vertices[i];
SmoothedPostions[i] = smoothFunc(Mesh, vID, a);
};
Action<int> project = (i) => {
Vector3d pos = SmoothedPostions[i];
SmoothedPostions[i] = ProjectF(pos, Vector3f.AxisY, Vertices[i]);
};
IndexRangeEnumerator indices = new IndexRangeEnumerator(0, NV);
for (int round = 0; round < num_rounds; ++round) {
gParallel.ForEach<int>(indices, smooth);
if ( ProjectF != null )
gParallel.ForEach<int>(indices, project);
// bake
for (int i = 0; i < NV; ++i)
Mesh.SetVertex(Vertices[i], SmoothedPostions[i]);
}
return true;
}
}
}