public static TriangleInfoList ConvertStringToTrianglesWithOuterPath(string text, FontStyle fontStyle, Polygon outerPath, out PolygonSet textAsPolygonSet, float glyphFontSize = 50f)
        {
            FontFamily fontFamily = FontFamily.GenericSansSerif;

            textAsPolygonSet = new PolygonSet();

            var triangles = new TriangleInfoList();

            try
            {
                var textAsPolygons = GeneratePolygonsFromGlyph(fontFamily, fontStyle, text, glyphFontSize, true);
                textAsPolygonSet = CreateSetFromList(textAsPolygons);
                var polygonSetWithOuterPath = new PolygonSet();
                foreach (var t in textAsPolygonSet.Polygons)
                {
                    foreach (var hole in t.Holes)
                    {
                        polygonSetWithOuterPath.Add(hole);
                    }
                    //t.Holes.Clear();
                    outerPath.Holes.Add(t);
                }
                polygonSetWithOuterPath.Add(outerPath);


                P2T.Triangulate(polygonSetWithOuterPath);

                foreach (var polygon in polygonSetWithOuterPath.Polygons)
                {
                    foreach (var polyTriangle in polygon.Triangles)
                    {
                        var triangle      = new Triangle();
                        var triangleIndex = 0;
                        foreach (var trianglePoint in polyTriangle.Points)
                        {
                            triangle.Vectors[triangleIndex].Position.X = (float)trianglePoint.X;
                            triangle.Vectors[triangleIndex].Position.Y = (float)trianglePoint.Y;

                            triangleIndex++;
                        }

                        triangles[0].Add(triangle);
                    }
                }
            }
            catch (Exception exc)
            {
                Debug.WriteLine(exc);
            }

            return(triangles);
        }
Exemple #2
0
 static void ProcessSetLevel(PolygonSet set, PolygonHierachy current)
 {
     while (current != null)
     {
         var poly = current.Current;
         foreach (var child in current.Childs)
         {
             poly.AddHole(child.Current);
             foreach (var grandchild in child.Childs)
             {
                 ProcessSetLevel(set, grandchild);
             }
         }
         set.Add(poly);
         current = current.Next;
     }
 }
Exemple #3
0
 static void InsertIntoSet(PolygonSet set, Polygon poly)
 {
     //first test to see if any of the existing polygons are inside our input.
     for (int i = set.Polygons.Count - 1; i >= 0; i--)
     {
         if (TryInsertHole(poly, set.Polygons[i]))
         {
             set.Polygons.RemoveAt(i); //we go from the end, so the indices remain valid.
         }
     }
     foreach (var item in set.Polygons)
     {
         if (TryInsertHole(item, poly))
         {
             return; //nothing more to do.
         }
     }
     set.Add(poly);
 }
Exemple #4
0
        public IEnumerable <MapObject> Create(IDGenerator generator, Box box, ITexture texture, int roundDecimals)
        {
            var width   = box.Width;
            var length  = Math.Max(1, Math.Abs((int)box.Length));
            var height  = box.Height;
            var flatten = (float)_flattenFactor.Value;
            var text    = _text.GetValue();

            var family = _fontChooser.GetFontFamily();
            var style  = Enum.GetValues(typeof(FontStyle)).OfType <FontStyle>().FirstOrDefault(fs => family.IsStyleAvailable(fs));

            if (!family.IsStyleAvailable(style))
            {
                family = FontFamily.GenericSansSerif;
            }

            var set = new PolygonSet();

            var sizes = new List <RectangleF>();

            using (var bmp = new Bitmap(1, 1))
            {
                using (var g = System.Drawing.Graphics.FromImage(bmp))
                {
                    using (var font = new Font(family, length, style, GraphicsUnit.Pixel))
                    {
                        for (var i = 0; i < text.Length; i += 32)
                        {
                            using (var sf = new StringFormat(StringFormat.GenericTypographic))
                            {
                                var rem   = Math.Min(text.Length, i + 32) - i;
                                var range = Enumerable.Range(0, rem).Select(x => new CharacterRange(x, 1)).ToArray();
                                sf.SetMeasurableCharacterRanges(range);
                                var reg = g.MeasureCharacterRanges(text.Substring(i, rem), font, new RectangleF(0, 0, float.MaxValue, float.MaxValue), sf);
                                sizes.AddRange(reg.Select(x => x.GetBounds(g)));
                            }
                        }
                    }
                }
            }

            var xOffset = box.Start.DX;
            var yOffset = box.End.DY;

            for (var ci = 0; ci < text.Length; ci++)
            {
                var c    = text[ci];
                var size = sizes[ci];

                var gp = new GraphicsPath();
                gp.AddString(c.ToString(CultureInfo.InvariantCulture), family, (int)style, length, new PointF(0, 0), StringFormat.GenericTypographic);
                gp.Flatten(new System.Drawing.Drawing2D.Matrix(), flatten);

                var polygons = new List <Polygon>();
                var poly     = new List <PolygonPoint>();

                for (var i = 0; i < gp.PointCount; i++)
                {
                    var type  = gp.PathTypes[i];
                    var point = gp.PathPoints[i];

                    poly.Add(new PolygonPoint(point.X + xOffset, -point.Y + yOffset));

                    if ((type & 0x80) == 0x80)
                    {
                        polygons.Add(new Polygon(poly));
                        poly.Clear();
                    }
                }

                var     tri     = new List <Polygon>();
                Polygon polygon = null;
                foreach (var p in polygons)
                {
                    if (polygon == null)
                    {
                        polygon = p;
                        tri.Add(p);
                    }
                    else if (p.CalculateWindingOrder() != polygon.CalculateWindingOrder())
                    {
                        polygon.AddHole(p);
                    }
                    else
                    {
                        polygon = null;
                        tri.Add(p);
                    }
                }

                foreach (var pp in tri)
                {
                    try
                    {
                        P2T.Triangulate(pp);
                        set.Add(pp);
                    }
                    catch
                    {
                        // Ignore
                    }
                }

                xOffset += size.Width;
            }

            var zOffset = box.Start.Z;

            foreach (var polygon in set.Polygons)
            {
                foreach (var t in polygon.Triangles)
                {
                    var points = t.Points.Select(x => new Coordinate((decimal)x.X, (decimal)x.Y, zOffset).Round(roundDecimals)).ToList();

                    var faces = new List <Coordinate[]>();

                    // Add the vertical faces
                    var z = new Coordinate(0, 0, height).Round(roundDecimals);
                    for (var j = 0; j < points.Count; j++)
                    {
                        var next = (j + 1) % points.Count;
                        faces.Add(new[] { points[j], points[j] + z, points[next] + z, points[next] });
                    }
                    // Add the top and bottom faces
                    faces.Add(points.ToArray());
                    faces.Add(points.Select(x => x + z).Reverse().ToArray());

                    // Nothing new here, move along
                    var solid = new Solid(generator.GetNextObjectID())
                    {
                        Colour = Colour.GetRandomBrushColour()
                    };
                    foreach (var arr in faces)
                    {
                        var face = new Face(generator.GetNextFaceID())
                        {
                            Parent  = solid,
                            Plane   = new Plane(arr[0], arr[1], arr[2]),
                            Colour  = solid.Colour,
                            Texture = { Texture = texture }
                        };
                        face.Vertices.AddRange(arr.Select(x => new Vertex(x, face)));
                        face.UpdateBoundingBox();
                        face.AlignTextureToFace();
                        solid.Faces.Add(face);
                    }
                    solid.UpdateBoundingBox();
                    yield return(solid);
                }
            }
        }
Exemple #5
0
        private void RefreshAsset(string name)
        {
            var asset = _data.GetAsset(name);

            _sw.Reset();

            foreach (var poly in asset.Polygons)
            {
                var v = new ContourVertex[poly.Count];
                for (int i = 0; i < poly.Count; i++)
                {
                    v[i].Position = new Vec3 { X = poly[i].X, Y = poly[i].Y };
                    v[i].Data = poly[i].Color;
                }
                _sw.Start();
                _tess.AddContour(v, poly.Orientation);
                _sw.Stop();
            }

            _sw.Start();
            _tess.Tessellate(_windingRule, ElementType.Polygons, _polySize, VertexCombine);
            _sw.Stop();

            var output = new PolygonSet();
            for (int i = 0; i < _tess.ElementCount; i++)
            {
                var poly = new Polygon();
                for (int j = 0; j < _polySize; j++)
                {
                    int index = _tess.Elements[i * _polySize + j];
                    if (index == -1)
                        continue;
                    var v = new PolygonPoint {
                        X = _tess.Vertices[index].Position.X,
                        Y = _tess.Vertices[index].Position.Y,
                        Color = (Color)_tess.Vertices[index].Data
                    };
                    poly.Add(v);
                }
                output.Add(poly);
            }

            statusMain.Text = string.Format("{0:F3} ms - {1} polygons (of {2} vertices) {3}", _sw.Elapsed.TotalMilliseconds, _tess.ElementCount, _polySize, _polySize == 3 ? "... triangles" : "");

            _canvas.Input = asset.Polygons;
            _canvas.Output = output;
            _canvas.Invalidate();
        }
Exemple #6
0
        public IEnumerable<MapObject> Create(IDGenerator generator, Box box, ITexture texture, int roundDecimals)
        {
            var width = box.Width;
            var length = Math.Max(1, Math.Abs((int) box.Length));
            var height = box.Height;
            var flatten = (float) _flattenFactor.Value;
            var text = _text.GetValue();

            var family = _fontChooser.GetFontFamily();
            var style = Enum.GetValues(typeof (FontStyle)).OfType<FontStyle>().FirstOrDefault(fs => family.IsStyleAvailable(fs));
            if (!family.IsStyleAvailable(style)) family = FontFamily.GenericSansSerif;

            var set = new PolygonSet();

            var sizes = new List<RectangleF>();
            using (var bmp = new Bitmap(1,1))
            {
                using (var g = System.Drawing.Graphics.FromImage(bmp))
                {
                    using (var font = new Font(family, length, style, GraphicsUnit.Pixel))
                    {
                        for (var i = 0; i < text.Length; i += 32)
                        {
                            using (var sf = new StringFormat(StringFormat.GenericTypographic))
                            {
                                var rem = Math.Min(text.Length, i + 32) - i;
                                var range = Enumerable.Range(0, rem).Select(x => new CharacterRange(x, 1)).ToArray();
                                sf.SetMeasurableCharacterRanges(range);
                                var reg = g.MeasureCharacterRanges(text.Substring(i, rem), font, new RectangleF(0, 0, float.MaxValue, float.MaxValue), sf);
                                sizes.AddRange(reg.Select(x => x.GetBounds(g)));
                            }
                        }
                    }
                }
            }

            var xOffset = box.Start.DX;
            var yOffset = box.End.DY;

            for (var ci = 0; ci < text.Length; ci++)
            {
                var c = text[ci];
                var size = sizes[ci];

                var gp = new GraphicsPath();
                gp.AddString(c.ToString(CultureInfo.InvariantCulture), family, (int)style, length, new PointF(0, 0), StringFormat.GenericTypographic);
                gp.Flatten(new System.Drawing.Drawing2D.Matrix(), flatten);

                var polygons = new List<Polygon>();
                var poly = new List<PolygonPoint>();

                for (var i = 0; i < gp.PointCount; i++)
                {
                    var type = gp.PathTypes[i];
                    var point = gp.PathPoints[i];

                    poly.Add(new PolygonPoint(point.X + xOffset, -point.Y + yOffset));

                    if ((type & 0x80) == 0x80)
                    {
                        polygons.Add(new Polygon(poly));
                        poly.Clear();
                    }
                }

                var tri = new List<Polygon>();
                Polygon polygon = null;
                foreach (var p in polygons)
                {
                    if (polygon == null)
                    {
                        polygon = p;
                        tri.Add(p);
                    }
                    else if (p.CalculateWindingOrder() != polygon.CalculateWindingOrder())
                    {
                        polygon.AddHole(p);
                    }
                    else
                    {
                        polygon = null;
                        tri.Add(p);
                    }
                }

                foreach (var pp in tri)
                {
                    try
                    {
                        P2T.Triangulate(pp);
                        set.Add(pp);
                    }
                    catch
                    {
                        // Ignore
                    }
                }

                xOffset += size.Width;
            }

            var zOffset = box.Start.Z;

            foreach (var polygon in set.Polygons)
            {
                foreach (var t in polygon.Triangles)
                {
                    var points = t.Points.Select(x => new Coordinate((decimal) x.X, (decimal) x.Y, zOffset).Round(roundDecimals)).ToList();

                    var faces = new List<Coordinate[]>();

                    // Add the vertical faces
                    var z = new Coordinate(0, 0, height).Round(roundDecimals);
                    for (var j = 0; j < points.Count; j++)
                    {
                        var next = (j + 1) % points.Count;
                        faces.Add(new[] {points[j], points[j] + z, points[next] + z, points[next]});
                    }
                    // Add the top and bottom faces
                    faces.Add(points.ToArray());
                    faces.Add(points.Select(x => x + z).Reverse().ToArray());

                    // Nothing new here, move along
                    var solid = new Solid(generator.GetNextObjectID()) {Colour = Colour.GetRandomBrushColour()};
                    foreach (var arr in faces)
                    {
                        var face = new Face(generator.GetNextFaceID())
                        {
                            Parent = solid,
                            Plane = new Plane(arr[0], arr[1], arr[2]),
                            Colour = solid.Colour,
                            Texture = {Texture = texture}
                        };
                        face.Vertices.AddRange(arr.Select(x => new Vertex(x, face)));
                        face.UpdateBoundingBox();
                        face.AlignTextureToFace();
                        solid.Faces.Add(face);
                    }
                    solid.UpdateBoundingBox();
                    yield return solid;
                }
            }
        }
Exemple #7
0
 private static PolygonSet FromTess(Tess tess)
 {
     var output = new PolygonSet();
     for (int i = 0; i < tess.ElementCount; i++)
     {
         var poly = new Polygon();
         for (int j = 0; j < 3; j++)
         {
             int index = tess.Elements[i * 3 + j];
             if (index == -1)
                 continue;
             var v = new PolygonPoint {
                 X = tess.Vertices[index].Position.X,
                 Y = tess.Vertices[index].Position.Y
             };
             poly.Add(v);
         }
         output.Add(poly);
     }
     return output;
 }
Exemple #8
0
 private static PolygonSet FromP2T(Poly2Tri.PolygonSet pset)
 {
     var result = new PolygonSet();
     foreach (var poly in pset.Polygons)
     {
         foreach (var tri in poly.Triangles)
         {
             var rtri = new Polygon();
             rtri.Add(new PolygonPoint { X = tri.Points[0].Xf, Y = tri.Points[0].Yf });
             rtri.Add(new PolygonPoint { X = tri.Points[1].Xf, Y = tri.Points[1].Yf });
             rtri.Add(new PolygonPoint { X = tri.Points[2].Xf, Y = tri.Points[2].Yf });
             result.Add(rtri);
         }
     }
     return result;
 }
 private static PolygonSet FromTess(Tess tess)
 {
     var output = new PolygonSet();
     for (int i = 0; i < tess.Elements.Count / 3; i++)
     {
         var poly = new Polygon();
         for (int j = 0; j < 3; j++)
         {
             int index = tess.Elements[i * 3 + j];
             if (index == -1)
                 continue;
             var v = new PolygonPoint
             {
                 X = tess.Vertices[index].X,
                 Y = tess.Vertices[index].Y,
                 //Color = _tess.Vertices[index].Data != null ? (Color)_tess.Vertices[index].Data : Color.White
             };
             poly.Add(v);
         }
         output.Add(poly);
     } 
     return output;
 }
        public static ComplexShape ToTriangles(this ComplexShape p_polygon)
        {
            var v_trianglesShape           = new ComplexShape();
            List <PolygonShape> v_holes    = p_polygon.GetHoles();
            List <PolygonShape> v_nonHoles = p_polygon.GetNonHoles();
            Dictionary <PolygonShape, List <PolygonShape> > v_shapeAndHoles = new Dictionary <PolygonShape, List <PolygonShape> >();

            foreach (var v_shape in v_nonHoles)
            {
                if (!v_shapeAndHoles.ContainsKey(v_shape))
                {
                    v_shapeAndHoles.Add(v_shape, new List <PolygonShape>());
                }
            }
            //Build dictionary that contains Hole Hierarchy per Shape
            foreach (var v_hole in v_holes)
            {
                foreach (var v_shape in v_nonHoles)
                {
                    bool v_isInsideShape = true;
                    //Detect if Point is in Shape
                    foreach (var v_holeVertice in v_hole.Vertices)
                    {
                        if (!v_shape.PointInShape(v_holeVertice))
                        {
                            v_isInsideShape = false;
                            break;
                        }
                    }
                    if (v_isInsideShape)
                    {
                        if (!v_shapeAndHoles[v_shape].Contains(v_hole))
                        {
                            v_shapeAndHoles[v_shape].Add(v_hole);
                        }
                        break;
                    }
                }
            }

            if (v_shapeAndHoles.Count > 0)
            {
                PolygonSet v_polygonSet = new PolygonSet();

                foreach (var v_shape in v_shapeAndHoles.Keys)
                {
                    var v_P2TPolygon = v_shape.ToP2TPolygon(v_shapeAndHoles[v_shape]);
                    if (v_P2TPolygon != null)
                    {
                        v_polygonSet.Add(v_P2TPolygon);
                    }
                }
                P2T.Triangulate(v_polygonSet);

                foreach (var v_P2TPolygon in v_polygonSet.Polygons)
                {
                    foreach (var v_P2TTriangle in v_P2TPolygon.Triangles)
                    {
                        PolygonShape v_triangle = new PolygonShape();
                        foreach (var v_point in v_P2TTriangle.Points)
                        {
                            v_triangle.Vertices.Add(new Vector2((float)v_point.X, (float)v_point.Y));
                        }
                        if (v_triangle.GetPolygonArea() != 0)
                        {
                            v_triangle.RecalcBounds();
                            if (!v_triangle.IsOrientedClockwise())
                            {
                                v_triangle.ReverseOrientation();
                            }
                            v_trianglesShape.AddShape(v_triangle, false);
                        }
                    }
                }
            }
            return(v_trianglesShape);
        }