public Shape GetAsShape() { var shape = new Shape(); int from = 0; int to = -1; for(int e = 0; e < EndPtsOfContours.Length; e++) { from = to + 1; to = EndPtsOfContours[e]; ExtractPath(shape, from, to); } return shape; }
public static VectorMesh TriangulateShape(Shape shape) { P2T.CreateContext(TriangulationAlgorithm.DTSweep); var vertexBufferGenerator = new BufferGenerator(); var indexBufferGenerator = new BufferGenerator(); int indexCount = 0; foreach(var path in shape.Paths) { AddPathToBuffers(path, vertexBufferGenerator, indexBufferGenerator, ref indexCount); } var vertexBuffer = BufferFactory.Allocate(BufferTarget.ArrayBuffer, BufferUsageHint.StaticDraw, vertexBufferGenerator.GetBuffer()); var indexBuffer = BufferFactory.Allocate(BufferTarget.ElementArrayBuffer, BufferUsageHint.StaticDraw, indexBufferGenerator.GetBuffer()); return new VectorMesh(vertexBuffer, indexBuffer, indexCount); }
private void ExtractPath(Shape shape, int from, int to) { double factor = 2000.0; var winding = 0.0; int length = to - from; Point pa, pb; int a, b; var path = new Path(); int i = 0; while (i <= length) { a = i; int j = i + 1; while (j <= length && (Flags[from + j] & GlyphFlag.OnCurve) != GlyphFlag.OnCurve) j++; b = (j) % (length + 1); int padding = j - i; pa = new Point(Points[from + a].X / factor, Points[from + a].Y / factor); pb = new Point(Points[from + b].X / factor, Points[from + b].Y / factor); if(padding > 3) { //TODO var pc = new Point(Points[from + a + 1].X / factor, Points[from + a + 1].Y / factor); path.AddPathSegment(new QuadraticCurveSegment(pa, pc, pb) { Convex = true }); } else if(padding == 3) { //TODO var pc = new Point(Points[from + a + 1].X / factor, Points[from + a + 1].Y / factor); path.AddPathSegment(new QuadraticCurveSegment(pa, pc, pb) { Convex = true }); } else if(padding == 2) { var pc = new Point(Points[from + a + 1].X / factor, Points[from + a + 1].Y / factor); path.AddPathSegment(new QuadraticCurveSegment(pa, pc, pb) { Convex = true }); } else { path.AddPathSegment(new LineSegment(pa, pb)); } winding += (pb.X - pa.X) * (pb.Y + pa.Y); i = j; } if (winding >= 0.0) path.CompositMode = CompositMode.Add; else path.CompositMode = CompositMode.Subtract; foreach(var segment in path.Segments) { if(segment is QuadraticCurveSegment) { var qcs = segment as QuadraticCurveSegment; var sign = Math.Sign(((qcs.End.X - qcs.Start.X) * (qcs.ControlPoint.Y - qcs.Start.Y)) - ((qcs.End.Y - qcs.Start.Y) * (qcs.ControlPoint.X - qcs.Start.X))); if(path.CompositMode == CompositMode.Subtract) qcs.Convex = sign >= 0.0 ? false : true; else qcs.Convex = sign >= 0.0 ? true : false; } } shape.AddPath(path); }