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))); } } }
//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)); } } } }