예제 #1
0
        /// <summary>
        /// Paints on a WriteableBitmap with a stylized airbrush
        /// </summary>
        /// <param name="bmp">The bitmap to modify</param>
        /// <param name="from">The starting point of the stroke</param>
        /// <param name="to">The end point of the stroke</param>
        /// <param name="color">The color of the stroke</param>
        /// <param name="size">The size of the stroke</param>
        public static unsafe void Airbrush(WriteableBitmap bmp, Point from, Point to, Color color, int size)
        {
            Random r = new Random();

            if (bmp == null) return;

            bmp.Lock();

            // Create a line segment representation
            MyLine line = new MyLine(from, to);

            // Get a bounding box for the painted area
            BoundingBox bitmapbounds = new BoundingBox();
            BoundingBox linebounds = new BoundingBox();

            bitmapbounds.AddPoint(0, 0, 0);
            bitmapbounds.AddPoint(bmp.PixelWidth - 1, bmp.PixelHeight - 1, 0);

            linebounds.AddPoint((int)from.X, (int)from.Y, size + AirbrushRadiu);
            linebounds.AddPoint((int)to.X, (int)to.Y, size + AirbrushRadiu);
            linebounds.Clip(bitmapbounds);

            UInt32* start = (UInt32*)bmp.BackBuffer.ToPointer();
            int stride = bmp.BackBufferStride / sizeof(UInt32);
            // Move from 'from' to 'to' along timestep intervals, with one dot painted per interval
            for (int i = 0; i < AirbrushDots; i++)
            {
                int x, y;
                line.Interpolate(i, AirbrushDots, out x, out y);

                int dist = r.Next() % size;
                double angle = r.NextDouble() * 2 * Math.PI;

                double dx = Math.Cos(angle) * dist;
                double dy = Math.Sqrt(dist * dist - dx * dx);
                if (angle > Math.PI) dy = -dy;

                int bx = x + (int)dx;
                int by = y + (int)dy;

                BoundingBox dotbounds = new BoundingBox();

                dotbounds.AddPoint(bx, by, AirbrushRadiu);
                dotbounds.Clip(bitmapbounds);

                for (int k = dotbounds.Top, row = 0; k < dotbounds.Bottom; k++, y++, row++)
                    for (int j = dotbounds.Left, col = 0; j < dotbounds.Right; j++, col++)
                        AlphaBlended(start + stride * k + j, Color.FromArgb(AirbrushBytes[row][col], color.R, color.G, color.B));
            }

            bmp.AddDirtyRect(new Int32Rect(linebounds.Left, linebounds.Top, linebounds.Width, linebounds.Height));
            bmp.Unlock();
        }
예제 #2
0
        /// <summary>
        /// Erases paint on a pbgra32 WriteableBitmap
        /// </summary>
        /// <param name="bmp">The bitmap to modify</param>
        /// <param name="from">The starting point of the stroke</param>
        /// <param name="to">The end point of the stroke</param>
        /// <param name="size">The stroke size</param>
        public static unsafe void Erase(WriteableBitmap bmp, Point from, Point to, int size)
        {
            if (bmp == null)
            {
                return;
            }

            bmp.Lock();

            // Intermediate storage of the square of the size
            int sizesize = size * size;

            // Create a line segment representation to compare distance to
            MyLine linesegment = new MyLine(from, to);

            // Get a bounding box for the line segment
            BoundingBox bitmapbounds  = new BoundingBox();
            BoundingBox segmentbounds = new BoundingBox();

            bitmapbounds.AddPoint(0, 0, 0);
            bitmapbounds.AddPoint(bmp.PixelWidth - 1, bmp.PixelHeight - 1, 0);

            segmentbounds.AddPoint((int)from.X, (int)from.Y, size);
            segmentbounds.AddPoint((int)to.X, (int)to.Y, size);
            segmentbounds.Clip(bitmapbounds);

            // Get a pointer to the back buffer (we use an int pointer here, since we can safely assume a 32-bit pixel format)
            Int32 *start = (Int32 *)bmp.BackBuffer.ToPointer();

            // Move the starting pixel to the x offset
            start += segmentbounds.Left;

            // Loop through the relevant portion of the image and figure out which pixels need to be erased
            for (int y = segmentbounds.Top; y < segmentbounds.Bottom; y++)
            {
                Int32 *pixel = start + bmp.BackBufferStride / sizeof(Int32) * y;

                for (int x = segmentbounds.Left; x < segmentbounds.Right; x++)
                {
                    if (linesegment.DistanceSquared(x, y) <= sizesize)
                    {
                        *pixel = 0;
                    }

                    // Move to the next pixel
                    pixel++;
                }
            }

            bmp.AddDirtyRect(new Int32Rect(segmentbounds.Left, segmentbounds.Top, segmentbounds.Width, segmentbounds.Height));
            bmp.Unlock();
        }
예제 #3
0
 internal override void IncorporatePointIntoBoundingBox(BoundingBox boundingBox)
 {
     foreach (DiffuseOnlyVertex vertex in vertices_)
     {
         boundingBox.AddPoint(vertex.Position);
     }
 }
예제 #4
0
파일: Contour.cs 프로젝트: miyu/Poly2Tri
        protected override void Add(Point2D p, int idx, bool bCalcWindingOrderAndEpsilon)
        {
            TriangulationPoint pt;

            if (p is TriangulationPoint)
            {
                pt = p as TriangulationPoint;
            }
            else
            {
                pt = new TriangulationPoint(p.X, p.Y);
            }
            if (idx < 0)
            {
                MPoints.Add(pt);
            }
            else
            {
                MPoints.Insert(idx, pt);
            }
            BoundingBox = BoundingBox.AddPoint(pt);
            if (bCalcWindingOrderAndEpsilon)
            {
                if (WindingOrder == WindingOrderType.Unknown)
                {
                    WindingOrder = CalculateWindingOrder();
                }
                Epsilon = CalculateEpsilon();
            }
        }
예제 #5
0
 private void CalculateBounds()
 {
     _boundingBox = new Rect2D();
     foreach (Point2D pt in MPoints)
     {
         BoundingBox = BoundingBox.AddPoint(pt);
     }
 }
예제 #6
0
        public static unsafe void Erase(WriteableBitmap bmp, Point from, Point to, int size)
        {
            if (bmp == null)
            {
                return;
            }

            bmp.Lock();
            int         sizesize      = size * size;
            LineSegment linesegment   = new LineSegment(from, to);
            BoundingBox bitmapbounds  = new BoundingBox();
            BoundingBox segmentbounds = new BoundingBox();

            bitmapbounds.AddPoint(0, 0, 0);
            bitmapbounds.AddPoint(bmp.PixelWidth - 1, bmp.PixelHeight - 1, 0);

            segmentbounds.AddPoint((int)from.X, (int)from.Y, size);
            segmentbounds.AddPoint((int)to.X, (int)to.Y, size);
            segmentbounds.Clip(bitmapbounds);
            Int32 *start = (Int32 *)bmp.BackBuffer.ToPointer();

            start += segmentbounds.Left;

            for (int y = segmentbounds.Top; y < segmentbounds.Bottom; y++)
            {
                Int32 *pixel = start + bmp.BackBufferStride / sizeof(Int32) * y;

                for (int x = segmentbounds.Left; x < segmentbounds.Right; x++)
                {
                    if (linesegment.DistanceSquared(x, y) <= sizesize)
                    {
                        *pixel = 0;
                    }

                    pixel++;
                }
            }

            bmp.AddDirtyRect(new Int32Rect(segmentbounds.Left, segmentbounds.Top, segmentbounds.Width, segmentbounds.Height));
            bmp.Unlock();
        }
예제 #7
0
파일: PointSet.cs 프로젝트: miyu/Poly2Tri
        protected PointSet(IEnumerable <TriangulationPoint> bounds)
        {
            //Points = new List<TriangulationPoint>();
            foreach (TriangulationPoint p in bounds)
            {
                Add(p, -1, false);

                // Only the initial points are counted toward min/max x/y as they
                // are considered to be the boundaries of the point-set
                BoundingBox = BoundingBox.AddPoint(p);
            }
            Epsilon      = CalculateEpsilon();
            WindingOrder = WindingOrderType.Unknown;   // not valid for a point-set
        }
예제 #8
0
파일: Contour.cs 프로젝트: miyu/Poly2Tri
        protected override void AddRange(IEnumerator <Point2D> iter, WindingOrderType windingOrder)
        {
            if (iter == null)
            {
                return;
            }

            if (WindingOrder == WindingOrderType.Unknown && Count == 0)
            {
                WindingOrder = windingOrder;
            }
            bool bReverseReadOrder = (WindingOrder != WindingOrderType.Unknown) && (windingOrder != WindingOrderType.Unknown) && (WindingOrder != windingOrder);
            bool bAddedFirst       = true;
            int  startCount        = MPoints.Count;

            iter.Reset();
            while (iter.MoveNext())
            {
                TriangulationPoint pt;
                if (iter.Current is TriangulationPoint)
                {
                    pt = iter.Current as TriangulationPoint;
                }
                else
                {
                    pt = new TriangulationPoint(iter.Current.X, iter.Current.Y);
                }
                if (!bAddedFirst)
                {
                    bAddedFirst = true;
                    MPoints.Add(pt);
                }
                else if (bReverseReadOrder)
                {
                    MPoints.Insert(startCount, pt);
                }
                else
                {
                    MPoints.Add(pt);
                }
                BoundingBox = BoundingBox.AddPoint(iter.Current);
            }
            if (WindingOrder == WindingOrderType.Unknown && windingOrder == WindingOrderType.Unknown)
            {
                WindingOrder = CalculateWindingOrder();
            }
            Epsilon = CalculateEpsilon();
        }
예제 #9
0
            /// <summary>
            /// Computes the bounding box of cell <paramref name="j"/>
            /// </summary>
            /// <param name="j">local cell index</param>
            /// <param name="bb">
            /// on exit, the bounding box of cell j.
            /// </param>
            public void GetCellBoundingBox(int j, BoundingBox bb)
            {
                int D = bb.D;

                if (bb.D != m_Owner.SpatialDimension)
                {
                    throw new ArgumentException("wrong dimension of bounding box.");
                }
                bb.Clear();

                MultidimensionalArray Points = m_Owner.m_VertexData.Coordinates;

                double[] pt = new double[D];

                foreach (int iVtx in this.CellVertices[j])
                {
                    Points.GetRow(iVtx, pt, 0, 1);
                    bb.AddPoint(pt);
                }
            }
예제 #10
0
 protected virtual void Add(Point2D p, int idx, bool bCalcWindingOrderAndEpsilon)
 {
     if (idx < 0)
     {
         MPoints.Add(p);
     }
     else
     {
         MPoints.Insert(idx, p);
     }
     BoundingBox = BoundingBox.AddPoint(p);
     if (bCalcWindingOrderAndEpsilon)
     {
         if (_windingOrder == WindingOrderType.Unknown)
         {
             _windingOrder = CalculateWindingOrder();
         }
         Epsilon = CalculateEpsilon();
     }
 }
예제 #11
0
        public static unsafe void Butterfly(WriteableBitmap bmp, Point from, Point to, Color color, int size)
        {
            AirbrushDots      = 2000;
            AirbrushDotRadius = 3;
            Random r = new Random();

            if (bmp == null)
            {
                return;
            }

            bmp.Lock();

            // Create a line segment representation
            LineSegment segment = new LineSegment(from, to);

            // Get a bounding box for the painted area
            BoundingBox bitmapbounds  = new BoundingBox();
            BoundingBox segmentbounds = new BoundingBox();

            bitmapbounds.AddPoint(0, 0, 0);
            bitmapbounds.AddPoint(bmp.PixelWidth - 1, bmp.PixelHeight - 1, 0);

            segmentbounds.AddPoint((int)from.X, (int)from.Y, 1500);
            segmentbounds.AddPoint((int)to.X, (int)to.Y, 1500);
            segmentbounds.Clip(bitmapbounds);

            UInt32 *start  = (UInt32 *)bmp.BackBuffer.ToPointer();
            int     stride = bmp.BackBufferStride / sizeof(UInt32);
            // Move from 'from' to 'to' along timestep0 intervals, with one dot painted per interval
            int ran;

            if (size < 10)
            {
                ran = (r.Next() % (300 - size * 20)) + 1;
            }
            else if (size < 20)
            {
                ran = (r.Next() % (450 - size * 20)) + 1;
            }

            else if (size < 30)
            {
                ran = (r.Next() % (600 - size * 30)) + 1;
            }
            else if (size < 40)
            {
                ran = (r.Next() % (1400 - size * 20)) + 1;
            }
            else
            {
                ran = (r.Next() % (3200 - size * 20)) + 1;
            }

            for (int i = 0; i < AirbrushDots; i++)
            {
                int x, y;

                temp = i;
                segment.Interpolate(i, AirbrushDots, out x, out y);

                int bx = x + temp;
                int by = y - (temp * temp) / ran;

                if (temp % 4 == 0)
                {
                    if (ran % 2 == 0)
                    {
                        bx = x + (temp * temp) / ran;
                        by = y - temp;
                    }
                    else
                    {
                        bx = x + temp;
                        by = y - (temp * temp) / ran;
                    }
                }
                else if (temp % 4 == 1)
                {
                    if (ran % 2 == 0)
                    {
                        bx = x + (temp * temp) / ran;
                        by = y + temp;
                    }
                    else
                    {
                        bx = x + temp;
                        by = y + (temp * temp) / ran;
                    }
                }
                else if (temp % 4 == 2)
                {
                    if (ran % 2 == 0)
                    {
                        bx = x - (temp * temp) / ran;
                        by = y + temp;
                    }
                    else
                    {
                        bx = x - temp;
                        by = y + (temp * temp) / ran;
                    }
                }
                else if (temp % 4 == 3)
                {
                    if (ran % 2 == 0)
                    {
                        bx = x - (temp * temp) / ran;
                        by = y - temp;
                    }
                    else
                    {
                        bx = x - temp;
                        by = y - (temp * temp) / ran;
                    }
                }

                if (Math.Sqrt((bx - x) * (bx - x) + (by - y) * (by - y)) > size * 10)
                {
                    continue;
                }



                BoundingBox dotbounds = new BoundingBox();

                dotbounds.AddPoint(bx, by, AirbrushDotRadius);
                dotbounds.Clip(bitmapbounds);

                for (int k = dotbounds.Top, row = 0; k < dotbounds.Bottom; k++, y++, row++)
                {
                    for (int j = dotbounds.Left, col = 0; j < dotbounds.Right; j++, col++)
                    {
                        WriteAlphaBlended(start + stride * k + j, Color.FromArgb(AirbrushDotKernel[row][col], color.R, color.G, color.B));
                    }
                }
            }

            bmp.AddDirtyRect(new Int32Rect(segmentbounds.Left, segmentbounds.Top, segmentbounds.Width, segmentbounds.Height));
            bmp.Unlock();
        }
예제 #12
0
        /// <summary>
        /// Erases paint on a WriteableBitmap
        /// </summary>
        /// <param name="bmp">The bitmap to modify</param>
        /// <param name="from">The starting point of the stroke</param>
        /// <param name="to">The end point of the stroke</param>
        /// <param name="size">The stroke size</param>
        public static unsafe void Erase(WriteableBitmap bmp, Point from, Point to, int size)
        {
            if (bmp == null) return;

            bmp.Lock();

            // Intermediate storage of the square of the size
            int area = size * size;

            // Create a line segment representation to compare distance to
            MyLine line = new MyLine(from, to);

            // Get a bounding box for the line segment
            BoundingBox bitmapbounds = new BoundingBox();
            BoundingBox linebounds = new BoundingBox();

            bitmapbounds.AddPoint(0, 0, 0);
            bitmapbounds.AddPoint(bmp.PixelWidth - 1, bmp.PixelHeight - 1, 0);

            linebounds.AddPoint((int)from.X, (int)from.Y, size);
            linebounds.AddPoint((int)to.X, (int)to.Y, size);
            linebounds.Clip(bitmapbounds);

            // Get a pointer to the back buffer (we use an int pointer here, since we can safely assume a 32-bit pixel format)
            Int32* start = (Int32*)bmp.BackBuffer.ToPointer();

            // Move the starting pixel to the x offset
            start += linebounds.Left;

            // Loop through the relevant portion of the image and figure out which pixels need to be erased
            for (int y = linebounds.Top; y < linebounds.Bottom; y++)
            {
                Int32* pixel = start + bmp.BackBufferStride / sizeof(Int32) * y;

                for (int x = linebounds.Left; x < linebounds.Right; x++)
                {
                    if (line.DistanceSquared(x, y) <= area)
                        *pixel = 0;

                    // Move to the next pixel
                    pixel++;
                }
            }

            bmp.AddDirtyRect(new Int32Rect(linebounds.Left, linebounds.Top, linebounds.Width, linebounds.Height));
            bmp.Unlock();
        }
예제 #13
0
        /// <summary>
        /// Paints on a WriteableBitmap like a paintbrush
        /// </summary>
        /// <param name="bmp">The bitmap to modify</param>
        /// <param name="from">The starting point of the stroke</param>
        /// <param name="to">The end point of the stroke</param>
        /// <param name="previous">The point prior to the 'from' point, or null</param>
        /// <param name="color">The color of the brush</param>
        /// <param name="size">The stroke size</param>
        public static unsafe void Brush(WriteableBitmap bmp, Point from, Point to, Point? previous, Color color, int size)
        {
            if (bmp == null) return;

            bmp.Lock();

            // Intermediate storage of the square of the size
            int area = size * size;
            uint flatcolor = (uint)((int)color.A << 24) + (uint)((int)color.R << 16) + (uint)((int)color.G << 8) + color.B;

            // Create a line segment representation to compare distance to
            MyLine line = new MyLine(from, to);

            // Get a bounding box for the line segment
            BoundingBox bitmapbounds = new BoundingBox();
            BoundingBox linebounds = new BoundingBox();

            bitmapbounds.AddPoint(0, 0, 0);
            bitmapbounds.AddPoint(bmp.PixelWidth - 1, bmp.PixelHeight - 1, 0);

            linebounds.AddPoint((int)from.X, (int)from.Y, size);
            linebounds.AddPoint((int)to.X, (int)to.Y, size);
            linebounds.Clip(bitmapbounds);

            // Get a pointer to the back buffer (we use an int pointer here, since we can safely assume a 32-bit pixel format)
            UInt32* start = (UInt32*)bmp.BackBuffer.ToPointer();

            // Move the starting pixel to the x offset
            start += linebounds.Left;

            if (previous.HasValue)
            {
                MyLine previoussegment = new MyLine(previous.Value, from);

                // Loop through the relevant portion of the image and figure out which pixels need to be erased
                for (int y = linebounds.Top; y < linebounds.Bottom; y++)
                {
                    UInt32* pixel = start + bmp.BackBufferStride / sizeof(UInt32) * y;

                    for (int x = linebounds.Left; x < linebounds.Right; x++)
                    {
                        if (line.DistanceSquared(x, y) <= area && previoussegment.DistanceSquared(x, y) > area)
                        {
                            if (color.A == 255)
                                *pixel = flatcolor;
                            else
                                AlphaBlended(pixel, color);
                        }

                        // Move to the next pixel
                        pixel++;
                    }
                }
            }
            else
            {
                // Loop through the relevant portion of the image and figure out which pixels need to be erased
                for (int y = linebounds.Top; y < linebounds.Bottom; y++)
                {
                    UInt32* pixel = start + bmp.BackBufferStride / sizeof(UInt32) * y;

                    for (int x = linebounds.Left; x < linebounds.Right; x++)
                    {
                        if (line.DistanceSquared(x, y) <= area)
                        {
                            if (color.A == 255)
                                *pixel = flatcolor;
                            else
                                AlphaBlended(pixel, color);
                        }

                        // Move to the next pixel
                        pixel++;
                    }
                }
            }

            bmp.AddDirtyRect(new Int32Rect(linebounds.Left, linebounds.Top, linebounds.Width, linebounds.Height));
            bmp.Unlock();
        }
예제 #14
0
 public override bool GetLocalBoundingBox(ref BoundingBox bbox)
 {
     PathNodeShape[] nodes = this.PathNodes;
       if (nodes == null || nodes.Length == 0)
     return false;
       bbox = new BoundingBox();
       foreach (PathNodeShape node in nodes)
     bbox.AddPoint(node.LocalSpacePosition);
       bbox.AddBorder(5.0f * EditorManager.Settings.GlobalUnitScaling);
       return true;
 }
예제 #15
0
        /// <summary>
        /// Constructs suitable quadrature rules cells in
        /// <paramref name="mask"/>.
        /// </summary>
        /// <param name="mask">
        /// Cells for which quadrature rules shall be created
        /// </param>
        /// <param name="order">
        /// Desired order of the moment-fitting system. Assuming that
        /// <see cref="surfaceRuleFactory"/> integrates the basis polynomials
        /// exactly over the zero iso-contour (which it usually
        /// doesn't!), the resulting quadrature rules will be exact up to this
        /// order.
        /// </param>
        /// <returns>A set of quadrature rules</returns>
        /// <remarks>
        /// Since the selected level set is generally discontinuous across cell
        /// boundaries, this method does not make use of the fact that
        /// neighboring cells share edges. That is, the optimization will be
        /// performed twice for each inner edge in <paramref name="mask"/>.
        /// </remarks>
        public IEnumerable <IChunkRulePair <QuadRule> > GetQuadRuleSet(ExecutionMask mask, int order)
        {
            using (var tr = new FuncTrace()) {
                CellMask cellMask = mask as CellMask;
                if (cellMask == null)
                {
                    throw new ArgumentException("Mask must be a volume mask", "mask");
                }

                // Note: This is a parallel call, so do this early to avoid parallel confusion
                localCellIndex2SubgridIndex = new SubGrid(cellMask).LocalCellIndex2SubgridIndex;

                int maxLambdaDegree = order + 1;
                int noOfLambdas     = GetNumberOfLambdas(maxLambdaDegree);
                int noOfEdges       = LevelSetData.GridDat.Grid.RefElements[0].NoOfFaces;
                int D = RefElement.SpatialDimension;

                // Get the basis polynomials and integrate them analytically
                Polynomial[] basePolynomials = RefElement.GetOrthonormalPolynomials(order).ToArray();
                Polynomial[] polynomials     = new Polynomial[basePolynomials.Length * D];
                for (int i = 0; i < basePolynomials.Length; i++)
                {
                    Polynomial p = basePolynomials[i];

                    for (int d = 0; d < D; d++)
                    {
                        Polynomial pNew = p.CloneAs();
                        for (int j = 0; j < p.Coeff.Length; j++)
                        {
                            pNew.Exponents[j, d]++;
                            pNew.Coeff[j] /= pNew.Exponents[j, d];
                            pNew.Coeff[j] /= D; // Make sure divergence is Phi again
                        }
                        polynomials[i * D + d] = pNew;
                    }
                }

                // basePolynomials[i] == div(polynomials[i*D], ... , polynomials[i*D + D - 1])
                lambdaBasis = new PolynomialList(polynomials);


                if (RestrictNodes)
                {
                    trafos = new AffineTrafo[mask.NoOfItemsLocally];

                    foreach (Chunk chunk in mask)
                    {
                        foreach (var cell in chunk.Elements.AsSmartEnumerable())
                        {
                            CellMask singleElementMask = new CellMask(
                                LevelSetData.GridDat, Chunk.GetSingleElementChunk(cell.Value));

                            LineAndPointQuadratureFactory.LineQRF lineFactory = this.edgeRuleFactory as LineAndPointQuadratureFactory.LineQRF;
                            if (lineFactory == null)
                            {
                                throw new Exception();
                            }
                            var lineRule  = lineFactory.GetQuadRuleSet(singleElementMask, order).Single().Rule;
                            var pointRule = lineFactory.m_Owner.GetPointFactory().GetQuadRuleSet(singleElementMask, order).Single().Rule;

                            // Also add point rule points since line rule points
                            // are constructed from Gauss rules that do not include
                            // the end points
                            BoundingBox box = new BoundingBox(lineRule.Nodes);
                            box.AddPoints(pointRule.Nodes);

                            int noOfRoots = pointRule.Nodes.GetLength(0);
                            if (noOfRoots <= 1)
                            {
                                // Cell is considered cut because the level set
                                // is very close, but actually isn't. Note that
                                // we can NOT omit the cell (as in the surface
                                // case) as it will be missing in the list of
                                // uncut cells, i.e. this cell would be ignored
                                // completely
                                trafos[localCellIndex2SubgridIndex[cell.Value]] =
                                    AffineTrafo.Identity(RefElement.SpatialDimension);
                                continue;
                            }
                            else if (noOfRoots == 2)
                            {
                                // Go a bit into the direction of the normal
                                // from the center between the nodes in order
                                // not to miss regions with strong curvature
                                double[] center = box.Min.CloneAs();
                                center.AccV(1.0, box.Max);
                                center.ScaleV(0.5);
                                NodeSet centerNode = new NodeSet(RefElement, center);
                                centerNode.LockForever();

                                MultidimensionalArray normal = LevelSetData.GetLevelSetReferenceNormals(centerNode, cell.Value, 1);
                                MultidimensionalArray dist   = LevelSetData.GetLevSetValues(centerNode, cell.Value, 1);

                                double scaling = Math.Sqrt(LevelSetData.GridDat.Cells.JacobiDet[cell.Value]);

                                double[] newPoint = new double[D];
                                for (int d = 0; d < D; d++)
                                {
                                    newPoint[d] = center[d] - normal[0, 0, d] * dist[0, 0] / scaling;
                                }

                                box.AddPoint(newPoint);

                                // Make sure points stay in box
                                for (int d = 0; d < D; d++)
                                {
                                    box.Min[d] = Math.Max(box.Min[d], -1);
                                    box.Max[d] = Math.Min(box.Max[d], 1);
                                }
                            }

                            MultidimensionalArray preImage = RefElement.Vertices.ExtractSubArrayShallow(
                                new int[] { 0, 0 }, new int[] { D, D - 1 });

                            MultidimensionalArray image = MultidimensionalArray.Create(D + 1, D);
                            image[0, 0] = box.Min[0]; // Top left
                            image[0, 1] = box.Max[1];
                            image[1, 0] = box.Max[0]; // Top right
                            image[1, 1] = box.Max[1];
                            image[2, 0] = box.Min[0]; // Bottom left;
                            image[2, 1] = box.Min[1];

                            AffineTrafo trafo = AffineTrafo.FromPoints(preImage, image);
                            trafos[localCellIndex2SubgridIndex[cell.Value]] = trafo;
                        }
                    }
                }

                LambdaCellBoundaryQuadrature cellBoundaryQuadrature =
                    new LambdaCellBoundaryQuadrature(this, edgeRuleFactory, cellMask);
                cellBoundaryQuadrature.Execute();

                LambdaLevelSetSurfaceQuadrature surfaceQuadrature =
                    new LambdaLevelSetSurfaceQuadrature(this, surfaceRuleFactory, cellMask);
                surfaceQuadrature.Execute();

                // Must happen _after_ all parallel calls (e.g., definition of
                // the sub-grid or quadrature) in order to avoid problems in
                // parallel runs
                if (mask.NoOfItemsLocally == 0)
                {
                    var empty = new ChunkRulePair <QuadRule> [0];
                    return(empty);
                }

                if (cachedRules.ContainsKey(order))
                {
                    order = cachedRules.Keys.Where(cachedOrder => cachedOrder >= order).Min();
                    CellMask cachedMask = new CellMask(mask.GridData, cachedRules[order].Select(p => p.Chunk).ToArray());

                    if (cachedMask.Equals(mask))
                    {
                        return(cachedRules[order]);
                    }
                    else
                    {
                        throw new NotImplementedException(
                                  "Case not yet covered yet in combination with caching; deactivate caching to get rid of this message");
                    }
                }

                double[,] quadResults = cellBoundaryQuadrature.Results;
                foreach (Chunk chunk in mask)
                {
                    for (int i = 0; i < chunk.Len; i++)
                    {
                        int iSubGrid = localCellIndex2SubgridIndex[chunk.i0 + i];

                        switch (jumpType)
                        {
                        case JumpTypes.Heaviside:
                            for (int k = 0; k < noOfLambdas; k++)
                            {
                                quadResults[iSubGrid, k] -= surfaceQuadrature.Results[iSubGrid, k];
                            }
                            break;

                        case JumpTypes.OneMinusHeaviside:
                            for (int k = 0; k < noOfLambdas; k++)
                            {
                                quadResults[iSubGrid, k] += surfaceQuadrature.Results[iSubGrid, k];
                            }
                            break;

                        case JumpTypes.Sign:
                            for (int k = 0; k < noOfLambdas; k++)
                            {
                                quadResults[iSubGrid, k] -= 2.0 * surfaceQuadrature.Results[iSubGrid, k];
                            }
                            break;

                        default:
                            throw new NotImplementedException();
                        }
                    }
                }

                BitArray voidCellsArray = new BitArray(LevelSetData.GridDat.Cells.NoOfLocalUpdatedCells);
                BitArray fullCellsArray = new BitArray(LevelSetData.GridDat.Cells.NoOfLocalUpdatedCells);
                foreach (Chunk chunk in cellMask)
                {
                    foreach (var cell in chunk.Elements)
                    {
                        double rhsL2Norm = 0.0;
                        for (int k = 0; k < noOfLambdas; k++)
                        {
                            double entry = quadResults[localCellIndex2SubgridIndex[cell], k];
                            rhsL2Norm += entry * entry;
                        }

                        if (rhsL2Norm < 1e-14)
                        {
                            // All integrals are zero => cell not really cut
                            // (level set is tangent) and fully in void region
                            voidCellsArray[cell] = true;
                            continue;
                        }

                        double l2NormFirstIntegral = quadResults[localCellIndex2SubgridIndex[cell], 0];
                        l2NormFirstIntegral *= l2NormFirstIntegral;
                        double rhsL2NormWithoutFirst = rhsL2Norm - l2NormFirstIntegral;

                        // Beware: This check is only sensible if basis is orthonormal on RefElement!
                        if (rhsL2NormWithoutFirst < 1e-14 &&
                            Math.Abs(l2NormFirstIntegral - RefElement.Volume) < 1e-14)
                        {
                            // All integrals are zero except integral over first integrand
                            // If basis is orthonormal, this implies that cell is uncut and
                            // fully in non-void region since then
                            // \int_K \Phi_i dV = \int_A \Phi_i dV = \delta_{0,i}
                            // However, we have to compare RefElement.Volume since
                            // integration is performed in reference coordinates!
                            fullCellsArray[cell] = true;
                        }
                    }
                }

                var result = new List <ChunkRulePair <QuadRule> >(cellMask.NoOfItemsLocally);

                CellMask emptyCells = new CellMask(LevelSetData.GridDat, voidCellsArray);
                foreach (Chunk chunk in emptyCells)
                {
                    foreach (int cell in chunk.Elements)
                    {
                        QuadRule emptyRule = QuadRule.CreateEmpty(RefElement, 1, RefElement.SpatialDimension);
                        emptyRule.Nodes.LockForever();
                        result.Add(new ChunkRulePair <QuadRule>(
                                       Chunk.GetSingleElementChunk(cell), emptyRule));
                    }
                }

                CellMask fullCells = new CellMask(LevelSetData.GridDat, fullCellsArray);
                foreach (Chunk chunk in fullCells)
                {
                    foreach (int cell in chunk.Elements)
                    {
                        QuadRule fullRule = RefElement.GetQuadratureRule(order);
                        result.Add(new ChunkRulePair <QuadRule>(
                                       Chunk.GetSingleElementChunk(cell), fullRule));
                    }
                }

                CellMask realCutCells = cellMask.Except(emptyCells).Except(fullCells);
                if (RestrictNodes)
                {
                    foreach (Chunk chunk in realCutCells)
                    {
                        foreach (int cell in chunk.Elements)
                        {
                            CellMask singleElementMask = new CellMask(
                                LevelSetData.GridDat, Chunk.GetSingleElementChunk(cell));

                            AffineTrafo trafo = trafos[localCellIndex2SubgridIndex[cell]];
                            Debug.Assert(Math.Abs(trafo.Matrix.Determinant()) > 1e-10);

                            NodeSet nodes       = GetNodes(noOfLambdas).CloneAs();
                            NodeSet mappedNodes = new NodeSet(RefElement, trafo.Transform(nodes));
                            mappedNodes.LockForever();

                            // Remove nodes in negative part
                            MultidimensionalArray levelSetValues  = LevelSetData.GetLevSetValues(mappedNodes, cell, 1);
                            List <int>            nodesToBeCopied = new List <int>(mappedNodes.GetLength(0));
                            for (int n = 0; n < nodes.GetLength(0); n++)
                            {
                                if (levelSetValues[0, n] >= 0.0)
                                {
                                    nodesToBeCopied.Add(n);
                                }
                            }

                            NodeSet reducedNodes = new NodeSet(
                                this.RefElement, nodesToBeCopied.Count, D);
                            for (int n = 0; n < nodesToBeCopied.Count; n++)
                            {
                                for (int d = 0; d < D; d++)
                                {
                                    reducedNodes[n, d] = mappedNodes[nodesToBeCopied[n], d];
                                }
                            }
                            reducedNodes.LockForever();

                            QuadRule optimizedRule = GetOptimizedRule(
                                cell,
                                trafo,
                                reducedNodes,
                                quadResults,
                                order);

                            result.Add(new ChunkRulePair <QuadRule>(
                                           singleElementMask.Single(), optimizedRule));
                        }
                    }
                }
                else
                {
                    // Use same nodes in all cells
                    QuadRule[] optimizedRules = GetOptimizedRules(
                        realCutCells, GetNodes(noOfLambdas), quadResults, order);
                    int ruleIndex = 0;
                    foreach (Chunk chunk in realCutCells)
                    {
                        foreach (var cell in chunk.Elements)
                        {
                            result.Add(new ChunkRulePair <QuadRule>(
                                           Chunk.GetSingleElementChunk(cell), optimizedRules[ruleIndex]));
                            ruleIndex++;
                        }
                    }
                }

                cachedRules[order] = result.OrderBy(p => p.Chunk.i0).ToArray();
                return(cachedRules[order]);
            }
        }
예제 #16
0
        /// <summary>
        /// Paints on a pbgra32 WriteableBitmap with a stylized airbrush
        /// </summary>
        /// <param name="bmp">The bitmap to modify</param>
        /// <param name="from">The starting point of the stroke</param>
        /// <param name="to">The end point of the stroke</param>
        /// <param name="color">The color of the stroke</param>
        /// <param name="size">The size of the stroke</param>
        public static unsafe void Airbrush(WriteableBitmap bmp, Point from, Point to, Color color, int size)
        {
            Random r = new Random();

            if (bmp == null)
            {
                return;
            }

            bmp.Lock();

            // Create a line segment representation
            MyLine segment = new MyLine(from, to);

            // Get a bounding box for the painted area
            BoundingBox bitmapbounds  = new BoundingBox();
            BoundingBox segmentbounds = new BoundingBox();

            bitmapbounds.AddPoint(0, 0, 0);
            bitmapbounds.AddPoint(bmp.PixelWidth - 1, bmp.PixelHeight - 1, 0);

            segmentbounds.AddPoint((int)from.X, (int)from.Y, size + AirbrushRadio);
            segmentbounds.AddPoint((int)to.X, (int)to.Y, size + AirbrushRadio);
            segmentbounds.Clip(bitmapbounds);

            UInt32 *start  = (UInt32 *)bmp.BackBuffer.ToPointer();
            int     stride = bmp.BackBufferStride / sizeof(UInt32);

            // Move from 'from' to 'to' along timestep intervals, with one dot painted per interval
            for (int i = 0; i < AirbrushDots; i++)
            {
                int x, y;
                segment.Interpolate(i, AirbrushDots, out x, out y);

                int    dist  = r.Next() % size;
                double angle = r.NextDouble() * 2 * Math.PI;

                double dx = Math.Cos(angle) * dist;
                double dy = Math.Sqrt(dist * dist - dx * dx);
                if (angle > Math.PI)
                {
                    dy = -dy;
                }

                int bx = x + (int)dx;
                int by = y + (int)dy;

                BoundingBox dotbounds = new BoundingBox();

                dotbounds.AddPoint(bx, by, AirbrushRadio);
                dotbounds.Clip(bitmapbounds);

                for (int k = dotbounds.Top, row = 0; k < dotbounds.Bottom; k++, y++, row++)
                {
                    for (int j = dotbounds.Left, col = 0; j < dotbounds.Right; j++, col++)
                    {
                        WriteAlphaBlended(start + stride * k + j, Color.FromArgb(AirbrushBytes[row][col], color.R, color.G, color.B));
                    }
                }
            }

            bmp.AddDirtyRect(new Int32Rect(segmentbounds.Left, segmentbounds.Top, segmentbounds.Width, segmentbounds.Height));
            bmp.Unlock();
        }
예제 #17
0
        // From Eric Jordan's convex decomposition library
        /// <summary>
        /// Merges all parallel edges in the list of vertices
        /// </summary>
        /// <param name="tolerance"></param>
        public void MergeParallelEdges(double tolerance)
        {
            if (Count <= 3)
            {
                // Can't do anything useful here to a triangle
                return;
            }

            bool[] mergeMe      = new bool[Count];
            int    newNVertices = Count;

            //Gather points to process
            for (int i = 0; i < Count; ++i)
            {
                int lower  = (i == 0) ? (Count - 1) : (i - 1);
                int middle = i;
                int upper  = (i == Count - 1) ? (0) : (i + 1);

                double dx0   = this[middle].X - this[lower].X;
                double dy0   = this[middle].Y - this[lower].Y;
                double dx1   = this[upper].Y - this[middle].X;
                double dy1   = this[upper].Y - this[middle].Y;
                double norm0 = Math.Sqrt(dx0 * dx0 + dy0 * dy0);
                double norm1 = Math.Sqrt(dx1 * dx1 + dy1 * dy1);

                if (!(norm0 > 0.0 && norm1 > 0.0) && newNVertices > 3)
                {
                    //Merge identical points
                    mergeMe[i] = true;
                    --newNVertices;
                }

                dx0 /= norm0;
                dy0 /= norm0;
                dx1 /= norm1;
                dy1 /= norm1;
                double cross = dx0 * dy1 - dx1 * dy0;
                double dot   = dx0 * dx1 + dy0 * dy1;

                if (Math.Abs(cross) < tolerance && dot > 0 && newNVertices > 3)
                {
                    mergeMe[i] = true;
                    --newNVertices;
                }
                else
                {
                    mergeMe[i] = false;
                }
            }

            if (newNVertices == Count || newNVertices == 0)
            {
                return;
            }

            int currIndex = 0;

            // Copy the vertices to a new list and clear the old
            Point2DList oldVertices = new Point2DList(this);

            Clear();

            for (int i = 0; i < oldVertices.Count; ++i)
            {
                if (mergeMe[i] || newNVertices == 0 || currIndex == newNVertices)
                {
                    continue;
                }

                if (currIndex >= newNVertices)
                {
                    throw new Exception("Point2DList::MergeParallelEdges - currIndex[ " + currIndex + "] >= newNVertices[" + newNVertices + "]");
                }

                MPoints.Add(oldVertices[i]);
                BoundingBox = BoundingBox.AddPoint(oldVertices[i]);
                ++currIndex;
            }
            _windingOrder = CalculateWindingOrder();
            Epsilon       = CalculateEpsilon();
        }
예제 #18
0
        public static unsafe void Test2(WriteableBitmap bmp, Point from, Point to, Color color, int size)
        {
            Random r = new Random();

            AirbrushDots      = 500;
            AirbrushDotRadius = 2;

            if (bmp == null)
            {
                return;
            }

            bmp.Lock();

            // Create a line segment representation
            LineSegment segment = new LineSegment(from, to);

            // Get a bounding box for the painted area
            BoundingBox bitmapbounds  = new BoundingBox();
            BoundingBox segmentbounds = new BoundingBox();

            bitmapbounds.AddPoint(0, 0, 0);
            bitmapbounds.AddPoint(bmp.PixelWidth - 1, bmp.PixelHeight - 1, 0);

            segmentbounds.AddPoint((int)from.X, (int)from.Y, size + AirbrushDotRadius);
            segmentbounds.AddPoint((int)to.X, (int)to.Y, size + AirbrushDotRadius);
            segmentbounds.Clip(bitmapbounds);

            UInt32 *start  = (UInt32 *)bmp.BackBuffer.ToPointer();
            int     stride = bmp.BackBufferStride / sizeof(UInt32);

            // Move from 'from' to 'to' along timestep intervals, with one dot painted per interval
            for (int i = 0; i < AirbrushDots; i++)
            {
                int x, y;
                segment.Interpolate(i, AirbrushDots, out x, out y);

                int    dist  = r.Next() % size;
                double angle = r.NextDouble() * 2 * Math.PI;

                double dx = Math.Cos(angle) * dist;
                double dy = Math.Sqrt(dist * dist - dx * dx);
                if (angle > Math.PI)
                {
                    dy = -dy;
                }

                int bx = x + (int)dx;
                int by = y + (int)dy;
                //세로로 rainbow
                if (i < 50)
                {
                    if ((i % 5) == 0)
                    {
                        color = Colors.Red;
                        // color = Color.FromArgb(20, 132, 200, 249);
                        bx = x + 0;
                        by = y + 0;
                    }
                    if ((i % 5) == 1)
                    {
                        color = Colors.Red;
                        //color = Color.FromArgb(15, 133, 199, 247);
                        bx = x + 0;
                        by = y + 3;
                    }
                    if ((i % 5) == 2)
                    {
                        color = Colors.Red;
                        //color = Color.FromArgb(15, 133, 199, 247);
                        bx = x + 0;
                        by = y - 3;
                    }
                    if ((i % 5) == 3)
                    {
                        color = Colors.Red;
                        //color = Color.FromArgb(10, 124, 201, 255);
                        bx = x + 0;
                        by = y + 6;
                    }
                    if ((i % 5) == 4)
                    {
                        color = Colors.Red;
                        //color = Color.FromArgb(10, 124, 201, 255);
                        bx = x + 0;
                        by = y - 6;
                    }
                }
                if (i >= 50 && i < 100)
                {
                    if ((i % 5) == 0)
                    {
                        color = Colors.Orange;
                        // color = Color.FromArgb(20, 132, 200, 249);
                        bx = x + 0;
                        by = y + 0;
                    }
                    if ((i % 5) == 1)
                    {
                        color = Colors.Orange;
                        //color = Color.FromArgb(15, 133, 199, 247);
                        bx = x + 0;
                        by = y + 3;
                    }
                    if ((i % 5) == 2)
                    {
                        color = Colors.Orange;
                        //color = Color.FromArgb(15, 133, 199, 247);
                        bx = x + 0;
                        by = y - 3;
                    }
                    if ((i % 5) == 3)
                    {
                        color = Colors.Orange;
                        //color = Color.FromArgb(10, 124, 201, 255);
                        bx = x + 0;
                        by = y + 6;
                    }
                    if ((i % 5) == 4)
                    {
                        color = Colors.Orange;
                        //color = Color.FromArgb(10, 124, 201, 255);
                        bx = x + 0;
                        by = y - 6;
                    }
                }
                if (i >= 100 && i < 150)
                {
                    if ((i % 5) == 0)
                    {
                        color = Colors.Yellow;
                        // color = Color.FromArgb(20, 132, 200, 249);
                        bx = x + 0;
                        by = y + 0;
                    }
                    if ((i % 5) == 1)
                    {
                        color = Colors.Yellow;
                        //color = Color.FromArgb(15, 133, 199, 247);
                        bx = x + 0;
                        by = y + 3;
                    }
                    if ((i % 5) == 2)
                    {
                        color = Colors.Yellow;
                        //color = Color.FromArgb(15, 133, 199, 247);
                        bx = x + 0;
                        by = y - 3;
                    }
                    if ((i % 5) == 3)
                    {
                        color = Colors.Yellow;
                        //color = Color.FromArgb(10, 124, 201, 255);
                        bx = x + 0;
                        by = y + 6;
                    }
                    if ((i % 5) == 4)
                    {
                        color = Colors.Yellow;
                        //color = Color.FromArgb(10, 124, 201, 255);
                        bx = x + 0;
                        by = y - 6;
                    }
                }
                if (i >= 150 && i < 200)
                {
                    if ((i % 5) == 0)
                    {
                        color = Colors.Green;
                        // color = Color.FromArgb(20, 132, 200, 249);
                        bx = x + 0;
                        by = y + 0;
                    }
                    if ((i % 5) == 1)
                    {
                        color = Colors.Green;
                        //color = Color.FromArgb(15, 133, 199, 247);
                        bx = x + 0;
                        by = y + 3;
                    }
                    if ((i % 5) == 2)
                    {
                        color = Colors.Green;
                        //color = Color.FromArgb(15, 133, 199, 247);
                        bx = x + 0;
                        by = y - 3;
                    }
                    if ((i % 5) == 3)
                    {
                        color = Colors.Green;
                        //color = Color.FromArgb(10, 124, 201, 255);
                        bx = x + 0;
                        by = y + 6;
                    }
                    if ((i % 5) == 4)
                    {
                        color = Colors.Green;
                        //color = Color.FromArgb(10, 124, 201, 255);
                        bx = x + 0;
                        by = y - 6;
                    }
                }
                if (i >= 200 && i < 250)
                {
                    if ((i % 5) == 0)
                    {
                        color = Colors.Blue;
                        // color = Color.FromArgb(20, 132, 200, 249);
                        bx = x + 0;
                        by = y + 0;
                    }
                    if ((i % 5) == 1)
                    {
                        color = Colors.Blue;
                        //color = Color.FromArgb(15, 133, 199, 247);
                        bx = x + 0;
                        by = y + 3;
                    }
                    if ((i % 5) == 2)
                    {
                        color = Colors.Blue;
                        //color = Color.FromArgb(15, 133, 199, 247);
                        bx = x + 0;
                        by = y - 3;
                    }
                    if ((i % 5) == 3)
                    {
                        color = Colors.Blue;
                        //color = Color.FromArgb(10, 124, 201, 255);
                        bx = x + 0;
                        by = y + 6;
                    }
                    if ((i % 5) == 4)
                    {
                        color = Colors.Blue;
                        //color = Color.FromArgb(10, 124, 201, 255);
                        bx = x + 0;
                        by = y - 6;
                    }
                }
                if (i >= 250 && i < 300)
                {
                    if ((i % 5) == 0)
                    {
                        color = Colors.Indigo;
                        // color = Color.FromArgb(20, 132, 200, 249);
                        bx = x + 0;
                        by = y + 0;
                    }
                    if ((i % 5) == 1)
                    {
                        color = Colors.Indigo;
                        //color = Color.FromArgb(15, 133, 199, 247);
                        bx = x + 0;
                        by = y + 3;
                    }
                    if ((i % 5) == 2)
                    {
                        color = Colors.Indigo;
                        //color = Color.FromArgb(15, 133, 199, 247);
                        bx = x + 0;
                        by = y - 3;
                    }
                    if ((i % 5) == 3)
                    {
                        color = Colors.Indigo;
                        //color = Color.FromArgb(10, 124, 201, 255);
                        bx = x + 0;
                        by = y + 6;
                    }
                    if ((i % 5) == 4)
                    {
                        color = Colors.Indigo;
                        //color = Color.FromArgb(10, 124, 201, 255);
                        bx = x + 0;
                        by = y - 6;
                    }
                }
                if (i >= 300 && i < 350)
                {
                    if ((i % 5) == 0)
                    {
                        color = Colors.BlueViolet;
                        // color = Color.FromArgb(20, 132, 200, 249);
                        bx = x + 0;
                        by = y + 0;
                    }
                    if ((i % 5) == 1)
                    {
                        color = Colors.BlueViolet;
                        //color = Color.FromArgb(15, 133, 199, 247);
                        bx = x + 0;
                        by = y + 3;
                    }
                    if ((i % 5) == 2)
                    {
                        color = Colors.BlueViolet;
                        //color = Color.FromArgb(15, 133, 199, 247);
                        bx = x + 0;
                        by = y - 3;
                    }
                    if ((i % 5) == 3)
                    {
                        color = Colors.BlueViolet;
                        //color = Color.FromArgb(10, 124, 201, 255);
                        bx = x + 0;
                        by = y + 6;
                    }
                    if ((i % 5) == 4)
                    {
                        color = Colors.BlueViolet;
                        //color = Color.FromArgb(10, 124, 201, 255);
                        bx = x + 0;
                        by = y - 6;
                    }
                }

                BoundingBox dotbounds = new BoundingBox();

                dotbounds.AddPoint(bx, by, AirbrushDotRadius);
                dotbounds.Clip(bitmapbounds);

                for (int k = dotbounds.Top, row = 0; k < dotbounds.Bottom; k++, y++, row++)
                {
                    for (int j = dotbounds.Left, col = 0; j < dotbounds.Right; j++, col++)
                    {
                        WriteAlphaBlended(start + stride * k + j, Color.FromArgb(AirbrushDotKernel[row][col], color.R, color.G, color.B));
                    }
                }
            }

            bmp.AddDirtyRect(new Int32Rect(segmentbounds.Left, segmentbounds.Top, segmentbounds.Width, segmentbounds.Height));
            bmp.Unlock();
        }
예제 #19
0
        public static unsafe void Brush(WriteableBitmap bmp, Point from, Point to, Point?previous, Color color, int size)
        {
            if (bmp == null)
            {
                return;
            }


            bmp.Lock();
            int  sizesize  = size * size;
            uint flatcolor = (uint)((int)color.A << 24) + (uint)((int)color.R << 16) + (uint)((int)color.G << 8) + color.B;

            LineSegment linesegment   = new LineSegment(from, to);
            BoundingBox bitmapbounds  = new BoundingBox();
            BoundingBox segmentbounds = new BoundingBox();

            bitmapbounds.AddPoint(0, 0, 0);
            bitmapbounds.AddPoint(bmp.PixelWidth - 1, bmp.PixelHeight - 1, 0);

            segmentbounds.AddPoint((int)from.X, (int)from.Y, size);
            segmentbounds.AddPoint((int)to.X, (int)to.Y, size);
            segmentbounds.Clip(bitmapbounds);

            UInt32 *start = (UInt32 *)bmp.BackBuffer.ToPointer();

            start += segmentbounds.Left;

            if (previous.HasValue)
            {
                LineSegment previoussegment = new LineSegment(previous.Value, from);

                for (int y = segmentbounds.Top; y < segmentbounds.Bottom; y++)
                {
                    UInt32 *pixel = start + bmp.BackBufferStride / sizeof(UInt32) * y;

                    for (int x = segmentbounds.Left; x < segmentbounds.Right; x++)
                    {
                        if (linesegment.DistanceSquared(x, y) <= sizesize && previoussegment.DistanceSquared(x, y) > sizesize)
                        {
                            if (color.A == 255)
                            {
                                *pixel = flatcolor;
                            }
                            else
                            {
                                WriteAlphaBlended(pixel, color);
                            }
                        }


                        pixel++;
                    }
                }
            }
            else
            {
                for (int y = segmentbounds.Top; y < segmentbounds.Bottom; y++)
                {
                    UInt32 *pixel = start + bmp.BackBufferStride / sizeof(UInt32) * y;

                    for (int x = segmentbounds.Left; x < segmentbounds.Right; x++)
                    {
                        if (linesegment.DistanceSquared(x, y) <= sizesize)
                        {
                            if (color.A == 255)
                            {
                                *pixel = flatcolor;
                            }
                            else
                            {
                                WriteAlphaBlended(pixel, color);
                            }
                        }


                        pixel++;
                    }
                }
            }



            bmp.AddDirtyRect(new Int32Rect(segmentbounds.Left, segmentbounds.Top, segmentbounds.Width, segmentbounds.Height));
            bmp.Unlock();
        }
예제 #20
0
        public void AddBlock(string block, Action action)
        {
            if (action == Action.New)
            {
                if (Loaded)
                {
                    gcode.Rows.Clear();
                }

                Reset();
                commands.Clear();
                gcode.BeginLoadData();

                filename = block;
            }
            else if (block != null && block.Trim().Length > 0)
            {
                try
                {
                    if (Parser.ParseBlock(block.Trim(), false))
                    {
                        gcode.Rows.Add(new object[] { LineNumber++, block, block.Length + 1, true, Parser.ProgramEnd, "", false });
                        while (commands.Count > 0)
                        {
                            gcode.Rows.Add(new object[] { LineNumber++, commands.Dequeue(), 20, true, false, "", false });
                        }
                    }
                }
                catch //(Exception e)
                {
                    //
                }
            }

            if (action == Action.End)
            {
                gcode.EndLoadData();

                //        GCodeParser.Save(@"d:\tokens.xml", Tokens);

                foreach (GCodeToken token in Tokens)
                {
                    //min_feed = Math.Min(min_feed, token.f);
                    //max_feed = Math.Max(max_feed, token.f);
                    if (token is GCLinearMotion)
                    {
                        BoundingBox.AddPoint(((GCLinearMotion)token).X, ((GCLinearMotion)token).Y, ((GCLinearMotion)token).Z);
                    }
                    else if (token is GCArc)
                    {
                        BoundingBox.AddPoint(((GCArc)token).X, ((GCArc)token).Y, ((GCArc)token).Z); // TODO: Expand...
                    }
                    else if (token is GCCannedDrill)
                    {
                        BoundingBox.AddPoint(((GCCannedDrill)token).X, ((GCCannedDrill)token).Y, ((GCCannedDrill)token).Z);
                    }
                }

                if (max_feed == double.MinValue)
                {
                    min_feed = 0.0;
                    max_feed = 0.0;
                }

                BoundingBox.Normalize();

                FileChanged?.Invoke(filename);
            }
        }
예제 #21
0
        /// <summary>
        /// Paints on a pbgra32 WriteableBitmap like a paintbrush
        /// </summary>
        /// <param name="bmp">The bitmap to modify</param>
        /// <param name="from">The starting point of the stroke</param>
        /// <param name="to">The end point of the stroke</param>
        /// <param name="previous">The point prior to the 'from' point, or null</param>
        /// <param name="color">The color of the brush</param>
        /// <param name="size">The stroke size</param>
        public static unsafe void Brush(WriteableBitmap bmp, Point from, Point to, Point?previous, Color color, int size)
        {
            if (bmp == null)
            {
                return;
            }

            bmp.Lock();

            // Intermediate storage of the square of the size
            int  sizesize  = size * size;
            uint flatcolor = (uint)((int)color.A << 24) + (uint)((int)color.R << 16) + (uint)((int)color.G << 8) + color.B;

            // Create a line segment representation to compare distance to
            MyLine linesegment = new MyLine(from, to);

            // Get a bounding box for the line segment
            BoundingBox bitmapbounds  = new BoundingBox();
            BoundingBox segmentbounds = new BoundingBox();

            bitmapbounds.AddPoint(0, 0, 0);
            bitmapbounds.AddPoint(bmp.PixelWidth - 1, bmp.PixelHeight - 1, 0);

            segmentbounds.AddPoint((int)from.X, (int)from.Y, size);
            segmentbounds.AddPoint((int)to.X, (int)to.Y, size);
            segmentbounds.Clip(bitmapbounds);

            // Get a pointer to the back buffer (we use an int pointer here, since we can safely assume a 32-bit pixel format)
            UInt32 *start = (UInt32 *)bmp.BackBuffer.ToPointer();

            // Move the starting pixel to the x offset
            start += segmentbounds.Left;

            if (previous.HasValue)
            {
                MyLine previoussegment = new MyLine(previous.Value, from);

                // Loop through the relevant portion of the image and figure out which pixels need to be erased
                for (int y = segmentbounds.Top; y < segmentbounds.Bottom; y++)
                {
                    UInt32 *pixel = start + bmp.BackBufferStride / sizeof(UInt32) * y;

                    for (int x = segmentbounds.Left; x < segmentbounds.Right; x++)
                    {
                        if (linesegment.DistanceSquared(x, y) <= sizesize && previoussegment.DistanceSquared(x, y) > sizesize)
                        {
                            if (color.A == 255)
                            {
                                *pixel = flatcolor;
                            }
                            else
                            {
                                WriteAlphaBlended(pixel, color);
                            }
                        }

                        // Move to the next pixel
                        pixel++;
                    }
                }
            }
            else
            {
                // Loop through the relevant portion of the image and figure out which pixels need to be erased
                for (int y = segmentbounds.Top; y < segmentbounds.Bottom; y++)
                {
                    UInt32 *pixel = start + bmp.BackBufferStride / sizeof(UInt32) * y;

                    for (int x = segmentbounds.Left; x < segmentbounds.Right; x++)
                    {
                        if (linesegment.DistanceSquared(x, y) <= sizesize)
                        {
                            if (color.A == 255)
                            {
                                *pixel = flatcolor;
                            }
                            else
                            {
                                WriteAlphaBlended(pixel, color);
                            }
                        }

                        // Move to the next pixel
                        pixel++;
                    }
                }
            }

            bmp.AddDirtyRect(new Int32Rect(segmentbounds.Left, segmentbounds.Top, segmentbounds.Width, segmentbounds.Height));
            bmp.Unlock();
        }
예제 #22
0
        public static unsafe void Test4(WriteableBitmap bmp, Point from, Point to, Color color, int size)
        {
            AirbrushDots      = 1000;
            AirbrushDotRadius = 4;

            if (bmp == null)
            {
                return;
            }
            bmp.Lock();
            // Create a line segment representation
            LineSegment segment = new LineSegment(from, to);

            //  Get a bounding box for the painted area
            BoundingBox bitmapbounds  = new BoundingBox();
            BoundingBox segmentbounds = new BoundingBox();

            bitmapbounds.AddPoint(0, 0, 0);
            bitmapbounds.AddPoint(bmp.PixelWidth - 1, bmp.PixelHeight - 1, 0);

            segmentbounds.AddPoint((int)from.X, (int)from.Y, size + 500 + AirbrushDotRadius);
            segmentbounds.AddPoint((int)to.X, (int)to.Y, size + 500 + AirbrushDotRadius);
            segmentbounds.Clip(bitmapbounds);

            UInt32 *start  = (UInt32 *)bmp.BackBuffer.ToPointer();
            int     stride = bmp.BackBufferStride / sizeof(UInt32);

            // Move from 'from' to 'to' along timestep intervals, with one dot painted per interval
            for (int i = 0; i < AirbrushDots; i++)
            {
                int x, y;
                segment.Interpolate(i, AirbrushDots, out x, out y);

                //int dist =size;
                //double angle =2 * Math.PI;

                //double dx = Math.Cos(angle) * dist;
                //double dy = Math.Sqrt(dist * dist - dx * dx);
                //if (angle > Math.PI) dy = -dy;

                int bx = x;
                int by = y;

                if (i % 4 == 0)
                {
                    bx = x + 500;
                    by = y + 500;
                }
                else if (i % 4 == 1)
                {
                    bx = x - 500;
                    by = y + 500;
                }
                else if (i % 4 == 2)
                {
                    bx = x + 500;
                    by = y - 500;
                }
                else if (i % 4 == 3)
                {
                    bx = x - 500;
                    by = y - 500;
                }


                //switch (i % 4)
                //{
                //    case 0:
                //       bx=
                //}

                BoundingBox dotbounds = new BoundingBox();

                dotbounds.AddPoint(bx, by, AirbrushDotRadius);
                dotbounds.Clip(bitmapbounds);

                for (int k = dotbounds.Top, row = 0; k < dotbounds.Bottom; k++, y++, row++)
                {
                    for (int j = dotbounds.Left, col = 0; j < dotbounds.Right; j++, col++)
                    {
                        WriteAlphaBlended(start + stride * k + j, Color.FromArgb(AirbrushDotKernel[row][col], color.R, color.G, color.B));
                    }
                }
            }

            bmp.AddDirtyRect(new Int32Rect(segmentbounds.Left, segmentbounds.Top, segmentbounds.Width, segmentbounds.Height));
            bmp.Unlock();
        }
예제 #23
0
파일: Atoms.cs 프로젝트: kwstanths/MRend
    void Start()
    {
        List <Atom>        atoms;
        List <List <int> > connections;
        string             model_name;

        try {
            model_name = ParseInputModelFile();
            PDBParser.ParseAtomsAndConnections(@"Assets/MModels/" + model_name, out atoms, out connections);
        }
        catch (System.IO.IOException) {
            print("Parsing input error");
            return;
        }


        /*  Spawn the objects */
        foreach (Atom atom in atoms)
        {
            /* Units in Nano meters */
            Vector3 atom_position = new Vector3(atom.x_, atom.y_, atom.z_);
            atoms_bounding_box_.AddPoint(atom_position);

            /* Instantiate the atom */
            GameObject temp = Instantiate(prefab_atom, atom_position, Quaternion.identity);
            temp.transform.parent = transform;
            temp.isStatic         = this.gameObject.isStatic;

            /* Find ISphere component, and set the atom information */
            ISphere isphere = temp.GetComponent <ISphere>();
            isphere.atom_ = atom;
            ispheres_.Add(isphere);

            /* Insert to the dictionaries used */
            InsertToAtomsDictionary(isphere);
            InsertToResiudesDictionary(isphere);
            InsertToChainsDictionary(isphere);
        }

        /* Parse connections, currently the application does not do something with these connections */
        foreach (List <int> c in connections)
        {
            int atom_id = c[0];
            for (int i = 1; i < c.Count; i++)
            {
                ISphere connection_isphere = ispheres_[c[i]];
                ispheres_[atom_id].connections_.Add(connection_isphere);
            }
        }

        /* Spawn bonds */
        Transform bonds_transform = transform.GetChild(0);
        int       bonds           = 0;

        /* For all resisudes */
        foreach (KeyValuePair <int, List <ISphere> > value in residue_dictionary)
        {
            /* Get combinations of two atoms */
            List <ISphere> resiude_atoms = value.Value;
            for (int ia = 0; ia < resiude_atoms.Count; ia++)
            {
                ISphere a                 = resiude_atoms[ia];
                Vector3 a_position        = a.transform.position;
                float   a_covalent_radius = AtomicRadii.GetCovalentRadius(a.atom_.element_);
                for (int ib = 0; ib < resiude_atoms.Count; ib++)
                {
                    if (!(ia > ib))
                    {
                        continue;
                    }
                    ISphere b = resiude_atoms[ib];

                    Vector3 b_position        = b.transform.position;
                    float   b_covalent_radius = AtomicRadii.radii_covalent[b.atom_.element_];

                    /* If their distance is smaller then the sume of radius + plus a bias, then spawn a bond */
                    float distance = Vector3.Distance(a_position, b_position);
                    if (distance <= a_covalent_radius + b_covalent_radius + 0.015)
                    {
                        bonds++;
                        GameObject temp = Instantiate(prefab_bond, a_position, Quaternion.identity);
                        temp.transform.parent = bonds_transform;
                        temp.isStatic         = this.gameObject.isStatic;

                        /* Rotate it accordingly */
                        Vector3    direction  = b_position - a_position;
                        Quaternion toRotation = Quaternion.FromToRotation(new Vector3(0, 1, 0), direction);
                        temp.transform.rotation = toRotation;

                        /* Set size and radius */
                        ICylinder icylinder = temp.GetComponent <ICylinder>();
                        icylinder.radius_ = AtomicRadii.ball_and_stick_bond_radius;
                        icylinder.height_ = distance;
                    }
                }
            }
        }
        Debug.Log("Spawned: " + bonds + " bonds");

        /* Position the model and the camera in the world */
        SetCameraAndPanelBoxPosition(atoms_bounding_box_);

        bonds_selected_[0] = null;
        bonds_selected_[1] = null;

        /* Set some default info on the world panel */
        SELECTION_MODE_SPHERE_RADIUS = AtomicRadii.ball_and_stick_radius * 5.0f;
        transform.GetChild(1).GetComponent <ModePanel>().SetRadius(SELECTION_MODE_SPHERE_RADIUS);

        info_ui_ = Camera.main.transform.Find("AtomInfoBox").GetComponent <AtomInfoBox>();
    }
예제 #24
0
        public void AddBlock(string block, Action action)
        {
            if (action == Action.New)
            {
                if (Loaded)
                {
                    gcode.Rows.Clear();
                }

                Reset();
                commands.Clear();
                gcode.BeginLoadData();

                filename = block;
            }
            else if (block != null && block.Trim().Length > 0)
            {
                try
                {
                    bool isComment;
                    block = block.Trim();
                    if (Parser.ParseBlock(ref block, false, out isComment))
                    {
                        gcode.Rows.Add(new object[] { LineNumber++, block, block.Length + 1, true, isComment, Parser.ProgramEnd, "", false });
                        while (commands.Count > 0)
                        {
                            block = commands.Dequeue();
                            gcode.Rows.Add(new object[] { LineNumber++, block, block.Length + 1, true, false, false, "", false });
                        }
                    }
                }
                catch //(Exception e)
                {
                    //
                }
            }

            if (action == Action.End)
            {
                gcode.EndLoadData();

#if DEBUG
                System.Diagnostics.Stopwatch stopWatch = new System.Diagnostics.Stopwatch();
                stopWatch.Start();
#endif

                // Calculate program limits (bounding box)

                GCodeEmulator emu = new GCodeEmulator(true);

                foreach (var cmd in emu.Execute(Tokens))
                {
                    if (cmd.Token is GCArc)
                    {
                        BoundingBox.AddBoundingBox((cmd.Token as GCArc).GetBoundingBox(emu.Plane, new double[] { cmd.Start.X, cmd.Start.Y, cmd.Start.Z }, emu.DistanceMode == DistanceMode.Incremental));
                    }
                    else if (cmd.Token is GCSpline)
                    {
                        BoundingBox.AddBoundingBox((cmd.Token as GCSpline).GetBoundingBox(emu.Plane, new double[] { cmd.Start.X, cmd.Start.Y, cmd.Start.Z }, emu.DistanceMode == DistanceMode.Incremental));
                    }
                    else
                    {
                        BoundingBox.AddPoint(cmd.End);
                    }
                }

                BoundingBox.Conclude();

#if DEBUG
                stopWatch.Stop();
#endif

                //GCodeParser.Save(@"d:\tokens.xml", Parser.Tokens);
                //GCodeParser.Save(@"d:\file.nc", GCodeParser.TokensToGCode(Parser.Tokens));

                FileChanged?.Invoke(filename);
            }
        }