HelixToolkit.Wpf.ObjReader.AddFace C# (CSharp) Method

AddFace() private method

Adds a face.
Adds a polygonal face. The numbers are indexes into the arrays of vertex positions, texture coordinates, and normal vectors respectively. A number may be omitted if, for example, texture coordinates are not being defined in the model. There is no maximum number of vertices that a single polygon may contain. The .obj file specification says that each face must be flat and convex.
private AddFace ( string values ) : void
values string /// The input values. ///
return void
        private void AddFace(string values)
        {
            var currentGroup = this.CurrentGroup;
            var builder = currentGroup.MeshBuilder;
            var positions = builder.Positions;
            var textureCoordinates = builder.TextureCoordinates;
            var normals = builder.Normals;

            Dictionary<int, int> smoothingGroupMap = null;

            // If a smoothing group is defined, get the map from obj-file-index to current-group-vertex-index.
            if (this.currentSmoothingGroup != 0)
            {
                if (!this.smoothingGroupMaps.TryGetValue(this.currentSmoothingGroup, out smoothingGroupMap))
                {
                    smoothingGroupMap = new Dictionary<int, int>();
                    this.smoothingGroupMaps.Add(this.currentSmoothingGroup, smoothingGroupMap);
                }
            }

            var fields = values.SplitOnWhitespace();
            var faceIndices = new List<int>();
            foreach (var field in fields)
            {
                if (string.IsNullOrEmpty(field))
                {
                    continue;
                }

                var ff = field.Split('/');
                int vi = int.Parse(ff[0]);
                int vti = ff.Length > 1 && ff[1].Length > 0 ? int.Parse(ff[1]) : int.MaxValue;
                int vni = ff.Length > 2 && ff[2].Length > 0 ? int.Parse(ff[2]) : int.MaxValue;

                // Handle relative indices (negative numbers)
                if (vi < 0)
                {
                    vi = this.Points.Count + vi + 1;
                }

                if (vti < 0)
                {
                    vti = this.TextureCoordinates.Count + vti + 1;
                }

                if (vni < 0)
                {
                    vni = this.Normals.Count + vni + 1;
                }

                // Check if the indices are valid
                if (vi - 1 >= this.Points.Count)
                {
                    if (this.IgnoreErrors)
                    {
                        return;
                    }

                    throw new FileFormatException(string.Format("Invalid vertex index ({0}) on line {1}.", vi, this.currentLineNo));
                }

                if (vti == int.MaxValue)
                {
                    // turn off texture coordinates in the builder
                    builder.CreateTextureCoordinates = false;
                }

                if (vni == int.MaxValue)
                {
                    // turn off normals in the builder
                    builder.CreateNormals = false;
                }

                // check if the texture coordinate index is valid
                if (builder.CreateTextureCoordinates && vti - 1 >= this.TextureCoordinates.Count)
                {
                    if (this.IgnoreErrors)
                    {
                        return;
                    }

                    throw new FileFormatException(
                            string.Format(
                                "Invalid texture coordinate index ({0}) on line {1}.", vti, this.currentLineNo));
                }

                // check if the normal index is valid
                if (builder.CreateNormals && vni - 1 >= this.Normals.Count)
                {
                    if (this.IgnoreErrors)
                    {
                        return;
                    }

                    throw new FileFormatException(
                            string.Format("Invalid normal index ({0}) on line {1}.", vni, this.currentLineNo));
                }

                bool addVertex = true;

                if (smoothingGroupMap != null)
                {
                    int vix;
                    if (smoothingGroupMap.TryGetValue(vi, out vix))
                    {
                        // use the index of a previously defined vertex
                        addVertex = false;
                    }
                    else
                    {
                        // add a new vertex
                        vix = positions.Count;
                        smoothingGroupMap.Add(vi, vix);
                    }

                    faceIndices.Add(vix);
                }
                else
                {
                    // if smoothing is off, always add a new vertex
                    faceIndices.Add(positions.Count);
                }

                if (addVertex)
                {
                    // add vertex
                    positions.Add(this.Points[vi - 1]);

                    // add texture coordinate (if enabled)
                    if (builder.CreateTextureCoordinates)
                    {
                        textureCoordinates.Add(this.TextureCoordinates[vti - 1]);
                    }

                    // add normal (if enabled)
                    if (builder.CreateNormals)
                    {
                        normals.Add(this.Normals[vni - 1]);
                    }
                }
            }

            if (faceIndices.Count <= 4)
            {
                // add triangles or quads
                builder.AddPolygon(faceIndices);
            }
            else
            {
                // add triangles by cutting ears algorithm
                // this algorithm is quite expensive...
                builder.AddPolygonByCuttingEars(faceIndices);
            }
        }