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(); }
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 } }