Ejemplo n.º 1
0
 /// <summary>
 /// get parsed obj model
 /// </summary>
 /// <returns></returns>
 public ObjModel GetModel()
 {
     if (_model == null)
     {
         var modelName = "Untitled";
         if (!String.IsNullOrEmpty(_objFile))
         {
             modelName = Path.GetFileNameWithoutExtension(_objFile);
         }
         _model = new ObjModel {
             Name = modelName
         };
         while (!_reader.EndOfStream)
         {
             var line = _reader.ReadLine().Trim();
             if (String.IsNullOrEmpty(line))
             {
                 continue;
             }
             if (line.StartsWith("#"))
             {
                 continue;
             }
             if (StartWith(line, "mtllib"))
             {
                 _model.MatFilename = line.Substring(6).Trim();
             }
             else if (StartWith(line, "v"))
             {
                 var vStr = line.Substring(1).Trim();
                 var strs = SplitLine(vStr);
                 var v    = new Vec3(double.Parse(strs[0]), double.Parse(strs[1]), double.Parse(strs[2]));
                 _model.Vertices.Add(v);
             }
             else if (StartWith(line, "vn"))
             {
                 var vnStr = line.Substring(2).Trim();
                 var strs  = SplitLine(vnStr);
                 var vn    = new Vec3(double.Parse(strs[0]), double.Parse(strs[1]), double.Parse(strs[2]));
                 _model.Normals.Add(vn);
             }
             else if (StartWith(line, "vt"))
             {
                 var vtStr = line.Substring(2).Trim();
                 var strs  = SplitLine(vtStr);
                 var vt    = new Vec2(double.Parse(strs[0]), double.Parse(strs[1]));
                 _model.Uvs.Add(vt);
             }
             else if (StartWith(line, "g"))
             {
                 var gStr = line.Substring(1).Trim();
                 var g    = new Geometry {
                     Id = gStr
                 };
                 _model.Geometries.Add(g);
             }
             else if (StartWith(line, "usemtl"))
             {
                 var umtl = line.Substring(6).Trim();
                 var g    = GetGeometry();
                 var face = new Face {
                     MatName = umtl
                 };
                 g.Faces.Add(face);
             }
             else if (StartWith(line, "f"))
             {
                 var  fStr = line.Substring(1).Trim();
                 var  g    = GetGeometry();
                 Face face = GetFace(g);
                 var  strs = SplitLine(fStr);
                 if (strs.Length < 3)
                 {
                     continue;                  // ignore face that has less than 3 vertices
                 }
                 if (strs.Length == 3)
                 {
                     var v1 = GetVertex(strs[0]);
                     var v2 = GetVertex(strs[1]);
                     var v3 = GetVertex(strs[2]);
                     var f  = new FaceTriangle(v1, v2, v3);
                     face.Triangles.Add(f);
                 }
                 else if (strs.Length == 4)
                 {
                     var v1 = GetVertex(strs[0]);
                     var v2 = GetVertex(strs[1]);
                     var v3 = GetVertex(strs[2]);
                     var f  = new FaceTriangle(v1, v2, v3);
                     face.Triangles.Add(f);
                     var v4 = GetVertex(strs[3]);
                     var ff = new FaceTriangle(v1, v3, v4);
                     face.Triangles.Add(ff);
                 }
                 else //if (strs.Length > 4)
                 {
                     var points = new List <Vec3>();
                     for (var i = 0; i < strs.Length; i++)
                     {
                         var vv = GetVertex(strs[i]);
                         var p  = _model.Vertices[vv.V - 1];
                         points.Add(p);
                     }
                     var planeAxis = GeomUtil.ComputeProjectTo2DArguments(points);
                     if (planeAxis != null)
                     {
                         var points2D = GeomUtil.CreateProjectPointsTo2DFunction(planeAxis, points);
                         var indices  = PolygonPipeline.Triangulate(points2D, null);
                         if (indices.Length == 0)
                         {
                             // TODO:
                         }
                         for (var i = 0; i < indices.Length - 2; i += 3)
                         {
                             var vv1 = GetVertex(strs[indices[i]]);
                             var vv2 = GetVertex(strs[indices[i + 1]]);
                             var vv3 = GetVertex(strs[indices[i + 2]]);
                             var ff  = new FaceTriangle(vv1, vv2, vv3);
                             face.Triangles.Add(ff);
                         }
                     }
                     else
                     {
                         // TODO:
                     }
                 }
             }
             else
             {
                 //var strs = SplitLine(line);
             }
         }
         if (!String.IsNullOrEmpty(_model.MatFilename))
         {
             var dir     = Path.GetDirectoryName(_objFile);
             var matFile = Path.Combine(dir, _model.MatFilename);
             using (var mtlParser = new MtlParser(matFile, _encoding))
             {
                 var mats = mtlParser.GetMats();
                 _model.Materials.AddRange(mats);
             }
         }
     }
     return(_model);
 }