/// <summary>
    /// Generate spaces on the voxels that are not inside the parts boudaries, or space or part
    /// The method is inspired by a BFS algorithm, continuously checking the neighbours of the
    /// processed voxels until the minimum area is reached. It is designed to be called in a loop
    /// that feeds the numbering / naming of the spaces
    /// </summary>
    /// <param name="number">Current number of the space</param>
    void GenerateSingleSpace(int number)
    {
        int maximumArea     = 1000; //in voxel ammount
        var availableVoxels = _grid.ActiveVoxelsAsList().Where(v => !_boundaries.Contains(v) && !v.IsOccupied && !v.InSpace).ToList();

        if (availableVoxels.Count == 0)
        {
            return;
        }
        Voxel originVoxel = availableVoxels[0];

        //Initiate a new space
        PPSpace space = new PPSpace(_grid);

        originVoxel.InSpace     = true;
        originVoxel.ParentSpace = space;
        space.Voxels.Add(originVoxel);
        space.Indices.Add(originVoxel.Index);
        //Keep running until the space area is under the minimum
        while (space.Voxels.Count < maximumArea)
        {
            List <Voxel> temp = new List <Voxel>();
            foreach (var voxel in space.Voxels)
            {
                //Get the face neighbours which are available
                var newNeighbours = voxel.GetFaceNeighbours().Where(n => availableVoxels.Contains(n));
                foreach (var neighbour in newNeighbours)
                {
                    var nIndex    = neighbour.Index;
                    var gridVoxel = _grid.Voxels[nIndex.x, nIndex.y, nIndex.z];
                    //Only add the nighbour it its not already in the space
                    //or temp list, is active, not occupied(in a part), or another space
                    if (!space.Voxels.Contains(neighbour) && !temp.Contains(neighbour))
                    {
                        if (gridVoxel.IsActive && !gridVoxel.IsOccupied && !gridVoxel.InSpace)
                        {
                            temp.Add(neighbour);
                        }
                    }
                }
            }
            //Break if the temp list returned empty
            if (temp.Count == 0)
            {
                break;
            }
            //Add found neighbours to the space until it reaches maximum capacity
            foreach (var v in temp)
            {
                if (space.Voxels.Count <= maximumArea)
                {
                    v.InSpace     = true;
                    v.ParentSpace = space;
                    space.Voxels.Add(v);
                    space.Indices.Add(v.Index);
                }
            }
        }
        space.Name = $"Space_{number.ToString()}";
        space.CreateArrow();
        _spaces.Add(space);
    }
    void GenerateSS_NAI(int number)
    {
        //Generate spaces on the voxels that are not inside the parts boudaries, or space or part
        //The method is inspired by a BFS algorithm, continuously checking the neighbours of the
        //processed voxels until the minimum area is reached

        Stopwatch singleSpace = new Stopwatch();

        singleSpace.Start();
        int maximumArea     = 1000; //in voxel ammount
        var availableVoxels = _grid.ActiveVoxelsAsList().Where(v => !_boundaries.Contains(v) && !v.IsOccupied && !v.InSpace).ToList();

        if (availableVoxels.Count == 0)
        {
            return;
        }
        Voxel originVoxel = availableVoxels[0];

        //Initiate a new space
        PPSpace space = new PPSpace(_grid);

        originVoxel.InSpace     = true;
        originVoxel.ParentSpace = space;
        space.Voxels.Add(originVoxel);
        space.Indices.Add(originVoxel.Index);
        //Keep running until the space area is under the minimum
        while (space.Voxels.Count < maximumArea)
        {
            List <Voxel> temp = new List <Voxel>();
            foreach (var voxel in space.Voxels)
            {
                //Get the face neighbours which are available
                var newNeighbours = voxel.GetFaceNeighbours().Where(n => availableVoxels.Contains(n));
                foreach (var neighbour in newNeighbours)
                {
                    var nIndex    = neighbour.Index;
                    var gridVoxel = _grid.Voxels[nIndex.x, nIndex.y, nIndex.z];
                    //Only add the nighbour it its not already in the space
                    //or temp list, is active, not occupied(in a part), or another space
                    if (!space.Voxels.Contains(neighbour) && !temp.Contains(neighbour))
                    {
                        if (gridVoxel.IsActive && !gridVoxel.IsOccupied && !gridVoxel.InSpace)
                        {
                            temp.Add(neighbour);
                        }
                    }
                }
            }
            //Break if the temp list returned empty
            if (temp.Count == 0)
            {
                break;
            }
            //Add found neighbours to the space until it reaches maximum capacity
            foreach (var v in temp)
            {
                if (space.Voxels.Count <= maximumArea)
                {
                    v.InSpace     = true;
                    v.ParentSpace = space;
                    space.Voxels.Add(v);
                    space.Indices.Add(v.Index);
                }
            }
        }
        space.Name = $"Space_{number.ToString()}";
        space.CreateArrow();
        _spaces.Add(space);
        //singleSpace.Stop();
        //_singleSpaceTime = (int)singleSpace.ElapsedMilliseconds;
    }