273 lines
10 KiB
C#
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;
|
|
}
|
|
}
|
|
} |