convert VB to C#
This commit is contained in:
476
Pilz.Simple3DFileParser/FileParser/Obj.cs
Normal file
476
Pilz.Simple3DFileParser/FileParser/Obj.cs
Normal file
@@ -0,0 +1,476 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using global::System.Globalization;
|
||||
using global::System.IO;
|
||||
using System.Linq;
|
||||
using global::System.Threading;
|
||||
using Microsoft.VisualBasic.CompilerServices;
|
||||
using global::Pilz.S3DFileParser.Exceptions;
|
||||
|
||||
namespace Pilz.S3DFileParser.ObjModule
|
||||
{
|
||||
public class ObjFile
|
||||
{
|
||||
public static Object3D FromFile(string FileName, bool LoadMaterials, UpAxis UpAxis)
|
||||
{
|
||||
var curThread = Thread.CurrentThread;
|
||||
var curCultInfo = curThread.CurrentCulture;
|
||||
var newCultInfo = new CultureInfo(curCultInfo.Name);
|
||||
newCultInfo.NumberFormat.NumberDecimalSeparator = ".";
|
||||
newCultInfo.NumberFormat.PercentDecimalSeparator = ".";
|
||||
newCultInfo.NumberFormat.CurrencyDecimalSeparator = ".";
|
||||
newCultInfo.NumberFormat.NumberGroupSeparator = ",";
|
||||
newCultInfo.NumberFormat.PercentGroupSeparator = ",";
|
||||
newCultInfo.NumberFormat.CurrencyGroupSeparator = ",";
|
||||
curThread.CurrentCulture = newCultInfo;
|
||||
var newObj = new Object3D();
|
||||
var newMesh = new Mesh();
|
||||
string curObjPath = Path.GetDirectoryName(FileName);
|
||||
var mtllibs = new Dictionary<string, MaterialLib>();
|
||||
MaterialLib curMaterialLib = null;
|
||||
Material curMaterial = null;
|
||||
var srObj = new StreamReader(FileName, System.Text.Encoding.ASCII);
|
||||
string line = "";
|
||||
while (!srObj.EndOfStream)
|
||||
{
|
||||
line = srObj.ReadLine().Trim();
|
||||
if (!string.IsNullOrEmpty(line))
|
||||
{
|
||||
switch (true)
|
||||
{
|
||||
case object _ when line.StartsWith("mtllib "):
|
||||
{
|
||||
string name = line.Substring(7);
|
||||
if (!mtllibs.ContainsKey(name))
|
||||
{
|
||||
string mtlfile = Path.Combine(curObjPath, name);
|
||||
if (!File.Exists(mtlfile))
|
||||
throw new MaterialException("Material Library not found!");
|
||||
var newmtl = new MaterialLib();
|
||||
newmtl.FromFile(mtlfile, LoadMaterials);
|
||||
mtllibs.Add(name, newmtl);
|
||||
curMaterialLib = newmtl;
|
||||
foreach (KeyValuePair<string, Material> kvp in curMaterialLib.Materials)
|
||||
{
|
||||
if (!newObj.Materials.ContainsKey(kvp.Key))
|
||||
newObj.Materials.Add(kvp.Key, kvp.Value);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
curMaterialLib = mtllibs[name];
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case object _ when line.StartsWith("usemtl "):
|
||||
{
|
||||
curMaterial = curMaterialLib.Materials[line.Substring(7)];
|
||||
break;
|
||||
}
|
||||
|
||||
case object _ when line.StartsWith("v "):
|
||||
{
|
||||
if (line.Contains("nan"))
|
||||
line = line.Replace("nan", "0");
|
||||
var splitXYZ = line.Substring(2).Split(' ');
|
||||
double tX = Convert.ToDouble(splitXYZ[0]);
|
||||
double tY = Convert.ToDouble(splitXYZ[1]);
|
||||
double tZ = Convert.ToDouble(splitXYZ[2]);
|
||||
var v = new Vertex();
|
||||
switch (UpAxis)
|
||||
{
|
||||
case UpAxis.Y:
|
||||
{
|
||||
v.X = tX;
|
||||
v.Y = tY;
|
||||
v.Z = tZ;
|
||||
break;
|
||||
}
|
||||
|
||||
case UpAxis.Z:
|
||||
{
|
||||
v.X = tY;
|
||||
v.Y = tZ;
|
||||
v.Z = tX;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
newMesh.Vertices.Add(v);
|
||||
break;
|
||||
}
|
||||
|
||||
case object _ when line.StartsWith("vt "):
|
||||
{
|
||||
var uvstr = line.Substring(3).Split(' ');
|
||||
var uv = new UV()
|
||||
{
|
||||
U = Convert.ToSingle(uvstr[0]),
|
||||
V = Convert.ToSingle(uvstr[1])
|
||||
};
|
||||
newMesh.UVs.Add(uv);
|
||||
break;
|
||||
}
|
||||
|
||||
case object _ when line.StartsWith("vn "):
|
||||
{
|
||||
var splitXYZ = line.Substring(3).Split(' ');
|
||||
float tX = Convert.ToSingle(splitXYZ[0]);
|
||||
float tY = Convert.ToSingle(splitXYZ[1]);
|
||||
float tZ = Convert.ToSingle(splitXYZ[2]);
|
||||
var n = new Normal();
|
||||
switch (UpAxis)
|
||||
{
|
||||
case UpAxis.Y:
|
||||
{
|
||||
n.X = tX;
|
||||
n.Y = tY;
|
||||
n.Z = tZ;
|
||||
break;
|
||||
}
|
||||
|
||||
case UpAxis.Z:
|
||||
{
|
||||
n.X = tZ;
|
||||
n.Y = tY;
|
||||
n.Z = tX;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
newMesh.Normals.Add(n);
|
||||
break;
|
||||
}
|
||||
|
||||
case object _ when line.StartsWith("vc "):
|
||||
{
|
||||
var splitRGB = line.Substring(3).Split(' ');
|
||||
float tX = Convert.ToSingle(splitRGB[0]);
|
||||
float tY = Convert.ToSingle(splitRGB[1]);
|
||||
float tZ = Convert.ToSingle(splitRGB[2]);
|
||||
var vc = new VertexColor();
|
||||
switch (UpAxis)
|
||||
{
|
||||
case UpAxis.Y:
|
||||
{
|
||||
vc.R = tX;
|
||||
vc.G = tY;
|
||||
vc.B = tZ;
|
||||
break;
|
||||
}
|
||||
|
||||
case UpAxis.Z:
|
||||
{
|
||||
vc.R = tY;
|
||||
vc.G = tZ;
|
||||
vc.B = tX;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
newMesh.VertexColors.Add(vc);
|
||||
break;
|
||||
}
|
||||
|
||||
case object _ when line.StartsWith("f "):
|
||||
{
|
||||
var tri = new Face() { Material = curMaterial };
|
||||
foreach (string xyz1 in line.Substring(2).Split(' '))
|
||||
{
|
||||
var xyz = xyz1.Trim();
|
||||
if (string.IsNullOrEmpty(xyz))
|
||||
continue;
|
||||
string[] splitsub = null;
|
||||
var p = new Point();
|
||||
switch (true)
|
||||
{
|
||||
case object _ when xyz.Contains("/"):
|
||||
{
|
||||
splitsub = xyz.Split('/');
|
||||
break;
|
||||
}
|
||||
|
||||
case object _ when xyz.Contains(@"\"):
|
||||
{
|
||||
splitsub = xyz.Split('\\');
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
splitsub = new string[] { 0.ToString(), 0.ToString(), 0.ToString() };
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
string v1 = splitsub[0];
|
||||
string v2 = splitsub[1];
|
||||
string v3 = splitsub[2];
|
||||
if (!string.IsNullOrEmpty(v1))
|
||||
{
|
||||
p.Vertex = newMesh.Vertices[Convert.ToInt32(v1) - 1];
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(v2))
|
||||
{
|
||||
p.UV = newMesh.UVs[Convert.ToInt32(v2) - 1];
|
||||
}
|
||||
else
|
||||
{
|
||||
var newUV = new UV() { U = 0f, V = 0f };
|
||||
p.UV = newUV;
|
||||
newMesh.UVs.Add(newUV);
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(v3))
|
||||
{
|
||||
p.Normal = newMesh.Normals[Convert.ToInt32(v3) - 1];
|
||||
}
|
||||
|
||||
if (splitsub.Count() > 3)
|
||||
{
|
||||
string v4 = splitsub[3];
|
||||
if (!string.IsNullOrEmpty(v4))
|
||||
p.VertexColor = newMesh.VertexColors[Convert.ToInt32(v4) - 1];
|
||||
}
|
||||
|
||||
tri.Points.Add(p);
|
||||
}
|
||||
|
||||
newMesh.Faces.Add(tri);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
newObj.Meshes.Add(newMesh);
|
||||
curThread.CurrentCulture = curCultInfo;
|
||||
srObj.Close();
|
||||
return newObj;
|
||||
}
|
||||
|
||||
public static void ToFile(string FileName, Object3D obj)
|
||||
{
|
||||
var fs = new FileStream(FileName, FileMode.Create, FileAccess.ReadWrite);
|
||||
var sw = new StreamWriter(fs, System.Text.Encoding.ASCII);
|
||||
if (obj.Materials.Count > 0)
|
||||
{
|
||||
string mtlName = Path.GetFileNameWithoutExtension(FileName) + ".mtl";
|
||||
string mtlFile = Path.Combine(Path.GetDirectoryName(FileName), mtlName);
|
||||
sw.WriteLine($"mtllib {mtlName}");
|
||||
MaterialLib.ToFile(mtlFile, obj);
|
||||
}
|
||||
|
||||
int curVertCount = 1;
|
||||
int curUVCount = 1;
|
||||
int curNormCount = 1;
|
||||
int curVertColCount = 1;
|
||||
foreach (Mesh m in obj.Meshes)
|
||||
{
|
||||
foreach (Vertex vert in m.Vertices)
|
||||
sw.WriteLine($"v {vert.X.ToString().Replace(",", ".")} {vert.Y.ToString().Replace(",", ".")} {vert.Z.ToString().Replace(",", ".")}");
|
||||
foreach (UV uv in m.UVs)
|
||||
sw.WriteLine($"vt {uv.U.ToString().Replace(",", ".")} {uv.V.ToString().Replace(",", ".")}");
|
||||
foreach (Normal norm in m.Normals)
|
||||
sw.WriteLine($"vn {norm.X.ToString().Replace(",", ".")} {norm.Y.ToString().Replace(",", ".")} {norm.Z.ToString().Replace(",", ".")}");
|
||||
foreach (VertexColor vertcol in m.VertexColors)
|
||||
sw.WriteLine($"vc {vertcol.R.ToString().Replace(",", ".")} {vertcol.G.ToString().Replace(",", ".")} {vertcol.B.ToString().Replace(",", ".")}");
|
||||
Material curMtl = null;
|
||||
foreach (Face f in m.Faces)
|
||||
{
|
||||
if (!ReferenceEquals(curMtl, f.Material))
|
||||
{
|
||||
curMtl = f.Material;
|
||||
sw.WriteLine($"usemtl _{GetIndexOfMaterialInList(obj, curMtl)}");
|
||||
}
|
||||
|
||||
sw.Write("f");
|
||||
foreach (Point p in f.Points)
|
||||
{
|
||||
sw.Write(" ");
|
||||
sw.Write(curVertCount + m.Vertices.IndexOf(p.Vertex));
|
||||
sw.Write("/");
|
||||
if (p.UV is object)
|
||||
sw.Write(curUVCount + m.UVs.IndexOf(p.UV));
|
||||
sw.Write("/");
|
||||
if (p.Normal is object)
|
||||
sw.Write(curNormCount + m.Normals.IndexOf(p.Normal));
|
||||
if (m.VertexColors.Count > 0)
|
||||
{
|
||||
sw.Write("/");
|
||||
if (p.VertexColor is object)
|
||||
sw.Write(curVertColCount + m.VertexColors.IndexOf(p.VertexColor));
|
||||
}
|
||||
}
|
||||
|
||||
sw.WriteLine();
|
||||
}
|
||||
|
||||
curVertCount += m.Vertices.Count;
|
||||
curUVCount += m.UVs.Count;
|
||||
curNormCount += m.Normals.Count;
|
||||
curVertColCount += m.VertexColors.Count;
|
||||
}
|
||||
|
||||
sw.Flush();
|
||||
fs.Close();
|
||||
}
|
||||
|
||||
public static int GetIndexOfMaterialInList(Object3D obj, Material matToFind)
|
||||
{
|
||||
for (int Index = 0, loopTo = obj.Materials.Count - 1; Index <= loopTo; Index++)
|
||||
{
|
||||
if (obj.Materials.ElementAt(Index).Value.Equals(matToFind))
|
||||
{
|
||||
return Index;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
public class MaterialLib
|
||||
{
|
||||
public Dictionary<string, Material> Materials { get; private set; } = new Dictionary<string, Material>();
|
||||
|
||||
private readonly Dictionary<string, Image> LoadedImages = new Dictionary<string, Image>();
|
||||
|
||||
public void FromFile(string fileName, bool LoadMaterials)
|
||||
{
|
||||
LoadedImages.Clear();
|
||||
string curMatLibPath = Path.GetDirectoryName(fileName);
|
||||
Material curMat = null;
|
||||
string curName = "";
|
||||
var srMtl = new StreamReader(fileName, System.Text.Encoding.ASCII);
|
||||
string line = "";
|
||||
while (!srMtl.EndOfStream)
|
||||
{
|
||||
line = srMtl.ReadLine();
|
||||
switch (true)
|
||||
{
|
||||
case object _ when line.StartsWith("newmtl "):
|
||||
{
|
||||
curMat = new Material();
|
||||
curName = line.Substring(7);
|
||||
Materials.Add(curName, curMat);
|
||||
break;
|
||||
}
|
||||
|
||||
case object _ when line.ToLower().StartsWith("kd "):
|
||||
{
|
||||
var splitColor = line.Substring(3).Split(' ');
|
||||
var col = Color.FromArgb((int)Convert.ToSingle(Math.Round(255d * Conversions.ToDouble(splitColor[0]))), (int)Convert.ToSingle(Math.Round(255d * Conversions.ToDouble(splitColor[1]))), (int)Convert.ToSingle(Math.Round(255d * Conversions.ToDouble(splitColor[2]))));
|
||||
curMat.Color = col;
|
||||
break;
|
||||
}
|
||||
|
||||
case object _ when line.ToLower().StartsWith("d "):
|
||||
{
|
||||
curMat.Opacity = Convert.ToSingle(line.Substring(2));
|
||||
break;
|
||||
}
|
||||
|
||||
case object _ when line.ToLower().StartsWith("tr "):
|
||||
{
|
||||
curMat.Opacity = 1f - Convert.ToSingle(line.Substring(2));
|
||||
break;
|
||||
}
|
||||
|
||||
case object _ when line.ToLower().StartsWith("map_kd "):
|
||||
{
|
||||
if (LoadMaterials)
|
||||
{
|
||||
string mtlpath = line.Substring(7);
|
||||
string combipath = Path.Combine(curMatLibPath, line.Substring(7));
|
||||
string imgfile;
|
||||
if (File.Exists(combipath))
|
||||
{
|
||||
imgfile = combipath;
|
||||
}
|
||||
else if (File.Exists(line.Substring(7)))
|
||||
{
|
||||
imgfile = mtlpath;
|
||||
}
|
||||
else
|
||||
{
|
||||
imgfile = "";
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(imgfile))
|
||||
{
|
||||
if (LoadedImages.ContainsKey(imgfile))
|
||||
{
|
||||
curMat.Image = LoadedImages[imgfile];
|
||||
}
|
||||
else
|
||||
{
|
||||
var fs = new FileStream(imgfile, FileMode.Open, FileAccess.Read);
|
||||
curMat.Image = Image.FromStream(fs);
|
||||
fs.Close();
|
||||
bool imgExists = false;
|
||||
foreach (var kvp in LoadedImages)
|
||||
{
|
||||
if (!imgExists && ((Bitmap)kvp.Value).IsTheSameAs((Bitmap)curMat.Image))
|
||||
{
|
||||
curMat.Image = kvp.Value;
|
||||
imgExists = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!imgExists)
|
||||
{
|
||||
LoadedImages.Add(imgfile, curMat.Image);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
srMtl.Close();
|
||||
}
|
||||
|
||||
public static void ToFile(string fileName, Object3D obj)
|
||||
{
|
||||
var fs = new FileStream(fileName, FileMode.Create, FileAccess.ReadWrite);
|
||||
var sw = new StreamWriter(fs, System.Text.Encoding.ASCII);
|
||||
string imgDirName = Path.GetFileNameWithoutExtension(fileName);
|
||||
string imgDirFull = Path.Combine(Path.GetDirectoryName(fileName), Path.GetFileNameWithoutExtension(fileName));
|
||||
foreach (KeyValuePair<string, Material> kvp in obj.Materials)
|
||||
{
|
||||
var mat = kvp.Value;
|
||||
string name = "_" + ObjFile.GetIndexOfMaterialInList(obj, mat);
|
||||
sw.WriteLine($"newmtl {name}");
|
||||
if (mat.Color is object)
|
||||
{
|
||||
sw.WriteLine($"kd {(mat.Color.Value.R / 255d).ToString().Replace(",", ".")} {(mat.Color.Value.G / 255d).ToString().Replace(",", ".")} {(mat.Color.Value.B / 255d).ToString().Replace(",", ".")}");
|
||||
}
|
||||
|
||||
if (mat.Opacity is object)
|
||||
{
|
||||
sw.WriteLine($"d {mat.Opacity.Value.ToString().Replace(",", ".")}");
|
||||
}
|
||||
|
||||
if (mat.Image is object)
|
||||
{
|
||||
string imgFile = name + ".png";
|
||||
if (!Directory.Exists(imgDirFull))
|
||||
Directory.CreateDirectory(imgDirFull);
|
||||
mat.Image.Save(Path.Combine(imgDirFull, imgFile), System.Drawing.Imaging.ImageFormat.Png);
|
||||
sw.WriteLine($"map_kd {Path.Combine(imgDirName, imgFile)}");
|
||||
}
|
||||
}
|
||||
|
||||
sw.Flush();
|
||||
fs.Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user