Exemple #1
0
        private CSG _differencePolygonBoundsOpt(CSG csg)
        {
            List <Polygon> inner = new List <Polygon>();
            List <Polygon> outer = new List <Polygon>();

            Bounds bounds = csg.getBounds();

            this.polygons.ForEach(p =>
            {
                if (bounds.intersects(p.getBounds()))
                {
                    inner.Add(p);
                }
                else
                {
                    outer.Add(p);
                }
            });

            CSG innerCSG = CSG.fromPolygons(inner);

            List <Polygon> allPolygons = new List <Polygon>();

            allPolygons.AddRange(outer);
            allPolygons.AddRange(innerCSG._differenceNoOpt(csg).polygons);

            return(CSG.fromPolygons(allPolygons).optimization(getOptType()));
        }
Exemple #2
0
        public static CSG hull(List <IVector3d> points, PropertyStorage storage)
        {
            Point3d[] hullPoints = points.Select(vec => new Point3d(vec.x(), vec.y(), vec.z())).ToArray();

            Hull hull = new Hull();

            hull.Build(hullPoints);
            hull.Triangulate();

            int[][] faces = hull.GetFaces();

            List <Polygon> polygons = new List <Polygon>();

            List <IVector3d> vertices = new List <IVector3d>();

            foreach (int[] verts in faces)
            {
                foreach (int i in verts)
                {
                    vertices.Add(points[hull.GetVertexPointIndices()[i]]);
                }

                polygons.Add(Polygon.fromPoints(vertices, storage));

                vertices.Clear();
            }

            return(CSG.fromPolygons(polygons));
        }
Exemple #3
0
        /// <summary>
        /// Optimizes for intersection. If csgs do not intersect create a new csg that consists of the polygon lists of this
        /// csg and the specified csg. In this case no further space partitioning is performed.
        /// </summary>
        ///
        /// <param name="csg">csg</param>
        /// <returns>the union of this csg and the specified csg</returns>
        ///
        private CSG _unionIntersectOpt(CSG csg)
        {
            bool intersects = false;

            Bounds bounds = csg.getBounds();

            foreach (Polygon p in polygons)
            {
                if (bounds.intersects(p.getBounds()))
                {
                    intersects = true;
                    break;
                }
            }

            List <Polygon> allPolygons = new List <Polygon>();

            if (intersects)
            {
                return(_unionNoOpt(csg));
            }
            else
            {
                allPolygons.AddRange(this.polygons);
                allPolygons.AddRange(csg.polygons);
            }

            return(CSG.fromPolygons(allPolygons).optimization(getOptType()));
        }
Exemple #4
0
        ///
        /// Loads a CSG from stl.
        ///
        /// <param name="path">file path</param>
        /// <returns>CSG</returns>
        /// @throws IOException if loading failed
        ///
        public static CSG file(string path)
        {
            var solid = STLSolid.CreateFromFile(path);

            List <Polygon>   polygons = new List <Polygon>();
            List <IVector3d> vertices = new List <IVector3d>();

            foreach (var facet in solid.Facets)
            {
                vertices.Add(Vector3d.xyz(facet.OuterLoop.V0.X, facet.OuterLoop.V0.Y, facet.OuterLoop.V0.Z));
                vertices.Add(Vector3d.xyz(facet.OuterLoop.V1.X, facet.OuterLoop.V1.Y, facet.OuterLoop.V1.Z));
                vertices.Add(Vector3d.xyz(facet.OuterLoop.V2.X, facet.OuterLoop.V2.Y, facet.OuterLoop.V2.Z));
                if (vertices.Count == 3)
                {
                    polygons.Add(Polygon.fromPoints(vertices));
                    vertices = new List <IVector3d>();
                }
            }

            //foreach (IVector3d p in loader.parse(path))
            //{
            //    vertices.Add(p.clone());
            //    if (vertices.Count == 3)
            //    {
            //        polygons.Add(Polygon.fromPoints(vertices));
            //        vertices = new List<IVector3d>();
            //    }
            //}

            return(CSG.fromPolygons(new PropertyStorage(), polygons));
        }
Exemple #5
0
        public CSG color(Color c)
        {
            CSG result = this.clone();

            storage.set("material:color", $"{c.R} {c.G} {c.B}");
            return(result);
        }
Exemple #6
0
        public CSG clone()
        {
            CSG csg = new CSG();

            csg.setOptType(this.getOptType());

            // sequential code
            //        csg.polygons = new ArrayList<>();
            //        polygons.forEach((polygon) -> {
            //            csg.polygons.add(polygon.clone());
            //        });

            var selector = new Func <Polygon, Polygon>(p => p.clone());

            if (polygons.Count > 200)
            {
                csg.polygons = polygons.AsParallel().Select(selector).ToList();
            }
            else
            {
                csg.polygons = polygons.Select(selector).ToList();
            }

            return(csg);
        }
Exemple #7
0
        /// <summary>
        /// Constructs a CSG from a list of <see cref="Polygon"/> instances.
        /// </summary>
        ///
        /// <param name="polygons">polygons</param>
        /// <returns>a CSG instance</returns>
        ///
        public static CSG fromPolygons(List <Polygon> polygons)
        {
            CSG csg = new CSG();

            csg.polygons = polygons;

            return(csg);
        }
Exemple #8
0
        public static CSG hull(CSG csg, PropertyStorage storage)
        {
            List <IVector3d> points = new List <IVector3d>(csg.getPolygons().Count * 3);

            csg.getPolygons().ForEach(p => p.vertices.ForEach(v => points.Add(v.pos)));

            return(hull(points, storage));
        }
Exemple #9
0
        /// <summary>
        /// Returns a csg consisting of the polygons of this csg and the specified csg.
        ///
        /// The purpose of this method is to allow fast union operations for objects that do not intersect.
        ///
        /// </summary>
        ///
        /// <p>
        /// <b>WARNING:</b> this method does not apply the csg algorithms. Therefore, please ensure that this csg and the
        /// specified csg do not intersect.
        ///
        /// <param name="csg">csg</param>
        ///
        /// <returns>a csg consisting of the polygons of this csg and the specified csg</returns>
        ///
        public CSG dumbUnion(CSG csg)
        {
            CSG result = this.clone();
            CSG other  = csg.clone();

            result.polygons.AddRange(other.polygons);

            return(result);
        }
Exemple #10
0
        /// <summary>
        /// Returns this bounding box as csg.
        /// </summary>
        /// <returns>this bounding box as csg</returns>
        ///
        public CSG toCSG()
        {
            if (csg == null)
            {
                csg = cube.toCSG();
            }

            return(csg);
        }
Exemple #11
0
        private CSG _differenceCSGBoundsOpt(CSG csg)
        {
            CSG b = csg;

            CSG a1 = this._differenceNoOpt(csg.getBounds().toCSG());
            CSG a2 = this.intersect(csg.getBounds().toCSG());

            return(a2._differenceNoOpt(b)._unionIntersectOpt(a1).optimization(getOptType()));
        }
Exemple #12
0
        /// <summary>
        /// Return a new CSG solid representing the union of this csg and the specified csgs.
        /// </summary>
        ///
        /// <b>Note:</b> Neither this csg nor the specified csg are weighted.
        ///
        /// <blockquote><pre>
        ///    A.union(B)
        ///
        ///    +-------+            +-------+
        ///    |       |            |       |
        ///    |   A   |            |       |
        ///    |    +--+----+   =   |       +----+
        ///    +----+--+    |       +----+       |
        ///         |   B   |            |       |
        ///         |       |            |       |
        ///         +-------+            +-------+
        /// </pre></blockquote>
        ///
        ///
        /// <param name="csgs">other csgs</param>
        ///
        /// <returns>union of this csg and the specified csgs</returns>
        ///
        public CSG union(List <CSG> csgs)
        {
            CSG result = this;

            foreach (CSG csg in csgs)
            {
                result = result.union(csg);
            }

            return(result);
        }
Exemple #13
0
        public static List <Polygon> boundaryPolygons(CSG csg)
        {
            List <Polygon> result = new List <Polygon>();

            foreach (List <Polygon> polygonGroup in searchPlaneGroups(csg.getPolygons()))
            {
                result.AddRange(boundaryPolygonsOfPlaneGroup(polygonGroup));
            }

            return(result);
        }
Exemple #14
0
 /// <summary>
 /// Saves the specified csg using STL ASCII format.
 /// </summary>
 /// <param name="path">destination path</param>
 /// <param name="csg">csg to save</param>
 /// <exception cref="IOException"></exception>
 ///
 public static void toStlFile(string p, CSG csg)
 {
     using (var file = File.Open(p, FileMode.Create | FileMode.Truncate))
     {
         using (var writer = new StreamWriter(file, Encoding.UTF8))
         {
             writer.Write("solid v3d.csg\n");
             csg.getPolygons().ForEach(poly => writer.Write(poly.toStlString()));
             writer.Write("endsolid v3d.csg\n");
         }
     }
 }
Exemple #15
0
        private CSG _unionNoOpt(CSG csg)
        {
            Node a = new Node(this.clone().polygons);
            Node b = new Node(csg.clone().polygons);

            a.clipTo(b);
            b.clipTo(a);
            b.invert();
            b.clipTo(a);
            b.invert();
            a.build(b.allPolygons());
            return(CSG.fromPolygons(a.allPolygons()).optimization(getOptType()));
        }
Exemple #16
0
        /// <summary>
        /// Return a new CSG solid representing the difference of this csg and the specified csg.
        /// </summary>
        ///
        /// <b>Note:</b> Neither this csg nor the specified csg are weighted.
        ///
        /// <code>
        /// A.difference(B)
        ///
        /// +-------+            +-------+
        /// |       |            |       |
        /// |   A   |            |       |
        /// |    +--+----+   =   |    +--+
        /// +----+--+    |       +----+
        ///      |   B   |
        ///      |       |
        ///      +-------+
        /// </code>
        ///
        /// <param name="csg">other csg</param>
        /// <returns>difference of this csg and the specified csg</returns>
        ///
        public CSG difference(CSG csg)
        {
            switch (getOptType())
            {
            case OptType.CSG_BOUND:
                return(_differenceCSGBoundsOpt(csg));

            case OptType.POLYGON_BOUND:
                return(_differencePolygonBoundsOpt(csg));

            default:
                return(_differenceNoOpt(csg));
            }
        }
Exemple #17
0
        /// <summary>
        /// Constructs a CSG from a list of <see cref="Polygon"/> instances.
        /// </summary>
        ///
        /// <param name="storage">shared storage</param>
        /// <param name="polygons">polygons</param>
        /// <returns>a CSG instance</returns>
        ///
        public static CSG fromPolygons(PropertyStorage storage, List <Polygon> polygons)
        {
            CSG csg = new CSG();

            csg.polygons = polygons;

            csg.storage = storage;

            foreach (Polygon polygon in polygons)
            {
                polygon.setStorage(storage);
            }

            return(csg);
        }
Exemple #18
0
        /// <summary>
        /// Return a new CSG solid representing the union of this csg and the specified csg.
        ///
        /// <b>Note:</b> Neither this csg nor the specified csg are weighted.
        ///
        /// <blockquote><pre>
        ///    A.union(B)
        ///
        ///    +-------+            +-------+
        ///    |       |            |       |
        ///    |   A   |            |       |
        ///    |    +--+----+   =   |       +----+
        ///    +----+--+    |       +----+       |
        ///         |   B   |            |       |
        ///         |       |            |       |
        ///         +-------+            +-------+
        /// </pre></blockquote>
        /// </summary>
        ///
        /// <param name="csg">other csg</param>
        ///
        /// <returns>union of this csg and the specified csg</returns>
        ///
        public CSG union(CSG csg)
        {
            switch (getOptType())
            {
            case OptType.CSG_BOUND:
                return(_unionCSGBoundsOpt(csg));

            case OptType.POLYGON_BOUND:
                return(_unionPolygonBoundsOpt(csg));

            default:
                //                return _unionIntersectOpt(csg);
                return(_unionNoOpt(csg));
            }
        }
Exemple #19
0
        /// <summary>
        /// Returns a transformed copy of this CSG.
        /// </summary>
        ///
        /// <param name="transform">the transform to apply</param>
        ///
        /// <returns>a transformed copy of this CSG</returns>
        ///
        public CSG transformed(CSharpVecMath.Transform transform)
        {
            if (polygons.Count == 0)
            {
                return(clone());
            }

            List <Polygon> newpolygons = this.polygons.Select(
                p => p.transformed(transform)).ToList();

            CSG result = CSG.fromPolygons(newpolygons).optimization(getOptType());

            result.storage = storage;

            return(result);
        }
Exemple #20
0
        /// <summary>
        /// Return a new CSG solid representing the intersection of this csg and the specified csgs.
        /// </summary>
        ///
        /// <b>Note:</b> Neither this csg nor the specified csgs are weighted.
        ///
        /// <code>
        ///     A.intersect(B)
        ///
        ///     +-------+
        ///     |       |
        ///     |   A   |
        ///     |    +--+----+   =   +--+
        ///     +----+--+    |       +--+
        ///          |   B   |
        ///          |       |
        ///          +-------+
        /// }
        /// </code>
        ///
        /// <param name="csgs">other csgs</param>
        /// <returns>intersection of this csg and the specified csgs</returns>
        ///
        public CSG intersect(List <CSG> csgs)
        {
            if (csgs.Count == 0)
            {
                return(this.clone());
            }

            CSG csgsUnion = csgs[0];

            for (int i = 1; i < csgs.Count; i++)
            {
                csgsUnion = csgsUnion.union(csgs[i]);
            }

            return(intersect(csgsUnion));
        }
Exemple #21
0
        public List <Polygon> toPolygons()
        {
            CSG spherePrototype
                = new Sphere(getCornerRadius(), getResolution() * 2, getResolution()).toCSG();

            double x = dimensions.x() / 2.0 - getCornerRadius();
            double y = dimensions.y() / 2.0 - getCornerRadius();
            double z = dimensions.z() / 2.0 - getCornerRadius();

            CSG sphere1 = spherePrototype.transformed(Transform.unity().translate(-x, -y, -z));
            CSG sphere2 = spherePrototype.transformed(Transform.unity().translate(x, -y, -z));
            CSG sphere3 = spherePrototype.transformed(Transform.unity().translate(x, y, -z));
            CSG sphere4 = spherePrototype.transformed(Transform.unity().translate(-x, y, -z));

            CSG sphere5 = spherePrototype.transformed(Transform.unity().translate(-x, -y, z));
            CSG sphere6 = spherePrototype.transformed(Transform.unity().translate(x, -y, z));
            CSG sphere7 = spherePrototype.transformed(Transform.unity().translate(x, y, z));
            CSG sphere8 = spherePrototype.transformed(Transform.unity().translate(-x, y, z));

            List <Polygon> result = sphere1.union(
                sphere2, sphere3, sphere4,
                sphere5, sphere6, sphere7, sphere8).hull().getPolygons();

            Transform locTransform = Transform.unity().translate(center);

            foreach (Polygon p in result)
            {
                p.transform(locTransform);
            }

            if (!centered)
            {
                Transform centerTransform = Transform.unity().
                                            translate(dimensions.x() / 2.0,
                                                      dimensions.y() / 2.0,
                                                      dimensions.z() / 2.0);

                foreach (Polygon p in result)
                {
                    p.transform(centerTransform);
                }
            }

            return(result);
        }
Exemple #22
0
        public double eval(IVector3d pos, CSG csg)
        {
            if (bounds == null)
            {
                this.bounds = csg.getBounds();
                sPerUnit    = (max - min) / (bounds.getMax().y() - bounds.getMin().y());
            }

            double s = sPerUnit * (pos.y() - bounds.getMin().y());

            if (centered)
            {
                s = s - (max - min) / 2.0;

                s = Math.Abs(s) * 2;
            }

            return(s);
        }
Exemple #23
0
        private static CSG extrude(IVector3d dir, Polygon polygon1)
        {
            List <Polygon> newPolygons = new List <Polygon>();

            if (dir.z() < 0)
            {
                throw new ArgumentException("z < 0 currently not supported for extrude: " + dir);
            }

            newPolygons.AddRange(PolygonUtil.concaveToConvex(polygon1));
            Polygon polygon2 = polygon1.translated(dir);

            int numvertices = polygon1.vertices.Count;

            for (int i = 0; i < numvertices; i++)
            {
                int nexti = (i + 1) % numvertices;

                IVector3d bottomV1 = polygon1.vertices[i].pos;
                IVector3d topV1    = polygon2.vertices[i].pos;
                IVector3d bottomV2 = polygon1.vertices[nexti].pos;
                IVector3d topV2    = polygon2.vertices[nexti].pos;

                List <IVector3d> pPoints = new List <IVector3d> {
                    bottomV2, topV2, topV1, bottomV1
                };

                newPolygons.Add(Polygon.fromPoints(pPoints, polygon1.getStorage()));
            }

            polygon2 = polygon2.flipped();
            List <Polygon> topPolygons = PolygonUtil.concaveToConvex(polygon2);

            newPolygons.AddRange(topPolygons);

            return(CSG.fromPolygons(newPolygons));
        }
Exemple #24
0
        /// <summary>
        /// Returns the convex hull of this csg and the union of the specified csgs.
        /// </summary>
        ///
        /// <param name="csgs">csgs</param>
        /// <returns>the convex hull of this csg and the specified csgs</returns>
        ///
        public CSG hull(List <CSG> csgs)
        {
            CSG csgsUnion = new CSG();

            csgsUnion.storage  = storage;
            csgsUnion.optType  = optType;
            csgsUnion.polygons = this.clone().polygons;

            csgs.ForEach(csg =>
            {
                csgsUnion.polygons.AddRange(csg.clone().polygons);
            });

            csgsUnion.polygons.ForEach(p => p.setStorage(storage));
            return(csgsUnion.hull());

            //        CSG csgsUnion = this;
            //
            //        for (CSG csg : csgs) {
            //            csgsUnion = csgsUnion.union(csg);
            //        }
            //
            //        return csgsUnion.hull();
        }
Exemple #25
0
 public double eval(IVector3d pos, CSG csg)
 {
     return(1.0);
 }
Exemple #26
0
 /// <summary>
 /// Combines two polygons into one CSG object. Polygons p1 and p2 are treated as top and
 /// bottom of a tube segment with p1 and p2 as the profile. <b>Note:</b> both polygons must have the
 /// same number of vertices. This method does not guarantee intersection-free CSGs. It is in the
 /// responsibility of the caller to ensure that the orientation of p1 and p2 allow for
 /// intersection-free combination of both.
 /// </summary>
 /// <param name="p1">first polygon</param>
 /// <param name="p2">second polygon</param>
 /// <returns>List of polygons</returns>
 ///
 public static CSG combine(Polygon p1, Polygon p2)
 {
     return(CSG.fromPolygons(combine(p1, p2, true, true)));
 }
Exemple #27
0
 /// <summary>
 /// Returns this primitive as <see cref="CSG"/>.
 /// </summary>
 /// <returns>this primitive as <see cref="CSG"/></returns>
 ///
 public static CSG toCSG(this IPrimitive primitive)
 {
     return(CSG.fromPolygons(primitive.getProperties(), primitive.toPolygons()));
 }
Exemple #28
0
 private CSG _unionCSGBoundsOpt(CSG csg)
 {
     Console.Error.WriteLine("WARNING: using " + OptType.NONE
                             + " since other optimization types missing for union operation.");
     return(_unionIntersectOpt(csg));
 }