/// <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); }
/// <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); }