Files
Pilz/Pilz.Simple3DFileParser/FileParser/Aspose3DLoader.cs
2020-09-24 11:21:53 +02:00

273 lines
10 KiB
C#

using System.Collections.Generic;
using System.Drawing;
using global::System.Globalization;
using global::System.IO;
using global::System.Threading;
using global::Aspose.ThreeD;
using global::Aspose.ThreeD.Entities;
using global::Aspose.ThreeD.Shading;
using global::Aspose.ThreeD.Utilities;
using Microsoft.VisualBasic.CompilerServices;
namespace Pilz.S3DFileParser.Aspose3DModule
{
public class Aspose3DLoader
{
private static bool hasActivatedMemoryPatching = false;
private static void ActivateMemoryPatching()
{
if (!hasActivatedMemoryPatching)
{
LicenseHelper.AsposeModifyInMemory.ActivateMemoryPatching();
hasActivatedMemoryPatching = true;
}
}
public static Object3D FromFile(string fileName, bool LoadMaterials, UpAxis UpAxis)
{
ActivateMemoryPatching();
// Create new Model
var obj3d = new Object3D();
// Create new temporary CultureInfo
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;
// Load Model from file
var scene = new Scene(fileName);
// Reset Cultur-Info
curThread.CurrentCulture = curCultInfo;
// Triangulate the Model
PolygonModifier.Triangulate(scene);
// Create Dictionary for Materials
var dicMaterials = new Dictionary<Aspose.ThreeD.Shading.Material, Material>();
// Create List of all avaiable Map-States
var MapNames = new[] { Aspose.ThreeD.Shading.Material.MapDiffuse, Aspose.ThreeD.Shading.Material.MapAmbient, Aspose.ThreeD.Shading.Material.MapSpecular, Aspose.ThreeD.Shading.Material.MapEmissive, Aspose.ThreeD.Shading.Material.MapNormal };
var ColorNames = new[] { "DiffuseColor", "AmbientColor", "SpecularColor", "EmissiveColor" };
foreach (Node node in scene.RootNode.ChildNodes)
{
// Add new Materials, if not added
foreach (Aspose.ThreeD.Shading.Material mat in node.Materials)
{
if (!dicMaterials.ContainsKey(mat))
{
// Create new Material
var newMat = new Material();
// Get TextureBase
TextureBase texBase = null;
byte curmnindex = 0;
while (texBase is null && curmnindex < MapNames.Length)
{
texBase = mat.GetTexture(MapNames[curmnindex]);
curmnindex = (byte)(curmnindex + 1);
}
if (texBase is object)
{
if (LoadMaterials)
{
// Get Texture Image
string imgFile = Conversions.ToString(texBase.GetPropertyValue("FileName"));
imgFile = imgFile.Replace("/", @"\");
// Load and set Image
if (!string.IsNullOrEmpty(imgFile))
{
var fs = new FileStream(imgFile, FileMode.Open, FileAccess.Read);
newMat.Image = Image.FromStream(fs);
fs.Close();
}
}
}
// Get Texture Color
Vector3? texcol = default;
byte curcnindex = 0;
while (texcol is null && curcnindex < ColorNames.Length)
{
texcol = (Vector3?)mat.GetPropertyValue(ColorNames[curcnindex]);
curcnindex = (byte)(curcnindex + 1);
}
if (texcol is object)
{
newMat.Color = Color.FromArgb((int)texcol?.x, (int)texcol?.y, (int)texcol?.z);
}
// Add Material to Object3D
obj3d.Materials.Add(mat.Name, newMat);
// Add Dictionary-Entry
dicMaterials.Add(mat, newMat);
}
}
// Get Aspose-Mesh
var curMesh = node.GetEntity<Aspose.ThreeD.Entities.Mesh>();
if (curMesh is object)
{
// Create new Mesh
var newMesh = new Mesh();
// Create Vertices
foreach (Vector4 vert in curMesh.ControlPoints)
{
// Create new Vertex
var newVert = new Vertex();
// Set Vertex Data
newVert.X = vert.x;
newVert.Y = vert.y;
newVert.Z = vert.z;
// Add new Vertex
newMesh.Vertices.Add(newVert);
}
// Create Normals
VertexElementNormal veNormals = (VertexElementNormal)curMesh.GetElement(VertexElementType.Normal);
if (veNormals is object)
{
foreach (Vector4 n in veNormals.Data)
{
// Create new Normal
var newNormal = new Normal();
// Set Normal Data
newNormal.X = (float)n.x;
newNormal.Y = (float)n.y;
newNormal.Z = (float)n.z;
// Add new Normal
newMesh.Normals.Add(newNormal);
}
}
// Create Normals
VertexElementUV veUVs = (VertexElementUV)curMesh.GetElement(VertexElementType.UV);
if (veUVs is object)
{
foreach (Vector4 uv in veUVs.Data)
{
// Create new UV
var newUV = new UV();
// Set UV Data
newUV.U = (float)uv.x;
newUV.V = (float)uv.y;
// Add new UV
newMesh.UVs.Add(newUV);
}
}
// Create Normals
VertexElementVertexColor veVertexColor = (VertexElementVertexColor)curMesh.GetElement(VertexElementType.VertexColor);
if (veVertexColor is object)
{
foreach (Vector4 n in veVertexColor.Data)
{
// Create new Normal
var newVC = new VertexColor();
// Set Normal Data
newVC.R = (float)n.x;
newVC.G = (float)n.y;
newVC.B = (float)n.z;
newVC.A = (float)n.w;
// Add new Normal
newMesh.VertexColors.Add(newVC);
}
}
// Get Material-Indicies
VertexElementMaterial veMaterials = (VertexElementMaterial)curMesh.GetElement(VertexElementType.Material);
// Definde Index for VertexElement.Indicies
int veIndex = 0;
// Build Polygones
for (int iPoly = 0, loopTo = curMesh.Polygons.Count - 1; iPoly <= loopTo; iPoly++)
{
// Get current Polygon
var poly = curMesh.Polygons[iPoly];
// Create new Face
var f = new Face();
// Set Texture, if avaiable
if (veMaterials is object)
{
f.Material = dicMaterials[node.Materials[veMaterials.Indices[iPoly]]];
}
else if (node.Material is object)
{
f.Material = dicMaterials[node.Material];
}
foreach (int index in poly)
{
// Create new Point
var p = new Point();
// Set Vertex
p.Vertex = newMesh.Vertices[index];
// Set Normal
if (veNormals is object)
{
p.Normal = newMesh.Normals[veNormals.Indices[veIndex]];
}
// Set UV
if (veUVs is object)
{
p.UV = newMesh.UVs[veUVs.Indices[veIndex]];
}
// Set Vertex Color
if (veVertexColor is object)
{
p.VertexColor = newMesh.VertexColors[veVertexColor.Indices[veIndex]];
}
// Add new Point
f.Points.Add(p);
// Increment VertexElementIndicies-Index
veIndex += 1;
}
// Add new Face
newMesh.Faces.Add(f);
}
// Add new Mesh
obj3d.Meshes.Add(newMesh);
}
}
// Return the new Object3D
return obj3d;
}
}
}