Пример #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);
 }
Пример #2
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="level">will generate level^3 models</param>
        /// <returns></returns>
        public List <ObjModel> Split(int level)
        {
            if (level <= 1)
            {
                return(new List <ObjModel> {
                    this
                });
            }
            var box     = GetBounding();
            var boxes   = box.Split(level);
            var geoes   = new List <Geometry> [boxes.Count];
            var pnts    = new List <int> [boxes.Count];
            var normals = new List <int> [boxes.Count];
            var uvs     = new List <int> [boxes.Count];

            for (var i = 0; i < geoes.Length; i++)
            {
                geoes[i]   = new List <Geometry>();
                pnts[i]    = new List <int>();
                normals[i] = new List <int>();
                uvs[i]     = new List <int>();
            }
            foreach (var g in Geometries)
            {
                var geoBox = GetBoxIndex(g, boxes);
                var index  = geoBox.Index;
                var gg     = AddGeo(g, geoBox, pnts[index], normals[index], uvs[index]);
                geoes[index].Add(gg);
            }
            var objModels = new List <ObjModel>();

            for (var i = 0; i < geoes.Length; i++)
            {
                if (geoes[i].Count == 0)
                {
                    continue;
                }
                var m = new ObjModel {
                    Geometries  = geoes[i], Name = Name + "_" + objModels.Count,
                    MatFilename = MatFilename, Materials = Materials
                };
                if (m.Vertices == null)
                {
                    m.Vertices = new List <Vec3>();
                }
                var ps = pnts[i];
                foreach (var v in ps)
                {
                    m.Vertices.Add(Vertices[v - 1]);
                }
                if (m.Normals == null)
                {
                    m.Normals = new List <Vec3>();
                }
                var ns = normals[i];
                foreach (var n in ns)
                {
                    m.Normals.Add(Normals[n - 1]);
                }
                if (m.Uvs == null)
                {
                    m.Uvs = new List <Vec2>();
                }
                var ts = uvs[i];
                foreach (var t in ts)
                {
                    m.Uvs.Add(Uvs[t - 1]);
                }
                objModels.Add(m);
            }
            return(objModels);
        }