Beispiel #1
0
        public static List <Mesh> MarchingCubes(this Mesh3D mesh3d, List <double> vertexValues, List <double> isoValues)
        {
            if (mesh3d?.Vertices == null || vertexValues == null || mesh3d.Vertices.Count != vertexValues.Count)
            {
                Reflection.Compute.RecordError("Number of vertexValues must match the number of vertices in the mesh.");
                return(new List <Mesh>());
            }

            if (isoValues == null)
            {
                return(new List <Mesh>());
            }

            // add empty lists
            List <List <Point> > vertices = new List <List <Point> >();
            List <List <Face> >  faces    = new List <List <Face> >();

            for (int i = 0; i < isoValues.Count; i++)
            {
                vertices.Add(new List <Point>());
                faces.Add(new List <Face>());
            }

            // SubMesh works on regular meshes, and since we're looking at it one cell at a time, the extra information in the mesh3d is not needed
            Mesh meshVersion = mesh3d.ToMesh();

            // Look at every cell
            foreach (List <Face> cell in mesh3d.Cells())
            {
                // Create a mesh from the cell
                var meshAndValues = SubMesh(meshVersion, cell, vertexValues);

                // Find the iso lines for the boundary of the cell
                List <List <Polyline> > pLines = MarchingSquares(meshAndValues.Item1, meshAndValues.Item2, isoValues).Select(x => x.Join()).ToList();

                // Create faces from the polyline
                // Note that each vertex may be added twice here from neighboring cells
                for (int j = 0; j < isoValues.Count; j++)
                {
                    foreach (Polyline polyline in pLines[j])
                    {
                        vertices[j].AddRange(polyline.ControlPoints.Skip(1));
                        int nPts = vertices[j].Count;

                        int first = polyline.ControlPoints.Count - 1;
                        // A rough triangulation of the imagined face covering the polyline, (assumes convex polyline)
                        for (int i = 1; i < first - 1; i++)
                        {
                            faces[j].Add(new Face()
                            {
                                A = nPts - first,
                                B = nPts - (i + 1),
                                C = nPts - i,
                            });
                        }
                    }
                }
            }

            return(vertices.Zip(faces, (v, f) => new Mesh()
            {
                Vertices = v,
                Faces = f,
            }).ToList());
        }