<commit_before>﻿// Copyright 2015-2020 Design Engineering Lab
// This file is a part of TVGL, Tessellation and Voxelization Geometry Library
// https://github.com/DesignEngrLab/TVGL
// It is licensed under MIT License (see LICENSE.txt for details)
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;

namespace TVGL
{
    /// <summary>
    ///     Class TessellatedSolid.
    /// </summary>
    /// <tags>help</tags>
    /// <remarks>
    ///     This is the currently the <strong>main</strong> class within TVGL all filetypes are read in as a TessellatedSolid,
    ///     and
    ///     all interesting operations work on the TessellatedSolid.
    /// </remarks>
    public partial class TessellatedSolid : Solid
    {
        #region Fields and Properties
        /// <summary>
        ///     Gets the faces.
        /// </summary>
        /// <value>The faces.</value>
        [JsonIgnore]
        public PolygonalFace[] Faces { get; private set; }

        /// <summary>
        ///     Gets the edges.
        /// </summary>
        /// <value>The edges.</value>
        [JsonIgnore]
        public Edge[] Edges
        {
            get
            {
                if (_edges == null) MakeEdges();
                return _edges;
            }
        }
        private Edge[] _edges;

        /// <summary>
        ///     Gets the vertices.
        /// </summary>
        /// <value>The vertices.</value>
        [JsonIgnore]
        public Vertex[] Vertices { get; private set; }

        /// <summary>
        ///     Gets the number of faces.
        /// </summary>
        /// <value>The number of faces.</value>
        [JsonIgnore]
        public int NumberOfFaces { get; private set; }

        /// <summary>
        ///     Gets the number of vertices.
        /// </summary>
        /// <value>The number of vertices.</value>
        [JsonIgnore]
        public int NumberOfVertices { get; private set; }

        /// <summary>
        ///     Gets the number of edges.
        /// </summary>
        /// <value>The number of edges.</value>
        [JsonIgnore]
        public int NumberOfEdges { get; private set; }

        /// <summary>
        ///     Errors in the tesselated solid
        /// </summary>
        [JsonIgnore]
        public TessellationError Errors { get; internal set; }

        /// <summary>
        /// Gets or sets the nonsmooth edges, which are the edges that do not exhibit C1 or C2 continuity.
        /// </summary>
        /// <value>The nonsmooth edges.</value>
        [JsonIgnore]
        public List<EdgePath> NonsmoothEdges { get; set; }
        #endregion

        #region Constructors
        /// <summary>
        /// Initializes a new instance of the <see cref="TessellatedSolid"/> class.
        /// </summary>
        public TessellatedSolid() { }

        /// <summary>
        /// Initializes a new instance of the <see cref="TessellatedSolid" /> class. This is the one that
        /// matches with the STL format.
        /// </summary>
        /// <param name="vertsPerFace">The verts per face.</param>
        /// <param name="createFullVersion">if set to <c>true</c> [make edges].</param>
        /// <param name="colors">The colors.</param>
        /// <param name="units">The units.</param>
        /// <param name="name">The name.</param>
        /// <param name="filename">The filename.</param>
        /// <param name="comments">The comments.</param>
        /// <param name="language">The language.</param>
        public TessellatedSolid(IEnumerable<List<Vector3>> vertsPerFace, bool createFullVersion, IList<Color> colors,
            UnitType units = UnitType.unspecified, string name = "", string filename = "", List<string> comments = null,
            string language = "")
            : base(units, name, filename, comments, language)
        {
            var vertsPerFaceList = vertsPerFace as IList<List<Vector3>> ?? vertsPerFace.ToList();
            DefineAxisAlignedBoundingBoxAndTolerance(vertsPerFaceList.SelectMany(v => v));
            var scaleFactor = 1.0;
            if ((Bounds[1] - Bounds[0]).Length() < 0.1)
            {
                if (units == UnitType.unspecified || units == UnitType.meter)
                {
                    units = UnitType.millimeter;
                    scaleFactor = 1000;
                }
                else if (units == UnitType.foot)
                {
                    units = UnitType.inch;
                    scaleFactor = 12;
                }
                DefineAxisAlignedBoundingBoxAndTolerance(vertsPerFaceList.SelectMany(vList => vList.Select(v => scaleFactor * v)));
            }
            MakeVertices(vertsPerFaceList, scaleFactor, out List<int[]> faceToVertexIndices);
            //Complete Construction with Common Functions
            MakeFaces(faceToVertexIndices, colors);
            if (createFullVersion) CompleteInitiation(true);
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="TessellatedSolid" /> class. This matches with formats
        /// that use indices to the vertices (almost everything except STL).
        /// </summary>
        /// <param name="vertices">The vertices.</param>
        /// <param name="faceToVertexIndices">The face to vertex indices.</param>
        /// <param name="createFullVersion">if set to <c>true</c> [make edges].</param>
        /// <param name="colors">The colors.</param>
        /// <param name="units">The units.</param>
        /// <param name="name">The name.</param>
        /// <param name="filename">The filename.</param>
        /// <param name="comments">The comments.</param>
        /// <param name="language">The language.</param>
        public TessellatedSolid(IList<Vector3> vertices, IList<int[]> faceToVertexIndices, bool createFullVersion,
            IList<Color> colors, UnitType units = UnitType.unspecified, string name = "", string filename = "",
            List<string> comments = null, string language = "") : base(units, name, filename, comments, language)
        {
            DefineAxisAlignedBoundingBoxAndTolerance(vertices);
            MakeVertices(vertices);
            //Complete Construction with Common Functions
            MakeFaces(faceToVertexIndices, colors);
            if (createFullVersion) CompleteInitiation();
        }

        public TessellatedSolid(IList<Vector3> vertices, IList<int[]> faceToVertexIndices, bool createFullVersion,
          IList<PrimitiveSurface> primitives, IList<Color> colors, UnitType units = UnitType.unspecified, string name = "", string filename = "",
          List<string> comments = null, string language = "") : base(units, name, filename, comments, language)
        {
            DefineAxisAlignedBoundingBoxAndTolerance(vertices);
            MakeVertices(vertices);
            //Complete Construction with Common Functions
            MakeFaces(faceToVertexIndices, primitives, colors);
            CompleteInitiation();
            if (createFullVersion)
            {
                //Create edges and then update primitives with links to Faces, Vertices, and Edges
                foreach (var prim in Primitives)
                    prim.CompletePostSerialization(this);
            }
        }

        [OnSerializing]
        protected void OnSerializingMethod(StreamingContext context)
        {
            //if (serializationData == null)
            serializationData = new Dictionary<string, JToken>();
            if(ConvexHull != null)
            {
                serializationData.Add("ConvexHullVertices",
                JToken.FromObject(ConvexHull.Vertices.Select(v => v.IndexInList)));
                serializationData.Add("ConvexHullFaces",
                    JToken.FromObject(ConvexHull.Faces.SelectMany(face => face.Vertices.Select(v => v.IndexInList))));
            }
            serializationData.Add("FaceIndices",
                JToken.FromObject(Faces.SelectMany(face => face.Vertices.Select(v => v.IndexInList)).ToArray()));
            serializationData.Add("VertexCoords",
               JToken.FromObject(Vertices.ConvertTo1DDoublesCollection()));
            if (HasUniformColor || Faces.All(f => f.Color == null || f.Color.Equals(Faces[0].Color)))
                serializationData.Add("Colors", SolidColor.ToString());
            else
            {
                var colorList = new List<string>();
                var lastColor = new Color(KnownColors.LightGray).ToString();
                foreach (var f in Faces)<commit_msg>Minor change to CGM TessellatedSolid constructor call.<commit_after>﻿// Copyright 2015-2020 Design Engineering Lab
// This file is a part of TVGL, Tessellation and Voxelization Geometry Library
// https://github.com/DesignEngrLab/TVGL
// It is licensed under MIT License (see LICENSE.txt for details)
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;

namespace TVGL
{
    /// <summary>
    ///     Class TessellatedSolid.
    /// </summary>
    /// <tags>help</tags>
    /// <remarks>
    ///     This is the currently the <strong>main</strong> class within TVGL all filetypes are read in as a TessellatedSolid,
    ///     and
    ///     all interesting operations work on the TessellatedSolid.
    /// </remarks>
    public partial class TessellatedSolid : Solid
    {
        #region Fields and Properties
        /// <summary>
        ///     Gets the faces.
        /// </summary>
        /// <value>The faces.</value>
        [JsonIgnore]
        public PolygonalFace[] Faces { get; private set; }

        /// <summary>
        ///     Gets the edges.
        /// </summary>
        /// <value>The edges.</value>
        [JsonIgnore]
        public Edge[] Edges
        {
            get
            {
                if (_edges == null) MakeEdges();
                return _edges;
            }
        }
        private Edge[] _edges;

        /// <summary>
        ///     Gets the vertices.
        /// </summary>
        /// <value>The vertices.</value>
        [JsonIgnore]
        public Vertex[] Vertices { get; private set; }

        /// <summary>
        ///     Gets the number of faces.
        /// </summary>
        /// <value>The number of faces.</value>
        [JsonIgnore]
        public int NumberOfFaces { get; private set; }

        /// <summary>
        ///     Gets the number of vertices.
        /// </summary>
        /// <value>The number of vertices.</value>
        [JsonIgnore]
        public int NumberOfVertices { get; private set; }

        /// <summary>
        ///     Gets the number of edges.
        /// </summary>
        /// <value>The number of edges.</value>
        [JsonIgnore]
        public int NumberOfEdges { get; private set; }

        /// <summary>
        ///     Errors in the tesselated solid
        /// </summary>
        [JsonIgnore]
        public TessellationError Errors { get; internal set; }

        /// <summary>
        /// Gets or sets the nonsmooth edges, which are the edges that do not exhibit C1 or C2 continuity.
        /// </summary>
        /// <value>The nonsmooth edges.</value>
        [JsonIgnore]
        public List<EdgePath> NonsmoothEdges { get; set; }
        #endregion

        #region Constructors
        /// <summary>
        /// Initializes a new instance of the <see cref="TessellatedSolid"/> class.
        /// </summary>
        public TessellatedSolid() { }

        /// <summary>
        /// Initializes a new instance of the <see cref="TessellatedSolid" /> class. This is the one that
        /// matches with the STL format.
        /// </summary>
        /// <param name="vertsPerFace">The verts per face.</param>
        /// <param name="createFullVersion">if set to <c>true</c> [make edges].</param>
        /// <param name="colors">The colors.</param>
        /// <param name="units">The units.</param>
        /// <param name="name">The name.</param>
        /// <param name="filename">The filename.</param>
        /// <param name="comments">The comments.</param>
        /// <param name="language">The language.</param>
        public TessellatedSolid(IEnumerable<List<Vector3>> vertsPerFace, bool createFullVersion, IList<Color> colors,
            UnitType units = UnitType.unspecified, string name = "", string filename = "", List<string> comments = null,
            string language = "")
            : base(units, name, filename, comments, language)
        {
            var vertsPerFaceList = vertsPerFace as IList<List<Vector3>> ?? vertsPerFace.ToList();
            DefineAxisAlignedBoundingBoxAndTolerance(vertsPerFaceList.SelectMany(v => v));
            var scaleFactor = 1.0;
            if ((Bounds[1] - Bounds[0]).Length() < 0.1)
            {
                if (units == UnitType.unspecified || units == UnitType.meter)
                {
                    units = UnitType.millimeter;
                    scaleFactor = 1000;
                }
                else if (units == UnitType.foot)
                {
                    units = UnitType.inch;
                    scaleFactor = 12;
                }
                DefineAxisAlignedBoundingBoxAndTolerance(vertsPerFaceList.SelectMany(vList => vList.Select(v => scaleFactor * v)));
            }
            MakeVertices(vertsPerFaceList, scaleFactor, out List<int[]> faceToVertexIndices);
            //Complete Construction with Common Functions
            MakeFaces(faceToVertexIndices, colors);
            if (createFullVersion) CompleteInitiation(true);
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="TessellatedSolid" /> class. This matches with formats
        /// that use indices to the vertices (almost everything except STL).
        /// </summary>
        /// <param name="vertices">The vertices.</param>
        /// <param name="faceToVertexIndices">The face to vertex indices.</param>
        /// <param name="createFullVersion">if set to <c>true</c> [make edges].</param>
        /// <param name="colors">The colors.</param>
        /// <param name="units">The units.</param>
        /// <param name="name">The name.</param>
        /// <param name="filename">The filename.</param>
        /// <param name="comments">The comments.</param>
        /// <param name="language">The language.</param>
        public TessellatedSolid(IList<Vector3> vertices, IList<int[]> faceToVertexIndices, bool createFullVersion,
            IList<Color> colors, UnitType units = UnitType.unspecified, string name = "", string filename = "",
            List<string> comments = null, string language = "") : base(units, name, filename, comments, language)
        {
            DefineAxisAlignedBoundingBoxAndTolerance(vertices);
            MakeVertices(vertices);
            //Complete Construction with Common Functions
            MakeFaces(faceToVertexIndices, colors);
            if (createFullVersion) CompleteInitiation();
        }

        public TessellatedSolid(IList<Vector3> vertices, IList<int[]> faceToVertexIndices, bool createFullVersion,
          IList<PrimitiveSurface> primitives, IList<Color> colors, UnitType units = UnitType.unspecified, string name = "", string filename = "",
          List<string> comments = null, string language = "") : base(units, name, filename, comments, language)
        {
            DefineAxisAlignedBoundingBoxAndTolerance(vertices);
            MakeVertices(vertices);
            //Complete Construction with Common Functions
            MakeFaces(faceToVertexIndices, primitives, colors);
            if (createFullVersion)
            {
                CompleteInitiation();
                //Create edges and then update primitives with links to Faces, Vertices, and Edges
                foreach (var prim in Primitives)
                    prim.CompletePostSerialization(this);
            }
            else CalculateVolume();
        }

        [OnSerializing]
        protected void OnSerializingMethod(StreamingContext context)
        {
            //if (serializationData == null)
            serializationData = new Dictionary<string, JToken>();
            if(ConvexHull != null)
            {
                serializationData.Add("ConvexHullVertices",
                JToken.FromObject(ConvexHull.Vertices.Select(v => v.IndexInList)));
                serializationData.Add("ConvexHullFaces",
                    JToken.FromObject(ConvexHull.Faces.SelectMany(face => face.Vertices.Select(v => v.IndexInList))));
            }
            serializationData.Add("FaceIndices",
                JToken.FromObject(Faces.SelectMany(face => face.Vertices.Select(v => v.IndexInList)).ToArray()));
            serializationData.Add("VertexCoords",
               JToken.FromObject(Vertices.ConvertTo1DDoublesCollection()));
            if (HasUniformColor || Faces.All(f => f.Color == null || f.Color.Equals(Faces[0].Color)))
                serializationData.Add("Colors", SolidColor.ToString());
            else
            {
                var colorList = new List<string>();
                var lastColor = new Color(KnownColors.LightGray).ToString();
                foreach (var f in Faces)
{'fraction_non_alphanumeric': 0.12251024767623117, 'fraction_numerical': 0.003233069684198372, 'mean_word_length': 1.9519427402862985, 'pattern_counts': {'":': 0, '<': 213, '<?xml version=': 0, '>': 229, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5454722', 'n_tokens_mistral': 4630, 'n_tokens_neox': 4458, 'n_words': 1163}