private static void DrawFieldSprtDoIt(byte[] pixels, double[] ink, bool[] blocked, int size, byte[] colorZFront, byte[] colorZBack, AxisFor pixelX, AxisFor pixelY, AxisFor pixelZ)
        {
            List<Mapping_2D_1D> flattened = new List<Mapping_2D_1D>();

            // Setup the pixel array
            //for (int y2D = pixelY.Start; pixelY.IsPos ? y2D <= pixelY.Stop : y2D >= pixelY.Stop; y2D += pixelY.Increment)
            foreach (int y2D in pixelY.Iterate())
            {
                int offsetY = pixelY.GetValueForOffset(y2D) * size;

                //for (int x2D = pixelX.Start; pixelX.IsPos ? x2D <= pixelX.Stop : x2D >= pixelX.Stop; x2D += pixelX.Increment)
                foreach (int x2D in pixelX.Iterate())
                {
                    int offset = offsetY + pixelX.GetValueForOffset(x2D);

                    flattened.Add(new Mapping_2D_1D(x2D, y2D, offset));
                }
            }

            // Each pixel of the output bitmap can be added up independently, so employ some threading
            flattened.AsParallel().ForAll(o =>
                {
                    //TODO: Color is 6.5 times slower than byte array
                    List<byte[]> colorColumn = new List<byte[]>();

                    for (int z2D = pixelZ.Start; pixelZ.IsPos ? z2D <= pixelZ.Stop : z2D >= pixelZ.Stop; z2D += pixelZ.Increment)
                    {
                        int x = -1, y = -1, z = -1;
                        pixelX.Set3DIndex(ref x, ref y, ref z, o.X);
                        pixelY.Set3DIndex(ref x, ref y, ref z, o.Y);
                        pixelZ.Set3DIndex(ref x, ref y, ref z, z2D);

                        int index = FluidField3D.Get1DIndex(x, y, z, size);
                        if (blocked[index])
                        {
                            // Blocked cells are all white, so save the overlay method a bit of work, and throw out everything behind this
                            colorColumn.Clear();
                            colorColumn.Add(new byte[] { 255, 255, 255, 255 });
                            continue;
                        }

                        double inkCell = ink[index];

                        if (Math1D.IsNearZero(inkCell))
                        {
                            continue;
                        }

                        byte[] depthColor = UtilityWPF.AlphaBlend(colorZBack, colorZFront, UtilityCore.GetScaledValue_Capped(0, 1, 0, size - 1, z));

                        int alpha = Convert.ToInt32(Math.Round(inkCell * 255));
                        if (alpha < 0)
                        {
                            alpha = 0;
                        }
                        else if (alpha > 255)
                        {
                            alpha = 255;
                        }

                        colorColumn.Add(new byte[] { Convert.ToByte(alpha), depthColor[1], depthColor[2], depthColor[3] });
                    }

                    byte[] color = colorColumn.Count > 0 ? UtilityWPF.OverlayColors(colorColumn) : new byte[] { 0, 0, 0, 0 };

                    pixels[o.Offset1D * 4 + 0] = color[3];   // Blue
                    pixels[o.Offset1D * 4 + 1] = color[2];     // Green
                    pixels[o.Offset1D * 4 + 2] = color[1];     // Red
                    pixels[o.Offset1D * 4 + 3] = color[0];   // Alpha
                });
        }
        /// <summary>
        /// Shifts values (the new margins get zero)
        /// </summary>
        /// <param name="sweep">The other axis (if x's are getting shifted, then do it for each y)</param>
        /// <param name="shift">The row/column that has values changing. ex: [x] = [x+1]</param>
        private void TranslateValues(AxisFor sweep, AxisFor shift)
        {
            int amount;
            if (!int.TryParse(txtMoveAmount.Text, out amount))
            {
                amount = 1;
            }

            amount *= shift.IsPos ? 1 : -1;

            foreach (int sweepIndex in sweep.Iterate())
            {
                foreach (int shiftIndex in shift.Iterate())
                {
                    int toX = -1;
                    int toY = -1;
                    sweep.Set2DIndex(ref toX, ref toY, sweepIndex);
                    shift.Set2DIndex(ref toX, ref toY, shiftIndex);

                    int fromX = -1;
                    int fromY = -1;
                    sweep.Set2DIndex(ref fromX, ref fromY, sweepIndex);
                    shift.Set2DIndex(ref fromX, ref fromY, shiftIndex + amount);

                    double value = 0;
                    if (fromX >= 0 && fromX < _width && fromY >= 0 && fromY < _height)
                    {
                        value = _values[fromY * _width + fromX];
                    }

                    _values[toY * _width + toX] = value;
                }
            }

            RebuildBars();
            PixelValueChanged();
        }
示例#3
0
        private static Convolution2D CopyRect(double[] values, int width, AxisFor edge, AxisFor orth, bool shouldRotate180)
        {
            if (shouldRotate180)
            {
                return CopyRect(values, width, new AxisFor(edge.Axis, edge.Stop, edge.Start), new AxisFor(orth.Axis, orth.Stop, orth.Start), false);
            }

            double[] retVal = new double[edge.Length * orth.Length];

            int index = 0;

            foreach (int orthIndex in orth.Iterate())
            {
                int x = -1;
                int y = -1;
                orth.Set2DIndex(ref x, ref y, orthIndex);

                foreach (int edgeIndex in edge.Iterate())
                {
                    edge.Set2DIndex(ref x, ref y, edgeIndex);

                    retVal[index] = values[(y * width) + x];

                    index++;
                }
            }

            return new Convolution2D(retVal, edge.Length, orth.Length, false);
        }
示例#4
0
        /// <summary>
        /// For each pixel in this row, pick a random pixel from a box above
        /// </summary>
        /// <remarks>
        /// At each pixel, this draws from a box of size orthDepth x (edgeDepth*2)+1
        /// </remarks>
        /// <param name="orthIndex">The row being copied to</param>
        private static void CopyRandomPixels(double[] values, int width, int orthIndex, int orthInc, int orthDepth, int edgeDepth, AxisFor orth, AxisFor edge, Random rand)
        {
            // See how many rows to randomly pull from
            int orthDepthStart = orthIndex + orthInc;
            int orthDepthStop = orthIndex + (orthDepth * orthInc);
            UtilityCore.MinMax(ref orthDepthStart, ref orthDepthStop);
            int orthAdd = orthInc < 0 ? 1 : 0;

            foreach (int edgeIndex in edge.Iterate())
            {
                // Figure out which column to pull from
                int toEdge = -1;
                do
                {
                    toEdge = rand.Next(edgeIndex - edgeDepth, edgeIndex + edgeDepth + 1);
                } while (!edge.IsBetween(toEdge));

                // Figure out which row to pull from
                int toOrth = rand.Next(orthDepthStart, orthDepthStop) + orthAdd;

                // From XY
                int fromX = -1;
                int fromY = -1;
                orth.Set2DIndex(ref fromX, ref fromY, toOrth);
                edge.Set2DIndex(ref fromX, ref fromY, toEdge);

                // To XY
                int toX = -1;
                int toY = -1;
                orth.Set2DIndex(ref toX, ref toY, orthIndex);
                edge.Set2DIndex(ref toX, ref toY, edgeIndex);

                // Copy pixel
                values[(toY * width) + toX] = values[(fromY * width) + fromX];
            }
        }
示例#5
0
        //TODO: Implement this properly
        private static void ExtendCorner(double[] values, int width, AxisFor orth, AxisFor edge)
        {
            Random rand = StaticRandom.GetRandomForThread();

            foreach (int edgeIndex in edge.Iterate())
            {
                foreach (int orthIndex in orth.Iterate())
                {
                    int x = -1;
                    int y = -1;
                    orth.Set2DIndex(ref x, ref y, orthIndex);
                    edge.Set2DIndex(ref x, ref y, edgeIndex);

                    values[(y * width) + x] = rand.Next(256);
                }
            }
        }
示例#6
0
        private static void ExtendEdge(double[] values, int width, int orthHeight, AxisFor orth, AxisFor edge)
        {
            const int EDGEDEPTH = 4;
            int ORTHDEPTH = Math.Min(5, orthHeight) + 1;

            const int EDGEMIDOFFSET = 5;

            // This isn't worth implementing, you just get a pixelated band
            //const int GAUSSOPACITYDIST = 1;       // how many pixels before the gaussian is full strength

            Random rand = StaticRandom.GetRandomForThread();

            Convolution2D gauss = Convolutions.GetGaussian(3);

            // Figure out which direction to copy rows from
            int orthInc = GetOrthIncrement(orth);

            #region Edge midpoint range

            // Each row, a random midpoint is chosen.  This way, an artifact won't be created down the middle.
            // mid start and stop are the range of possible values that the random midpoint can be from

            int edgeMidStart = edge.Start;
            int edgeMidStop = edge.Stop;

            UtilityCore.MinMax(ref edgeMidStart, ref edgeMidStop);

            edgeMidStart += EDGEMIDOFFSET;
            edgeMidStop -= EDGEMIDOFFSET;

            #endregion

            foreach (int orthIndex in orth.Iterate())
            {
                CopyRandomPixels(values, width, orthIndex, orthInc, ORTHDEPTH, EDGEDEPTH, orth, edge, rand);

                OverlayBlurredPixels(values, width, orthHeight, orthIndex, orthInc, edgeMidStart, edgeMidStop, orth, edge, gauss, /*GAUSSOPACITYDIST,*/ rand);
            }
        }