private void MarshalInputAndOutput(SpanFillInput input, SpanFillResult ret, Block block, BlockIR_SP bir)
 {
     if (bir.GetIsFirst())
     {
         input.width = block.actualWidth;
         input.height = block.actualHeight;
         input.depth = block.actualDepth;
         input.data = buffer;
         input.seed = bir.singleSeed;
         input.mask = block.boundaryMask;
         input.flagsMap = block.GetFlagMap3d();
         input.overstepPointList = null;
         input.overstepRangeList = null;
         ret.resultCount=0;
         ret.resultSet.Clear();
     }
     else
     {
         input.width = block.actualWidth;
         input.height = block.actualHeight;
         input.depth = block.actualDepth;
         input.data = buffer;
         input.mask = block.boundaryMask;
         input.flagsMap = block.GetFlagMap3d();
         input.seed = new Int16Triple(-1, -1, -1);
         input.overstepPointList = bir.boundarySeedXsInside;
         input.overstepRangeList = bir.boundaryRangesYZInside;
         ret.resultCount = 0;
         ret.resultSet.Clear();
     }
 }
 public void MergeResult(LargeSeededGrowResult lsg, SpanFillResult ret)
 {
     lsg.resultSet.AddRange(ret.resultSet);
     lsg.Count += ret.resultCount;
 }
        public void ExecuteSeededGrow(Int16Triple firstseed)
        {
            if (buffer == null || seedGrowExecutor == null || dataProvider == null)
                throw new Exception();
            SpanFillInput input = new SpanFillInput();
            SpanFillResult ret = new SpanFillResult();
            resultSum = new LargeSeededGrowResult();
            queue = new Container_Stack<Block>();
            Block firstB = GetFirstBlock(firstseed);
            BlockIR_SP firstBir = GetBlockIR(firstB.indexX, firstB.indexY, firstB.indexZ);
            firstBir.singleSeed = ConvertGlobalCoodToBlockCoord(firstB, firstseed);
            queue.Push(firstB);
            while (!queue.Empty())
            {
                Block block = queue.Pop();
                block.VisitedCount++;
                BlockIR_SP bir = GetBlockIR(block.indexX, block.indexY, block.indexZ);
                FillBlockData(block);

                MarshalInputAndOutput(input, ret, block, bir);
                seedGrowExecutor.ExecuteSeededGrow(input, ret);

                if (input.GetIsFirst())
                    bir.singleSeed = new Int16Triple(-1, -1, -1);

                ConvertBlockCoordsToGlobalCoords(block, ret.resultSet);
                MergeResult(resultSum, ret);


                for (int i = 0; i < 2;i++ )
                {
                    if (ret.GetNeedsToSeekX(i))
                    {
                        Block t = image.GetBlock(block.indexX + AdX[i].X, block.indexY, block.indexZ);
                        if (t.VisitedCount < 1)
                        {
                            ConvertThisBlockCoordsToOtherBlockCoords(block, t, ret.boundaryPoints_X[i]);
                            BlockIR_SP tbir = GetBlockIR(t.indexX, t.indexY, t.indexZ);
                            List<Int16Triple> oppInput = tbir.boundarySeedXsInside[OppositePos_X[i]];
                            if (oppInput != null && oppInput.Count != 0)
                            {
                                oppInput.AddRange(ret.boundaryPoints_X[i]);
                                ret.boundaryPoints_X[i].Clear();
                                tbir.boundarySeedXsInside[OppositePos_X[i]] = oppInput;
                            }
                            else
                            {
                                oppInput = ret.boundaryPoints_X[i];
                                ret.boundaryPoints_X[i] = new List<Int16Triple>();
                                tbir.boundarySeedXsInside[OppositePos_X[i]] = oppInput;
                            }
                            queue.Push(t);
                        }
                        else
                        {
                            ret.boundaryPoints_X[i].Clear();
                        }
                    }
                }
                for (int i = 0; i < 4; i++)
                {
                    if (ret.GetNeedsToSeekYZ(i))
                    {
                        Block t = image.GetBlock(block.indexX, block.indexY + AdYZ[i].Y, block.indexZ + AdYZ[i].Z);
                        if (t.VisitedCount < 1000)
                        {
                            ConvertThisBlockRangesToOtherBlockRanges(block, t, ret.boundaryRanges_YZ[i]);
                            BlockIR_SP tbir = GetBlockIR(t.indexX, t.indexY, t.indexZ);
                            List<Range> oppInput = tbir.boundaryRangesYZInside[OppositePos_YZ[i]];
                            if (oppInput != null && oppInput.Count != 0)
                            {
                                oppInput.AddRange(ret.boundaryRanges_YZ[i]);
                                ret.boundaryRanges_YZ[i].Clear();
                                tbir.boundaryRangesYZInside[OppositePos_YZ[i]] = oppInput;
                            }
                            else
                            {
                                oppInput = ret.boundaryRanges_YZ[i];
                                ret.boundaryRanges_YZ[i] = new List<Range>();
                                tbir.boundaryRangesYZInside[OppositePos_YZ[i]] = oppInput;
                            }
                            queue.Push(t);
                        }
                        else
                        {
                            ret.boundaryRanges_YZ[i].Clear();
                        }
                    }
                }
                input.ClearAll();
            }
            ClearTail();
        }
Ejemplo n.º 4
0
        public virtual void ExecuteSeededGrow(SpanFillInput input, SpanFillResult ret)
        {
            this.data = new BitMap3d(input.data, input.width, input.height, input.depth);
            if (input.flagsMap == null)
            {
                this.flagsMap = new FlagMap3d(input.width, input.height, input.depth);
            }
            else
            {
                this.flagsMap = input.flagsMap;
            }
            this.result = ret;
            this.mask   = input.mask;

            if (input.GetIsFirst())
            {
                ProcessFirstSeed(input);
            }
            else
            {
                ProcessYZSeedRanges(input);
                ProcessXSeeds(input);
            }

            while (!container.Empty())
            {
                Span span = container.Pop();
                #region AllRez
                if (span.Extended == ExtendTypes.AllRez)
                {
                    if (span.ParentDirection == ParentDirections.Y2)
                    {
                        if (span.Y - 1 >= 0)//[spx-spy,y-1,z]
                        {
                            CheckRange(span.XLeft, span.XRight, span.Y - 1, span.Z, ParentDirections.Y2);
                        }
                        else
                        {
                            OnOverstepY0RangeFound(span.XLeft, span.XRight, span.Y - 1, span.Z);
                        }

                        if (span.Z - 1 >= 0)//[spx-spy,y,z-1]
                        {
                            CheckRange(span.XLeft, span.XRight, span.Y, span.Z - 1, ParentDirections.Z2);
                        }
                        else
                        {
                            OnOverstepZ0RangeFound(span.XLeft, span.XRight, span.Y, span.Z - 1);
                        }

                        if (span.Z + 1 < data.depth)//[spx-spy,y,z+1]
                        {
                            CheckRange(span.XLeft, span.XRight, span.Y, span.Z + 1, ParentDirections.Z0);
                        }
                        else
                        {
                            OnOverstepZ2RangeFound(span.XLeft, span.XRight, span.Y, span.Z + 1);
                        }
                        continue;
                    }
                    if (span.ParentDirection == ParentDirections.Y0)
                    {
                        if (span.Y + 1 < data.height)//[spx-spy,y+1,z]
                        {
                            CheckRange(span.XLeft, span.XRight, span.Y + 1, span.Z, ParentDirections.Y0);
                        }
                        else
                        {
                            OnOverstepY2RangeFound(span.XLeft, span.XRight, span.Y + 1, span.Z);
                        }

                        if (span.Z - 1 >= 0)//[spx-spy,y,z-1]
                        {
                            CheckRange(span.XLeft, span.XRight, span.Y, span.Z - 1, ParentDirections.Z2);
                        }
                        else
                        {
                            OnOverstepZ0RangeFound(span.XLeft, span.XRight, span.Y, span.Z - 1);
                        }

                        if (span.Z + 1 < data.depth)//[spx-spy,y,z+1]
                        {
                            CheckRange(span.XLeft, span.XRight, span.Y, span.Z + 1, ParentDirections.Z0);
                        }
                        else
                        {
                            OnOverstepZ2RangeFound(span.XLeft, span.XRight, span.Y, span.Z + 1);
                        }
                        continue;
                    }
                    if (span.ParentDirection == ParentDirections.Z2)
                    {
                        if (span.Y - 1 >= 0)//[spx-spy,y-1,z]
                        {
                            CheckRange(span.XLeft, span.XRight, span.Y - 1, span.Z, ParentDirections.Y2);
                        }
                        else
                        {
                            OnOverstepY0RangeFound(span.XLeft, span.XRight, span.Y - 1, span.Z);
                        }

                        if (span.Y + 1 < data.height)//[spx-spy,y+1,z]
                        {
                            CheckRange(span.XLeft, span.XRight, span.Y + 1, span.Z, ParentDirections.Y0);
                        }
                        else
                        {
                            OnOverstepY2RangeFound(span.XLeft, span.XRight, span.Y + 1, span.Z);
                        }

                        if (span.Z - 1 >= 0)//[spx-spy,y,z-1]
                        {
                            CheckRange(span.XLeft, span.XRight, span.Y, span.Z - 1, ParentDirections.Z2);
                        }
                        else
                        {
                            OnOverstepZ0RangeFound(span.XLeft, span.XRight, span.Y, span.Z - 1);
                        }
                        continue;
                    }
                    if (span.ParentDirection == ParentDirections.Z0)
                    {
                        if (span.Y - 1 >= 0)
                        {
                            CheckRange(span.XLeft, span.XRight, span.Y - 1, span.Z, ParentDirections.Y2);
                        }
                        else
                        {
                            OnOverstepY0RangeFound(span.XLeft, span.XRight, span.Y - 1, span.Z);
                        }

                        if (span.Y + 1 < data.height)
                        {
                            CheckRange(span.XLeft, span.XRight, span.Y + 1, span.Z, ParentDirections.Y0);
                        }
                        else
                        {
                            OnOverstepY2RangeFound(span.XLeft, span.XRight, span.Y + 1, span.Z);
                        }

                        if (span.Z + 1 < data.depth)
                        {
                            CheckRange(span.XLeft, span.XRight, span.Y, span.Z + 1, ParentDirections.Z0);
                        }
                        else
                        {
                            OnOverstepZ2RangeFound(span.XLeft, span.XRight, span.Y, span.Z + 1);
                        }
                        continue;
                    }
                    throw new Exception();
                }
                #endregion
                #region UnRez
                if (span.Extended == ExtendTypes.UnRez)
                {
                    int xl = FindXLeft(span.XLeft, span.Y, span.Z);
                    int xr = FindXRight(span.XRight, span.Y, span.Z);
                    if (span.ParentDirection == ParentDirections.Y2)
                    {
                        if (span.Y - 1 >= 0)
                        {
                            CheckRange(xl, xr, span.Y - 1, span.Z, ParentDirections.Y2);
                        }
                        else
                        {
                            OnOverstepY0RangeFound(xl, xr, span.Y - 1, span.Z);
                        }

                        if (span.Y + 1 < data.height)
                        {
                            if (xl != span.XLeft)
                            {
                                CheckRange(xl, span.XLeft, span.Y + 1, span.Z, ParentDirections.Y0);
                            }
                            if (span.XRight != xr)
                            {
                                CheckRange(span.XRight, xr, span.Y + 1, span.Z, ParentDirections.Y0);
                            }
                        }
                        else
                        {
                            if (xl != span.XLeft)
                            {
                                OnOverstepY2RangeFound(xl, span.XLeft, span.Y + 1, span.Z);
                            }
                            if (span.XRight != xr)
                            {
                                OnOverstepY2RangeFound(span.XRight, xr, span.Y + 1, span.Z);
                            }
                        }

                        if (span.Z - 1 >= 0)
                        {
                            CheckRange(xl, xr, span.Y, span.Z - 1, ParentDirections.Z2);
                        }
                        else
                        {
                            OnOverstepZ0RangeFound(xl, xr, span.Y, span.Z - 1);
                        }

                        if (span.Z + 1 < data.depth)
                        {
                            CheckRange(xl, xr, span.Y, span.Z + 1, ParentDirections.Z0);
                        }
                        else
                        {
                            OnOverstepZ2RangeFound(xl, xr, span.Y, span.Z + 1);
                        }
                        continue;
                    }
                    if (span.ParentDirection == ParentDirections.Y0)
                    {
                        if (span.Y + 1 < data.height)
                        {
                            CheckRange(xl, xr, span.Y + 1, span.Z, ParentDirections.Y0);
                        }
                        else
                        {
                            OnOverstepY2RangeFound(xl, xr, span.Y + 1, span.Z);
                        }

                        if (span.Y - 1 >= 0)
                        {
                            if (xl != span.XLeft)
                            {
                                CheckRange(xl, span.XLeft, span.Y - 1, span.Z, ParentDirections.Y2);
                            }
                            if (span.XRight != xr)
                            {
                                CheckRange(span.XRight, xr, span.Y - 1, span.Z, ParentDirections.Y2);
                            }
                        }
                        else
                        {
                            if (xl != span.XLeft)
                            {
                                OnOverstepY0RangeFound(xl, span.XLeft, span.Y - 1, span.Z);
                            }
                            if (span.XRight != xr)
                            {
                                OnOverstepY0RangeFound(span.XRight, xr, span.Y - 1, span.Z);
                            }
                        }

                        if (span.Z - 1 >= 0)
                        {
                            CheckRange(xl, xr, span.Y, span.Z - 1, ParentDirections.Z2);
                        }
                        else
                        {
                            OnOverstepZ0RangeFound(xl, xr, span.Y, span.Z - 1);
                        }

                        if (span.Z + 1 < data.depth)
                        {
                            CheckRange(xl, xr, span.Y, span.Z + 1, ParentDirections.Z0);
                        }
                        else
                        {
                            OnOverstepZ2RangeFound(xl, xr, span.Y, span.Z + 1);
                        }
                        continue;
                    }
                    if (span.ParentDirection == ParentDirections.Z2)
                    {
                        if (span.Y - 1 >= 0)
                        {
                            CheckRange(xl, xr, span.Y - 1, span.Z, ParentDirections.Y2);
                        }
                        else
                        {
                            OnOverstepY0RangeFound(xl, xr, span.Y - 1, span.Z);
                        }

                        if (span.Y + 1 < data.height)
                        {
                            CheckRange(xl, xr, span.Y + 1, span.Z, ParentDirections.Y0);
                        }
                        else
                        {
                            OnOverstepY2RangeFound(xl, xr, span.Y + 1, span.Z);
                        }

                        if (span.Z - 1 >= 0)
                        {
                            CheckRange(xl, xr, span.Y, span.Z - 1, ParentDirections.Z2);
                        }
                        else
                        {
                            OnOverstepZ0RangeFound(xl, xr, span.Y, span.Z - 1);
                        }

                        if (span.Z + 1 < data.depth)
                        {
                            if (xl != span.XLeft)
                            {
                                CheckRange(xl, span.XLeft, span.Y, span.Z + 1, ParentDirections.Z0);
                            }
                            if (span.XRight != xr)
                            {
                                CheckRange(span.XRight, xr, span.Y, span.Z + 1, ParentDirections.Z0);
                            }
                        }
                        else
                        {
                            if (xl != span.XLeft)
                            {
                                OnOverstepZ2RangeFound(xl, span.XLeft, span.Y, span.Z + 1);
                            }
                            if (span.XRight != xr)
                            {
                                OnOverstepZ2RangeFound(span.XRight, xr, span.Y, span.Z + 1);
                            }
                        }
                        continue;
                    }
                    if (span.ParentDirection == ParentDirections.Z0)
                    {
                        if (span.Y - 1 >= 0)
                        {
                            CheckRange(xl, xr, span.Y - 1, span.Z, ParentDirections.Y2);
                        }
                        else
                        {
                            OnOverstepY0RangeFound(xl, xr, span.Y - 1, span.Z);
                        }

                        if (span.Y + 1 < data.height)
                        {
                            CheckRange(xl, xr, span.Y + 1, span.Z, ParentDirections.Y0);
                        }
                        else
                        {
                            OnOverstepY2RangeFound(xl, xr, span.Y + 1, span.Z);
                        }

                        if (span.Z - 1 >= 0)
                        {
                            if (xl != span.XLeft)
                            {
                                CheckRange(xl, span.XLeft, span.Y, span.Z - 1, ParentDirections.Z2);
                            }
                            if (span.XRight != xr)
                            {
                                CheckRange(span.XRight, xr, span.Y, span.Z - 1, ParentDirections.Z2);
                            }
                        }
                        else
                        {
                            if (xl != span.XLeft)
                            {
                                OnOverstepZ0RangeFound(xl, span.XLeft, span.Y, span.Z - 1);
                            }
                            if (span.XRight != xr)
                            {
                                OnOverstepZ0RangeFound(span.XRight, xr, span.Y, span.Z - 1);
                            }
                        }

                        if (span.Z + 1 < data.depth)
                        {
                            CheckRange(xl, xr, span.Y, span.Z + 1, ParentDirections.Z0);
                        }
                        else
                        {
                            OnOverstepZ2RangeFound(xl, xr, span.Y, span.Z + 1);
                        }

                        continue;
                    }
                    if (span.ParentDirection == ParentDirections.Non)
                    {
                        if (span.Y + 1 < data.height)
                        {
                            CheckRange(xl, xr, span.Y + 1, span.Z, ParentDirections.Y0);
                        }
                        else
                        {
                            OnOverstepY2RangeFound(xl, xr, span.Y + 1, span.Z);
                        }

                        if (span.Y - 1 >= 0)
                        {
                            CheckRange(xl, xr, span.Y - 1, span.Z, ParentDirections.Y2);
                        }
                        else
                        {
                            OnOverstepY0RangeFound(xl, xr, span.Y - 1, span.Z);
                        }

                        if (span.Z - 1 >= 0)
                        {
                            CheckRange(xl, xr, span.Y, span.Z - 1, ParentDirections.Z2);
                        }
                        else
                        {
                            OnOverstepZ0RangeFound(xl, xr, span.Y, span.Z - 1);
                        }

                        if (span.Z + 1 < data.depth)
                        {
                            CheckRange(xl, xr, span.Y, span.Z + 1, ParentDirections.Z0);
                        }
                        else
                        {
                            OnOverstepZ2RangeFound(xl, xr, span.Y, span.Z + 1);
                        }
                        continue;
                    }
                    throw new Exception();
                }
                #endregion
                #region LeftRequired
                if (span.Extended == ExtendTypes.LeftRequired)
                {
                    int xl = FindXLeft(span.XLeft, span.Y, span.Z);
                    if (span.ParentDirection == ParentDirections.Y2)
                    {
                        if (span.Y - 1 >= 0)
                        {
                            CheckRange(xl, span.XRight, span.Y - 1, span.Z, ParentDirections.Y2);
                        }
                        else
                        {
                            OnOverstepY0RangeFound(xl, span.XRight, span.Y - 1, span.Z);
                        }

                        if (span.Y + 1 < data.height && xl != span.XLeft)
                        {
                            CheckRange(xl, span.XLeft, span.Y + 1, span.Z, ParentDirections.Y0);
                        }
                        else if (xl != span.XLeft)
                        {
                            OnOverstepY2RangeFound(xl, span.XLeft, span.Y + 1, span.Z);
                        }

                        if (span.Z - 1 >= 0)
                        {
                            CheckRange(xl, span.XRight, span.Y, span.Z - 1, ParentDirections.Z2);
                        }
                        else
                        {
                            OnOverstepZ0RangeFound(xl, span.XRight, span.Y, span.Z - 1);
                        }

                        if (span.Z + 1 < data.depth)
                        {
                            CheckRange(xl, span.XRight, span.Y, span.Z + 1, ParentDirections.Z0);
                        }
                        else
                        {
                            OnOverstepZ2RangeFound(xl, span.XRight, span.Y, span.Z + 1);
                        }
                        continue;
                    }
                    if (span.ParentDirection == ParentDirections.Y0)
                    {
                        if (span.Y - 1 >= 0 && xl != span.XLeft)
                        {
                            CheckRange(xl, span.XLeft, span.Y - 1, span.Z, ParentDirections.Y2);
                        }
                        else if (xl != span.XLeft)
                        {
                            OnOverstepY0RangeFound(xl, span.XLeft, span.Y - 1, span.Z);
                        }

                        if (span.Y + 1 < data.height)
                        {
                            CheckRange(xl, span.XRight, span.Y + 1, span.Z, ParentDirections.Y0);
                        }
                        else
                        {
                            OnOverstepY2RangeFound(xl, span.XRight, span.Y + 1, span.Z);
                        }

                        if (span.Z - 1 >= 0)
                        {
                            CheckRange(xl, span.XRight, span.Y, span.Z - 1, ParentDirections.Z2);
                        }
                        else
                        {
                            OnOverstepZ0RangeFound(xl, span.XRight, span.Y, span.Z - 1);
                        }

                        if (span.Z + 1 < data.depth)
                        {
                            CheckRange(xl, span.XRight, span.Y, span.Z + 1, ParentDirections.Z0);
                        }
                        else
                        {
                            OnOverstepZ2RangeFound(xl, span.XRight, span.Y, span.Z + 1);
                        }
                        continue;
                    }
                    if (span.ParentDirection == ParentDirections.Z2)
                    {
                        if (span.Y - 1 >= 0)
                        {
                            CheckRange(xl, span.XRight, span.Y - 1, span.Z, ParentDirections.Y2);
                        }
                        else
                        {
                            OnOverstepY0RangeFound(xl, span.XRight, span.Y - 1, span.Z);
                        }

                        if (span.Y + 1 < data.height)
                        {
                            CheckRange(xl, span.XRight, span.Y + 1, span.Z, ParentDirections.Y0);
                        }
                        else
                        {
                            OnOverstepY2RangeFound(xl, span.XRight, span.Y + 1, span.Z);
                        }

                        if (span.Z - 1 >= 0)
                        {
                            CheckRange(xl, span.XRight, span.Y, span.Z - 1, ParentDirections.Z2);
                        }
                        else
                        {
                            OnOverstepZ0RangeFound(xl, span.XRight, span.Y, span.Z - 1);
                        }

                        if (span.Z + 1 < data.depth && xl != span.XLeft)
                        {
                            CheckRange(xl, span.XLeft, span.Y, span.Z + 1, ParentDirections.Z0);
                        }
                        else if (xl != span.XLeft)
                        {
                            OnOverstepZ2RangeFound(xl, span.XLeft, span.Y, span.Z + 1);
                        }
                        continue;
                    }
                    if (span.ParentDirection == ParentDirections.Z0)
                    {
                        if (span.Y - 1 >= 0)
                        {
                            CheckRange(xl, span.XRight, span.Y - 1, span.Z, ParentDirections.Y2);
                        }
                        else
                        {
                            OnOverstepY0RangeFound(xl, span.XRight, span.Y - 1, span.Z);
                        }

                        if (span.Y + 1 < data.height)
                        {
                            CheckRange(xl, span.XRight, span.Y + 1, span.Z, ParentDirections.Y0);
                        }
                        else
                        {
                            OnOverstepY2RangeFound(xl, span.XRight, span.Y + 1, span.Z);
                        }

                        if (span.Z - 1 >= 0 && xl != span.XLeft)
                        {
                            CheckRange(xl, span.XLeft, span.Y, span.Z - 1, ParentDirections.Z2);
                        }
                        else if (xl != span.XLeft)
                        {
                            OnOverstepZ0RangeFound(xl, span.XLeft, span.Y, span.Z - 1);
                        }

                        if (span.Z + 1 < data.depth)
                        {
                            CheckRange(xl, span.XRight, span.Y, span.Z + 1, ParentDirections.Z0);
                        }
                        else
                        {
                            OnOverstepZ2RangeFound(xl, span.XRight, span.Y, span.Z + 1);
                        }
                        continue;
                    }
                    throw new Exception();
                }
                #endregion
                #region RightRequired
                if (span.Extended == ExtendTypes.RightRequired)
                {
                    int xr = FindXRight(span.XRight, span.Y, span.Z);

                    if (span.ParentDirection == ParentDirections.Y2)
                    {
                        if (span.Y - 1 >= 0)
                        {
                            CheckRange(span.XLeft, xr, span.Y - 1, span.Z, ParentDirections.Y2);
                        }
                        else
                        {
                            OnOverstepY0RangeFound(span.XLeft, xr, span.Y - 1, span.Z);
                        }

                        if (span.Y + 1 < data.height && span.XRight != xr)
                        {
                            CheckRange(span.XRight, xr, span.Y + 1, span.Z, ParentDirections.Y0);
                        }
                        else if (span.XRight != xr)
                        {
                            OnOverstepY2RangeFound(span.XRight, xr, span.Y + 1, span.Z);
                        }

                        if (span.Z - 1 >= 0)
                        {
                            CheckRange(span.XLeft, xr, span.Y, span.Z - 1, ParentDirections.Z2);
                        }
                        else
                        {
                            OnOverstepZ0RangeFound(span.XLeft, xr, span.Y, span.Z - 1);
                        }

                        if (span.Z + 1 < data.depth)
                        {
                            CheckRange(span.XLeft, xr, span.Y, span.Z + 1, ParentDirections.Z0);
                        }
                        else
                        {
                            OnOverstepZ2RangeFound(span.XLeft, xr, span.Y, span.Z + 1);
                        }
                        continue;
                    }

                    if (span.ParentDirection == ParentDirections.Y0)
                    {
                        if (span.Y + 1 < data.height)
                        {
                            CheckRange(span.XLeft, xr, span.Y + 1, span.Z, ParentDirections.Y0);
                        }
                        else
                        {
                            OnOverstepY2RangeFound(span.XLeft, xr, span.Y + 1, span.Z);
                        }

                        if (span.Y - 1 >= 0 && span.XRight != xr)
                        {
                            CheckRange(span.XRight, xr, span.Y - 1, span.Z, ParentDirections.Y2);
                        }
                        else if (span.XRight != xr)
                        {
                            OnOverstepY0RangeFound(span.XRight, xr, span.Y - 1, span.Z);
                        }

                        if (span.Z - 1 >= 0)
                        {
                            CheckRange(span.XLeft, xr, span.Y, span.Z - 1, ParentDirections.Z2);
                        }
                        else
                        {
                            OnOverstepZ0RangeFound(span.XLeft, xr, span.Y, span.Z - 1);
                        }

                        if (span.Z + 1 < data.depth)
                        {
                            CheckRange(span.XLeft, xr, span.Y, span.Z + 1, ParentDirections.Z0);
                        }
                        else
                        {
                            OnOverstepZ2RangeFound(span.XLeft, xr, span.Y, span.Z + 1);
                        }
                        continue;
                    }
                    if (span.ParentDirection == ParentDirections.Z2)
                    {
                        if (span.Y - 1 >= 0)
                        {
                            CheckRange(span.XLeft, xr, span.Y - 1, span.Z, ParentDirections.Y2);
                        }
                        else
                        {
                            OnOverstepY0RangeFound(span.XLeft, xr, span.Y - 1, span.Z);
                        }

                        if (span.Y + 1 < data.height)
                        {
                            CheckRange(span.XLeft, xr, span.Y + 1, span.Z, ParentDirections.Y0);
                        }
                        else
                        {
                            OnOverstepY2RangeFound(span.XLeft, xr, span.Y + 1, span.Z);
                        }

                        if (span.Z - 1 >= 0)
                        {
                            CheckRange(span.XLeft, xr, span.Y, span.Z - 1, ParentDirections.Z2);
                        }
                        else
                        {
                            OnOverstepZ0RangeFound(span.XLeft, xr, span.Y, span.Z - 1);
                        }

                        if (span.Z + 1 < data.depth && span.XRight != xr)
                        {
                            CheckRange(span.XRight, xr, span.Y, span.Z + 1, ParentDirections.Z0);
                        }
                        else if (span.XRight != xr)
                        {
                            OnOverstepZ2RangeFound(span.XRight, xr, span.Y, span.Z + 1);
                        }
                        continue;
                    }
                    if (span.ParentDirection == ParentDirections.Z0)
                    {
                        if (span.Y - 1 >= 0)
                        {
                            CheckRange(span.XLeft, xr, span.Y - 1, span.Z, ParentDirections.Y2);
                        }
                        else
                        {
                            OnOverstepY0RangeFound(span.XLeft, xr, span.Y - 1, span.Z);
                        }

                        if (span.Y + 1 < data.height)
                        {
                            CheckRange(span.XLeft, xr, span.Y + 1, span.Z, ParentDirections.Y0);
                        }
                        else
                        {
                            OnOverstepY2RangeFound(span.XLeft, xr, span.Y + 1, span.Z);
                        }

                        if (span.Z - 1 >= 0 && span.XRight != xr)
                        {
                            CheckRange(span.XRight, xr, span.Y, span.Z - 1, ParentDirections.Z2);
                        }
                        else if (span.XRight != xr)
                        {
                            OnOverstepZ0RangeFound(span.XRight, xr, span.Y, span.Z - 1);
                        }

                        if (span.Z + 1 < data.depth)
                        {
                            CheckRange(span.XLeft, xr, span.Y, span.Z + 1, ParentDirections.Z0);
                        }
                        else
                        {
                            OnOverstepZ2RangeFound(span.XLeft, xr, span.Y, span.Z + 1);
                        }
                        continue;
                    }
                    throw new Exception();
                }
                #endregion
            }
        }