Пример #1
0
        /// <summary>
        /// Initializes the marching cubes scene by loading the dataset from disk and creating a mesh for it.
        /// </summary>
        public override void Initialize()
        {
            base.Initialize();
            _brush = new NormalBrush();
            _pen   = new SolidColorPen(Color.Black);

            var triangleBuilder = new TriangleMeshDescriptionBuilder();
            // isolevel defines which points are inside/outside the structure
            int lastProgress = 0;

            // for each point we will at all 8 points forming a cube, we will simply take the index + 1 in each direction, thus our iteration counters must be reduced by 1 to prevent out of bound exception
            int xlen = InputData.XLength - 1;
            int ylen = InputData.YLength - 1;
            int zlen = InputData.ZLength - 1;

            var mcAlgo = new MarchingCubesAlgorithm(false);
            var box    = new BoundingBox();

            for (int x = 0; x < xlen; x++)
            {
                for (int y = 0; y < ylen; y++)
                {
                    // report progress here as one dimension by itself would progress really fast (too small increments)
                    var progress    = (y + x * ylen) / (float)(ylen * xlen);
                    var newProgress = (int)(progress * 100);
                    if (newProgress >= 100)
                    {
                        newProgress = 99; // don't send 100 yet, send it only once at the end of the method
                    }
                    if (newProgress != lastProgress)
                    {
                        var p = InitializeProgress;
                        p?.Invoke(this, newProgress);
                        lastProgress = newProgress;
                    }
                    for (int z = 0; z < zlen; z++)
                    {
                        box.Min.X = x;
                        box.Min.Y = y;
                        box.Min.Z = z;
                        box.Max.X = x + 1;
                        box.Max.Y = y + 1;
                        box.Max.Z = z + 1;
                        var vertices = mcAlgo.Polygonize(InputData, _isolevel, box);
                        if (vertices != null && vertices.Count > 0)
                        {
                            triangleBuilder.Vertices.AddRange(vertices);
                        }
                    }
                }
            }
            _dataMesh = RenderContext.MeshCreator.CreateMesh(triangleBuilder);

            var i = InitializeProgress;

            i?.Invoke(this, 100);
            InitializeProgress = null;
            Initialized        = true;
        }
Пример #2
0
        public List <GridCube> Сheck(double from, double to, double step)
        {
            var edgesPerSide = Region3D.GetLenght(from, to) / step;
            var countOfCubes = Math.Pow(edgesPerSide, 3);

            var vertexPerSide      = edgesPerSide + 1;
            var uniqueEdgesPerSide = edgesPerSide * vertexPerSide;

            uniqueEdgesPerSide += uniqueEdgesPerSide;

            var edjesCount = vertexPerSide * uniqueEdgesPerSide + (vertexPerSide * vertexPerSide * edgesPerSide);


            var marchingCubes = new MarchingCubesAlgorithm(null);
            var region        = new CommonTypes.Region3D(from, to, from, to, from, to);
            var cubes         = marchingCubes.BuildGrid(region, step);

            Assert.AreEqual(cubes.Count, countOfCubes);

            var uniqueVertexes = new List <Point>();
            // 18 unique edges
            var lines = new List <GridLine>();

            foreach (var cube in cubes)
            {
                foreach (var edge in cube.Edges)
                {
                    if (!lines.Contains(edge))
                    {
                        lines.Add(edge);
                    }
                }

                foreach (var vert in cube.Vertex)
                {
                    // Check that objects are not created. Exclude overriden values.
                    //if (!uniqueVertexes.Any(p => object.ReferenceEquals(uniqueVertexes, vert)))
                    if (!uniqueVertexes.Contains(vert))
                    {
                        uniqueVertexes.Add(vert);
                    }
                }
            }

            var totalVertexes = vertexPerSide * vertexPerSide * vertexPerSide;

            Assert.AreEqual(uniqueVertexes.Count, totalVertexes);

            Assert.AreEqual(lines.Count, edjesCount);

            // Check last cube vertex
            var firstCube = cubes.FirstOrDefault();

            CheckVertexes(firstCube, from, from + step);
            var lastCube = cubes.LastOrDefault();

            CheckVertexes(lastCube, to - step, to);
            return(cubes);
        }
Пример #3
0
        /// <summary>
        /// Creates a new instance of the visualizer
        /// </summary>
        /// <param name="renderContext"></param>
        /// <param name="inputData"></param>
        /// <param name="isoLevel"></param>
        public VisualizerBackgroundWorker(IRenderContext renderContext, IInputData inputData, int isoLevel)
        {
            _inputData = inputData;
            _isoLevel  = isoLevel;

            _backgroundWorker                     = new BackgroundWorker();
            _backgroundWorker.DoWork             += MarchCube;
            _backgroundWorker.RunWorkerCompleted += CubeMarched;

            _mesh1    = renderContext.MeshCreator.CreateDynamicMesh(PrimitiveType.TriangleList, typeof(VertexPositionNormal), VertexPositionNormal.VertexDeclaration, DynamicMeshUsage.UpdateOften);
            _mesh2    = renderContext.MeshCreator.CreateDynamicMesh(PrimitiveType.TriangleList, typeof(VertexPositionNormal), VertexPositionNormal.VertexDeclaration, DynamicMeshUsage.UpdateOften);
            _vertices = new List <VertexPositionNormal>();
            _marchingCubesAlgorithm = new MarchingCubesAlgorithm(false);

            // setup our indices so we don't have to recheck everytime we need this info
            // technically the marching cube algorithm will run over all cubes, but we will skip all that have 0 as a value

            // precalculate all the indices where data exists
            var data = new List <int>();

            for (int z = 0; z < _inputData.ZLength - 1; z++)
            {
                for (int y = 0; y < _inputData.YLength - 1; y++)
                {
                    for (int x = 0; x < _inputData.XLength - 1; x++)
                    {
                        // skipping doesn't work because it will skip edge cases such as flat surfaces
                        // -> the cube doesn't have any data in it, but is next to one that does -> marching cubes will insert flat pane
                        // if we skip it the final result will contain missing parts
                        //if (_inputData[x, y, z] > 0)
                        {
                            var index = x + _inputData.XLength * (y + z * _inputData.YLength);
                            data.Add(index);
                        }
                    }
                }
            }
            _filledDataIndices          = data.ToArray();
            _primitiveCountPerDataPoint = new int[_filledDataIndices.Length];
        }