protected void CheckRange(int xleft, int xright, int y, int z, ParentDirections ptype) { for (int i = xleft; i <= xright;) { if ((!flagsMap.GetFlagOn(i, y, z)) && IncludePredicate(i, y, z)) { int lb = i; int rb = i + 1; while (rb <= xright && (!flagsMap.GetFlagOn(rb, y, z)) && IncludePredicate(rb, y, z)) { rb++; } rb--; Span span = new Span(); span.XLeft = lb; span.XRight = rb; span.Y = y; span.Z = z; if (lb == xleft && rb == xright) { span.Extended = ExtendTypes.UnRez; } else if (rb == xright) { span.Extended = ExtendTypes.RightRequired; } else if (lb == xleft) { span.Extended = ExtendTypes.LeftRequired; } else { span.Extended = ExtendTypes.AllRez; } span.ParentDirection = ptype; for (int j = lb; j <= rb; j++) { flagsMap.SetFlagOn(j, y, z, true); Process(new Int16Triple(j, y, z)); } container.Push(span); i = rb + 1; } else { i++; } } }//区段法的CheckRange 注意与扫描线的CheckRange的不同
private void CheckRange(int xleft, int xright, int y, int z, ParentDirections ptype) { for (int i = xleft; i <= xright;) { if (IncludePredicate(i, y, z)) { int lb = i; int rb = i + 1; while (rb <= xright && (IncludePredicate(rb, y, z))) { rb++; } rb--; Span span = new Span(); span.XLeft = lb; span.XRight = rb; span.Y = y; span.Z = z; if (lb == xleft && rb == xright) { span.Extended = ExtendTypes.UnRez; } else if (rb == xright) { span.Extended = ExtendTypes.RightRequired; } else if (lb == xleft) { span.Extended = ExtendTypes.LeftRequired; } else { span.Extended = ExtendTypes.AllRez; } span.ParentDirection = ptype; for (int j = lb; j <= rb; j++) { Process(j, y, z); } container.Push(span); i = rb + 1; } else { i++; } } }
protected void OnOverstepSpanFound(int xleft, int xright, int y, int z, ParentDirections ptype, ref SpanFillResult ret) { if (z == -1) { Range r = new Range(xleft, xright, y, z); ret.boundaryRequestPoints[0].Add(r); } else if (z == data.depth) { Range r = new Range(xleft, xright, y, z); ret.boundaryRequestPoints[1].Add(r); } else { throw new Exception(); } }
public virtual SpanFillResult ExecuteSeededGrow(SpanFillInput input) { this.data = new BitMap3d(input.data, input.width, input.height, input.depth); flagsMap = input.flag; //result.Clear() resultCount = 0; container.Clear(); SpanFillResult ret = new SpanFillResult(); ret.Init(); if (input.IsFirst) { Int16Triple seed = input.seed; Process(seed); flagsMap.SetFlagOn(seed.X, seed.Y, seed.Z, true); Span seedspan = new Span(); seedspan.XLeft = seed.X; seedspan.XRight = seed.X; seedspan.Y = seed.Y; seedspan.Z = seed.Z; seedspan.ParentDirection = ParentDirections.Non; seedspan.Extended = ExtendTypes.UnRez; container.Push(seedspan); } else { ParentDirections p = (input.spanlist[0].Z == 0) ? ParentDirections.Z0 : ParentDirections.Z2; for (int i = 0; i < input.spanlist.Count; i++) { Range r = input.spanlist[i]; CheckRange(r.XLeft, r.XRight, r.Y, r.Z, p); } } 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); } if (span.Z - 1 >= 0)//[spx-spy,y,z-1] { CheckRange(span.XLeft, span.XRight, span.Y, span.Z - 1, ParentDirections.Z2); } else { OnOverstepSpanFound(span.XLeft, span.XRight, span.Y, span.Z - 1, ParentDirections.Z2, ref ret); } if (span.Z + 1 < data.depth)//[spx-spy,y,z+1] { CheckRange(span.XLeft, span.XRight, span.Y, span.Z + 1, ParentDirections.Z0); } else { OnOverstepSpanFound(span.XLeft, span.XRight, span.Y, span.Z + 1, ParentDirections.Z0, ref ret); } 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); } if (span.Z - 1 >= 0)//[spx-spy,y,z-1] { CheckRange(span.XLeft, span.XRight, span.Y, span.Z - 1, ParentDirections.Z2); } else { OnOverstepSpanFound(span.XLeft, span.XRight, span.Y, span.Z - 1, ParentDirections.Z2, ref ret); } if (span.Z + 1 < data.depth)//[spx-spy,y,z+1] { CheckRange(span.XLeft, span.XRight, span.Y, span.Z + 1, ParentDirections.Z0); } else { OnOverstepSpanFound(span.XLeft, span.XRight, span.Y, span.Z + 1, ParentDirections.Z0, ref ret); } 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); } if (span.Y + 1 < data.height)//[spx-spy,y+1,z] { CheckRange(span.XLeft, span.XRight, span.Y + 1, span.Z, ParentDirections.Y0); } if (span.Z - 1 >= 0)//[spx-spy,y,z-1] { CheckRange(span.XLeft, span.XRight, span.Y, span.Z - 1, ParentDirections.Z2); } else { OnOverstepSpanFound(span.XLeft, span.XRight, span.Y, span.Z - 1, ParentDirections.Z2, ref ret); } continue; } if (span.ParentDirection == ParentDirections.Z0) { if (span.Y - 1 >= 0) { CheckRange(span.XLeft, span.XRight, span.Y - 1, span.Z, ParentDirections.Y2); } if (span.Y + 1 < data.height) { CheckRange(span.XLeft, span.XRight, span.Y + 1, span.Z, ParentDirections.Y0); } if (span.Z + 1 < data.depth) { CheckRange(span.XLeft, span.XRight, span.Y, span.Z + 1, ParentDirections.Z0); } else { OnOverstepSpanFound(span.XLeft, span.XRight, span.Y, span.Z + 1, ParentDirections.Z0, ref ret); } 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); } 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); } } if (span.Z - 1 >= 0) { CheckRange(xl, xr, span.Y, span.Z - 1, ParentDirections.Z2); } else { OnOverstepSpanFound(xl, xr, span.Y, span.Z - 1, ParentDirections.Z2, ref ret); } if (span.Z + 1 < data.depth) { CheckRange(xl, xr, span.Y, span.Z + 1, ParentDirections.Z0); } else { OnOverstepSpanFound(xl, xr, span.Y, span.Z + 1, ParentDirections.Z0, ref ret); } continue; } if (span.ParentDirection == ParentDirections.Y0) { if (span.Y + 1 < data.height) { CheckRange(xl, xr, span.Y + 1, span.Z, ParentDirections.Y0); } 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); } } if (span.Z - 1 >= 0) { CheckRange(xl, xr, span.Y, span.Z - 1, ParentDirections.Z2); } else { OnOverstepSpanFound(xl, xr, span.Y, span.Z - 1, ParentDirections.Z2, ref ret); } if (span.Z + 1 < data.depth) { CheckRange(xl, xr, span.Y, span.Z + 1, ParentDirections.Z0); } else { OnOverstepSpanFound(xl, xr, span.Y, span.Z + 1, ParentDirections.Z0, ref ret); } continue; } if (span.ParentDirection == ParentDirections.Z2) { if (span.Y - 1 >= 0) { CheckRange(xl, xr, span.Y - 1, span.Z, ParentDirections.Y2); } if (span.Y + 1 < data.height) { CheckRange(xl, xr, span.Y + 1, span.Z, ParentDirections.Y0); } if (span.Z - 1 >= 0) { CheckRange(xl, xr, span.Y, span.Z - 1, ParentDirections.Z2); } else { OnOverstepSpanFound(xl, xr, span.Y, span.Z - 1, ParentDirections.Z2, ref ret); } 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) { OnOverstepSpanFound(xl, span.XLeft, span.Y, span.Z + 1, ParentDirections.Z0, ref ret); } if (span.XRight != xr) { OnOverstepSpanFound(span.XRight, xr, span.Y, span.Z + 1, ParentDirections.Z0, ref ret); } } continue; } if (span.ParentDirection == ParentDirections.Z0) { if (span.Y - 1 >= 0) { CheckRange(xl, xr, span.Y - 1, span.Z, ParentDirections.Y2); } if (span.Y + 1 < data.height) { CheckRange(xl, xr, span.Y + 1, span.Z, ParentDirections.Y0); } 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) { OnOverstepSpanFound(xl, span.XLeft, span.Y, span.Z - 1, ParentDirections.Z2, ref ret); } if (span.XRight != xr) { OnOverstepSpanFound(span.XRight, xr, span.Y, span.Z - 1, ParentDirections.Z2, ref ret); } } if (span.Z + 1 < data.depth) { CheckRange(xl, xr, span.Y, span.Z + 1, ParentDirections.Z0); } else { OnOverstepSpanFound(xl, xr, span.Y, span.Z + 1, ParentDirections.Z0, ref ret); } continue; } if (span.ParentDirection == ParentDirections.Non) { if (span.Y + 1 < data.height) { CheckRange(xl, xr, span.Y + 1, span.Z, ParentDirections.Y0); } if (span.Y - 1 >= 0) { CheckRange(xl, xr, span.Y - 1, span.Z, ParentDirections.Y2); } if (span.Z - 1 >= 0) { CheckRange(xl, xr, span.Y, span.Z - 1, ParentDirections.Z2); } else { OnOverstepSpanFound(xl, xr, span.Y, span.Z - 1, ParentDirections.Z2, ref ret); } if (span.Z + 1 < data.depth) { CheckRange(xl, xr, span.Y, span.Z + 1, ParentDirections.Z0); } else { OnOverstepSpanFound(xl, xr, span.Y, span.Z + 1, ParentDirections.Z0, ref ret); } 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); } if (span.Y + 1 < data.height && xl != span.XLeft) { CheckRange(xl, span.XLeft, span.Y + 1, span.Z, ParentDirections.Y0); } if (span.Z - 1 >= 0) { CheckRange(xl, span.XRight, span.Y, span.Z - 1, ParentDirections.Z2); } else { OnOverstepSpanFound(xl, span.XRight, span.Y, span.Z - 1, ParentDirections.Z2, ref ret); } if (span.Z + 1 < data.depth) { CheckRange(xl, span.XRight, span.Y, span.Z + 1, ParentDirections.Z0); } else { OnOverstepSpanFound(xl, span.XRight, span.Y, span.Z + 1, ParentDirections.Z0, ref ret); } 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); } if (span.Y + 1 < data.height) { CheckRange(xl, span.XRight, span.Y + 1, span.Z, ParentDirections.Y0); } if (span.Z - 1 >= 0) { CheckRange(xl, span.XRight, span.Y, span.Z - 1, ParentDirections.Z2); } else { OnOverstepSpanFound(xl, span.XRight, span.Y, span.Z - 1, ParentDirections.Z2, ref ret); } if (span.Z + 1 < data.depth) { CheckRange(xl, span.XRight, span.Y, span.Z + 1, ParentDirections.Z0); } else { OnOverstepSpanFound(xl, span.XRight, span.Y, span.Z + 1, ParentDirections.Z0, ref ret); } continue; } if (span.ParentDirection == ParentDirections.Z2) { if (span.Y - 1 >= 0) { CheckRange(xl, span.XRight, span.Y - 1, span.Z, ParentDirections.Y2); } if (span.Y + 1 < data.height) { CheckRange(xl, span.XRight, span.Y + 1, span.Z, ParentDirections.Y0); } if (span.Z - 1 >= 0) { CheckRange(xl, span.XRight, span.Y, span.Z - 1, ParentDirections.Z2); } else { OnOverstepSpanFound(xl, span.XRight, span.Y, span.Z - 1, ParentDirections.Z2, ref ret); } 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) { OnOverstepSpanFound(xl, span.XLeft, span.Y, span.Z + 1, ParentDirections.Z0, ref ret); } continue; } if (span.ParentDirection == ParentDirections.Z0) { if (span.Y - 1 >= 0) { CheckRange(xl, span.XRight, span.Y - 1, span.Z, ParentDirections.Y2); } if (span.Y + 1 < data.height) { CheckRange(xl, span.XRight, span.Y + 1, span.Z, ParentDirections.Y0); } if (span.Z - 1 >= 0 && xl != span.XLeft) { CheckRange(xl, span.XLeft, span.Y, span.Z - 1, ParentDirections.Z2); } else if (xl != span.XLeft) { OnOverstepSpanFound(xl, span.XLeft, span.Y, span.Z - 1, ParentDirections.Z2, ref ret); } if (span.Z + 1 < data.depth) { CheckRange(xl, span.XRight, span.Y, span.Z + 1, ParentDirections.Z0); } else { OnOverstepSpanFound(xl, span.XRight, span.Y, span.Z + 1, ParentDirections.Z0, ref ret); } 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); } if (span.Y + 1 < data.height && span.XRight != xr) { CheckRange(span.XRight, xr, span.Y + 1, span.Z, ParentDirections.Y0); } if (span.Z - 1 >= 0) { CheckRange(span.XLeft, xr, span.Y, span.Z - 1, ParentDirections.Z2); } else { OnOverstepSpanFound(span.XLeft, xr, span.Y, span.Z - 1, ParentDirections.Z2, ref ret); } if (span.Z + 1 < data.depth) { CheckRange(span.XLeft, xr, span.Y, span.Z + 1, ParentDirections.Z0); } else { OnOverstepSpanFound(span.XLeft, xr, span.Y, span.Z + 1, ParentDirections.Z0, ref ret); } continue; } if (span.ParentDirection == ParentDirections.Y0) { if (span.Y + 1 < data.height) { CheckRange(span.XLeft, xr, span.Y + 1, span.Z, ParentDirections.Y0); } if (span.Y - 1 >= 0 && span.XRight != xr) { CheckRange(span.XRight, xr, span.Y - 1, span.Z, ParentDirections.Y2); } if (span.Z - 1 >= 0) { CheckRange(span.XLeft, xr, span.Y, span.Z - 1, ParentDirections.Z2); } else { OnOverstepSpanFound(span.XLeft, xr, span.Y, span.Z - 1, ParentDirections.Z2, ref ret); } if (span.Z + 1 < data.depth) { CheckRange(span.XLeft, xr, span.Y, span.Z + 1, ParentDirections.Z0); } else { OnOverstepSpanFound(span.XLeft, xr, span.Y, span.Z + 1, ParentDirections.Z0, ref ret); } continue; } if (span.ParentDirection == ParentDirections.Z2) { if (span.Y - 1 >= 0) { CheckRange(span.XLeft, xr, span.Y - 1, span.Z, ParentDirections.Y2); } if (span.Y + 1 < data.height) { CheckRange(span.XLeft, xr, span.Y + 1, span.Z, ParentDirections.Y0); } if (span.Z - 1 >= 0) { CheckRange(span.XLeft, xr, span.Y, span.Z - 1, ParentDirections.Z2); } else { OnOverstepSpanFound(span.XLeft, xr, span.Y, span.Z - 1, ParentDirections.Z2, ref ret); } 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) { OnOverstepSpanFound(span.XRight, xr, span.Y, span.Z + 1, ParentDirections.Z0, ref ret); } continue; } if (span.ParentDirection == ParentDirections.Z0) { if (span.Y - 1 >= 0) { CheckRange(span.XLeft, xr, span.Y - 1, span.Z, ParentDirections.Y2); } if (span.Y + 1 < data.height) { CheckRange(span.XLeft, xr, span.Y + 1, span.Z, ParentDirections.Y0); } if (span.Z - 1 >= 0 && span.XRight != xr) { CheckRange(span.XRight, xr, span.Y, span.Z - 1, ParentDirections.Z2); } else if (span.XRight != xr) { OnOverstepSpanFound(span.XRight, xr, span.Y, span.Z - 1, ParentDirections.Z2, ref ret); } if (span.Z + 1 < data.depth) { CheckRange(span.XLeft, xr, span.Y, span.Z + 1, ParentDirections.Z0); } else { OnOverstepSpanFound(span.XLeft, xr, span.Y, span.Z + 1, ParentDirections.Z0, ref ret); } continue; } throw new Exception(); } #endregion } //ret.resultPointSet = this.result; ret.resultCount = this.resultCount; return(ret); }