Пример #1
0
        /// <summary>
        /// Test intersections in 3D on a big dataset.
        /// </summary>
        public static void TestIntersectExampleData()
        {
            var parser     = new Parser();
            var generators = new List <Vertex>();

            using (var streamReader = new StreamReader("Data/exampleVoronoi.txt"))
            {
                int    i = 0;
                string line;
                while ((line = streamReader.ReadLine()) != null)
                {
                    var vertex = parser.ParseVertex(line);
                    vertex.Index = i;
                    generators.Add(vertex);
                    i++;
                }
            }

            var reader             = new TriangulationReader();
            var tetrahedralization = reader.Read("Data/exampleTetra.dat");

            for (int i = 0; i < tetrahedralization.Indices.Count; i++)
            {
                var indices = tetrahedralization.Indices[i].Indices;

                for (int j = 0; j < indices.Length; j++)
                {
                    indices[j] = indices[j] - 1;
                }
            }

            //var boundingBox = CreateBoundingBox3D(tetrahedralization.Vertices);

            //var voronoiData = new VolumeData3D();
            //voronoiData.FromVoronoi(generators);

            var tetrahedralizationData = new VolumeData3D();

            tetrahedralizationData.FromTriangulation(tetrahedralization.Vertices, tetrahedralization.Indices);

            //var bitmap = new System.Drawing.Bitmap(800, 800);
            //VolumeVisualisator.Visualise3D(bitmap, 0.4, voronoiData, boundingBox);
            //bitmap.Save("export000.png");

            //bitmap = new System.Drawing.Bitmap(800, 800);
            //VolumeVisualisator.Visualise3D(bitmap, 0.4, tetrahedralizationData, boundingBox);
            //bitmap.Save("example.png");

            var volumeIntersection = new VolumeIntersection3D(new BruteForceHalfSpaceRemoval3D());
            var volumeData         = volumeIntersection.Intersect(tetrahedralization.Vertices, tetrahedralization.Indices, generators);

            var writer = new VolumeData3DWriter(',');

            writer.Write("exampleIntersection.txt", volumeData);

            //bitmap = new System.Drawing.Bitmap(800, 800);
            //VolumeVisualisator.Visualise3D(bitmap, 0.4, volumeData, boundingBox);
            //bitmap.Save("intersectExample.png");
        }
Пример #2
0
        /// <summary>
        /// Visualises a slice of a 3D volumetric data.
        /// </summary>
        /// <param name="bitmap">Bitmap that contains the visualisation.</param>
        /// <param name="zValue">Slicing value.</param>
        /// <param name="volume">3D Volumetric data.</param>
        /// <param name="volumeBoundingBox">Bounding box.</param>
        public static void Visualise3D(Bitmap bitmap, double zValue, VolumeData3D volume, BoundingBox3D volumeBoundingBox)
        {
            // Setup color of each cell
            var colors = SetupColors(volume.Cells.Count);

            // Access bitmap data
            int        width      = bitmap.Width;
            int        height     = bitmap.Height;
            BitmapData bitmapData = bitmap.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);

            unsafe
            {
                // Get pointer to bitmap data
                byte *pointer = (byte *)bitmapData.Scan0;

                // Setup a point
                var point = new Vector3D();
                point.Z = zValue;

                // For each pixel of a bitmap find a cell and color the pixel.
                for (int i = 0; i < height; i++)
                {
                    // Remap pixel to a position in 3D space.
                    point.Y = MathUtils.Remap(i, 0, height, volumeBoundingBox.Max.Y, volumeBoundingBox.Min.Y);

                    for (int j = 0; j < width; j++)
                    {
                        // Remap pixel to a position in 3D space
                        point.X = MathUtils.Remap(j, 0, width, volumeBoundingBox.Min.X, volumeBoundingBox.Max.X);

                        // For each cell check if it contains the point
                        for (int k = 0; k < volume.Cells.Count; k++)
                        {
                            if (volume.Cells[k].Contains(point))
                            {
                                // Color the pixel
                                pointer[0] = colors[k].B;
                                pointer[1] = colors[k].G;
                                pointer[2] = colors[k].R;
                                pointer[3] = colors[k].A;
                                break;
                            }
                        }

                        pointer += BytesPerPixel;
                    }
                }
            }

            bitmap.UnlockBits(bitmapData);
        }
Пример #3
0
        /// <summary>
        /// Test triangulation volumetric data in 3D.
        /// </summary>
        public static void TestFromTriangulationSingleTetrahedron()
        {
            var vertices = new List <Vertex>()
            {
                new Vertex(0, 0, 0),
                new Vertex(1, 0, 0),
                new Vertex(0, 1, 0),
                new Vertex(0, 0, 1)
            };

            var tetrahedra = new List <Triangle>()
            {
                new Triangle(0, 1, 2, 3)
            };

            var volumeData = new VolumeData3D();

            volumeData.FromTriangulation(vertices, tetrahedra);
        }
Пример #4
0
        /// <summary>
        /// Test intersection in 3D on a small dataset.
        /// </summary>
        public static void TestIntersectSmallData()
        {
            var reader             = new TriangulationReader();
            var tetrahedralization = reader.Read("Data/smallTetra.dat");

            Random rd         = new Random();
            var    generators = new List <Vertex>();

            for (int i = 0; i < 5; i++)
            {
                generators.Add(new Vertex(rd.NextDouble() * 0.6 + 0.1, rd.NextDouble() * 0.9, rd.NextDouble() * 0.7 + 0.2)
                {
                    Index = i
                });
            }

            var boundingBox = CreateBoundingBox3D(tetrahedralization.Vertices);

            var voronoiData = new VolumeData3D();

            voronoiData.FromVoronoi(generators);

            var tetrahedralizationData = new VolumeData3D();

            tetrahedralizationData.FromTriangulation(tetrahedralization.Vertices, tetrahedralization.Indices);

            var bitmap = new System.Drawing.Bitmap(800, 800);

            VolumeVisualisator.Visualise3D(bitmap, 0.4, voronoiData, boundingBox);
            bitmap.Save("smallVoronoi.png");

            bitmap = new System.Drawing.Bitmap(800, 800);
            VolumeVisualisator.Visualise3D(bitmap, 0.4, tetrahedralizationData, boundingBox);
            bitmap.Save("smallTetra.png");

            var volumeData = new VolumeIntersection3D(new BruteForceHalfSpaceRemoval3D()).Intersect(tetrahedralization.Vertices, tetrahedralization.Indices, generators);

            bitmap = new System.Drawing.Bitmap(800, 800);
            VolumeVisualisator.Visualise3D(bitmap, 0.4, volumeData, boundingBox);
            bitmap.Save("intersectSmallData.png");
        }
Пример #5
0
        /// <summary>
        /// Test voronoi volumetric data in 3D
        /// </summary>
        public static void TestFromVoronoi3D()
        {
            var generators = new List <Vertex>()
            {
                new Vertex(1, 0, 0)
                {
                    Index = 0
                },
                new Vertex(0, 0, 0)
                {
                    Index = 1
                },
                new Vertex(-1, 0, 0)
                {
                    Index = 2
                },
                new Vertex(0, 1, 0)
                {
                    Index = 3
                },
                new Vertex(0, -1, 0)
                {
                    Index = 4
                },
                new Vertex(0, 0, 1)
                {
                    Index = 5
                },
                new Vertex(0, 0, -1)
                {
                    Index = 6
                }
            };

            var volumeData = new VolumeData3D();

            volumeData.FromVoronoi(generators);
        }
Пример #6
0
        /// <summary>
        /// Writer 3D volumetric data to a file.
        /// </summary>
        /// <param name="path">Path of a file.</param>
        /// <param name="volumeData">3D data.</param>
        public void Write(string path, VolumeData3D volumeData)
        {
            StreamWriter writer = new StreamWriter(path);

            writer.WriteLine("# centroid.X" + separator + "centroid.Y" + separator + "centroid.Z" + separator + "triangleIndex" + separator + "voronoiIndex" + separator + "weight" + separator + "visited" + separator + "edgeIndices");

            var edgeList = new List <Edge3D>();

            foreach (var cell in volumeData.Cells)
            {
                writer.Write(cell.Centroid.X);
                writer.Write(separator);
                writer.Write(cell.Centroid.Y);
                writer.Write(separator);
                writer.Write(cell.Centroid.Z);
                writer.Write(separator);
                writer.Write(cell.TriangleIndex);
                writer.Write(separator);
                writer.Write(cell.VoronoiIndex);
                writer.Write(separator);
                writer.Write(cell.Weight);
                writer.Write(separator);
                writer.Write(cell.Visited);

                for (int i = 0; i < cell.Edges.Count; i++)
                {
                    writer.Write(separator);
                    writer.Write(edgeList.Count);

                    edgeList.Add(cell.Edges[i]);
                }

                writer.WriteLine();
            }

            writer.WriteLine("# normal.x" + separator + "normal.y" + separator + "normal.z" + separator + "c" + separator + "sourceIndex" + separator + "targetIndex");
            foreach (var edge in edgeList)
            {
                writer.Write(edge.Normal.X);
                writer.Write(separator);
                writer.Write(edge.Normal.Y);
                writer.Write(separator);
                writer.Write(edge.Normal.Z);
                writer.Write(separator);
                writer.Write(edge.C);
                writer.Write(separator);

                int sourceIndex = -1;
                int targetIndex = -1;

                for (int i = 0; i < volumeData.Cells.Count; i++)
                {
                    if (volumeData.Cells[i] == edge.Source)
                    {
                        sourceIndex = i;
                    }

                    if (volumeData.Cells[i] == edge.Target)
                    {
                        targetIndex = i;
                    }

                    if (sourceIndex != -1 && targetIndex != -1)
                    {
                        break;
                    }
                }

                writer.Write(sourceIndex);
                writer.Write(separator);
                writer.Write(targetIndex);

                writer.WriteLine();
            }

            writer.Close();
        }