public static void PaintBucket(this MatrixWorld matrix, Coord coord, float val, float threshold = 0.0001f, int maxIterations = 10) /// Like a paintBucket tool in photoshop /// Fills all zero (lower than threshold) values with val, until meets borders /// Doesnt guarantee filling (areas after the corner could be missed) /// Use threshold to change between mask -1 or 0 /// TODO: to matrix ops { CoordRect rect = matrix.rect; Coord min = rect.Min; Coord max = rect.Max; MatrixOps.Stripe stripe = new MatrixOps.Stripe(Mathf.Max(rect.size.x, rect.size.z)); stripe.length = rect.size.x; matrix[coord] = -256; //starting mask //first vertical spread is one row-only MatrixOps.ReadRow(stripe, matrix, coord.x, matrix.rect.offset.z); PaintBucketMaskStripe(stripe, threshold); MatrixOps.WriteRow(stripe, matrix, coord.x, matrix.rect.offset.z); for (int i = 0; i < maxIterations; i++) //ten tries, but hope it will end before that { bool change = false; //horizontally for (int z = min.z; z < max.z; z++) { MatrixOps.ReadLine(stripe, matrix, rect.offset.x, z); change = PaintBucketMaskStripe(stripe, threshold) || change; MatrixOps.WriteLine(stripe, matrix, rect.offset.x, z); } //vertically for (int x = min.x; x < max.x; x++) { MatrixOps.ReadRow(stripe, matrix, x, matrix.rect.offset.z); change = PaintBucketMaskStripe(stripe, threshold) || change; MatrixOps.WriteRow(stripe, matrix, x, matrix.rect.offset.z); } if (!change) { break; } //if (i==maxIterations-1 && !change) // Debug.Log("Reached max iterations"); } //filling masked values with val for (int i = 0; i < matrix.arr.Length; i++) { if (matrix.arr[i] < -255) { matrix.arr[i] = val; } } }
private static bool PaintBucketMaskStripe(MatrixOps.Stripe stripe, float threshold = 0.0001f) /// Fills stripe until first unmasked value with -256 /// Returns true if anything masked { bool changed = false; //to right bool masking = false; for (int i = 0; i < stripe.length; i++) { if (stripe.arr[i] < -255) { masking = true; continue; } if (stripe.arr[i] < threshold) { if (masking) { stripe.arr[i] = -256; changed = true; } } else { masking = false; } } //to left masking = false; for (int i = stripe.length - 1; i >= 0; i--) { if (stripe.arr[i] < -255) { masking = true; continue; } if (stripe.arr[i] < threshold) { if (masking) { stripe.arr[i] = -256; changed = true; } } else { masking = false; } } return(changed); }
private void DragSlice(Matrix matrix) { Vector2 cursorRect = new Vector2(UI.current.mousePos.x, -UI.current.mousePos.y); if (DragDrop.TryDrag(Cell.current, cursorRect)) { Rect rect = new Rect(DragDrop.initialMousePos, DragDrop.totalDelta); rect = To1PixelRect(rect); Draw.Rect(FlipVertical(rect), new Color(0, 1, 0, 0.5f)); } DragDrop.TryStart(Cell.current, cursorRect, Cell.current.GetRect()); if (DragDrop.TryRelease(Cell.current, cursorRect)) { Rect rect = new Rect(DragDrop.initialMousePos, DragDrop.totalDelta); rect = To1PixelRect(rect); int x = (int)rect.x; // + matrix.rect.offset.x; int z = (int)(rect.y + 1); //ceil? //)matrix.rect.size.z - (int)rect.y + matrix.rect.offset.z - 1; if (rect.width != 0 && rect.height != 0) { if (rect.width > rect.height) { //line = new float[(int)rect.width]; slice = new MatrixOps.Stripe((int)rect.width); MatrixOps.ReadLine(slice, matrix, x, z); } else { //line = new float[(int)rect.height]; slice = new MatrixOps.Stripe((int)rect.height); MatrixOps.ReadRow(slice, matrix, x, z - slice.length); } //{ // slice = new Matrix.Stripe( Mathf.Max((int)rect.width, (int)rect.height) ); // matrix.ReadDiagonal(stripe, x, z); //} sliceRect = rect; //MatrixLineTesterWindow lineTesterWindow = (MatrixLineTesterWindow)GetWindow(typeof (MatrixLineTesterWindow)); //lineTesterWindow.src = slice; } } }