Inheritance: Triangulatable
示例#1
0
文件: Mesh.cs 项目: langerv/osm
        /// <summary>
        /// Cap mesh
        /// </summary>
        /// <param name="color"></param>
        public void Cap(Color color)
        {
            if (Vertices == null || Vertices.Length < 6)
            {
                return;
            }

            // Convert to PolygonPointExt (2D + index)
            // Convention: bottom vertices start at 0, top at 1 - continue every 2 vertices
            var points = new List <PolygonPointExt>();

            for (var idx = 0; idx < Vertices.Length; idx += 2)
            {
                points.Add(new PolygonPointExt(Vertices[idx].X, Vertices[idx].Z, idx));
            }

            var poly = new Poly2TriPolygon.Polygon(points);

            try
            {
                P2T.Triangulate(poly);

                // Get resulting faces
                var faces = new List <int>(Faces);
                foreach (var tri in poly.Triangles)
                {
                    var i0 = tri.Points[0] as PolygonPointExt;
                    var i1 = tri.Points[1] as PolygonPointExt;
                    var i2 = tri.Points[2] as PolygonPointExt;
                    // apply to bottom
                    faces.Add(i2.Idx);
                    faces.Add(i1.Idx);
                    faces.Add(i0.Idx);
                    // apply to top
                    faces.Add(i2.Idx + 1);
                    faces.Add(i1.Idx + 1);
                    faces.Add(i0.Idx + 1);
                    // Add roof color
                    Colors[i0.Idx + 1] = color;
                    Colors[i2.Idx + 1] = color;
                    Colors[i1.Idx + 1] = color;
                }

                Faces   = faces.ToArray();
                Normals = ComputeNormals(Vertices, Faces);
            }
            catch (Exception ex)
            {
                // TODO
                Console.WriteLine(ex.Message);
            }
        }
示例#2
0
        public PolygonObject( GameWorld world, Vertices points, Texture2D texture,
                             float density = 1.0f, float friction = 0, float restitution = 0.7f,
                             float destroy_threshold = 0.0f, String name = "PolygonObject",
                             String texture_name = TNames.wall )
            : base(world, texture, density, friction, restitution,
                   is_destructible: ( destroy_threshold > 0 ),
                   destroy_threshold: destroy_threshold, name: name, texture_name: texture_name)
        {
            List<PolygonPoint> polypoints = new List<PolygonPoint>();
            foreach ( Vector2 pt in points ) {
                polypoints.Add( new PolygonPoint( pt.X, pt.Y ) );
            }

            Polygon polygon = new Polygon( polypoints );
        }
示例#3
0
        public static List<Vertices> ConvexPartition(DetectedVertices vertices)
        {
            Polygon poly = new Polygon();
            foreach (var vertex in vertices)
                poly.Points.Add(new TriangulationPoint(vertex.X, vertex.Y));

            if (vertices.Holes != null)
            {
                foreach (var holeVertices in vertices.Holes)
                {
                    Polygon hole = new Polygon();
                    foreach (var vertex in holeVertices)
                        hole.Points.Add(new TriangulationPoint(vertex.X, vertex.Y));

                    poly.AddHole(hole);
                }
            }

            DTSweepContext tcx = new DTSweepContext();
            tcx.PrepareTriangulation(poly);
            DTSweep.Triangulate(tcx);

            List<Vertices> results = new List<Vertices>();

            foreach (DelaunayTriangle triangle in poly.Triangles)
            {
                Vertices v = new Vertices();
                foreach (TriangulationPoint p in triangle.Points)
                {
                    v.Add(new FVector2((float)p.X, (float)p.Y));
                }
                results.Add(v);
            }

            return results;
        }
示例#4
0
 /// <summary>
 /// Add a hole to the polygon.
 /// </summary>
 /// <param name="poly">A subtraction polygon fully contained inside this polygon.</param>
 public void AddHole(Polygon poly)
 {
     if (_holes == null) _holes = new List<Polygon>();
     _holes.Add(poly);
     // XXX: tests could be made here to be sure it is fully inside
     //        addSubtraction( poly.getPoints() );
 }
 public void Add(Polygon p)
 {
     _polygons.Add(p);
 }
 public PolygonSet(Polygon poly)
 {
     _polygons.Add(poly);
 }
示例#7
0
        public IEnumerable <IMapObject> Create(UniqueNumberGenerator generator, Box box, string texture, int roundfloats)
        {
            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 List <Polygon>();

            var sizes = new List <RectangleF>();

            using (var bmp = new Bitmap(1, 1))
            {
                using (var g = 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.X;
            var yOffset = box.End.Y;

            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)
            {
                foreach (var t in polygon.Triangles)
                {
                    var points = t.Points.Select(x => new Vector3((float)x.X, (float)x.Y, zOffset).Round(roundfloats)).ToList();

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

                    // Add the vertical faces
                    var z = new Vector3(0, 0, height).Round(roundfloats);
                    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.Next("MapObject"));
                    solid.Data.Add(new ObjectColor(Colour.GetRandomBrushColour()));

                    foreach (var arr in faces)
                    {
                        var face = new Face(generator.Next("Face"))
                        {
                            Plane   = new Plane(arr[0], arr[1], arr[2]),
                            Texture = { Name = texture }
                        };
                        face.Vertices.AddRange(arr.Select(x => x.Round(roundfloats)));
                        solid.Data.Add(face);
                    }
                    solid.DescendantsChanged();
                    yield return(solid);
                }
            }
        }
示例#8
0
 public void Add(Polygon p)
 {
     _polygons.Add(p);
 }
示例#9
0
 public PolygonSet(Polygon poly)
 {
     _polygons.Add(poly);
 }
示例#10
0
        public static MeshGeometryModel3D Create3DPolygon(List <Vector2> points, float height, Material material)
        {
            MeshBuilder builder = new MeshBuilder();

            if (points.Count < 3)
            {
                return(null);
            }

            // Create poly now to indicate winding order
            Polygon_Poly2Tri upPolygon = new Polygon_Poly2Tri(
                points: points.Select(point => new PolygonPoint(point.X, point.Y)));

            List <Vector2> pointByClockwise =
                upPolygon.WindingOrder == Point2DList.WindingOrderType.AntiClockwise
                                        ? points.AsEnumerable().Reverse().ToList()
                                        : points;

            // Adding walls
            Vector3 firstUpPoint   = pointByClockwise.First().AddZ(height);
            Vector3 firstDownPoint = pointByClockwise.First().AddZ(0);
            Vector3 lastUpPoint    = firstUpPoint;
            Vector3 lastDownPoint  = firstDownPoint;

            for (int i = 1; i < pointByClockwise.Count; i++)
            {
                Vector3 currentUpPoint   = pointByClockwise[i].AddZ(height);
                Vector3 currentDownPoint = pointByClockwise[i].AddZ(0);

                builder.AddQuad(
                    currentDownPoint.Map(),
                    lastDownPoint.Map(),
                    lastUpPoint.Map(),
                    currentUpPoint.Map());

                lastUpPoint   = currentUpPoint;
                lastDownPoint = currentDownPoint;
            }

            // Create cycle
            builder.AddQuad(
                firstDownPoint.Map(),
                lastDownPoint.Map(),
                lastUpPoint.Map(),
                firstUpPoint.Map());

            // Adding Upper Part
            P2T.Triangulate(upPolygon);
            foreach (var trianglePoints in upPolygon.Triangles.Select(x => x.Points))
            {
                builder.AddTriangle(
                    p0: new Vector3_SharpDX((float)trianglePoints.Item0.X, (float)trianglePoints.Item0.Y, height),
                    p1: new Vector3_SharpDX((float)trianglePoints.Item1.X, (float)trianglePoints.Item1.Y, height),
                    p2: new Vector3_SharpDX((float)trianglePoints.Item2.X, (float)trianglePoints.Item2.Y, height));
            }

            MeshGeometry3D      polyWall = builder.ToMesh();
            MeshGeometryModel3D element  = new MeshGeometryModel3D()
            {
                Geometry = polyWall,
                Material = material
            };

            return(element);
        }
示例#11
0
        /// <summary>
        /// Create builidng esh
        /// </summary>
        /// <param name="building"></param>
        /// <returns></returns>
        public static Mesh CreateMesh(BuildingPart building)
        {
            var minY  = building.Body.min_height;
            var maxY  = building.Body.height;
            var poly  = building.Footprint;
            var total = poly.Points.Count;

            if (poly is MultiPolygon)
            {
                (poly as MultiPolygon).Holes.ForEach(x => total += x.Points.Count);
            }

            // Build mesh
            var vertices = new Vector3[total * 2];
            var faces    = new List <int>();
            var colors   = Enumerable.Repeat(building.Body.surface.color, total * 2).ToArray();

            // Create vertices and polygon for triangulation
            var idx       = 0;
            var P2Tpoints = new List <PolygonPointExt>();

            foreach (var point in poly.Points)
            {
                vertices[idx]         = new Vector3(point.X, minY, -point.Y);
                vertices[idx + total] = new Vector3(point.X, maxY, -point.Y);
                P2Tpoints.Add(new PolygonPointExt(point.X, point.Y, idx++));
            }
            var P2Tpoly = new Poly2TriPolygon.Polygon(P2Tpoints);

            // add faces = 2 triangles
            for (var i = 0; i < poly.Points.Count - 1; i++)
            {
                faces.Add(i + total);
                faces.Add(i);
                faces.Add(i + 1);
                faces.Add(i + total);
                faces.Add(i + 1);
                faces.Add(i + total + 1);
            }

            if (poly is MultiPolygon)
            {
                (poly as MultiPolygon).Holes.ForEach(hole =>
                {
                    // Create holes vertices and holes for triangulation
                    var P2Thole = new List <PolygonPointExt>();
                    for (var i = 0; i < hole.Points.Count; i++)
                    {
                        vertices[idx + i]         = new Vector3(hole.Points[i].X, minY, -hole.Points[i].Y);
                        vertices[idx + i + total] = new Vector3(hole.Points[i].X, maxY, -hole.Points[i].Y);
                        P2Thole.Add(new PolygonPointExt(hole.Points[i].X, hole.Points[i].Y, idx + i));
                    }

                    // Create holes faces = 2 triangles
                    for (var i = 0; i < hole.Points.Count - 1; i++)
                    {
                        faces.Add(idx + i + total);
                        faces.Add(idx + i);
                        faces.Add(idx + i + 1);
                        faces.Add(idx + i + total);
                        faces.Add(idx + i + 1);
                        faces.Add(idx + i + total + 1);
                    }

                    P2Tpoly.AddHole(new Poly2TriPolygon.Polygon(P2Thole));
                    idx += hole.Points.Count;
                });
            }

            try
            {
                P2T.Triangulate(P2Tpoly);

                // Add triangulated top faces
                foreach (var tri in P2Tpoly.Triangles)
                {
                    var i0 = tri.Points[0] as PolygonPointExt;
                    var i1 = tri.Points[1] as PolygonPointExt;
                    var i2 = tri.Points[2] as PolygonPointExt;

                    // apply to bottom
                    //                    faces.Add(i2.Idx);
                    //                    faces.Add(i1.Idx);
                    //                    faces.Add(i0.Idx);

                    // apply to top
                    faces.Add(i2.Idx + total);
                    faces.Add(i1.Idx + total);
                    faces.Add(i0.Idx + total);

                    // Add roof color
                    colors[i0.Idx + total] = building.Roof.surface.color;
                    colors[i2.Idx + total] = building.Roof.surface.color;
                    colors[i1.Idx + total] = building.Roof.surface.color;
                }
                return(new Mesh(vertices, faces.ToArray(), colors));
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }

            return(null);
        }
示例#12
-1
        public static List<Vertices> ConvexPartition(Vertices vertices)
        {
            Polygon poly = new Polygon();

            foreach (FVector2 vertex in vertices)
            {
                poly.Points.Add(new TriangulationPoint(vertex.X, vertex.Y));
            }

            DTSweepContext tcx = new DTSweepContext();
            tcx.PrepareTriangulation(poly);
            DTSweep.Triangulate(tcx);

            List<Vertices> results = new List<Vertices>();

            foreach (DelaunayTriangle triangle in poly.Triangles)
            {
                Vertices v = new Vertices();
                foreach (TriangulationPoint p in triangle.Points)
                {
                    v.Add(new FVector2((float)p.X, (float)p.Y));
                }
                results.Add(v);
            }

            return results;
        }