예제 #1
0
        public static void GenerateSdf_legacy(FloatBmp output,
                                              Shape shape,
                                              double range,
                                              Vector2 scale,
                                              Vector2 translate)
        {
            int w = output.Width;
            int h = output.Height;

            for (int y = 0; y < h; ++y)
            {
                int row = shape.InverseYAxis ? h - y - 1 : y;
                for (int x = 0; x < w; ++x)
                {
                    double         dummy       = 0;
                    Vector2        p           = (new Vector2(x + 0.5f, y + 0.5) * scale) - translate;
                    SignedDistance minDistance = SignedDistance.INFINITE;
                    //TODO: review here
                    List <Contour> contours = shape.contours;
                    int            m        = contours.Count;
                    for (int n = 0; n < m; ++n)
                    {
                        Contour           contour = contours[n];
                        List <EdgeHolder> edges   = contour.edges;
                        int nn = edges.Count;
                        for (int i = 0; i < nn; ++i)
                        {
                            EdgeHolder     edge     = edges[i];
                            SignedDistance distance = edge.edgeSegment.signedDistance(p, out dummy);
                            if (distance < minDistance)
                            {
                                minDistance = distance;
                            }
                        }
                    }
                    output.SetPixel(x, row, (float)(minDistance.distance / (range + 0.5f)));
                }
            }
        }
예제 #2
0
        //siged distance field generator

        public static void GenerateSdf(FloatBmp output,
                                       Shape shape,
                                       double range,
                                       Vector2 scale,
                                       Vector2 translate)
        {
            List <Contour> contours = shape.contours;
            int            contourCount = contours.Count;
            int            w = output.Width, h = output.Height;
            List <int>     windings = new List <int>(contourCount);

            for (int i = 0; i < contourCount; ++i)
            {
                windings.Add(contours[i].winding());
            }

            //# ifdef MSDFGEN_USE_OPENMP
            //#pragma omp parallel
            //#endif
            {
                //# ifdef MSDFGEN_USE_OPENMP
                //#pragma omp for
                //#endif
                double[] contourSD = new double[contourCount];
                for (int y = 0; y < h; ++y)
                {
                    int row = shape.InverseYAxis ? h - y - 1 : y;
                    for (int x = 0; x < w; ++x)
                    {
                        double  dummy   = 0;
                        Vector2 p       = (new Vector2(x + .5, y + .5) / scale) - translate;
                        double  negDist = -SignedDistance.INFINITE.distance;
                        double  posDist = SignedDistance.INFINITE.distance;
                        int     winding = 0;


                        for (int i = 0; i < contourCount; ++i)
                        {
                            Contour           contour     = contours[i];
                            SignedDistance    minDistance = SignedDistance.INFINITE;
                            List <EdgeHolder> edges       = contour.edges;
                            int edgeCount = edges.Count;
                            for (int ee = 0; ee < edgeCount; ++ee)
                            {
                                EdgeHolder     edge     = edges[ee];
                                SignedDistance distance = edge.edgeSegment.signedDistance(p, out dummy);
                                if (distance < minDistance)
                                {
                                    minDistance = distance;
                                }
                            }

                            contourSD[i] = minDistance.distance;
                            if (windings[i] > 0 && minDistance.distance >= 0 && Math.Abs(minDistance.distance) < Math.Abs(posDist))
                            {
                                posDist = minDistance.distance;
                            }
                            if (windings[i] < 0 && minDistance.distance <= 0 && Math.Abs(minDistance.distance) < Math.Abs(negDist))
                            {
                                negDist = minDistance.distance;
                            }
                        }

                        double sd = SignedDistance.INFINITE.distance;
                        if (posDist >= 0 && Math.Abs(posDist) <= Math.Abs(negDist))
                        {
                            sd      = posDist;
                            winding = 1;
                            for (int i = 0; i < contourCount; ++i)
                            {
                                if (windings[i] > 0 && contourSD[i] > sd && Math.Abs(contourSD[i]) < Math.Abs(negDist))
                                {
                                    sd = contourSD[i];
                                }
                            }
                        }
                        else if (negDist <= 0 && Math.Abs(negDist) <= Math.Abs(posDist))
                        {
                            sd      = negDist;
                            winding = -1;
                            for (int i = 0; i < contourCount; ++i)
                            {
                                if (windings[i] < 0 && contourSD[i] < sd && Math.Abs(contourSD[i]) < Math.Abs(posDist))
                                {
                                    sd = contourSD[i];
                                }
                            }
                        }
                        for (int i = 0; i < contourCount; ++i)
                        {
                            if (windings[i] != winding && Math.Abs(contourSD[i]) < Math.Abs(sd))
                            {
                                sd = contourSD[i];
                            }
                        }

                        output.SetPixel(x, row, (float)(sd / range + .5));
                    }
                }
            }
        }