Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- public enum SaveFormat {
- OBJ,
- QMO
- }
- public enum LoadFormat {
- Auto,
- OBJ,
- QMO
- }
- public static class ImportExport {
- // NEW CODE (more complex but can load .obj from "anywhere" (normally) and generated files are lighter)
- /// <summary>
- /// Save a Mesh to a file.
- /// path : the path were the mesh will be created WITHOUT THE EXTENSION.
- /// format : format of the file (obj/qmo).
- /// overwrite : if the file already exists, should it overwrite ?
- /// </summary>
- public static void SaveToFile (this Mesh mesh, string path, SaveFormat format, bool overwrite) {
- path = path + '.' + format.ToString ().ToLower ();
- try {
- if (!File.Exists (path) || overwrite) {
- File.WriteAllText (path, mesh.SaveToText (format));
- }
- else {
- Debug.LogWarning ("This file already exists, can't save mesh : " + mesh.name + ", or set overwrite to true.\n@" + path);
- }
- }
- catch (Exception ex) {
- Debug.LogWarning ("Exception while saving mesh : " + mesh.name + "\n@ " + path + "\nex: " + ex);
- }
- }
- /// <summary>
- /// Save a Mesh to a text.
- /// </summary>
- public static string SaveToText (this Mesh mesh, SaveFormat format) {
- StringBuilder text = new StringBuilder ();
- if (format == SaveFormat.OBJ) {
- text.AppendFormat ("# ModelisaTools exported obj file\n\no {0}\n\n", mesh.name);
- List<Vector3> vertices = new List<Vector3> ();
- List<int> veIndex = new List<int> ();
- List<Vector3> uv = new List<Vector3> ();
- List<int> uvIndex = new List<int> ();
- List<Vector3> normals = new List<Vector3> ();
- List<int> noIndex = new List<int> ();
- Vector3 tempV3;
- Vector2 tempV2;
- for (int i = 0; i < mesh.vertices.Length; i++) {
- if (!vertices.Contains (mesh.vertices[i])) {
- vertices.Add (mesh.vertices[i]);
- veIndex.Add (vertices.Count - 1);
- }
- else {
- veIndex.Add (vertices.IndexOf (mesh.vertices[i]));
- }
- }
- for (int i = 0; i < mesh.uv.Length; i++) {
- if (!uv.Contains (mesh.uv[i])) {
- uv.Add (mesh.uv[i]);
- uvIndex.Add (uv.Count - 1);
- }
- else {
- uvIndex.Add (uv.IndexOf (mesh.uv[i]));
- }
- }
- for (int i = 0; i < mesh.normals.Length; i++) {
- if (!normals.Contains (mesh.normals[i])) {
- normals.Add (mesh.normals[i]);
- noIndex.Add (normals.Count - 1);
- }
- else {
- noIndex.Add (normals.IndexOf (mesh.normals[i]));
- }
- }
- for (int i = 0; i < vertices.Count; i++) {
- tempV3 = vertices[i];
- text.AppendFormat ("v {0} {1} {2}\n", tempV3.x, tempV3.y, tempV3.z);
- }
- text.Append ("\n");
- for (int i = 0; i < uv.Count; i++) {
- tempV2 = uv[i];
- text.AppendFormat ("vt {0} {1}\n", tempV2.x, tempV2.y);
- }
- text.Append ("\n");
- for (int i = 0; i < normals.Count; i++) {
- tempV3 = normals[i];
- text.AppendFormat ("vn {0} {1} {2}\n", tempV3.x, tempV3.y, tempV3.z);
- }
- text.Append ("\ns off\n\n"); // smoothing group, but unity doesn't support it :/
- for (int i = 0; i < mesh.triangles.Length; i += 3) {
- text.AppendFormat ("f {0}/{1}/{2} {3}/{4}/{5} {6}/{7}/{8}\n",
- veIndex[ mesh.triangles[ i ] ] + 1,
- uvIndex[ mesh.triangles[ i ] ] + 1,
- noIndex[ mesh.triangles[ i ] ] + 1,
- veIndex[ mesh.triangles[ i + 1 ] ] + 1,
- uvIndex[ mesh.triangles[ i + 1 ] ] + 1,
- noIndex[ mesh.triangles[ i + 1 ] ] + 1,
- veIndex[ mesh.triangles[ i + 2 ] ] + 1,
- uvIndex[ mesh.triangles[ i + 2 ] ] + 1,
- noIndex[ mesh.triangles[ i + 2 ] ] + 1
- );
- }
- }
- if (format == SaveFormat.QMO) {
- throw new NotImplementedException ();
- }
- return text.ToString ();
- }
- /// <summary>
- /// Load a Mesh from a file.
- /// path : the path were the mesh will be loaded, WITHOUT THE EXTENSION.
- /// format : format of mesh (obj/qmo).
- /// </summary>
- public static void LoadFromFile (this Mesh mesh, string path, LoadFormat format) {
- path = path + '.' + format.ToString ().ToLower ();
- try {
- if (File.Exists (path)) {
- mesh.LoadFromStream (File.OpenText (path), format);
- }
- else {
- Debug.LogWarning ("This file doesn't exists, can't load mesh @ " + path);
- }
- }
- catch (Exception ex) {
- Debug.LogWarning ("Exception while loading mesh : " + ((mesh == null) ? "NULL_MESH" : mesh.name) + "\n@ " + path + "\nex: " + ex);
- }
- }
- /// <summary>
- /// Load a Mesh from a TextReader (StringReader or StreamReader).
- /// </summary>
- public static void LoadFromStream (this Mesh mesh, TextReader reader, LoadFormat format) {
- string line;
- int lineNumber = 0;
- string[] datas;
- string[] v0Datas;
- string[] v1Datas;
- string[] v2Datas;
- string[] v3Datas;
- Vector3 tempV3;
- Vector2 tempV2;
- // "raw" data
- List<Vector3> tempVertices = new List<Vector3> ();
- List<Vector2> tempUV = new List<Vector2> ();
- List<Vector3> tempNormals = new List<Vector3> ();
- // ordered data
- List<Vector3> vertices = new List<Vector3> ();
- List<Vector2> uv = new List<Vector2> ();
- List<Vector3> normals = new List<Vector3> ();
- List<int> triangles = new List<int> ();
- if (format == LoadFormat.OBJ) {
- while ((line = reader.ReadLine()) != null) {
- lineNumber++;
- line = line.Replace ('\t', ' ');
- datas = line.Split (' ');
- if (datas.Length == 0) continue;
- // mesh name
- if (datas[0] == "o") {
- try {
- mesh.name = datas[1];
- }
- catch (Exception ex) {
- mesh.name = "undefined";
- Debug.LogWarning ("PARSE ERROR (name) : line " + lineNumber + " while loading mesh : " + mesh.name + "\n" + ex);
- }
- }
- // vertex
- if (datas[0] == "v") {
- try {
- tempV3.x = float.Parse (datas[1]);
- tempV3.y = float.Parse (datas[2]);
- tempV3.z = float.Parse (datas[3]);
- tempVertices.Add (tempV3);
- }
- catch (Exception ex) {
- tempVertices.Add (Vector3.zero);
- Debug.LogWarning ("PARSE ERROR (vertex) : line " + lineNumber + " while loading mesh : " + mesh.name + "\n" + ex);
- }
- }
- // uv (vt = vertex texture)
- if (datas[0] == "vt") {
- try {
- tempV2.x = float.Parse (datas[1]);
- tempV2.y = float.Parse (datas[2]);
- tempUV.Add (tempV2);
- }
- catch (Exception ex) {
- tempUV.Add (Vector2.zero);
- Debug.LogWarning ("PARSE ERROR (uv) : line " + lineNumber + " while loading mesh : " + mesh.name + "\n" + ex);
- }
- }
- // normal
- if (datas[0] == "vn") {
- try {
- tempV3.x = float.Parse (datas[1]);
- tempV3.y = float.Parse (datas[2]);
- tempV3.z = float.Parse (datas[3]);
- tempNormals.Add (tempV3);
- }
- catch (Exception ex) {
- tempNormals.Add (Vector3.zero);
- Debug.LogWarning ("PARSE ERROR (normal) : line " + lineNumber + " while loading mesh : " + mesh.name + "\n" + ex);
- }
- }
- // face
- if (datas[0] == "f") {
- // triangle or quad
- if (datas.Length >= 4) {
- try {
- v0Datas = datas[1].Split ('/');
- v1Datas = datas[2].Split ('/');
- v2Datas = datas[3].Split ('/');
- vertices.Add ( tempVertices[ int.Parse (v0Datas[0]) - 1 ] );
- vertices.Add ( tempVertices[ int.Parse (v1Datas[0]) - 1 ] );
- vertices.Add ( tempVertices[ int.Parse (v2Datas[0]) - 1 ] );
- uv.Add ( tempUV[ int.Parse (v0Datas[1]) - 1 ] );
- uv.Add ( tempUV[ int.Parse (v1Datas[1]) - 1 ] );
- uv.Add ( tempUV[ int.Parse (v2Datas[1]) - 1 ] );
- normals.Add ( tempNormals[ int.Parse (v0Datas[2]) - 1 ] );
- normals.Add ( tempNormals[ int.Parse (v1Datas[2]) - 1 ] );
- normals.Add ( tempNormals[ int.Parse (v2Datas[2]) - 1 ] );
- int i = triangles.Count;
- triangles.Add (i);
- triangles.Add (i + 1);
- triangles.Add (i + 2);
- if (datas.Length >= 5) {
- v3Datas = datas[4].Split ('/');
- vertices.Add ( tempVertices[ int.Parse (v3Datas[0]) ] );
- uv.Add ( tempUV[ int.Parse (v3Datas[1]) ] );
- normals.Add ( tempNormals[ int.Parse (v3Datas[2]) ] );
- triangles.Add (i + 1);
- triangles.Add (i + 2);
- triangles.Add (i + 3);
- }
- }
- catch (Exception ex) {
- Debug.LogWarning ("PARSE ERROR (face:" + (datas.Length-1) + ") : line " + lineNumber + " while loading mesh : " + mesh.name + "\n" + ex);
- }
- }
- }
- // else it's :
- // - a comment (#)
- // - a smoothing group (s on or s off), but unity doesn't support it
- // - a unsupported instruction (ex : mtl)
- }
- mesh.Clear ();
- mesh.vertices = vertices.ToArray ();
- mesh.uv = uv.ToArray ();
- mesh.normals = normals.ToArray ();
- mesh.triangles = triangles.ToArray ();
- }
- if (format == LoadFormat.QMO) {
- throw new NotImplementedException ();
- }
- reader.Close ();
- }
- // NEW CODE
- // OLD CODE (simpler but surely faster, WARNING : can load only .obj saved with this code (can have issue when loading .obj from other softwares))
- public static string SimpleSaveToText (this Mesh mesh) { return mesh.SimpleSaveToText (SaveFormat.OBJ); }
- /// <summary>
- /// Save a Mesh to a text.
- /// sFormat : format of the text (obj/qmo). Optional : default .obj.
- /// </summary>
- public static string SimpleSaveToText (this Mesh mesh, SaveFormat sFormat) {
- StringBuilder text = new StringBuilder ();
- if (sFormat == SaveFormat.OBJ) {
- text.AppendFormat("# ModelisaTools exported obj file\n\no {0}\n\n", mesh.name);
- foreach (Vector3 v in mesh.vertices) {
- text.AppendFormat ("v {0} {1} {2}\n", v.x, v.y, v.z);
- }
- text.Append ("\n");
- foreach (Vector2 u in mesh.uv) {
- text.AppendFormat ("vt {0} {1}\n", u.x, u.y);
- }
- text.Append ("\n");
- foreach (Vector3 n in mesh.normals) {
- text.AppendFormat ("vn {0} {1} {2}\n", n.x, n.y, n.z);
- }
- text.Append ("\ns off\n\n"); // smoothing group, but unity doesn't support it :/
- for (int i = 0; i < mesh.triangles.Length; i += 3) {
- text.AppendFormat ("f {0}/{0}/{0} {1}/{1}/{1} {2}/{2}/{2}\n", mesh.triangles[i]+1, mesh.triangles[i+1]+1, mesh.triangles[i+2]+1);
- }
- }
- if (sFormat == SaveFormat.QMO) {
- throw new NotImplementedException ();
- }
- return text.ToString ();
- }
- public static void SimpleSaveToFile (this Mesh mesh, string path) { mesh.SimpleSaveToFile (path, SaveFormat.OBJ, false); }
- public static void SimpleSaveToFile (this Mesh mesh, string path, SaveFormat sFormat) { mesh.SimpleSaveToFile (path, sFormat, false); }
- public static void SimpleSaveToFile (this Mesh mesh, string path, bool overwrite) { mesh.SimpleSaveToFile (path, SaveFormat.OBJ, overwrite); }
- /// <summary>
- /// Save a Mesh to a file.
- /// path : the path were the mesh will be created WITHOUT THE EXTENSION.
- /// sFormat : format of the file (obj/qmo). Optional : default .obj.
- /// overwrite : if the file already exists, should it overwrite ? Optional : default false.
- /// </summary>
- public static void SimpleSaveToFile (this Mesh mesh, string path, SaveFormat sFormat, bool overwrite) {
- path = path + '.' + sFormat.ToString ().ToLower ();
- try {
- if (!File.Exists (path) || overwrite) {
- File.WriteAllText (path, mesh.SimpleSaveToText (sFormat));
- }
- else {
- Debug.LogWarning ("This file already exists, can't save mesh : " + mesh.name + ", or set overwrite to true.\n@" + path);
- }
- }
- catch (Exception ex) {
- Debug.LogWarning ("Exception while saving mesh : " + mesh.name + "\n@ " + path + "\nex: " + ex);
- }
- }
- public static void SimpleLoadFromFile (this Mesh mesh, string path) { mesh.SimpleLoadFromFile (path, LoadFormat.Auto); }
- /// <summary>
- /// Load a Mesh from a file.
- /// path : the path were the mesh will be loaded, WITH THE EXTENSION if lFormat is AUTO, and WITHOUT if lFormat is : OBJ, QMO.
- /// lFormat : format of mesh (obj/qmo). Optional : default AUTO
- /// </summary>
- public static void SimpleLoadFromFile (this Mesh mesh, string path, LoadFormat lFormat) {
- if (lFormat != LoadFormat.Auto) {
- path = path + '.' + lFormat.ToString ().ToLower ();
- }
- try {
- if (File.Exists (path)) {
- string extension = Path.GetExtension (path);
- LoadFormat format;
- if (extension == ".obj") {
- format = LoadFormat.OBJ;
- }
- else if (extension == ".qmo") {
- format = LoadFormat.QMO;
- }
- else {
- format = LoadFormat.Auto;
- }
- mesh.SimpleLoadFromStream (File.OpenText (path), format);
- }
- else {
- Debug.LogWarning ("This file doesn't exists, can't load mesh @ " + path);
- }
- }
- catch (Exception ex) {
- Debug.LogWarning ("Exception while loading mesh : " + mesh.name + "\n@ " + path + "\nex: " + ex);
- }
- }
- /// <summary>
- /// Load a Mesh from a TextReader (StringReader or StreamReader).
- /// </summary>
- public static void SimpleLoadFromStream (this Mesh mesh, TextReader reader, LoadFormat lFormat) {
- string line;
- int lineNumber = 0;
- string[] datas;
- Vector3 tempVector3;
- Vector2 tempVector2;
- List<Vector3> vertices = new List<Vector3> ();
- List<Vector2> uv = new List<Vector2> ();
- List<Vector3> normals = new List<Vector3> ();
- List<int> triangles = new List<int> ();
- if (lFormat == LoadFormat.Auto) {
- Debug.LogWarning ("Can't load mesh : " + mesh.name + ", format is not supported.");
- return;
- }
- if (lFormat == LoadFormat.OBJ) {
- while ((line = reader.ReadLine()) != null) {
- datas = line.Split (' '); // so datas[0] == o || v || vt || vn || f || ...
- // mesh name
- if (line.StartsWith ("o")) {
- mesh.name = datas[1];
- }
- // vertex
- if (line.StartsWith ("v ")) {
- try {
- tempVector3.x = float.Parse (datas[1]);
- tempVector3.y = float.Parse (datas[2]);
- tempVector3.z = float.Parse (datas[3]);
- vertices.Add (tempVector3);
- }
- catch (Exception ex) {
- Debug.LogWarning ("PARSE ERROR (vertex) : line " + lineNumber + " while loading mesh : " + mesh.name + "\n" + ex);
- vertices.Add (Vector3.zero);
- }
- }
- // uv - texture coordinate
- if (line.StartsWith ("vt")) {
- try {
- tempVector2.x = float.Parse (datas[1]);
- tempVector2.y = float.Parse (datas[2]);
- uv.Add (tempVector2);
- }
- catch (Exception ex) {
- Debug.LogWarning ("PARSE ERROR (uv) : line " + lineNumber + " while loading mesh : " + mesh.name + "\n" + ex);
- uv.Add (Vector2.zero);
- }
- }
- // normal
- if (line.StartsWith ("vn")) {
- try {
- tempVector3.x = float.Parse (datas[1]);
- tempVector3.y = float.Parse (datas[2]);
- tempVector3.z = float.Parse (datas[3]);
- normals.Add (tempVector3);
- }
- catch (Exception ex) {
- Debug.LogWarning ("PARSE ERROR (normal) : line " + lineNumber + " while loading mesh : " + mesh.name + "\n" + ex);
- normals.Add (Vector3.zero);
- }
- }
- // triangle (face)
- if (line.StartsWith ("f")) {
- try {
- triangles.Add (int.Parse (datas[1].Split ('/')[0]) - 1);
- triangles.Add (int.Parse (datas[2].Split ('/')[0]) - 1);
- triangles.Add (int.Parse (datas[3].Split ('/')[0]) - 1);
- }
- catch (Exception ex) {
- Debug.LogWarning ("PARSE ERROR (triangle) : line " + lineNumber + " while loading mesh : " + mesh.name + "\n" + ex);
- triangles.Add (1);
- triangles.Add (2);
- triangles.Add (3);
- // beurk beurk, but we preserve vertex/face order
- }
- }
- // else it's :
- // _ a comment (#...)
- // _ a smoothing group, but unity doesn't support it (s on/s off)
- // _ a unsupported operation (ex : mtl)
- lineNumber++;
- }
- mesh.Clear ();
- mesh.vertices = vertices.ToArray ();
- mesh.uv = uv.ToArray ();
- mesh.normals = normals.ToArray ();
- mesh.triangles = triangles.ToArray ();
- }
- if (lFormat == LoadFormat.QMO) {
- //
- }
- reader.Close ();
- }
- /// <summary>
- /// Load a Mesh from a String (internally convert into a StringReader and call LoadFromStream).
- /// lFormat : format of mesh (obj/qmo)
- /// </summary>
- public static void SimpleLoadFromText (this Mesh mesh, string text, LoadFormat lFormat) {
- mesh.SimpleLoadFromStream (new StringReader (text), lFormat);
- }
- // OLD CODE
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement