Exemplo n.º 1
0
        Solid IntersectSub(Solid csg, bool retesselate, bool canonicalize)
        {
            Tree a = new Tree(Polygons);
            Tree b = new Tree(csg.Polygons);

            a.Invert();
            b.ClipTo(a);
            b.Invert();
            a.ClipTo(b);
            b.ClipTo(a);
            a.AddPolygons(b.AllPolygons());
            a.Invert();

            Solid result = Solid.FromPolygons(a.AllPolygons());

            if (retesselate)
            {
                result = result.Retesselated();
            }
            if (canonicalize)
            {
                result = result.Canonicalized();
            }
            return(result);
        }
Exemplo n.º 2
0
        Solid UnionSub(Solid csg, bool retesselate, bool canonicalize)
        {
            if (!MayOverlap(csg))
            {
                return(UnionForNonIntersecting(csg));
            }
            else
            {
                Tree a = new Tree(Polygons);
                Tree b = new Tree(csg.Polygons);

                a.ClipTo(b, false);
                b.ClipTo(a);
                b.Invert();
                b.ClipTo(a);
                b.Invert();

                Polygon[] ArrayPolygonA   = a.AllPolygons().ToArray();
                Polygon[] ArrayPolygonB   = b.AllPolygons().ToArray();
                Polygon[] ArrayNewPolygon = new Polygon[ArrayPolygonA.Length + ArrayPolygonB.Length];
                Array.Copy(ArrayPolygonA, 0, ArrayNewPolygon, 0, ArrayPolygonA.Length);
                Array.Copy(ArrayPolygonB, 0, ArrayNewPolygon, ArrayPolygonA.Length, ArrayPolygonB.Length);

                Solid result = Solid.FromPolygons(ArrayNewPolygon.ToList());
                if (retesselate)
                {
                    result = result.Retesselated();
                }
                if (canonicalize)
                {
                    result = result.Canonicalized();
                }
                return(result);
            }
        }
Exemplo n.º 3
0
        public static Solid Cube(CubeOptions options)
        {
            var c = options.Center;
            var r = options.Radius.Abs(); // negative radii make no sense

            if (r.X == 0.0 || r.Y == 0.0 || r.Z == 0.0)
            {
                return(new Solid());
            }
            var result = Solid.FromPolygons(cubeData.Select(info =>
            {
                //var normal = new Vector3(info[1]);
                //var plane = new Plane(normal, 1);
                IEnumerable <Vertex> vertices = info[0].Select(i =>
                {
                    var pos = new Vector3(
                        c.X + r.X * (2 * ((i & 1) != 0 ? 1 : 0) - 1),
                        c.Y + r.Y * (2 * ((i & 2) != 0 ? 1 : 0) - 1),
                        c.Z + r.Z * (2 * ((i & 4) != 0 ? 1 : 0) - 1));
                    return(NoTexVertex(pos));
                });
                return(new Polygon(options.SolidColor, vertices.ToArray()));
            }).ToList());

            return(result);
        }
Exemplo n.º 4
0
        public Solid GetCsg(Solid sourcecsg)
        {
            List <Polygon> newpolygons = new List <Polygon>();

            foreach (Polygon polygon in sourcecsg.Polygons)
            {
                Polygon newpolygon = GetPolygon(polygon);
                if (newpolygon.Vertices.Length >= 3)
                {
                    newpolygons.Add(newpolygon);
                }
            }
            return(Solid.FromPolygons(newpolygons));
        }
Exemplo n.º 5
0
        Solid UnionForNonIntersecting(Solid csg)
        {
            Polygon[] ArrayPolygonA   = Polygons.ToArray();
            Polygon[] ArrayPolygonB   = csg.Polygons.ToArray();
            Polygon[] ArrayNewPolygon = new Polygon[ArrayPolygonA.Length + ArrayPolygonB.Length];
            Array.Copy(ArrayPolygonA, 0, ArrayNewPolygon, 0, ArrayPolygonA.Length);
            Array.Copy(ArrayPolygonB, 0, ArrayNewPolygon, ArrayPolygonA.Length, ArrayPolygonB.Length);

            Solid result = Solid.FromPolygons(ArrayNewPolygon.ToList());

            result.IsCanonicalized = IsCanonicalized && csg.IsCanonicalized;
            result.IsRetesselated  = IsRetesselated && csg.IsRetesselated;
            return(result);
        }
Exemplo n.º 6
0
        public Solid Retesselated()
        {
            if (IsRetesselated)
            {
                return(this);
            }
            else
            {
                Solid csg = this;
                Dictionary <Plane, List <Polygon> > polygonsPerPlane = new Dictionary <Plane, List <Polygon> >();

                foreach (Polygon polygon in csg.Polygons)
                {
                    Plane plane = polygon.Plane;

                    List <Polygon> ppp;
                    if (polygonsPerPlane.TryGetValue(plane, out ppp))
                    {
                        ppp.Add(polygon);
                    }
                    else
                    {
                        ppp = new List <Polygon>(1);
                        ppp.Add(polygon);
                        polygonsPerPlane.Add(plane, ppp);
                    }
                }
                var destpolygons = new List <Polygon>();

                foreach (KeyValuePair <Plane, List <Polygon> > planetag in polygonsPerPlane)
                {
                    var sourcepolygons = planetag.Value;
                    if (sourcepolygons.Count < 2)
                    {
                        destpolygons.AddRange(sourcepolygons);
                    }
                    else
                    {
                        List <Polygon> retesselatedpolygons = new List <Polygon>(sourcepolygons.Count);
                        Solid.RetesselateCoplanarPolygons(sourcepolygons, retesselatedpolygons);
                        destpolygons.AddRange(retesselatedpolygons);
                    }
                }

                Solid result = Solid.FromPolygons(destpolygons);
                result.IsRetesselated = true;
                return(result);
            }
        }
Exemplo n.º 7
0
        public Solid Transform(Matrix matrix4x4)
        {
            Dictionary <Vertex, Vertex> transformedvertices = new Dictionary <Vertex, Vertex>();
            Dictionary <Plane, Plane>   transformedplanes   = new Dictionary <Plane, Plane>();

            Polygon[] ArrayNewPolygon = new Polygon[Polygons.Count];

            for (int i = 0; i < Polygons.Count; i++)
            {
                Polygon ActivePolygon = Polygons[i];
                Plane   newplane;
                Plane   plane = ActivePolygon.Plane;
                if (transformedplanes.ContainsKey(plane))
                {
                    newplane = transformedplanes[plane];
                }
                else
                {
                    newplane = plane.Project(matrix4x4);
                    transformedplanes[plane] = newplane;
                }

                Vertex[] ArrayNewVertex = new Vertex[ActivePolygon.Vertices.Length];

                for (int V = 0; V < ActivePolygon.Vertices.Length; ++V)
                {
                    Vertex ActiveVertex = ActivePolygon.Vertices[V];
                    Vertex newvertex;

                    if (transformedvertices.ContainsKey(ActiveVertex))
                    {
                        newvertex = transformedvertices[ActiveVertex];
                    }
                    else
                    {
                        newvertex = ActiveVertex.Transform(matrix4x4);
                        transformedvertices[ActiveVertex] = newvertex;
                    }
                    ArrayNewVertex[V] = newvertex;
                }
                ArrayNewPolygon[i] = new Polygon(ActivePolygon.PolygonColor, ArrayNewVertex, newplane);
            }
            Solid result = Solid.FromPolygons(ArrayNewPolygon.ToList());

            result.IsRetesselated  = this.IsRetesselated;
            result.IsCanonicalized = this.IsCanonicalized;
            return(result);
        }
Exemplo n.º 8
0
        public static Solid Sphere(SphereOptions options)
        {
            var   center = options.Center;
            float radius = Math.Abs(options.Radius);

            if (radius == 0.0)
            {
                return(new Solid());
            }
            var resolution = options.Resolution;
            var xvector    = options.XAxis * radius;
            var yvector    = options.YAxis * radius;
            var zvector    = options.ZAxis * radius;

            if (resolution < 4)
            {
                resolution = 4;
            }
            var qresolution       = resolution / 4;
            var prevcylinderpoint = new Vector3(0, 0, 0);
            var polygons          = new List <Polygon>();

            for (var slice1 = 0; slice1 <= resolution; slice1++)
            {
                float   angle         = (float)Math.PI * 2.0f * slice1 / resolution;
                Vector3 cylinderpoint = xvector * ((float)Math.Cos(angle)) + (yvector * ((float)Math.Sin(angle)));
                if (slice1 > 0)
                {
                    float prevcospitch = 0, prevsinpitch = 0;
                    for (var slice2 = 0; slice2 <= qresolution; slice2++)
                    {
                        float pitch    = 0.5f * (float)Math.PI * slice2 / qresolution;
                        float cospitch = (float)Math.Cos(pitch);
                        float sinpitch = (float)Math.Sin(pitch);
                        if (slice2 > 0)
                        {
                            List <Vertex> vertices = new List <Vertex>();
                            vertices.Add(NoTexVertex(center + (prevcylinderpoint * (prevcospitch) - (zvector * (prevsinpitch)))));
                            vertices.Add(NoTexVertex(center + (cylinderpoint * (prevcospitch) - (zvector * (prevsinpitch)))));
                            if (slice2 < qresolution)
                            {
                                vertices.Add(NoTexVertex(center + (cylinderpoint * (cospitch) - (zvector * (sinpitch)))));
                            }
                            vertices.Add(NoTexVertex(center + (prevcylinderpoint * (cospitch) - (zvector * (sinpitch)))));
                            polygons.Add(new Polygon(options.SolidColor, vertices.ToArray()));
                            vertices = new List <Vertex>();
                            vertices.Add(NoTexVertex(center + (prevcylinderpoint * (prevcospitch) + (zvector * (prevsinpitch)))));
                            vertices.Add(NoTexVertex(center + (cylinderpoint * (prevcospitch) + (zvector * (prevsinpitch)))));
                            if (slice2 < qresolution)
                            {
                                vertices.Add(NoTexVertex(center + (cylinderpoint * (cospitch) + (zvector * (sinpitch)))));
                            }
                            vertices.Add(NoTexVertex(center + (prevcylinderpoint * (cospitch) + (zvector * (sinpitch)))));
                            vertices.Reverse();
                            polygons.Add(new Polygon(options.SolidColor, vertices.ToArray()));
                        }
                        prevcospitch = cospitch;
                        prevsinpitch = sinpitch;
                    }
                }
                prevcylinderpoint = cylinderpoint;
            }
            var result = Solid.FromPolygons(polygons);

            return(result);
        }
Exemplo n.º 9
0
        public static Solid Cylinder(CylinderOptions options)
        {
            var s      = options.Start;
            var e      = options.End;
            var r      = Math.Abs(options.RadiusStart);
            var rEnd   = Math.Abs(options.RadiusEnd);
            var rStart = r;
            var alpha  = options.SectorAngle;

            alpha = alpha > 360 ? alpha % 360 : alpha;

            if ((rEnd == 0) && (rStart == 0))
            {
                return(new Solid());
            }
            if (s.Equals(e))
            {
                return(new Solid());
            }

            var     slices = options.Resolution;
            var     ray    = e - (s);
            Vector3 axisZ  = ray.Unit();
            Vector3 axisX  = axisZ.RandomNonParallelVector().Unit();

            Vector3 axisY = axisX.Cross(axisZ).Unit();

            axisX = axisZ.Cross(axisY).Unit();
            var start    = NoTexVertex(s);
            var end      = NoTexVertex(e);
            var polygons = new List <Polygon>();

            Func <float, float, float, Vertex> point = (stack, slice, radius) =>
            {
                var     angle = slice * Math.PI * alpha / 180;
                Vector3 outp  = axisX * ((float)Math.Cos(angle)) + (axisY * ((float)Math.Sin(angle)));
                var     pos   = s + (ray * (stack)) + (outp * (radius));
                return(NoTexVertex(pos));
            };

            if (alpha > 0)
            {
                for (var i = 0; i < slices; i++)
                {
                    float t0 = (float)i / slices;
                    float t1 = (float)(i + 1) / slices;
                    if (rEnd == rStart)
                    {
                        polygons.Add(new Polygon(options.SolidColor, start, point(0, t0, rEnd), point(0, t1, rEnd)));
                        polygons.Add(new Polygon(options.SolidColor, point(0, t1, rEnd), point(0, t0, rEnd), point(1, t0, rEnd), point(1, t1, rEnd)));
                        polygons.Add(new Polygon(options.SolidColor, end, point(1, t1, rEnd), point(1, t0, rEnd)));
                    }
                    else
                    {
                        if (rStart > 0)
                        {
                            polygons.Add(new Polygon(options.SolidColor, start, point(0, t0, rStart), point(0, t1, rStart)));
                            polygons.Add(new Polygon(options.SolidColor, point(0, t0, rStart), point(1, t0, rEnd), point(0, t1, rStart)));
                        }
                        if (rEnd > 0)
                        {
                            polygons.Add(new Polygon(options.SolidColor, end, point(1, t1, rEnd), point(1, t0, rEnd)));
                            polygons.Add(new Polygon(options.SolidColor, point(1, t0, rEnd), point(1, t1, rEnd), point(0, t1, rStart)));
                        }
                    }
                }
                if (alpha < 360)
                {
                    polygons.Add(new Polygon(options.SolidColor, start, end, point(0, 0, rStart)));
                    polygons.Add(new Polygon(options.SolidColor, point(0, 0, rStart), end, point(1, 0, rEnd)));
                    polygons.Add(new Polygon(options.SolidColor, start, point(0, 1, rStart), end));
                    polygons.Add(new Polygon(options.SolidColor, point(0, 1, rStart), point(1, 1, rEnd), end));
                }
            }
            var result = Solid.FromPolygons(polygons);

            return(result);
        }