Ejemplo n.º 1
0
        /// <summary>
        /// Return the f line string (i.e. 1/1/1 2/2/2 3/3/3)
        /// </summary>
        /// <param name="vertIndexes"></param>
        /// <param name="indexesObj"></param>
        /// <returns></returns>
        private static string GetDataF(VertIndexesObj vertIndexes, LocalIndexesObj indexesObj)
        {
            const string strSpace = " ";

            string[] strIndexesF = new string[vertIndexes.VertIndexList.Count];
            int      i           = 0;

            foreach (VertIndexObj vertIndex in vertIndexes.VertIndexList)
            {
                int?V  = vertIndex.V;
                int?Vt = vertIndex.Vt;
                int?Vn = vertIndex.Vn;
                if (V != null)
                {
                    V = V + 1 + indexesObj.vIndex;
                }
                if (Vt != null)
                {
                    Vt = Vt + 1 + indexesObj.vtIndex;
                }
                if (Vn != null)
                {
                    Vn = Vn + 1 + indexesObj.vnIndex;
                }

                strIndexesF[i] = GetIndexesF(V, Vt, Vn); // Add the 1/1/1
                i++;
            }
            return(string.Join(strSpace, strIndexesF));
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Return one object from the obj file
        /// </summary>
        /// <param name="listKeysValues"></param>
        /// <param name="allVertices"></param>
        /// <param name="startIndex"></param>
        /// <param name="endIndex"></param>
        /// <returns></returns>
        private static ObjectObj ObjectData(List <Tuple <string, string> > listKeysValues, AllVerticesDataObj allVertices,
                                            int startIndex, int endIndex)
        {
            LocalIndexesObj indexesObj = new LocalIndexesObj();
            ObjectObj       objectObj  = new ObjectObj();
            int             i          = startIndex;

            while (i < endIndex)
            {
                Tuple <string, string> keyValue = listKeysValues[i];
                if (keyValue != null)
                {
                    string key   = keyValue.Item1;
                    string value = keyValue.Item2.TrimEnd('\0').Trim(); // Remove the null character and any blank space
                    if (ObjUtils.IsVertData(key))                       // f
                    {
                        VerticeData(value, objectObj, allVertices, indexesObj);
                    }
                    else // Other key (o, g, s, usemtl)
                    {
                        switch (key)
                        {
                        case "usemtl":
                            objectObj.MaterialName = value;
                            break;

                        case "o":
                            objectObj.ObjectName = value;
                            break;

                        case "g":
                            objectObj.GroupName = value;
                            break;

                        case "s":
                            if (value != "off")
                            {
                                if (Int32.TryParse(value, out int s))
                                {
                                    objectObj.Smooth = s;
                                }
                            }
                            break;

                        default:
                            break;
                        }
                    }
                }
                i++;
            }
            return(objectObj);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Create the obj and mtl files with the given data
        /// </summary>
        /// <param name="objData">Data parsed from the obj file</param>
        /// <param name="mtlData">Data parsed from the mtl file</param>
        /// <param name="objFilename">Output path</param>
        /// <param name="makeMtl">Create a mtl file</param>
        /// <param name="useExistingMtl">Use the mtlData to create the mtl file</param>
        /// <returns></returns>
        public static bool WriteObj(ObjData objData, MtlData mtlData, string objFilename, bool makeMtl, bool useExistingMtl)
        {
            // objFilename has the .obj extension
            string directory   = System.IO.Path.GetDirectoryName(objFilename);
            string noExtension = System.IO.Path.GetFileNameWithoutExtension(objFilename);
            string mtlRelative = string.Format("{0}.mtl", noExtension);
            string mtlFilename = System.IO.Path.Combine(directory, mtlRelative);

            List <string> mtlLines = new List <string>(); // To store the lines to append to the mtl file

            try
            {
                using (StreamWriter obj = new StreamWriter(objFilename))
                {
                    // mtllib, o, v, vt, g, usemtl, s, f

                    obj.WriteLine(GenericUtils.GetCreditsFile());
                    if (makeMtl)
                    {
                        obj.WriteLine(ObjUtils.GetNewMtlLib(mtlRelative));
                    }

                    LocalIndexesObj indexesObj = new LocalIndexesObj();

                    foreach (ObjectObj objectObj in objData.ObjectsList)
                    {
                        if (objectObj.ObjectName != null)
                        {
                            obj.WriteLine(ObjUtils.GetNewObject(objectObj.ObjectName)); // o
                        }
                        foreach (Point p in objectObj.VerticesList)
                        {
                            obj.WriteLine(ObjUtils.GetNewCoord(p.ToString())); // v
                        }
                        foreach (UVCoordinates uv in objectObj.UVsList)
                        {
                            obj.WriteLine(ObjUtils.GetNewTexCoord(uv.ToString())); // vt
                        }
                        foreach (Vector v in objectObj.NormalsList)
                        {
                            obj.WriteLine(ObjUtils.GetNewVertNormal(v.ToString())); // vn
                        }
                        if (objectObj.GroupName != null)
                        {
                            obj.WriteLine(ObjUtils.GetNewGroup(objectObj.GroupName)); // g
                        }
                        if (objectObj.MaterialName != null)
                        {
                            obj.WriteLine(ObjUtils.GetNewUseMtl(objectObj.MaterialName)); // usemtl
                            // Store lines in the mtl array to append to the file later
                            mtlLines.Add(MtlUtils.GetMtlData(objectObj.MaterialName, objectObj.TextureName));
                        }

                        if (objectObj.Smooth == -1)
                        {
                            obj.WriteLine(ObjUtils.GetNewSmoothGroup()); // s
                        }
                        else
                        {
                            obj.WriteLine(ObjUtils.GetNewSmoothGroup(objectObj.Smooth)); // s
                        }
                        foreach (VertIndexesObj vertIndexes in objectObj.VertIndexesList)
                        {
                            obj.WriteLine(ObjUtils.GetNewF(GetDataF(vertIndexes, indexesObj))); // f
                        }
                        indexesObj.vIndex  += objectObj.VerticesList.Count;
                        indexesObj.vtIndex += objectObj.UVsList.Count;
                        indexesObj.vnIndex += objectObj.NormalsList.Count;
                    }
                }
            }
            catch
            {
                return(false);
            }

            if (makeMtl)                               // If we dont delete materials
            {
                if (useExistingMtl && mtlData != null) // Use the parsed mtl
                {
                    return(MtlExporter.WriteMtl(mtlData, mtlFilename));
                }
                else // Create a mtl from the data obtained in the obj
                {
                    return(MtlExporter.WriteMtl(mtlLines, mtlFilename));
                }
            }

            return(true);
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Store the f, v, vt and vn lines into the object
        /// </summary>
        /// <param name="value"></param>
        /// <param name="objectObj"></param>
        /// <param name="allVertices"></param>
        /// <param name="indexesObj"></param>
        private static void VerticeData(string value, ObjectObj objectObj, AllVerticesDataObj allVertices, LocalIndexesObj indexesObj)
        {
            VertIndexesObj vertIndexes = new VertIndexesObj();

            foreach (string indexes in ObjUtils.SplitVertData(value))
            {
                VertIndexObj vertIndex = new VertIndexObj();

                string[] indexList = ObjUtils.SplitIndexes(indexes);

                int length = indexList.Length;

                for (int i = 0; i < length; i++)
                {
                    int index = 0;
                    if (indexList[i] != "")                                 // the vt line can be empty
                    {
                        if (Int32.TryParse(indexList[i], out int tmpIndex)) // Get the index
                        {
                            index = tmpIndex;
                        }
                    }

                    if (i == 0) // v
                    {
                        if (index != 0)
                        {
                            vertIndex.V = indexesObj.vIndex;
                            string vLine = allVertices.GetVIndex(index - 1); // Obj index start at 1
                            if (vLine != null)
                            {
                                objectObj.VerticesList.Add(new Point(vLine));
                                indexesObj.vIndex++;
                            }
                        }
                    }
                    else if (i == 1) // vt
                    {
                        if (index != 0)
                        {
                            vertIndex.Vt = indexesObj.vtIndex;
                            string vtLine = allVertices.GetVtIndex(index - 1); // Obj index start at 1
                            if (vtLine != null)
                            {
                                objectObj.UVsList.Add(new UVCoordinates(vtLine));
                                indexesObj.vtIndex++;
                            }
                        }
                    }
                    else if (i == 2) // vn
                    {
                        if (index != 0)
                        {
                            vertIndex.Vn = indexesObj.vnIndex;
                            string vnLine = allVertices.GetVnIndex(index - 1); // Obj index start at 1
                            if (vnLine != null)
                            {
                                objectObj.NormalsList.Add(new Vector(vnLine));
                                indexesObj.vnIndex++;
                            }
                        }
                    }
                }
                vertIndexes.VertIndexList.Add(vertIndex);
            }
            objectObj.VertIndexesList.Add(vertIndexes);
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Merge together every group in the array
        /// </summary>
        /// <param name="objData">Data parsed from the obj file</param>
        /// <param name="textureName">Path to the texture file</param>
        /// <param name="groups">List of groups index</param>
        /// <returns></returns>
        private static ObjectObj MergeObjects(ObjData objData, string textureName, List <int> groups)
        {
            int length = groups.Count;

            if (length >= 1) // Should always be the case
            {
                // If the texture name is a relative/absolute path to the file, we only keep the name
                string relativeTexture = System.IO.Path.GetFileName(textureName);

                ObjectObj objectObj = new ObjectObj(objData.ObjectsList[groups[0]])
                {
                    MaterialName = relativeTexture, // Materialname will be the same as the texture file
                    GroupName    = relativeTexture,
                    ObjectName   = relativeTexture,
                    TextureName  = textureName
                };
                if (length == 1) // Only one group
                {
                    return(objectObj);
                }
                else // More group to merge with the first one
                {
                    LocalIndexesObj localIndexes = new LocalIndexesObj
                    {
                        vIndex  = objectObj.VerticesList.Count,
                        vtIndex = objectObj.UVsList.Count,
                        vnIndex = objectObj.NormalsList.Count
                    };

                    for (int i = 1; i < length; i++)
                    {
                        ObjectObj nextObjectObj = objData.ObjectsList[groups[i]];

                        foreach (Point p in nextObjectObj.VerticesList)
                        {
                            objectObj.VerticesList.Add(p);
                        }
                        foreach (UVCoordinates uv in nextObjectObj.UVsList)
                        {
                            objectObj.UVsList.Add(uv);
                        }
                        foreach (Vector v in nextObjectObj.NormalsList)
                        {
                            objectObj.NormalsList.Add(v);
                        }

                        foreach (VertIndexesObj vertIndexes in nextObjectObj.VertIndexesList)
                        {
                            foreach (VertIndexObj vertIndex in vertIndexes.VertIndexList)
                            {
                                if (vertIndex.V != null)
                                {
                                    vertIndex.V += localIndexes.vIndex;
                                }
                                if (vertIndex.Vt != null)
                                {
                                    vertIndex.Vt += localIndexes.vtIndex;
                                }
                                if (vertIndex.Vn != null)
                                {
                                    vertIndex.Vn += localIndexes.vnIndex;
                                }
                            }
                            objectObj.VertIndexesList.Add(vertIndexes);
                        }
                        localIndexes.vIndex  += nextObjectObj.VerticesList.Count;
                        localIndexes.vtIndex += nextObjectObj.UVsList.Count;
                        localIndexes.vnIndex += nextObjectObj.NormalsList.Count;
                    }
                    return(objectObj);
                }
            }
            return(null);
        }
Ejemplo n.º 6
0
        /// <summary>
        /// Calculate the normal vector for each triangle
        /// </summary>
        /// <param name="objData">Data parsed from the obj file</param>
        public static void CalculateNormal(ObjData objData)
        {
            foreach (ObjectObj objectObj in objData.ObjectsList)
            {
                // A triangle is made from 3 points
                LocalIndexesObj localIndexes = new LocalIndexesObj();
                List <Vector>   normalsList  = objectObj.NormalsList;

                localIndexes.vnIndex = normalsList.Count; // Set the current max vnIndex

                List <Point> verticesList   = objectObj.VerticesList;
                int          verticesLength = verticesList.Count;

                foreach (VertIndexesObj vertIndexes in objectObj.VertIndexesList)
                {
                    if (vertIndexes.VertIndexList.Count >= 3) // Should always be the case
                    {
                        VertIndexObj vertIndex1 = vertIndexes.VertIndexList[0];
                        VertIndexObj vertIndex2 = vertIndexes.VertIndexList[1];
                        VertIndexObj vertIndex3 = vertIndexes.VertIndexList[2];

                        // If a normal needs to be calculated
                        if (vertIndex1.Vn == null || vertIndex2.Vn == null || vertIndex3.Vn == null)
                        {
                            // If all points indexes are correctly defined
                            if (vertIndex1.V != null && vertIndex2.V != null && vertIndex3.V != null)
                            {
                                Point p1 = (vertIndex1.V < verticesLength) ? verticesList[(int)vertIndex1.V] : null;
                                Point p2 = (vertIndex2.V < verticesLength) ? verticesList[(int)vertIndex2.V] : null;
                                Point p3 = (vertIndex3.V < verticesLength) ? verticesList[(int)vertIndex3.V] : null;

                                // If all indexes lead to existing points
                                if (p1 != null && p2 != null && p3 != null)
                                {
                                    Vector vector1 = new Vector(p1, p2);
                                    Vector vector2 = new Vector(p2, p3);

                                    Vector vectorNormal = Vector.GetNormalVector(vector1, vector2);
                                    normalsList.Add(vectorNormal.GetUnitVector()); // Add to the list the unit vector

                                    // We assign the index of the normal vector to
                                    if (vertIndex1.Vn == null)
                                    {
                                        vertIndex1.Vn = localIndexes.vnIndex;
                                    }
                                    if (vertIndex2.Vn == null)
                                    {
                                        vertIndex2.Vn = localIndexes.vnIndex;
                                    }
                                    if (vertIndex3.Vn == null)
                                    {
                                        vertIndex3.Vn = localIndexes.vnIndex;
                                    }

                                    // Increment the index for the next normal vector
                                    localIndexes.vnIndex++;
                                }
                            }
                        }
                    }
                }
            }
        }