Open ghost opened 5 years ago
Yeah Build() takes ~vertices~ points, but the part that is tripping me up is the triangles parameter.
I figured I could add three values of the ~vertex's~ point's index to the triangle list in my for loop, but that throws an out of bounds exception.
If I only add one value per vertex to the triangle list, that throws an out of bounds exception in a different place.
Here's my test code FWIW
Mesh unityMesh = _meshGO.GetComponent<MeshFilter>().mesh;
MeshUtilities.StartPointGeneration(unityMesh);
List<Vector3d> points = new List<Vector3d>();
List<int> tris = new List<int>();
List<Vector3d> normals = new List<Vector3d>();
for (int i = 0; i < pointsResolution; i++)
{
Vector3 normal = Vector3.one;
Vector3 p = MeshUtilities.GetRandomPointOnMesh(pointsTowardVertsBias, out normal);
float min = 1f - (pointsJitterAmount / 2f);
float max = 1f + (pointsJitterAmount / 2f);
p *= UnityEngine.Random.Range(min, max);
points.Add(new Vector3d(p.x, p.y, p.z));
tris.Add(i);
tris.Add(i);
tris.Add(i);
normals.Add(new Vector3d(normal.x, normal.y, normal.z));
}
MeshUtilities.FinishPointGeneration();
DMesh3 pointSet = DMesh3Builder.Build(points, tris, normals);
PointAABBTree3 pointBVTree = new PointAABBTree3(pointSet, true);
// estimate point area based on nearest-neighbour distance
double[] areas = new double[pointSet.MaxVertexID];
foreach (int vertID in pointSet.VertexIndices())
{
pointBVTree.PointFilterF = (i) => { return i != vertID; }; // otherwise vid is nearest to vid!
int nearestVertID = pointBVTree.FindNearestPoint(pointSet.GetVertex(vertID));
double dist = pointSet.GetVertex(vertID).Distance(pointSet.GetVertex(nearestVertID));
areas[vertID] = Circle2d.RadiusArea(dist);
}
pointBVTree.FWNAreaEstimateF = (vid) => {
return areas[vid];
};
MarchingCubes mc = new MarchingCubes();
mc.Implicit = new PWNImplicit() { Spatial = pointBVTree };
mc.IsoValue = 0.0;
mc.CubeSize = pointBVTree.Bounds.MaxDim / implicitSurfaceCellCount;
mc.Bounds = pointBVTree.Bounds.Expanded(mc.CubeSize * 3);
mc.RootMode = MarchingCubes.RootfindingModes.Bisection;
mc.Generate();
DMesh3 resultMesh = mc.Mesh;
g3UnityUtils.SetGOMesh(_meshGO, resultMesh);
PWNImplicit comes from http://www.gradientspace.com/tutorials/2018/9/14/point-set-fast-winding
Ok, I've been able to determine that my code does in fact work, but it seems only for lower sample counts. Somewhere around 64 points is when things start to break down and trigger either one of two array bounds exceptions, or it just freezes the Unity editor.
Ohhh k, got it. It was unclear that you need to call FastWindingNumber() first before using it for PointAABBTree3 like you do for using it with Dmesh3AABBTree3. Adding that fixed the issue.
DMesh3 pointSet = DMesh3Builder.Build(points, tris, normals);
PointAABBTree3 pointBVTree = new PointAABBTree3(pointSet, true);
pointBVTree.FastWindingNumber(Vector3d.Zero); // build approximation also needed for points
What is the value of implicitSurfaceCellCount
?
Hi Ryan, is it possible to generate a set of random points and then generate a concave mesh around them? I am an artist who can code a bit and i use unity c#. Problem is that i dont have the triangles when i just have random points and the delaunay triangulation is only 2d. As far as i understand you can do this with Surfacing Point Sets? But i dont get how to get my random points into the PointSet.
DMesh3 pointSet = DMesh3Builder.Build(); <- Random Points ?? PointAABBTree3 bvtree = new PointAABBTree3(pointSet, true); ...
Sorry for this simple question :) Thanks, Chris