/// <summary>
        /// Tekla's method overload, using <see cref="Geometry3d.Line"/> as input object.
        /// Returns a list of line - solid intersection points.
        /// </summary>
        /// <param name="solid">Solid to be intersect.</param>
        /// <param name="line">The intersection line to be used.</param>
        /// <returns>An array list of intersection points.</returns>
        public static ArrayList Intersect(this Model.Solid solid, Geometry3d.Line line)
        {
            var points = new Geometry3d.Point[]
            {
                new Geometry3d.Point(line.Origin),
                new Geometry3d.Point(line.Origin) + line.Direction * Math.Pow(10, 9) // Vector length must be increased, otherwise Tekla may not find any intersection points.
            };

            return(solid.Intersect(points[0], points[1]));
        }
        /// <summary>
        /// Tekla's method overload, using coordinate system object instead of 3 points.
        /// Returns an enumerator for an array list of lists of plane - solid intersection points from all intersecting faces.
        /// The first item of one list contains points of the outmost intersection polygon and then the inner polygons (if there are any).
        /// </summary>
        /// <param name="solid">Solid to be intersected with a plane.</param>
        /// <param name="coordinateSystem">Coordinate system defining a plane.</param>
        /// <returns>Enumerator of point lists.</returns>
        public static IEnumerator IntersectAllFaces(this Model.Solid solid, Geometry3d.CoordinateSystem coordinateSystem)
        {
            var point2 = new Geometry3d.Point(coordinateSystem.Origin);
            var point3 = new Geometry3d.Point(coordinateSystem.Origin);

            point2.Translate(coordinateSystem.AxisX);
            point3.Translate(coordinateSystem.AxisY);

            return(solid.IntersectAllFaces(coordinateSystem.Origin, point2, point3));
        }
        /// <summary>
        /// Ray tracing algorithm implementation for Tekla Structures.
        /// </summary>
        /// <param name="point">Point to be checked.</param>
        /// <param name="solid">Solid, against which the point is going to be checked.</param>
        /// <returns>True if point is inside or on the surface of the solid, false otherwise.</returns>
        public static bool IsInside(this Geometry3d.Point point, Model.Solid solid)
        {
            var randomVector = GetRandomVector();
            var intersection = solid.Intersect(new Geometry3d.Line(point, randomVector)).Cast <Geometry3d.Point>();
            // Tekla does not support rays, a line will be used instead. All points found on opposite direction must be excluded.
            var pointsOnRay = intersection.Where(x =>
            {
                var vectorToIntersectionPoint = new Geometry3d.Vector(x - point);
                var factor = Math.Round(vectorToIntersectionPoint.X / randomVector.X, 3);
                return(factor == Math.Round(vectorToIntersectionPoint.Y / randomVector.Y, 3) && factor == Math.Round(vectorToIntersectionPoint.Z / randomVector.Z, 3));
            });

            // If point is inside solid, there will be odd numbers of intersections between solid faces and any ray originated in given point.
            return(pointsOnRay.Count() % 2 != 0);
        }
        /// <summary>
        /// Tekla's method overload, using geometric plane object instead of 3 points.
        /// Returns an enumerator for an array list of lists of plane - solid intersection points from all intersecting faces.
        /// The first item of one list contains points of the outmost intersection polygon and then the inner polygons (if there are any).
        /// </summary>
        /// <param name="solid">Solid to be intersected with a plane.</param>
        /// <param name="plane">Geometric plane.</param>
        /// <returns>Enumerator of point lists.</returns>
        public static IEnumerator IntersectAllFaces(this Model.Solid solid, Geometry3d.GeometricPlane plane)
        {
            var normalVector = plane.GetNormal();
            var randomVector = GetRandomVector();

            while (normalVector.GetAngleBetween(randomVector) == 0 || normalVector.GetAngleBetween(randomVector) == Math.PI)
            {
                randomVector = GetRandomVector();
            }

            var firstVectorOnPlane  = normalVector.Cross(randomVector);
            var secondVectorOnPlane = normalVector.Cross(firstVectorOnPlane);

            var point2 = new Geometry3d.Point(plane.Origin);
            var point3 = new Geometry3d.Point(plane.Origin);

            point2.Translate(firstVectorOnPlane);
            point3.Translate(secondVectorOnPlane);

            return(solid.IntersectAllFaces(plane.Origin, point2, point3));
        }