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