I make a mesh to obj function (Get an obj object from mesh) but now I was trying to re convert it to mesh but the problem is that the mesh created is not valid and the function ‘IsValidWithLog’ give me: “ON_Mesh.m_F[0] has degenerate double precision vertex locations.\n”
string[] objFile = Regex.Split(s, "\r\n|\r|\n");
Mesh ms = new Mesh();
System.Globalization.CultureInfo customCulture = (System.Globalization.CultureInfo)System.Threading.Thread.CurrentThread.CurrentCulture.Clone();
customCulture.NumberFormat.NumberDecimalSeparator = ".";
System.Threading.Thread.CurrentThread.CurrentCulture = customCulture;
foreach (string line in objFile)
{
string[] sLine = line.Split(' ');
switch (sLine[0])
{
case "v": //Vertices
ms.Vertices.Add(float.Parse(sLine[1]), float.Parse(sLine[2]), float.Parse(sLine[3]));
break;
case "vt": //TextureCoordinates
ms.TextureCoordinates.Add(float.Parse(sLine[1]), float.Parse(sLine[2]));
break;
case "vn": //Normals
ms.Normals.Add(float.Parse(sLine[1]), float.Parse(sLine[2]), float.Parse(sLine[3]));
break;
case "f": //Faces
if (sLine.Length == 4) //triangle
{
ms.Faces.AddFace(int.Parse(sLine[1].Split('/')[0]), int.Parse(sLine[2].Split('/')[0]), int.Parse(sLine[3].Split('/')[0]));
}
else //quadrat
{
ms.Faces.AddFace(int.Parse(sLine[1].Split('/')[0]), int.Parse(sLine[2].Split('/')[0]), int.Parse(sLine[3].Split('/')[0]), int.Parse(sLine[4].Split('/')[0]));
}
break;
case "#fn": //FaceNormals
ms.FaceNormals.AddFaceNormal(float.Parse(sLine[1]), float.Parse(sLine[2]), float.Parse(sLine[3]));
break;
/*case "#tv": //TopologyVertices
ms.TopologyVertices. //.AddFaceNormal(float.Parse(sLine[1]), float.Parse(sLine[2]), float.Parse(sLine[3]));
break;*/
}
}
var l = ms.IsValidWithLog(out string log);
doc.Objects.AddMesh(ms);
doc.Views.Redraw();
hi @dale, I attached the sourcecode at my first post, but I’ll put more information. I have this function (that recive a string s that is in format obj and a RhinoDoc doc that I wand to create the 3d object form a string:
Sourcecode:
public static Result loadObj(string s, RhinoDoc doc)
{
string objFile = Regex.Split(s, “\r\n|\r|\n”);
Mesh ms = new Mesh();
System.Globalization.CultureInfo customCulture = (System.Globalization.CultureInfo)System.Threading.Thread.CurrentThread.CurrentCulture.Clone();
customCulture.NumberFormat.NumberDecimalSeparator = “.”;
System.Threading.Thread.CurrentThread.CurrentCulture = customCulture;
foreach (string line in objFile)
{
string[] sLine = line.Split(' ');
switch (sLine[0])
{
case "v": //Vertices
ms.Vertices.Add(float.Parse(sLine[1]), float.Parse(sLine[2]), float.Parse(sLine[3]));
break;
case "vt": //TextureCoordinates
ms.TextureCoordinates.Add(float.Parse(sLine[1]), float.Parse(sLine[2]));
break;
case "vn": //Normals
ms.Normals.Add(float.Parse(sLine[1]), float.Parse(sLine[2]), float.Parse(sLine[3]));
break;
case "f": //Faces
if (sLine.Length == 4) //triangle
{
ms.Faces.AddFace(int.Parse(sLine[1].Split('/')[0]), int.Parse(sLine[2].Split('/')[0]), int.Parse(sLine[3].Split('/')[0]));
}
else //quadrat
{
ms.Faces.AddFace(int.Parse(sLine[1].Split('/')[0]), int.Parse(sLine[2].Split('/')[0]), int.Parse(sLine[3].Split('/')[0]), int.Parse(sLine[4].Split('/')[0]));
}
break;
}
}
var l = ms.IsValidWithLog(out string log);
doc.Objects.AddMesh(ms);
doc.Views.Redraw();
return Result.Success;
}
And the obj that is in the string:
v -2.452513 -1.350659 0
v -2.452513 -1.350659 2.847046
v 3.945347 -1.350659 0
v 3.945347 -1.350659 2.847046
v 3.945347 -1.350659 0
v 3.945347 -1.350659 2.847046
v 3.945347 2.559144 0
v 3.945347 2.559144 2.847046
v 3.945347 2.559144 0
v 3.945347 2.559144 2.847046
v -2.452513 2.559144 0
v -2.452513 2.559144 2.847046
v -2.452513 2.559144 0
v -2.452513 2.559144 2.847046
v -2.452513 -1.350659 0
v -2.452513 -1.350659 2.847046
v -2.452513 -1.350659 0
v 3.945347 -1.350659 0
v 3.945347 2.559144 0
v -2.452513 2.559144 0
v -2.452513 -1.350659 2.847046
v 3.945347 -1.350659 2.847046
v 3.945347 2.559144 2.847046
v -2.452513 2.559144 2.847046
vt 0 0
vt 0 0.633455
vt 0.3103448 0
vt 0.3103448 0.633455
vt 0.3103448 0
vt 0.3103448 0.633455
vt 0.5 0
vt 0.5 0.633455
vt 0.5 0
vt 0.5 0.633455
vt 0.8103448 0
vt 0.8103448 0.633455
vt 0.8103448 0
vt 0.8103448 0.633455
vt 1 0
vt 1 0.633455
vt 0 1
vt 0.3103448 1
vt 0.3103448 0.6334557
vt 0 0.6334557
vt 0.6896552 0.6334557
vt 1 0.6334557
vt 1 1
vt 0.6896552 1
vn 0 -1 0
vn 0 -1 0
vn 0 -1 0
vn 0 -1 0
vn 1 0 0
vn 1 0 0
vn 1 0 0
vn 1 0 0
vn 0 1 0
vn 0 1 0
vn 0 1 0
vn 0 1 0
vn -1 0 0
vn -1 0 0
vn -1 0 0
vn -1 0 0
vn 0 0 -1
vn 0 0 -1
vn 0 0 -1
vn 0 0 -1
vn 0 0 1
vn 0 0 1
vn 0 0 1
vn 0 0 1
f 1/1/1 3/3/3 4/4/4 2/2/2
f 5/5/5 7/7/7 8/8/8 6/6/6
f 9/9/9 11/11/11 12/12/12 10/10/10
f 13/13/13 15/15/15 16/16/16 14/14/14
f 18/18/18 17/17/17 20/20/20
f 20/20/20 19/19/19 18/18/18
f 22/22/22 24/24/24 21/21/21
f 24/24/24 22/22/22 23/23/23
Visiado and @dale, The .OBJ file uses 1-based indexing. So you need to subtract 1 from the 3 or 4 face vertex indices. Here is the code with this fix. Try it now and see how it works.
string[] objFile = Regex.Split(s, "\r\n|\r|\n");
Mesh ms = new Mesh();
System.Globalization.CultureInfo customCulture = (System.Globalization.CultureInfo)System.Threading.Thread.CurrentThread.CurrentCulture.Clone();
customCulture.NumberFormat.NumberDecimalSeparator = ".";
System.Threading.Thread.CurrentThread.CurrentCulture = customCulture;
foreach (string line in objFile)
{
string[] sLine = line.Split(' ');
switch (sLine[0])
{
case "v": //Vertices
ms.Vertices.Add(float.Parse(sLine[1]), float.Parse(sLine[2]), float.Parse(sLine[3]));
break;
case "vt": //TextureCoordinates
ms.TextureCoordinates.Add(float.Parse(sLine[1]), float.Parse(sLine[2]));
break;
case "vn": //Normals
ms.Normals.Add(float.Parse(sLine[1]), float.Parse(sLine[2]), float.Parse(sLine[3]));
break;
case "f": //Faces
if (sLine.Length == 4) //triangle
{
ms.Faces.AddFace(int.Parse(sLine[1].Split('/')[0])-1, int.Parse(sLine[2].Split('/')[0])-1, int.Parse(sLine[3].Split('/')[0])-1);
}
else //quadrat
{
ms.Faces.AddFace(int.Parse(sLine[1].Split('/')[0])-1, int.Parse(sLine[2].Split('/')[0])-1, int.Parse(sLine[3].Split('/')[0])-1, int.Parse(sLine[4].Split('/')[0])-1);
}
break;
case "#fn": //FaceNormals
ms.FaceNormals.AddFaceNormal(float.Parse(sLine[1]), float.Parse(sLine[2]), float.Parse(sLine[3]));
break;
/*case "#tv": //TopologyVertices
ms.TopologyVertices. //.AddFaceNormal(float.Parse(sLine[1]), float.Parse(sLine[2]), float.Parse(sLine[3]));
break;*/
}
}
var l = ms.IsValidWithLog(out string log);
doc.Objects.AddMesh(ms);
doc.Views.Redraw();