/// <summary>
        /// Constructs a partial box with specified faces
        /// </summary>
        public static MeshDraft PartialBox(Vector3 width, Vector3 depth, Vector3 height, Directions parts, bool generateUV = true)
        {
            Vector3 v000 = -width / 2 - depth / 2 - height / 2;
            Vector3 v001 = v000 + height;
            Vector3 v010 = v000 + width;
            Vector3 v011 = v000 + width + height;
            Vector3 v100 = v000 + depth;
            Vector3 v101 = v000 + depth + height;
            Vector3 v110 = v000 + width + depth;
            Vector3 v111 = v000 + width + depth + height;

            var draft = new MeshDraft {
                name = "Partial box"
            };

            if (generateUV)
            {
                Vector2 uv0 = new Vector2(0, 0);
                Vector2 uv1 = new Vector2(0, 1);
                Vector2 uv2 = new Vector2(1, 1);
                Vector2 uv3 = new Vector2(1, 0);

                if (parts.HasFlag(Directions.Left))
                {
                    draft.AddQuad(v100, v101, v001, v000, true, uv0, uv1, uv2, uv3);
                }
                if (parts.HasFlag(Directions.Right))
                {
                    draft.AddQuad(v010, v011, v111, v110, true, uv0, uv1, uv2, uv3);
                }
                if (parts.HasFlag(Directions.Down))
                {
                    draft.AddQuad(v010, v110, v100, v000, true, uv0, uv1, uv2, uv3);
                }
                if (parts.HasFlag(Directions.Up))
                {
                    draft.AddQuad(v111, v011, v001, v101, true, uv0, uv1, uv2, uv3);
                }
                if (parts.HasFlag(Directions.Back))
                {
                    draft.AddQuad(v000, v001, v011, v010, true, uv0, uv1, uv2, uv3);
                }
                if (parts.HasFlag(Directions.Forward))
                {
                    draft.AddQuad(v110, v111, v101, v100, true, uv0, uv1, uv2, uv3);
                }
            }
            else
            {
                if (parts.HasFlag(Directions.Left))
                {
                    draft.AddQuad(v100, v101, v001, v000, true);
                }
                if (parts.HasFlag(Directions.Right))
                {
                    draft.AddQuad(v010, v011, v111, v110, true);
                }
                if (parts.HasFlag(Directions.Down))
                {
                    draft.AddQuad(v010, v110, v100, v000, true);
                }
                if (parts.HasFlag(Directions.Up))
                {
                    draft.AddQuad(v111, v011, v001, v101, true);
                }
                if (parts.HasFlag(Directions.Back))
                {
                    draft.AddQuad(v000, v001, v011, v010, true);
                }
                if (parts.HasFlag(Directions.Forward))
                {
                    draft.AddQuad(v110, v111, v101, v100, true);
                }
            }
            return(draft);
        }
        /// <summary>
        /// Constructs a flat revolution surface draft
        /// </summary>
        public static MeshDraft FlatRevolutionSurface(
            Func <float, float, float, float, Vector3> surfaceFunction,
            float radius,
            float height,
            int horizontalSegments,
            int verticalSegments,
            bool generateUV = true)
        {
            float horizontalSegmentAngle = 360f / horizontalSegments;
            float verticalSegmentAngle   = 180f / verticalSegments;
            float currentVerticalAngle   = -90;
            int   horizontalCount        = horizontalSegments + 1;

            var ringsVertices = new List <List <Vector3> >(verticalSegments);
            var ringsUV       = new List <List <Vector2> >(verticalSegments);

            for (int y = 0; y <= verticalSegments; y++)
            {
                float currentHorizontalAngle = 0f;
                var   ringVertices           = new List <Vector3>(horizontalCount);
                var   ringUV = new List <Vector2>(horizontalCount);

                for (int x = 0; x <= horizontalSegments; x++)
                {
                    var point = surfaceFunction(radius, height, currentHorizontalAngle, currentVerticalAngle);
                    ringVertices.Add(point);
                    if (generateUV)
                    {
                        ringUV.Add(new Vector2(1 - (float)x / horizontalSegments, (float)y / verticalSegments));
                    }
                    currentHorizontalAngle += horizontalSegmentAngle;
                }
                ringsVertices.Add(ringVertices);
                ringsUV.Add(ringUV);
                currentVerticalAngle += verticalSegmentAngle;
            }

            var draft = new MeshDraft {
                name = "Flat revolution surface"
            };

            for (int y = 0; y < ringsVertices.Count - 1; y++)
            {
                var lowerRingVertices = ringsVertices[y];
                var upperRingVertices = ringsVertices[y + 1];
                var lowerRingUV       = ringsUV[y];
                var upperRingUV       = ringsUV[y + 1];
                for (int x = 0; x < horizontalSegments; x++)
                {
                    Vector3 v00  = lowerRingVertices[x + 1];
                    Vector3 v01  = upperRingVertices[x + 1];
                    Vector3 v11  = upperRingVertices[x];
                    Vector3 v10  = lowerRingVertices[x];
                    Vector2 uv00 = lowerRingUV[x + 1];
                    Vector2 uv01 = upperRingUV[x + 1];
                    Vector2 uv11 = upperRingUV[x];
                    Vector2 uv10 = lowerRingUV[x];
                    draft.AddQuad(v00, v01, v11, v10, true, uv00, uv01, uv11, uv10);
                }
            }
            return(draft);
        }