Esempio n. 1
0
        public void Build(List <Polygon> polygons)
        {
            if (polygons.Count == 0)
            {
                return;
            }
            if (Plane == null)
            {
                Plane = polygons[0].Plane.Clone();
            }
            var pp    = Plane.ToPrecisionPlane();
            var front = new List <Polygon>();
            var back  = new List <Polygon>();

            foreach (var polygon in polygons.Select(x => x.ToPrecisionPolygon()))
            {
                polygon.Split(pp, out var b, out var f, out var cb, out var cf);
                if (f != null)
                {
                    front.Add(f.ToStandardPolygon());
                }
                if (b != null)
                {
                    back.Add(b.ToStandardPolygon());
                }
                if (cf != null)
                {
                    front.Add(cf.ToStandardPolygon());
                }
                if (cb != null)
                {
                    back.Add(cb.ToStandardPolygon());
                }
            }
            if (front.Count > 0)
            {
                if (Front == null)
                {
                    Front = new CsgNode();
                }
                Front.Build(front);
            }
            if (back.Count > 0)
            {
                if (Back == null)
                {
                    Back = new CsgNode();
                }
                Back.Build(back);
            }
        }
Esempio n. 2
0
        private List <Polygon> ClipPolygons(IEnumerable <Polygon> polygons)
        {
            if (Plane == null)
            {
                return(polygons.ToList());
            }
            var pp    = Plane.ToPrecisionPlane();
            var front = new List <Polygon>();
            var back  = new List <Polygon>();

            foreach (var polygon in polygons.Select(x => x.ToPrecisionPolygon()))
            {
                polygon.Split(pp, out var b, out var f, out var cb, out var cf);
                if (f != null)
                {
                    front.Add(f.ToStandardPolygon());
                }
                if (b != null)
                {
                    back.Add(b.ToStandardPolygon());
                }
                if (cf != null)
                {
                    front.Add(cf.ToStandardPolygon());
                }
                if (cb != null)
                {
                    back.Add(cb.ToStandardPolygon());
                }
            }
            if (Front != null)
            {
                front = Front.ClipPolygons(front);
            }
            back = Back != null?Back.ClipPolygons(back) : new List <Polygon>();

            return(front.Concat(back).ToList());
        }
Esempio n. 3
0
 /// <summary>
 /// Creates a polygon from a plane and a radius.
 /// Expands the plane to the radius size to create a large polygon with 4 vertices.
 /// This constructor uses high-precision operations.
 /// </summary>
 /// <param name="plane">The polygon plane</param>
 /// <param name="radius">The polygon radius</param>
 public Polygon(Plane plane, float radius = 100000f)
 {
     Vertices = new Precision.Polygon(plane.ToPrecisionPlane(), radius).Vertices.Select(x => x.ToStandardVector3()).ToList();
 }
Esempio n. 4
0
        protected override void Render(MapDocument document, BufferBuilder builder, ResourceCollector resourceCollector)
        {
            base.Render(document, builder, resourceCollector);

            if (_state != ClipState.None && _clipPlanePoint1 != null && _clipPlanePoint2 != null && _clipPlanePoint3 != null)
            {
                // Draw the lines
                var p1 = _clipPlanePoint1.Value;
                var p2 = _clipPlanePoint2.Value;
                var p3 = _clipPlanePoint3.Value;

                builder.Append(
                    new []
                {
                    new VertexStandard {
                        Position = p1, Colour = Vector4.One, Tint = Vector4.One
                    },
                    new VertexStandard {
                        Position = p2, Colour = Vector4.One, Tint = Vector4.One
                    },
                    new VertexStandard {
                        Position = p3, Colour = Vector4.One, Tint = Vector4.One
                    },
                },
                    new uint [] { 0, 1, 1, 2, 2, 0 },
                    new []
                {
                    new BufferGroup(PipelineType.Wireframe, CameraType.Both, 0, 6)
                }
                    );

                if (!p1.EquivalentTo(p2) &&
                    !p2.EquivalentTo(p3) &&
                    !p1.EquivalentTo(p3) &&
                    !document.Selection.IsEmpty)
                {
                    var plane = new Plane(p1, p2, p3);
                    var pp    = plane.ToPrecisionPlane();

                    // Draw the clipped solids
                    var faces = new List <Polygon>();
                    foreach (var solid in document.Selection.OfType <Solid>().ToList())
                    {
                        var s = solid.ToPolyhedron().ToPrecisionPolyhedron();
                        s.Split(pp, out var back, out var front);

                        if (_side != ClipSide.Front && back != null)
                        {
                            faces.AddRange(back.Polygons.Select(x => x.ToStandardPolygon()));
                        }
                        if (_side != ClipSide.Back && front != null)
                        {
                            faces.AddRange(front.Polygons.Select(x => x.ToStandardPolygon()));
                        }
                    }

                    var verts   = new List <VertexStandard>();
                    var indices = new List <int>();

                    foreach (var polygon in faces)
                    {
                        var c = verts.Count;
                        verts.AddRange(polygon.Vertices.Select(x => new VertexStandard {
                            Position = x, Colour = Vector4.One, Tint = Vector4.One
                        }));
                        for (var i = 0; i < polygon.Vertices.Count; i++)
                        {
                            indices.Add(c + i);
                            indices.Add(c + (i + 1) % polygon.Vertices.Count);
                        }
                    }

                    builder.Append(
                        verts, indices.Select(x => (uint)x),
                        new[] { new BufferGroup(PipelineType.Wireframe, CameraType.Both, 0, (uint)indices.Count) }
                        );

                    // Draw the clipping plane

                    var poly  = new DataStructures.Geometric.Precision.Polygon(pp);
                    var bbox  = document.Selection.GetSelectionBoundingBox();
                    var point = bbox.Center;
                    foreach (var boxPlane in bbox.GetBoxPlanes())
                    {
                        var proj = boxPlane.Project(point);
                        var dist = (point - proj).Length() * 0.1f;
                        var pln  = new Plane(boxPlane.Normal, proj + boxPlane.Normal * Math.Max(dist, 100)).ToPrecisionPlane();
                        if (poly.Split(pln, out var b, out _))
                        {
                            poly = b;
                        }
                    }

                    verts.Clear();
                    indices.Clear();

                    var clipPoly = poly.ToStandardPolygon();
                    var colour   = Color.FromArgb(64, Color.Turquoise).ToVector4();

                    // Add the face in both directions so it renders on both sides
                    var polies = new[] { clipPoly.Vertices.ToList(), clipPoly.Vertices.Reverse().ToList() };
                    foreach (var p in polies)
                    {
                        var offs = verts.Count;
                        verts.AddRange(p.Select(x => new VertexStandard
                        {
                            Position = x,
                            Colour   = Vector4.One,
                            Tint     = colour,
                            Flags    = VertexFlags.FlatColour
                        }));

                        for (var i = 2; i < clipPoly.Vertices.Count; i++)
                        {
                            indices.Add(offs);
                            indices.Add(offs + i - 1);
                            indices.Add(offs + i);
                        }
                    }

                    builder.Append(
                        verts, indices.Select(x => (uint)x),
                        new[] { new BufferGroup(PipelineType.TexturedAlpha, CameraType.Perspective, p1, 0, (uint)indices.Count) }
                        );
                }
            }
        }