/// <summary> /// Adds a face from the importer to the geometry container /// </summary> /// <param name="gf">GeoFace object from the importer</param> private void AddFace(GeoFace gf) { // Add a face container. _LfacePtrCont.Add( new FacePtrCont() { _h = new HandleHalfEdge() { _DataIndex = -1 } } ); // Add a face handle. _LfaceHndl.Add( new HandleFace() { _DataIndex = _LfacePtrCont.Count - 1 } ); // Insert all the vertices for the face. List<HandleVertex> LHandleVertsForFace = new List<HandleVertex>(); foreach (float3 vVal in gf._LFVertices) { LHandleVertsForFace.Add( AddVertex(vVal) ); } // Insert all the uv coordinates for the face. List<HandleVertexUV> LHandleUVsForFace = new List<HandleVertexUV>(); foreach (float2 uvVal in gf._UV) { _LuvCoordinates.Add(uvVal); LHandleUVsForFace.Add(new HandleVertexUV() { _DataIndex = _LuvCoordinates.Count - 1 }); } // Build up the half-edge connections for the face List<HandleHalfEdge> LHandleHEForFace = new List<HandleHalfEdge>(); for (int i = 0; i < LHandleVertsForFace.Count; i++) { HandleVertex fromVert = LHandleVertsForFace[i]; HandleVertex toVert = i + 1 < LHandleVertsForFace.Count ? LHandleVertsForFace[i + 1] : LHandleVertsForFace[0]; LHandleHEForFace.Add( CreateConnection(fromVert, toVert) ); } // Loop over all the half-edges for the face and concat them and set the correct uv coordinates. for (int i = 0; i < LHandleHEForFace.Count; i++) { HandleHalfEdge currentHedge = LHandleHEForFace[i]; HEdgePtrCont hedge = _LhedgePtrCont[currentHedge]; HandleHalfEdge nextHedge = i + 1 < LHandleHEForFace.Count ? LHandleHEForFace[i + 1] : LHandleHEForFace[0]; hedge._nhe = nextHedge; if (LHandleUVsForFace.Count > 0) { HandleVertexUV currentUV = i + 1 < LHandleUVsForFace.Count ? LHandleUVsForFace[i + 1] : LHandleUVsForFace[0]; hedge._vuv = currentUV; } //_LhedgePtrCont.RemoveAt(currentHedge); //_LhedgePtrCont.Insert(currentHedge, hedge); _LhedgePtrCont[currentHedge] = new HEdgePtrCont() { _f = hedge._f, _he = hedge._he, _nhe = hedge._nhe, _v = hedge._v, _vn = hedge._vn, _vuv = hedge._vuv }; } // Set the half-edge the face points to. FacePtrCont face = _LfacePtrCont.Last(); face._h = new HandleHalfEdge(LHandleHEForFace.First()); _LfacePtrCont.RemoveAt(_LfacePtrCont.Count - 1); _LfacePtrCont.Add(face); }
/// <summary> /// Loads an asset from file to the memory. /// </summary> /// <param name="pathToAsset"></param> public List <GeoFace> LoadAsset(String pathToAsset) { _SassetFileContent = ""; List <String> LvertexHelper = new List <string>(); List <String> LfaceHelper = new List <string>(); String[] splitChar = { " " }; String[] splitChar2 = { "/" }; // Load the file information to the memory List <String> LgeoValues = LoadFile(pathToAsset); if (LgeoValues != null) { List <float3> LvertexAttr = new List <float3>(); foreach (String line in LgeoValues) { string lineStart = line.Length > 2 ? line.Substring(0, 2) : line.Substring(0, line.Length); if (line.StartsWith("vt")) { string[] lineSplitted = line.Split(splitChar, StringSplitOptions.None); // vertex texture coordinates if (LFGMessages._DEBUGOUTPUT) { Console.WriteLine(LFGMessages.INFO_UVFOUND + line); } List <Double> tmpSave = new List <double>(); foreach (string str in lineSplitted) { if (!str.StartsWith("vt") && !str.Equals("")) { tmpSave.Add(MeshReader.Double_Parse(str)); } } float2 uvVal = new float2( (float)tmpSave[0], (float)tmpSave[1] ); _LuvCoords.Add(uvVal); } else if (line.StartsWith("vn")) { // vertex normals } else if (line.StartsWith("v")) { // vertex string[] lineSplitted = line.Split(splitChar, StringSplitOptions.None); List <Double> tmpSave = new List <double>(); foreach (string str in lineSplitted) { if (!str.StartsWith("v") && !str.Equals("")) { tmpSave.Add(MeshReader.Double_Parse(str)); } } float3 fVal = new float3( (float)tmpSave[0], (float)tmpSave[1], (float)tmpSave[2] ); LvertexAttr.Add(fVal); } else if (line.StartsWith("p")) { // point } else if (line.StartsWith("l")) { // line } else if (line.StartsWith("f")) { // there are faces, faces with texture coord, faces with vertex normals and faces with text and normals if (LFGMessages._DEBUGOUTPUT) { Console.WriteLine(LFGMessages.INFO_FACEFOUND + line); } string[] lineSplitted = line.Split(splitChar, StringSplitOptions.None); List <Double> tmpSave = new List <double>(); GeoFace geoF = new GeoFace(); geoF._LFVertices = new List <float3>(); geoF._UV = new List <float2>(); foreach (string str in lineSplitted) { if (!str.StartsWith("f")) { string[] faceSplit = str.Split(splitChar2, StringSplitOptions.None); string s = faceSplit[0]; if (LFGMessages._DEBUGOUTPUT) { Console.WriteLine(LFGMessages.INFO_VERTEXIDFORFACE + s); } //if (s != null || s != "" || !s.Equals("") || !s.Equals(" ") || s != " " || !s.Equals("\n") || s != "\n" || s != "\0" || !s.Equals("\0") || !s.Equals("\r") || s != "\r") if (!s.Equals("\r")) { try { int fv = Convert.ToInt32(s); geoF._LFVertices.Add(LvertexAttr[fv - 1]); if (faceSplit.Length >= 1) { string uvIndex = faceSplit[1]; // TODO: Changed for TESTING! Was 1 int uvAdress = Convert.ToInt32(uvIndex); geoF._UV.Add(_LuvCoords[uvAdress - 1]); _LKVuvandvert.Add(new KeyValuePair <int, int>(uvAdress - 1, fv - 1)); } } catch (FormatException e) { if (LFGMessages._DEBUGOUTPUT) { Console.WriteLine(LFGMessages.WARNING_INVALIDCHAR + s + e); } //Debug.WriteLine(e.StackTrace); continue; } } } } _LgeoFaces.Add(geoF); } else if (line.StartsWith("g")) { // group } else if (line.StartsWith("usemtl")) { // use material } else if (line.StartsWith("usemtllib")) { // material lib } } } // Clear the content after the import is done _SassetFileContent = ""; if (_LgeoFaces != null) { return(_LgeoFaces); } else { return(null); } }