convert VB to C#
This commit is contained in:
273
Pilz.Simple3DFileParser/FileParser/Aspose3DLoader.cs
Normal file
273
Pilz.Simple3DFileParser/FileParser/Aspose3DLoader.cs
Normal file
@@ -0,0 +1,273 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,250 +0,0 @@
|
||||
Imports System.Globalization
|
||||
Imports System.IO
|
||||
Imports System.Threading
|
||||
Imports Aspose.ThreeD
|
||||
Imports Aspose.ThreeD.Entities
|
||||
Imports Aspose.ThreeD.Formats
|
||||
Imports Aspose.ThreeD.Shading
|
||||
Imports Aspose.ThreeD.Utilities
|
||||
|
||||
Namespace Aspose3DModule
|
||||
|
||||
Public Class Aspose3DLoader
|
||||
|
||||
Private Shared hasActivatedMemoryPatching As Boolean = False
|
||||
|
||||
Private Shared Sub ActivateMemoryPatching()
|
||||
If Not hasActivatedMemoryPatching Then
|
||||
LicenseHelper.AsposeModifyInMemory.ActivateMemoryPatching()
|
||||
hasActivatedMemoryPatching = True
|
||||
End If
|
||||
End Sub
|
||||
|
||||
Public Shared Function FromFile(fileName As String, LoadMaterials As Boolean, UpAxis As UpAxis) As Object3D
|
||||
ActivateMemoryPatching()
|
||||
|
||||
'Create new Model
|
||||
Dim obj3d As New Object3D
|
||||
|
||||
'Create new temporary CultureInfo
|
||||
Dim curThread As Thread = Thread.CurrentThread
|
||||
Dim curCultInfo As CultureInfo = curThread.CurrentCulture
|
||||
Dim newCultInfo As 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
|
||||
Dim scene As New Scene(fileName)
|
||||
|
||||
'Reset Cultur-Info
|
||||
curThread.CurrentCulture = curCultInfo
|
||||
|
||||
'Triangulate the Model
|
||||
PolygonModifier.Triangulate(scene)
|
||||
|
||||
'Create Dictionary for Materials
|
||||
Dim dicMaterials As New Dictionary(Of Aspose.ThreeD.Shading.Material, Material)
|
||||
|
||||
'Create List of all avaiable Map-States
|
||||
Dim MapNames As String() = {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}
|
||||
Dim ColorNames As String() = {"DiffuseColor", "AmbientColor", "SpecularColor", "EmissiveColor"}
|
||||
|
||||
For Each node As Node In scene.RootNode.ChildNodes
|
||||
|
||||
'Add new Materials, if not added
|
||||
For Each mat As Aspose.ThreeD.Shading.Material In node.Materials
|
||||
If Not dicMaterials.ContainsKey(mat) Then
|
||||
|
||||
'Create new Material
|
||||
Dim newMat As New Material
|
||||
|
||||
'Get TextureBase
|
||||
Dim texBase As TextureBase = Nothing
|
||||
Dim curmnindex As Byte = 0
|
||||
Do While texBase Is Nothing AndAlso curmnindex < MapNames.Length
|
||||
texBase = mat.GetTexture(MapNames(curmnindex))
|
||||
curmnindex += 1
|
||||
Loop
|
||||
|
||||
If texBase IsNot Nothing Then
|
||||
If LoadMaterials Then
|
||||
'Get Texture Image
|
||||
Dim imgFile As String = texBase.GetPropertyValue("FileName")
|
||||
imgFile = imgFile.Replace("/", "\")
|
||||
|
||||
'Load and set Image
|
||||
If imgFile <> "" Then
|
||||
Dim fs As New FileStream(imgFile, FileMode.Open, FileAccess.Read)
|
||||
newMat.Image = Image.FromStream(fs)
|
||||
fs.Close()
|
||||
End If
|
||||
End If
|
||||
End If
|
||||
|
||||
'Get Texture Color
|
||||
Dim texcol As Vector3? = Nothing
|
||||
Dim curcnindex As Byte = 0
|
||||
Do While texcol Is Nothing AndAlso curcnindex < ColorNames.Length
|
||||
texcol = mat.GetPropertyValue(ColorNames(curcnindex))
|
||||
curcnindex += 1
|
||||
Loop
|
||||
|
||||
If texcol IsNot Nothing Then
|
||||
newMat.Color = Color.FromArgb(texcol?.x, texcol?.y, texcol?.z)
|
||||
End If
|
||||
|
||||
'Add Material to Object3D
|
||||
obj3d.Materials.Add(mat.Name, newMat)
|
||||
|
||||
'Add Dictionary-Entry
|
||||
dicMaterials.Add(mat, newMat)
|
||||
|
||||
End If
|
||||
Next
|
||||
|
||||
'Get Aspose-Mesh
|
||||
Dim curMesh As Entities.Mesh = node.GetEntity(Of Entities.Mesh)
|
||||
|
||||
If curMesh IsNot Nothing Then
|
||||
|
||||
'Create new Mesh
|
||||
Dim newMesh As New Mesh
|
||||
|
||||
'Create Vertices
|
||||
For Each vert As Vector4 In curMesh.ControlPoints
|
||||
'Create new Vertex
|
||||
Dim newVert As New Vertex
|
||||
|
||||
'Set Vertex Data
|
||||
newVert.X = vert.x
|
||||
newVert.Y = vert.y
|
||||
newVert.Z = vert.z
|
||||
|
||||
'Add new Vertex
|
||||
newMesh.Vertices.Add(newVert)
|
||||
Next
|
||||
|
||||
'Create Normals
|
||||
Dim veNormals As VertexElementNormal = curMesh.GetElement(VertexElementType.Normal)
|
||||
If veNormals IsNot Nothing Then
|
||||
For Each n As Vector4 In veNormals.Data
|
||||
'Create new Normal
|
||||
Dim newNormal As New Normal
|
||||
|
||||
'Set Normal Data
|
||||
newNormal.X = n.x
|
||||
newNormal.Y = n.y
|
||||
newNormal.Z = n.z
|
||||
|
||||
'Add new Normal
|
||||
newMesh.Normals.Add(newNormal)
|
||||
Next
|
||||
End If
|
||||
|
||||
'Create Normals
|
||||
Dim veUVs As VertexElementUV = curMesh.GetElement(VertexElementType.UV)
|
||||
If veUVs IsNot Nothing Then
|
||||
For Each uv As Vector4 In veUVs.Data
|
||||
'Create new UV
|
||||
Dim newUV As New UV
|
||||
|
||||
'Set UV Data
|
||||
newUV.U = uv.x
|
||||
newUV.V = uv.y
|
||||
|
||||
'Add new UV
|
||||
newMesh.UVs.Add(newUV)
|
||||
Next
|
||||
End If
|
||||
|
||||
'Create Normals
|
||||
Dim veVertexColor As VertexElementVertexColor = curMesh.GetElement(VertexElementType.VertexColor)
|
||||
If veVertexColor IsNot Nothing Then
|
||||
For Each n As Vector4 In veVertexColor.Data
|
||||
'Create new Normal
|
||||
Dim newVC As New VertexColor
|
||||
|
||||
'Set Normal Data
|
||||
newVC.R = n.x
|
||||
newVC.G = n.y
|
||||
newVC.B = n.z
|
||||
newVC.A = n.w
|
||||
|
||||
'Add new Normal
|
||||
newMesh.VertexColors.Add(newVC)
|
||||
Next
|
||||
End If
|
||||
|
||||
'Get Material-Indicies
|
||||
Dim veMaterials As VertexElementMaterial = curMesh.GetElement(VertexElementType.Material)
|
||||
|
||||
'Definde Index for VertexElement.Indicies
|
||||
Dim veIndex As Integer = 0
|
||||
|
||||
'Build Polygones
|
||||
For iPoly = 0 To curMesh.Polygons.Count - 1
|
||||
'Get current Polygon
|
||||
Dim poly As Integer() = curMesh.Polygons(iPoly)
|
||||
|
||||
'Create new Face
|
||||
Dim f As New Face
|
||||
|
||||
'Set Texture, if avaiable
|
||||
If veMaterials IsNot Nothing Then
|
||||
f.Material = dicMaterials(node.Materials(veMaterials.Indices(iPoly)))
|
||||
ElseIf node.Material IsNot Nothing Then
|
||||
f.Material = dicMaterials(node.Material)
|
||||
End If
|
||||
|
||||
For Each index As Integer In poly
|
||||
'Create new Point
|
||||
Dim p As New Point
|
||||
|
||||
'Set Vertex
|
||||
p.Vertex = newMesh.Vertices(index)
|
||||
|
||||
'Set Normal
|
||||
If veNormals IsNot Nothing Then
|
||||
p.Normal = newMesh.Normals(veNormals.Indices(veIndex))
|
||||
End If
|
||||
|
||||
'Set UV
|
||||
If veUVs IsNot Nothing Then
|
||||
p.UV = newMesh.UVs(veUVs.Indices(veIndex))
|
||||
End If
|
||||
|
||||
'Set Vertex Color
|
||||
If veVertexColor IsNot Nothing Then
|
||||
p.VertexColor = newMesh.VertexColors(veVertexColor.Indices(veIndex))
|
||||
End If
|
||||
|
||||
'Add new Point
|
||||
f.Points.Add(p)
|
||||
|
||||
'Increment VertexElementIndicies-Index
|
||||
veIndex += 1
|
||||
Next
|
||||
|
||||
'Add new Face
|
||||
newMesh.Faces.Add(f)
|
||||
Next
|
||||
|
||||
'Add new Mesh
|
||||
obj3d.Meshes.Add(newMesh)
|
||||
|
||||
End If
|
||||
|
||||
Next
|
||||
|
||||
'Return the new Object3D
|
||||
Return obj3d
|
||||
End Function
|
||||
|
||||
End Class
|
||||
|
||||
End Namespace
|
||||
540
Pilz.Simple3DFileParser/FileParser/AssimpLoader.cs
Normal file
540
Pilz.Simple3DFileParser/FileParser/AssimpLoader.cs
Normal file
@@ -0,0 +1,540 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using global::System.IO;
|
||||
using System.Linq;
|
||||
using global::Assimp;
|
||||
using global::Assimp.Unmanaged;
|
||||
|
||||
namespace Pilz.S3DFileParser.AssimpModule
|
||||
{
|
||||
internal class ConversionContext
|
||||
{
|
||||
public Scene DaeMdl { get; set; }
|
||||
public UpAxis UpAxis { get; set; }
|
||||
public Mesh NewMesh { get; set; } = new Mesh();
|
||||
public Object3D NewObj { get; set; } = new Object3D();
|
||||
public Dictionary<Material, int> ChannelIndicies { get; set; } = new Dictionary<Material, int>();
|
||||
|
||||
public ConversionContext(Scene daeMdlP, UpAxis upAxis)
|
||||
{
|
||||
DaeMdl = daeMdlP;
|
||||
UpAxis = upAxis;
|
||||
NewObj.Meshes.Add(NewMesh);
|
||||
}
|
||||
}
|
||||
|
||||
internal class ParsingContext
|
||||
{
|
||||
public ConversionContext ConversionContext { get; private set; }
|
||||
public Dictionary<Vector3D, Vertex> DicVertices { get; set; } = new Dictionary<Vector3D, Vertex>();
|
||||
public Dictionary<Vector3D, Normal> DicNormals { get; set; } = new Dictionary<Vector3D, Normal>();
|
||||
public Dictionary<Vector3D, UV> DicUVs { get; set; } = new Dictionary<Vector3D, UV>();
|
||||
public Dictionary<Color4D, VertexColor> DicVertexColors { get; set; } = new Dictionary<Color4D, VertexColor>();
|
||||
|
||||
public ParsingContext(ConversionContext ctx)
|
||||
{
|
||||
ConversionContext = ctx;
|
||||
}
|
||||
}
|
||||
|
||||
public class AssimpLoader
|
||||
{
|
||||
public static event LoadingAssimpLibsEventHandler LoadingAssimpLibs;
|
||||
|
||||
public delegate void LoadingAssimpLibsEventHandler();
|
||||
|
||||
public static event LoadedAssimpLibsEventHandler LoadedAssimpLibs;
|
||||
|
||||
public delegate void LoadedAssimpLibsEventHandler();
|
||||
|
||||
public static string PathToAssimpLib32 { get; set; } = "Assimp32.dll";
|
||||
public static string PathToAssimpLib64 { get; set; } = "Assimp64.dll";
|
||||
|
||||
internal static void LoadAssimpLibs()
|
||||
{
|
||||
if (!AssimpLibrary.Instance.IsLibraryLoaded)
|
||||
{
|
||||
LoadingAssimpLibs?.Invoke();
|
||||
AssimpLibrary.Instance.LoadLibrary(PathToAssimpLib32, PathToAssimpLib64);
|
||||
LoadedAssimpLibs?.Invoke();
|
||||
}
|
||||
}
|
||||
|
||||
private static void ComputeNewObj(ConversionContext cc)
|
||||
{
|
||||
var identity = Matrix4x4.Identity;
|
||||
ComputeNode(cc.DaeMdl.RootNode, identity, new ParsingContext(cc));
|
||||
}
|
||||
|
||||
private static void ComputeNode(Node node, Matrix4x4 trafo, ParsingContext pc)
|
||||
{
|
||||
var newObj = pc.ConversionContext.NewObj;
|
||||
var newMesh = pc.ConversionContext.NewMesh;
|
||||
var daeMdl = pc.ConversionContext.DaeMdl;
|
||||
var channelIndicies = pc.ConversionContext.ChannelIndicies;
|
||||
var UpAxis = pc.ConversionContext.UpAxis;
|
||||
var dicVertices = pc.DicVertices;
|
||||
var dicNormals = pc.DicNormals;
|
||||
var dicUVs = pc.DicUVs;
|
||||
var dicVertexColors = pc.DicVertexColors;
|
||||
trafo = trafo * node.Transform;
|
||||
if (node.HasMeshes)
|
||||
{
|
||||
foreach (var meshIndex in node.MeshIndices)
|
||||
{
|
||||
var m = daeMdl.Meshes[meshIndex];
|
||||
Material curMat;
|
||||
if (m.MaterialIndex > -1 && newObj.Materials.Count > m.MaterialIndex)
|
||||
{
|
||||
curMat = newObj.Materials.ElementAt(m.MaterialIndex).Value;
|
||||
}
|
||||
else
|
||||
{
|
||||
curMat = null;
|
||||
}
|
||||
|
||||
foreach (Vector3D untransformedN in m.Normals)
|
||||
{
|
||||
var n = trafo * untransformedN;
|
||||
if (!dicNormals.ContainsKey(n))
|
||||
{
|
||||
var newNormal = new Normal();
|
||||
switch (UpAxis)
|
||||
{
|
||||
case UpAxis.Y:
|
||||
{
|
||||
newNormal.X = n.X;
|
||||
newNormal.Y = n.Y;
|
||||
newNormal.Z = n.Z;
|
||||
break;
|
||||
}
|
||||
|
||||
case UpAxis.Z:
|
||||
{
|
||||
newNormal.X = n.Y;
|
||||
newNormal.Y = n.Z;
|
||||
newNormal.Z = n.X;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
newMesh.Normals.Add(newNormal);
|
||||
dicNormals.Add(n, newNormal);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (Vector3D untranformedV in m.Vertices)
|
||||
{
|
||||
var v = trafo * untranformedV;
|
||||
if (!dicVertices.ContainsKey(v))
|
||||
{
|
||||
var newVert = new Vertex();
|
||||
switch (UpAxis)
|
||||
{
|
||||
case UpAxis.Y:
|
||||
{
|
||||
newVert.X = v.X;
|
||||
newVert.Y = v.Y;
|
||||
newVert.Z = v.Z;
|
||||
break;
|
||||
}
|
||||
|
||||
case UpAxis.Z:
|
||||
{
|
||||
newVert.X = v.Y;
|
||||
newVert.Y = v.Z;
|
||||
newVert.Z = v.X;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
newMesh.Vertices.Add(newVert);
|
||||
dicVertices.Add(v, newVert);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (List<Vector3D> uvList in m.TextureCoordinateChannels)
|
||||
{
|
||||
foreach (Vector3D uv in uvList)
|
||||
{
|
||||
if (!dicUVs.ContainsKey(uv))
|
||||
{
|
||||
var newUV = new UV();
|
||||
newUV.U = uv.X;
|
||||
newUV.V = uv.Y;
|
||||
newMesh.UVs.Add(newUV);
|
||||
dicUVs.Add(uv, newUV);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach (List<Color4D> vcList in m.VertexColorChannels)
|
||||
{
|
||||
foreach (Color4D vc in vcList)
|
||||
{
|
||||
if (!dicVertexColors.ContainsKey(vc))
|
||||
{
|
||||
var newVC = new VertexColor();
|
||||
newVC.R = vc.R;
|
||||
newVC.G = vc.G;
|
||||
newVC.B = vc.B;
|
||||
newVC.A = vc.A;
|
||||
newMesh.VertexColors.Add(newVC);
|
||||
dicVertexColors.Add(vc, newVC);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach (Assimp.Face f in m.Faces)
|
||||
{
|
||||
if (f.HasIndices)
|
||||
{
|
||||
var newFace = new Face() { Material = curMat };
|
||||
foreach (int index in f.Indices)
|
||||
{
|
||||
if (index > -1)
|
||||
{
|
||||
var newPoint = new Point();
|
||||
if (m.HasVertices)
|
||||
{
|
||||
var v = trafo * m.Vertices[index];
|
||||
newPoint.Vertex = dicVertices[v];
|
||||
}
|
||||
|
||||
if (m.HasNormals)
|
||||
{
|
||||
var n = trafo * m.Normals[index];
|
||||
newPoint.Normal = dicNormals[n];
|
||||
}
|
||||
|
||||
if (curMat is object && channelIndicies.ContainsKey(curMat))
|
||||
{
|
||||
int tkey = channelIndicies[curMat];
|
||||
if (m.HasTextureCoords(tkey))
|
||||
{
|
||||
newPoint.UV = dicUVs[m.TextureCoordinateChannels[tkey][index]];
|
||||
}
|
||||
|
||||
if (m.HasVertexColors(tkey))
|
||||
{
|
||||
newPoint.VertexColor = dicVertexColors[m.VertexColorChannels[tkey][index]];
|
||||
}
|
||||
}
|
||||
|
||||
newFace.Points.Add(newPoint);
|
||||
}
|
||||
}
|
||||
|
||||
if (newFace.Points.Count == 3)
|
||||
{
|
||||
newMesh.Faces.Add(newFace);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var n in node.Children)
|
||||
ComputeNode(n, trafo, pc);
|
||||
}
|
||||
|
||||
public static Object3D FromFile(string fileName, bool LoadMaterials, UpAxis UpAxis)
|
||||
{
|
||||
var LoadedImages = new Dictionary<string, Image>();
|
||||
var ac = new AssimpContext();
|
||||
var cc = new ConversionContext(ac.ImportFile(fileName, PostProcessPreset.TargetRealTimeMaximumQuality | PostProcessSteps.Triangulate), UpAxis);
|
||||
var newObj = cc.NewObj;
|
||||
var daeMdl = cc.DaeMdl;
|
||||
var channelIndicies = cc.ChannelIndicies;
|
||||
foreach (EmbeddedTexture et in daeMdl.Textures)
|
||||
{
|
||||
if (et.HasCompressedData)
|
||||
{
|
||||
var newMat = new Material();
|
||||
var ms = new MemoryStream(et.CompressedData);
|
||||
newMat.Image = Image.FromStream(ms);
|
||||
ms.Close();
|
||||
newObj.Materials.Add("tex_" + daeMdl.Textures.IndexOf(et), newMat);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (Assimp.Material mat in daeMdl.Materials)
|
||||
{
|
||||
var newMat = new Material();
|
||||
TextureSlot? texSlot = default;
|
||||
Color4D? col4d = default;
|
||||
newMat.Opacity = mat.Opacity;
|
||||
switch (true)
|
||||
{
|
||||
case object _ when mat.HasTextureNormal:
|
||||
{
|
||||
texSlot = mat.TextureNormal;
|
||||
break;
|
||||
}
|
||||
|
||||
case object _ when mat.HasTextureDiffuse:
|
||||
{
|
||||
texSlot = mat.TextureDiffuse;
|
||||
break;
|
||||
}
|
||||
|
||||
case object _ when mat.HasTextureAmbient:
|
||||
{
|
||||
texSlot = mat.TextureAmbient;
|
||||
break;
|
||||
}
|
||||
|
||||
case object _ when mat.HasTextureSpecular:
|
||||
{
|
||||
texSlot = mat.TextureSpecular;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
switch (true)
|
||||
{
|
||||
case object _ when mat.HasColorDiffuse:
|
||||
{
|
||||
col4d = mat.ColorDiffuse;
|
||||
break;
|
||||
}
|
||||
|
||||
case object _ when mat.HasColorAmbient:
|
||||
{
|
||||
col4d = mat.ColorAmbient;
|
||||
break;
|
||||
}
|
||||
|
||||
case object _ when mat.HasColorSpecular:
|
||||
{
|
||||
col4d = mat.ColorSpecular;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (texSlot is object)
|
||||
{
|
||||
string filePath = texSlot.Value.FilePath;
|
||||
if (LoadMaterials)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(filePath))
|
||||
{
|
||||
string combiPath = Path.Combine(Path.GetDirectoryName(fileName), filePath);
|
||||
if (File.Exists(combiPath))
|
||||
{
|
||||
newMat.Image = LoadImage(combiPath, LoadedImages);
|
||||
}
|
||||
else if (File.Exists(filePath))
|
||||
{
|
||||
newMat.Image = LoadImage(filePath, LoadedImages);
|
||||
}
|
||||
}
|
||||
else if (texSlot.Value.TextureIndex > -1 && daeMdl.Textures.Count > texSlot.Value.TextureIndex)
|
||||
{
|
||||
var et = daeMdl.Textures[texSlot.Value.TextureIndex];
|
||||
if (et.HasCompressedData)
|
||||
{
|
||||
var ms = new MemoryStream(et.CompressedData);
|
||||
newMat.Image = Image.FromStream(ms);
|
||||
ms.Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
channelIndicies.Add(newMat, texSlot.Value.UVIndex);
|
||||
}
|
||||
|
||||
if (col4d is object)
|
||||
{
|
||||
newMat.Color = Color.FromArgb((int)(col4d.Value.R * 255f), (int)(col4d.Value.G * 255f), (int)(col4d.Value.B * 255f));
|
||||
}
|
||||
|
||||
newObj.Materials.Add(mat.Name, newMat);
|
||||
}
|
||||
|
||||
ComputeNewObj(cc);
|
||||
return newObj;
|
||||
}
|
||||
|
||||
public static void ToFile(string fileName, Object3D obj)
|
||||
{
|
||||
var mdl = new Scene();
|
||||
var dicMatIndex = new Dictionary<Material, int>();
|
||||
string texDir = "";
|
||||
if (obj.Materials.Count > 0)
|
||||
{
|
||||
texDir = Path.Combine(Path.GetDirectoryName(fileName), Path.GetFileNameWithoutExtension(fileName));
|
||||
if (!Directory.Exists(texDir))
|
||||
{
|
||||
Directory.CreateDirectory(texDir);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (KeyValuePair<string, Material> kvp in obj.Materials)
|
||||
{
|
||||
var mat = new Assimp.Material();
|
||||
mat.Name = !string.IsNullOrEmpty(kvp.Key) ? kvp.Key : "_" + mdl.Materials.Count;
|
||||
mat.Opacity = mat.Opacity;
|
||||
var texslot = new TextureSlot();
|
||||
texslot.TextureIndex = mdl.Textures.Count;
|
||||
texslot.TextureType = TextureType.Diffuse;
|
||||
texslot.UVIndex = 0;
|
||||
var ms = new MemoryStream();
|
||||
kvp.Value.Image.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
|
||||
// Dim tex As New EmbeddedTexture("png", ms.GetBuffer)
|
||||
ms.Close();
|
||||
if (kvp.Value.Image is object)
|
||||
{
|
||||
texslot.FilePath = Path.Combine(texDir, mat.Name + ".png");
|
||||
File.WriteAllBytes(texslot.FilePath, ms.GetBuffer());
|
||||
}
|
||||
|
||||
// mdl.Textures.Add(tex)
|
||||
mat.AddMaterialTexture(ref texslot);
|
||||
mdl.Materials.Add(mat);
|
||||
if (kvp.Value.Color is object)
|
||||
{
|
||||
{
|
||||
var withBlock = kvp.Value.Color.Value;
|
||||
mat.ColorDiffuse = new Color4D((float)(withBlock.R / 255d), (float)(withBlock.G / 255d), (float)(withBlock.B / 255d), 1f);
|
||||
}
|
||||
}
|
||||
|
||||
dicMatIndex.Add(kvp.Value, mdl.Materials.Count - 1);
|
||||
}
|
||||
|
||||
var dicTexMesh = new Dictionary<Material, Assimp.Mesh>();
|
||||
var dicMeshDicVertIndex = new Dictionary<Assimp.Mesh, Dictionary<Vertex, int>>();
|
||||
var dicCounter = new Dictionary<Assimp.Mesh, int>();
|
||||
foreach (Mesh mesh in obj.Meshes)
|
||||
{
|
||||
foreach (Face f in mesh.Faces)
|
||||
{
|
||||
Assimp.Mesh m;
|
||||
if (dicTexMesh.ContainsKey(f.Material))
|
||||
{
|
||||
m = dicTexMesh[f.Material];
|
||||
}
|
||||
else
|
||||
{
|
||||
m = new Assimp.Mesh("Mesh_" + (mdl.MeshCount + 1));
|
||||
m.PrimitiveType = PrimitiveType.Triangle;
|
||||
if (dicMatIndex.ContainsKey(f.Material))
|
||||
{
|
||||
m.MaterialIndex = dicMatIndex[f.Material];
|
||||
}
|
||||
|
||||
mdl.Meshes.Add(m);
|
||||
dicTexMesh.Add(f.Material, m);
|
||||
dicMeshDicVertIndex.Add(m, new Dictionary<Vertex, int>());
|
||||
dicCounter.Add(m, 0);
|
||||
}
|
||||
|
||||
var newFace = new Assimp.Face();
|
||||
foreach (Point p in f.Points)
|
||||
{
|
||||
newFace.Indices.Add(dicCounter[m]);
|
||||
if (p.Vertex is object)
|
||||
{
|
||||
var vert = new Vector3D();
|
||||
vert.X = (float)p.Vertex.X;
|
||||
vert.Y = (float)p.Vertex.Y;
|
||||
vert.Z = (float)p.Vertex.Z;
|
||||
m.Vertices.Add(vert);
|
||||
}
|
||||
else
|
||||
{
|
||||
m.Vertices.Add(new Vector3D(0f, 0f, 0f));
|
||||
}
|
||||
|
||||
if (p.Normal is object)
|
||||
{
|
||||
var norm = new Vector3D();
|
||||
norm.X = p.Normal.X;
|
||||
norm.Y = p.Normal.Y;
|
||||
norm.Z = p.Normal.Z;
|
||||
m.Normals.Add(norm);
|
||||
}
|
||||
else
|
||||
{
|
||||
m.Normals.Add(new Vector3D(0f, 0f, 0f));
|
||||
}
|
||||
|
||||
// If p.UV IsNot Nothing Then
|
||||
// Dim uv As New Vector3D
|
||||
// uv.X = p.UV.U
|
||||
// uv.Y = p.UV.V
|
||||
// m.TextureCoordinateChannels(0).Add(uv)
|
||||
// Else
|
||||
// m.TextureCoordinateChannels(0).Add(New Vector3D(0, 0, 0))
|
||||
// End If
|
||||
|
||||
// If p.VertexColor IsNot Nothing Then
|
||||
// Dim vc As New Color4D
|
||||
// vc.R = p.VertexColor.R
|
||||
// vc.G = p.VertexColor.G
|
||||
// vc.B = p.VertexColor.B
|
||||
// vc.A = p.VertexColor.A
|
||||
// m.VertexColorChannels(0).Add(vc)
|
||||
// Else
|
||||
// m.VertexColorChannels(0).Add(New Color4D(0, 0, 0, 0))
|
||||
// End If
|
||||
|
||||
dicCounter[m] += 1;
|
||||
}
|
||||
|
||||
m.Faces.Add(newFace);
|
||||
}
|
||||
}
|
||||
|
||||
// Add Root Node
|
||||
mdl.RootNode = new Node(Path.GetFileName(fileName));
|
||||
|
||||
// Add Mesh Indicies
|
||||
for (int i = 0, loopTo = mdl.MeshCount - 1; i <= loopTo; i++)
|
||||
mdl.RootNode.MeshIndices.Add(i);
|
||||
var ac = new AssimpContext();
|
||||
string formatID = "";
|
||||
string myExt = Path.GetExtension(fileName).ToLower().Substring(1);
|
||||
foreach (ExportFormatDescription efd in ac.GetSupportedExportFormats())
|
||||
{
|
||||
if ((myExt ?? "") == (efd.FileExtension ?? ""))
|
||||
{
|
||||
formatID = efd.FormatId;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ac.ExportFile(mdl, fileName, formatID);
|
||||
}
|
||||
|
||||
private static Image LoadImage(string fileName, Dictionary<string, Image> loadedImages)
|
||||
{
|
||||
if (File.Exists(fileName))
|
||||
{
|
||||
if (loadedImages.ContainsKey(fileName))
|
||||
{
|
||||
return loadedImages[fileName];
|
||||
}
|
||||
else
|
||||
{
|
||||
var fs = new FileStream(fileName, FileMode.Open, FileAccess.Read);
|
||||
var img = Image.FromStream(fs);
|
||||
fs.Close();
|
||||
foreach (var kvp in loadedImages)
|
||||
{
|
||||
if (((Bitmap)img).IsTheSameAs((Bitmap)kvp.Value))
|
||||
{
|
||||
return kvp.Value;
|
||||
}
|
||||
}
|
||||
|
||||
loadedImages.Add(fileName, img);
|
||||
return img;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,453 +0,0 @@
|
||||
Imports System.IO
|
||||
Imports Assimp
|
||||
Imports Assimp.Unmanaged
|
||||
|
||||
Namespace AssimpModule
|
||||
|
||||
Friend Class ConversionContext
|
||||
|
||||
Public Property DaeMdl As Scene
|
||||
Public Property UpAxis As UpAxis
|
||||
Public Property NewMesh As New Mesh
|
||||
Public Property NewObj As New Object3D
|
||||
Public Property ChannelIndicies As New Dictionary(Of Material, Integer)
|
||||
|
||||
Public Sub New(daeMdlP As Scene, upAxis As UpAxis)
|
||||
DaeMdl = daeMdlP
|
||||
Me.UpAxis = upAxis
|
||||
|
||||
NewObj.Meshes.Add(NewMesh)
|
||||
End Sub
|
||||
|
||||
End Class
|
||||
|
||||
Friend Class ParsingContext
|
||||
|
||||
Public ReadOnly Property ConversionContext As ConversionContext
|
||||
Public Property DicVertices As New Dictionary(Of Vector3D, Vertex)
|
||||
Public Property DicNormals As New Dictionary(Of Vector3D, Normal)
|
||||
Public Property DicUVs As New Dictionary(Of Vector3D, UV)
|
||||
Public Property DicVertexColors As New Dictionary(Of Color4D, VertexColor)
|
||||
|
||||
Public Sub New(ctx As ConversionContext)
|
||||
ConversionContext = ctx
|
||||
End Sub
|
||||
|
||||
End Class
|
||||
|
||||
Public Class AssimpLoader
|
||||
|
||||
Public Shared Event LoadingAssimpLibs()
|
||||
Public Shared Event LoadedAssimpLibs()
|
||||
|
||||
Public Shared Property PathToAssimpLib32 As String = "Assimp32.dll"
|
||||
Public Shared Property PathToAssimpLib64 As String = "Assimp64.dll"
|
||||
|
||||
Friend Shared Sub LoadAssimpLibs()
|
||||
If Not AssimpLibrary.Instance.IsLibraryLoaded Then
|
||||
RaiseEvent LoadingAssimpLibs()
|
||||
AssimpLibrary.Instance.LoadLibrary(PathToAssimpLib32, PathToAssimpLib64)
|
||||
RaiseEvent LoadedAssimpLibs()
|
||||
End If
|
||||
End Sub
|
||||
|
||||
Private Shared Sub ComputeNewObj(cc As ConversionContext)
|
||||
Dim identity As Matrix4x4 = Matrix4x4.Identity
|
||||
ComputeNode(cc.DaeMdl.RootNode, identity, New ParsingContext(cc))
|
||||
End Sub
|
||||
|
||||
Private Shared Sub ComputeNode(node As Node, trafo As Matrix4x4, pc As ParsingContext)
|
||||
Dim newObj = pc.ConversionContext.NewObj
|
||||
Dim newMesh = pc.ConversionContext.NewMesh
|
||||
Dim daeMdl = pc.ConversionContext.DaeMdl
|
||||
Dim channelIndicies = pc.ConversionContext.ChannelIndicies
|
||||
Dim UpAxis = pc.ConversionContext.UpAxis
|
||||
Dim dicVertices = pc.DicVertices
|
||||
Dim dicNormals = pc.DicNormals
|
||||
Dim dicUVs = pc.DicUVs
|
||||
Dim dicVertexColors = pc.DicVertexColors
|
||||
|
||||
trafo = trafo * node.Transform
|
||||
|
||||
If node.HasMeshes Then
|
||||
For Each meshIndex In node.MeshIndices
|
||||
Dim m As Assimp.Mesh = daeMdl.Meshes(meshIndex)
|
||||
|
||||
Dim curMat As Material
|
||||
If m.MaterialIndex > -1 AndAlso newObj.Materials.Count > m.MaterialIndex Then
|
||||
curMat = newObj.Materials.ElementAt(m.MaterialIndex).Value
|
||||
Else
|
||||
curMat = Nothing
|
||||
End If
|
||||
|
||||
For Each untransformedN As Vector3D In m.Normals
|
||||
Dim n = trafo * untransformedN
|
||||
If Not dicNormals.ContainsKey(n) Then
|
||||
Dim newNormal As New Normal
|
||||
|
||||
Select Case UpAxis
|
||||
Case UpAxis.Y
|
||||
newNormal.X = n.X
|
||||
newNormal.Y = n.Y
|
||||
newNormal.Z = n.Z
|
||||
Case UpAxis.Z
|
||||
newNormal.X = n.Y
|
||||
newNormal.Y = n.Z
|
||||
newNormal.Z = n.X
|
||||
End Select
|
||||
|
||||
newMesh.Normals.Add(newNormal)
|
||||
dicNormals.Add(n, newNormal)
|
||||
End If
|
||||
Next
|
||||
|
||||
For Each untranformedV As Vector3D In m.Vertices
|
||||
Dim v = trafo * untranformedV
|
||||
If Not dicVertices.ContainsKey(v) Then
|
||||
Dim newVert As New Vertex
|
||||
|
||||
Select Case UpAxis
|
||||
Case UpAxis.Y
|
||||
newVert.X = v.X
|
||||
newVert.Y = v.Y
|
||||
newVert.Z = v.Z
|
||||
Case UpAxis.Z
|
||||
newVert.X = v.Y
|
||||
newVert.Y = v.Z
|
||||
newVert.Z = v.X
|
||||
End Select
|
||||
|
||||
newMesh.Vertices.Add(newVert)
|
||||
dicVertices.Add(v, newVert)
|
||||
End If
|
||||
Next
|
||||
|
||||
For Each uvList As List(Of Vector3D) In m.TextureCoordinateChannels
|
||||
For Each uv As Vector3D In uvList
|
||||
If Not dicUVs.ContainsKey(uv) Then
|
||||
Dim newUV As New UV
|
||||
|
||||
newUV.U = uv.X
|
||||
newUV.V = uv.Y
|
||||
|
||||
newMesh.UVs.Add(newUV)
|
||||
dicUVs.Add(uv, newUV)
|
||||
End If
|
||||
Next
|
||||
Next
|
||||
|
||||
For Each vcList As List(Of Color4D) In m.VertexColorChannels
|
||||
For Each vc As Color4D In vcList
|
||||
If Not dicVertexColors.ContainsKey(vc) Then
|
||||
Dim newVC As New VertexColor
|
||||
|
||||
newVC.R = vc.R
|
||||
newVC.G = vc.G
|
||||
newVC.B = vc.B
|
||||
newVC.A = vc.A
|
||||
|
||||
newMesh.VertexColors.Add(newVC)
|
||||
dicVertexColors.Add(vc, newVC)
|
||||
End If
|
||||
Next
|
||||
Next
|
||||
|
||||
For Each f As Assimp.Face In m.Faces
|
||||
If f.HasIndices Then
|
||||
Dim newFace As New Face With {.Material = curMat}
|
||||
|
||||
For Each index As Integer In f.Indices
|
||||
If index > -1 Then
|
||||
Dim newPoint As New Point
|
||||
|
||||
If m.HasVertices Then
|
||||
Dim v = trafo * m.Vertices(index)
|
||||
newPoint.Vertex = dicVertices(v)
|
||||
End If
|
||||
|
||||
If m.HasNormals Then
|
||||
Dim n = trafo * m.Normals(index)
|
||||
newPoint.Normal = dicNormals(n)
|
||||
End If
|
||||
|
||||
If curMat IsNot Nothing AndAlso channelIndicies.ContainsKey(curMat) Then
|
||||
Dim tkey As Integer = channelIndicies(curMat)
|
||||
|
||||
If m.HasTextureCoords(tkey) Then
|
||||
newPoint.UV = dicUVs(m.TextureCoordinateChannels(tkey)(index))
|
||||
End If
|
||||
|
||||
If m.HasVertexColors(tkey) Then
|
||||
newPoint.VertexColor = dicVertexColors(m.VertexColorChannels(tkey)(index))
|
||||
End If
|
||||
End If
|
||||
|
||||
newFace.Points.Add(newPoint)
|
||||
End If
|
||||
Next
|
||||
|
||||
If newFace.Points.Count = 3 Then
|
||||
newMesh.Faces.Add(newFace)
|
||||
End If
|
||||
End If
|
||||
Next
|
||||
Next
|
||||
End If
|
||||
|
||||
For Each n In node.Children
|
||||
ComputeNode(n, trafo, pc)
|
||||
Next
|
||||
End Sub
|
||||
|
||||
Public Shared Function FromFile(fileName As String, LoadMaterials As Boolean, UpAxis As UpAxis) As Object3D
|
||||
Dim LoadedImages As New Dictionary(Of String, Image)
|
||||
Dim ac As New AssimpContext
|
||||
|
||||
Dim cc As New ConversionContext(ac.ImportFile(fileName, PostProcessPreset.TargetRealTimeMaximumQuality Or PostProcessSteps.Triangulate), UpAxis)
|
||||
|
||||
Dim newObj = cc.NewObj
|
||||
Dim daeMdl = cc.DaeMdl
|
||||
Dim channelIndicies = cc.ChannelIndicies
|
||||
|
||||
For Each et As EmbeddedTexture In daeMdl.Textures
|
||||
If et.HasCompressedData Then
|
||||
Dim newMat As New Material
|
||||
|
||||
Dim ms As New MemoryStream(et.CompressedData)
|
||||
newMat.Image = Image.FromStream(ms)
|
||||
ms.Close()
|
||||
|
||||
newObj.Materials.Add("tex_" & daeMdl.Textures.IndexOf(et), newMat)
|
||||
End If
|
||||
Next
|
||||
|
||||
For Each mat As Assimp.Material In daeMdl.Materials
|
||||
Dim newMat As New Material
|
||||
Dim texSlot As TextureSlot? = Nothing
|
||||
Dim col4d As Color4D? = Nothing
|
||||
|
||||
newMat.Opacity = mat.Opacity
|
||||
|
||||
Select Case True
|
||||
Case mat.HasTextureNormal
|
||||
texSlot = mat.TextureNormal
|
||||
Case mat.HasTextureDiffuse
|
||||
texSlot = mat.TextureDiffuse
|
||||
Case mat.HasTextureAmbient
|
||||
texSlot = mat.TextureAmbient
|
||||
Case mat.HasTextureSpecular
|
||||
texSlot = mat.TextureSpecular
|
||||
End Select
|
||||
|
||||
Select Case True
|
||||
Case mat.HasColorDiffuse
|
||||
col4d = mat.ColorDiffuse
|
||||
Case mat.HasColorAmbient
|
||||
col4d = mat.ColorAmbient
|
||||
Case mat.HasColorSpecular
|
||||
col4d = mat.ColorSpecular
|
||||
End Select
|
||||
|
||||
If texSlot IsNot Nothing Then
|
||||
Dim filePath As String = texSlot.Value.FilePath
|
||||
|
||||
If LoadMaterials Then
|
||||
If filePath <> "" Then
|
||||
Dim combiPath As String = Path.Combine(Path.GetDirectoryName(fileName), filePath)
|
||||
If File.Exists(combiPath) Then
|
||||
newMat.Image = LoadImage(combiPath, LoadedImages)
|
||||
ElseIf File.Exists(filePath) Then
|
||||
newMat.Image = LoadImage(filePath, LoadedImages)
|
||||
End If
|
||||
ElseIf texSlot.Value.TextureIndex > -1 AndAlso daeMdl.Textures.Count > texSlot.Value.TextureIndex Then
|
||||
Dim et As EmbeddedTexture = daeMdl.Textures(texSlot.Value.TextureIndex)
|
||||
If et.HasCompressedData Then
|
||||
Dim ms As New MemoryStream(et.CompressedData)
|
||||
newMat.Image = Image.FromStream(ms)
|
||||
ms.Close()
|
||||
End If
|
||||
End If
|
||||
End If
|
||||
|
||||
channelIndicies.Add(newMat, texSlot.Value.UVIndex)
|
||||
End If
|
||||
|
||||
If col4d IsNot Nothing Then
|
||||
newMat.Color = Color.FromArgb(col4d.Value.R * 255, col4d.Value.G * 255, col4d.Value.B * 255)
|
||||
End If
|
||||
|
||||
newObj.Materials.Add(mat.Name, newMat)
|
||||
Next
|
||||
|
||||
ComputeNewObj(cc)
|
||||
|
||||
Return newObj
|
||||
End Function
|
||||
|
||||
Public Shared Sub ToFile(fileName As String, obj As Object3D)
|
||||
Dim mdl As New Scene
|
||||
Dim dicMatIndex As New Dictionary(Of Material, Integer)
|
||||
|
||||
Dim texDir As String = ""
|
||||
If obj.Materials.Count > 0 Then
|
||||
texDir = Path.Combine(Path.GetDirectoryName(fileName), Path.GetFileNameWithoutExtension(fileName))
|
||||
If Not Directory.Exists(texDir) Then
|
||||
Directory.CreateDirectory(texDir)
|
||||
End If
|
||||
End If
|
||||
|
||||
For Each kvp As KeyValuePair(Of String, Material) In obj.Materials
|
||||
Dim mat As New Assimp.Material
|
||||
|
||||
mat.Name = If(kvp.Key <> "", kvp.Key, "_" & mdl.Materials.Count)
|
||||
mat.Opacity = mat.Opacity
|
||||
|
||||
Dim texslot As New TextureSlot
|
||||
texslot.TextureIndex = mdl.Textures.Count
|
||||
texslot.TextureType = TextureType.Diffuse
|
||||
texslot.UVIndex = 0
|
||||
|
||||
Dim ms As New MemoryStream
|
||||
kvp.Value.Image.Save(ms, Imaging.ImageFormat.Png)
|
||||
'Dim tex As New EmbeddedTexture("png", ms.GetBuffer)
|
||||
ms.Close()
|
||||
|
||||
If kvp.Value.Image IsNot Nothing Then
|
||||
texslot.FilePath = Path.Combine(texDir, mat.Name & ".png")
|
||||
File.WriteAllBytes(texslot.FilePath, ms.GetBuffer)
|
||||
End If
|
||||
|
||||
'mdl.Textures.Add(tex)
|
||||
mat.AddMaterialTexture(texslot)
|
||||
mdl.Materials.Add(mat)
|
||||
|
||||
If kvp.Value.Color IsNot Nothing Then
|
||||
With kvp.Value.Color.Value
|
||||
mat.ColorDiffuse = New Color4D(.R / 255, .G / 255, .B / 255, 1)
|
||||
End With
|
||||
End If
|
||||
|
||||
dicMatIndex.Add(kvp.Value, mdl.Materials.Count - 1)
|
||||
Next
|
||||
|
||||
Dim dicTexMesh As New Dictionary(Of Material, Assimp.Mesh)
|
||||
Dim dicMeshDicVertIndex As New Dictionary(Of Assimp.Mesh, Dictionary(Of Vertex, Integer))
|
||||
Dim dicCounter As New Dictionary(Of Assimp.Mesh, Integer)
|
||||
|
||||
For Each mesh As Mesh In obj.Meshes
|
||||
For Each f As Face In mesh.Faces
|
||||
Dim m As Assimp.Mesh
|
||||
|
||||
If dicTexMesh.ContainsKey(f.Material) Then
|
||||
m = dicTexMesh(f.Material)
|
||||
Else
|
||||
m = New Assimp.Mesh("Mesh_" & mdl.MeshCount + 1)
|
||||
m.PrimitiveType = PrimitiveType.Triangle
|
||||
If dicMatIndex.ContainsKey(f.Material) Then
|
||||
m.MaterialIndex = dicMatIndex(f.Material)
|
||||
End If
|
||||
mdl.Meshes.Add(m)
|
||||
dicTexMesh.Add(f.Material, m)
|
||||
dicMeshDicVertIndex.Add(m, New Dictionary(Of Vertex, Integer))
|
||||
dicCounter.Add(m, 0)
|
||||
End If
|
||||
|
||||
Dim newFace As New Assimp.Face
|
||||
|
||||
For Each p As Point In f.Points
|
||||
newFace.Indices.Add(dicCounter(m))
|
||||
|
||||
If p.Vertex IsNot Nothing Then
|
||||
Dim vert As New Vector3D
|
||||
vert.X = p.Vertex.X
|
||||
vert.Y = p.Vertex.Y
|
||||
vert.Z = p.Vertex.Z
|
||||
m.Vertices.Add(vert)
|
||||
Else
|
||||
m.Vertices.Add(New Vector3D(0, 0, 0))
|
||||
End If
|
||||
|
||||
If p.Normal IsNot Nothing Then
|
||||
Dim norm As New Vector3D
|
||||
norm.X = p.Normal.X
|
||||
norm.Y = p.Normal.Y
|
||||
norm.Z = p.Normal.Z
|
||||
m.Normals.Add(norm)
|
||||
Else
|
||||
m.Normals.Add(New Vector3D(0, 0, 0))
|
||||
End If
|
||||
|
||||
'If p.UV IsNot Nothing Then
|
||||
' Dim uv As New Vector3D
|
||||
' uv.X = p.UV.U
|
||||
' uv.Y = p.UV.V
|
||||
' m.TextureCoordinateChannels(0).Add(uv)
|
||||
'Else
|
||||
' m.TextureCoordinateChannels(0).Add(New Vector3D(0, 0, 0))
|
||||
'End If
|
||||
|
||||
'If p.VertexColor IsNot Nothing Then
|
||||
' Dim vc As New Color4D
|
||||
' vc.R = p.VertexColor.R
|
||||
' vc.G = p.VertexColor.G
|
||||
' vc.B = p.VertexColor.B
|
||||
' vc.A = p.VertexColor.A
|
||||
' m.VertexColorChannels(0).Add(vc)
|
||||
'Else
|
||||
' m.VertexColorChannels(0).Add(New Color4D(0, 0, 0, 0))
|
||||
'End If
|
||||
|
||||
dicCounter(m) += 1
|
||||
Next
|
||||
|
||||
m.Faces.Add(newFace)
|
||||
Next
|
||||
Next
|
||||
|
||||
'Add Root Node
|
||||
mdl.RootNode = New Node(Path.GetFileName(fileName))
|
||||
|
||||
'Add Mesh Indicies
|
||||
For i As Integer = 0 To mdl.MeshCount - 1
|
||||
mdl.RootNode.MeshIndices.Add(i)
|
||||
Next
|
||||
|
||||
Dim ac As New AssimpContext
|
||||
|
||||
Dim formatID As String = ""
|
||||
Dim myExt As String = Path.GetExtension(fileName).ToLower.Substring(1)
|
||||
For Each efd As ExportFormatDescription In ac.GetSupportedExportFormats
|
||||
If myExt = efd.FileExtension Then
|
||||
formatID = efd.FormatId
|
||||
Exit For
|
||||
End If
|
||||
Next
|
||||
|
||||
ac.ExportFile(mdl, fileName, formatID)
|
||||
End Sub
|
||||
|
||||
Private Shared Function LoadImage(fileName As String, loadedImages As Dictionary(Of String, Image)) As Image
|
||||
If File.Exists(fileName) Then
|
||||
If loadedImages.ContainsKey(fileName) Then
|
||||
Return loadedImages(fileName)
|
||||
Else
|
||||
Dim fs As New FileStream(fileName, FileMode.Open, FileAccess.Read)
|
||||
Dim img As Image = Image.FromStream(fs)
|
||||
fs.Close()
|
||||
|
||||
For Each kvp In loadedImages
|
||||
If IsTheSameAs(img, kvp.Value) Then
|
||||
Return kvp.Value
|
||||
End If
|
||||
Next
|
||||
|
||||
loadedImages.Add(fileName, img)
|
||||
Return img
|
||||
End If
|
||||
End If
|
||||
Return Nothing
|
||||
End Function
|
||||
|
||||
End Class
|
||||
|
||||
End Namespace
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,391 +0,0 @@
|
||||
Imports System.Globalization
|
||||
Imports System.IO
|
||||
Imports System.Threading
|
||||
Imports Pilz.S3DFileParser.Exceptions
|
||||
|
||||
Namespace ObjModule
|
||||
|
||||
Public Class ObjFile
|
||||
|
||||
Public Shared Function FromFile(FileName As String, LoadMaterials As Boolean, UpAxis As UpAxis) As Object3D
|
||||
Dim curThread As Thread = Thread.CurrentThread
|
||||
Dim curCultInfo As CultureInfo = curThread.CurrentCulture
|
||||
Dim newCultInfo As 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
|
||||
|
||||
Dim newObj As New Object3D
|
||||
Dim newMesh As New Mesh
|
||||
Dim curObjPath As String = Path.GetDirectoryName(FileName)
|
||||
|
||||
Dim mtllibs As New Dictionary(Of String, MaterialLib)
|
||||
|
||||
Dim curMaterialLib As MaterialLib = Nothing
|
||||
Dim curMaterial As Material = Nothing
|
||||
|
||||
Dim srObj As New StreamReader(FileName, Text.Encoding.ASCII)
|
||||
Dim line As String = ""
|
||||
|
||||
Do Until srObj.EndOfStream
|
||||
line = srObj.ReadLine.Trim
|
||||
|
||||
If line <> "" Then
|
||||
|
||||
Select Case True
|
||||
Case line.StartsWith("mtllib ")
|
||||
Dim name As String = line.Substring(7)
|
||||
|
||||
If Not mtllibs.ContainsKey(name) Then
|
||||
Dim mtlfile As String = Path.Combine(curObjPath, name)
|
||||
If Not File.Exists(mtlfile) Then Throw New MaterialException("Material Library not found!")
|
||||
|
||||
Dim newmtl As New MaterialLib
|
||||
newmtl.FromFile(mtlfile, LoadMaterials)
|
||||
mtllibs.Add(name, newmtl)
|
||||
curMaterialLib = newmtl
|
||||
|
||||
For Each kvp As KeyValuePair(Of String, Material) In curMaterialLib.Materials
|
||||
If Not newObj.Materials.ContainsKey(kvp.Key) Then newObj.Materials.Add(kvp.Key, kvp.Value)
|
||||
Next
|
||||
Else
|
||||
curMaterialLib = mtllibs(name)
|
||||
End If
|
||||
|
||||
Case line.StartsWith("usemtl ")
|
||||
curMaterial = curMaterialLib.Materials(line.Substring(7))
|
||||
|
||||
Case line.StartsWith("v ")
|
||||
If line.Contains("nan") Then line = line.Replace("nan", "0")
|
||||
Dim splitXYZ() As String = line.Substring(2).Split(" "c)
|
||||
|
||||
Dim tX As Double = Convert.ToDouble(splitXYZ(0))
|
||||
Dim tY As Double = Convert.ToDouble(splitXYZ(1))
|
||||
Dim tZ As Double = Convert.ToDouble(splitXYZ(2))
|
||||
|
||||
Dim v As New Vertex
|
||||
Select Case UpAxis
|
||||
Case UpAxis.Y
|
||||
v.X = tX
|
||||
v.Y = tY
|
||||
v.Z = tZ
|
||||
Case UpAxis.Z
|
||||
v.X = tY
|
||||
v.Y = tZ
|
||||
v.Z = tX
|
||||
End Select
|
||||
newMesh.Vertices.Add(v)
|
||||
|
||||
Case line.StartsWith("vt ")
|
||||
Dim uvstr() As String = line.Substring(3).Split(" "c)
|
||||
Dim uv As New UV With {
|
||||
.U = Convert.ToSingle(uvstr(0)),
|
||||
.V = Convert.ToSingle(uvstr(1))}
|
||||
newMesh.UVs.Add(uv)
|
||||
|
||||
Case line.StartsWith("vn ")
|
||||
Dim splitXYZ() As String = line.Substring(3).Split(" "c)
|
||||
|
||||
Dim tX As Single = Convert.ToSingle(splitXYZ(0))
|
||||
Dim tY As Single = Convert.ToSingle(splitXYZ(1))
|
||||
Dim tZ As Single = Convert.ToSingle(splitXYZ(2))
|
||||
|
||||
Dim n As New Normal
|
||||
Select Case UpAxis
|
||||
Case UpAxis.Y
|
||||
n.X = tX
|
||||
n.Y = tY
|
||||
n.Z = tZ
|
||||
Case UpAxis.Z
|
||||
n.X = tZ
|
||||
n.Y = tY
|
||||
n.Z = tX
|
||||
End Select
|
||||
newMesh.Normals.Add(n)
|
||||
|
||||
Case line.StartsWith("vc ")
|
||||
Dim splitRGB() As String = line.Substring(3).Split(" "c)
|
||||
|
||||
Dim tX As Single = Convert.ToSingle(splitRGB(0))
|
||||
Dim tY As Single = Convert.ToSingle(splitRGB(1))
|
||||
Dim tZ As Single = Convert.ToSingle(splitRGB(2))
|
||||
|
||||
Dim vc As New VertexColor
|
||||
Select Case UpAxis
|
||||
Case UpAxis.Y
|
||||
vc.R = tX
|
||||
vc.G = tY
|
||||
vc.B = tZ
|
||||
Case UpAxis.Z
|
||||
vc.R = tY
|
||||
vc.G = tZ
|
||||
vc.B = tX
|
||||
End Select
|
||||
newMesh.VertexColors.Add(vc)
|
||||
|
||||
Case line.StartsWith("f ")
|
||||
Dim tri As New Face With {.Material = curMaterial}
|
||||
|
||||
For Each xyz As String In line.Substring(2).Split(" "c)
|
||||
xyz = xyz.Trim
|
||||
If xyz = "" Then Continue For
|
||||
|
||||
Dim splitsub() As String = Nothing
|
||||
Dim p As New Point
|
||||
|
||||
Select Case True
|
||||
Case xyz.Contains("/")
|
||||
splitsub = xyz.Split("/"c)
|
||||
Case xyz.Contains("\")
|
||||
splitsub = xyz.Split("\"c)
|
||||
Case Else
|
||||
splitsub = {0, 0, 0}
|
||||
End Select
|
||||
|
||||
Dim v1 As String = splitsub(0)
|
||||
Dim v2 As String = splitsub(1)
|
||||
Dim v3 As String = splitsub(2)
|
||||
|
||||
If v1 <> "" Then
|
||||
p.Vertex = newMesh.Vertices(Convert.ToInt32(v1) - 1)
|
||||
End If
|
||||
|
||||
If v2 <> "" Then
|
||||
p.UV = newMesh.UVs(Convert.ToInt32(v2) - 1)
|
||||
Else
|
||||
Dim newUV As New UV With {.U = 0, .V = 0}
|
||||
p.UV = newUV
|
||||
newMesh.UVs.Add(newUV)
|
||||
End If
|
||||
|
||||
If v3 <> "" Then
|
||||
p.Normal = newMesh.Normals(Convert.ToInt32(v3) - 1)
|
||||
End If
|
||||
|
||||
If splitsub.Count > 3 Then
|
||||
Dim v4 As String = splitsub(3)
|
||||
If v4 <> "" Then p.VertexColor = newMesh.VertexColors(Convert.ToInt32(v4) - 1)
|
||||
End If
|
||||
|
||||
tri.Points.Add(p)
|
||||
Next
|
||||
|
||||
newMesh.Faces.Add(tri)
|
||||
|
||||
End Select
|
||||
|
||||
End If
|
||||
|
||||
Loop
|
||||
newObj.Meshes.Add(newMesh)
|
||||
|
||||
curThread.CurrentCulture = curCultInfo
|
||||
|
||||
srObj.Close()
|
||||
Return newObj
|
||||
End Function
|
||||
|
||||
Public Shared Sub ToFile(FileName As String, obj As Object3D)
|
||||
Dim fs As New FileStream(FileName, FileMode.Create, FileAccess.ReadWrite)
|
||||
Dim sw As New StreamWriter(fs, Text.Encoding.ASCII)
|
||||
|
||||
If obj.Materials.Count > 0 Then
|
||||
Dim mtlName As String = Path.GetFileNameWithoutExtension(FileName) & ".mtl"
|
||||
Dim mtlFile As String = Path.Combine(Path.GetDirectoryName(FileName), mtlName)
|
||||
sw.WriteLine($"mtllib {mtlName}")
|
||||
MaterialLib.ToFile(mtlFile, obj)
|
||||
End If
|
||||
|
||||
Dim curVertCount As Integer = 1
|
||||
Dim curUVCount As Integer = 1
|
||||
Dim curNormCount As Integer = 1
|
||||
Dim curVertColCount As Integer = 1
|
||||
|
||||
For Each m As Mesh In obj.Meshes
|
||||
|
||||
For Each vert As Vertex In m.Vertices
|
||||
sw.WriteLine($"v {vert.X.ToString.Replace(",", ".")} {vert.Y.ToString.Replace(",", ".")} {vert.Z.ToString.Replace(",", ".")}")
|
||||
Next
|
||||
|
||||
For Each uv As UV In m.UVs
|
||||
sw.WriteLine($"vt {uv.U.ToString.Replace(",", ".")} {uv.V.ToString.Replace(",", ".")}")
|
||||
Next
|
||||
|
||||
For Each norm As Normal In m.Normals
|
||||
sw.WriteLine($"vn {norm.X.ToString.Replace(",", ".")} {norm.Y.ToString.Replace(",", ".")} {norm.Z.ToString.Replace(",", ".")}")
|
||||
Next
|
||||
|
||||
For Each vertcol As VertexColor In m.VertexColors
|
||||
sw.WriteLine($"vc {vertcol.R.ToString.Replace(",", ".")} {vertcol.G.ToString.Replace(",", ".")} {vertcol.B.ToString.Replace(",", ".")}")
|
||||
Next
|
||||
|
||||
Dim curMtl As Material = Nothing
|
||||
|
||||
For Each f As Face In m.Faces
|
||||
If curMtl IsNot f.Material Then
|
||||
curMtl = f.Material
|
||||
sw.WriteLine($"usemtl _{GetIndexOfMaterialInList(obj, curMtl)}")
|
||||
End If
|
||||
|
||||
sw.Write("f")
|
||||
|
||||
For Each p As Point In f.Points
|
||||
sw.Write(" ")
|
||||
sw.Write(curVertCount + m.Vertices.IndexOf(p.Vertex))
|
||||
|
||||
sw.Write("/")
|
||||
If p.UV IsNot Nothing Then sw.Write(curUVCount + m.UVs.IndexOf(p.UV))
|
||||
|
||||
sw.Write("/")
|
||||
If p.Normal IsNot Nothing Then sw.Write(curNormCount + m.Normals.IndexOf(p.Normal))
|
||||
|
||||
If m.VertexColors.Count > 0 Then
|
||||
sw.Write("/")
|
||||
If p.VertexColor IsNot Nothing Then sw.Write(curVertColCount + m.VertexColors.IndexOf(p.VertexColor))
|
||||
End If
|
||||
Next
|
||||
|
||||
sw.WriteLine()
|
||||
Next
|
||||
|
||||
curVertCount += m.Vertices.Count
|
||||
curUVCount += m.UVs.Count
|
||||
curNormCount += m.Normals.Count
|
||||
curVertColCount += m.VertexColors.Count
|
||||
Next
|
||||
|
||||
sw.Flush()
|
||||
fs.Close()
|
||||
End Sub
|
||||
|
||||
Public Shared Function GetIndexOfMaterialInList(obj As Object3D, matToFind As Material) As Integer
|
||||
For Index As Integer = 0 To obj.Materials.Count - 1
|
||||
If obj.Materials.ElementAt(Index).Value.Equals(matToFind) Then
|
||||
Return Index
|
||||
End If
|
||||
Next
|
||||
Return -1
|
||||
End Function
|
||||
|
||||
End Class
|
||||
|
||||
Public Class MaterialLib
|
||||
|
||||
Public ReadOnly Property Materials As New Dictionary(Of String, Material)
|
||||
Private ReadOnly LoadedImages As New Dictionary(Of String, Image)
|
||||
|
||||
Public Sub FromFile(fileName As String, LoadMaterials As Boolean)
|
||||
LoadedImages.Clear()
|
||||
|
||||
Dim curMatLibPath As String = Path.GetDirectoryName(fileName)
|
||||
|
||||
Dim curMat As Material = Nothing
|
||||
Dim curName As String = ""
|
||||
|
||||
Dim srMtl As New StreamReader(fileName, Text.Encoding.ASCII)
|
||||
Dim line As String = ""
|
||||
|
||||
Do Until srMtl.EndOfStream
|
||||
line = srMtl.ReadLine
|
||||
|
||||
Select Case True
|
||||
Case line.StartsWith("newmtl ")
|
||||
curMat = New Material
|
||||
curName = line.Substring(7)
|
||||
Materials.Add(curName, curMat)
|
||||
|
||||
Case line.ToLower.StartsWith("kd ")
|
||||
Dim splitColor() As String = line.Substring(3).Split(" "c)
|
||||
Dim col As Color = Color.FromArgb(
|
||||
Convert.ToSingle(Math.Round(255 * splitColor(0))),
|
||||
Convert.ToSingle(Math.Round(255 * splitColor(1))),
|
||||
Convert.ToSingle(Math.Round(255 * splitColor(2))))
|
||||
curMat.Color = col
|
||||
|
||||
Case line.ToLower.StartsWith("d ")
|
||||
curMat.Opacity = Convert.ToSingle(line.Substring(2))
|
||||
|
||||
Case line.ToLower.StartsWith("tr ")
|
||||
curMat.Opacity = 1 - Convert.ToSingle(line.Substring(2))
|
||||
|
||||
Case line.ToLower.StartsWith("map_kd ")
|
||||
If LoadMaterials Then
|
||||
Dim mtlpath As String = line.Substring(7)
|
||||
Dim combipath As String = Path.Combine(curMatLibPath, line.Substring(7))
|
||||
Dim imgfile As String
|
||||
|
||||
If File.Exists(combipath) Then
|
||||
imgfile = combipath
|
||||
ElseIf File.Exists(line.Substring(7)) Then
|
||||
imgfile = mtlpath
|
||||
Else
|
||||
imgfile = ""
|
||||
End If
|
||||
|
||||
If imgfile <> "" Then
|
||||
If LoadedImages.ContainsKey(imgfile) Then
|
||||
curMat.Image = LoadedImages(imgfile)
|
||||
Else
|
||||
Dim fs As New FileStream(imgfile, FileMode.Open, FileAccess.Read)
|
||||
curMat.Image = Image.FromStream(fs)
|
||||
fs.Close()
|
||||
Dim imgExists As Boolean = False
|
||||
For Each kvp In LoadedImages
|
||||
If Not imgExists AndAlso IsTheSameAs(kvp.Value, curMat.Image) Then
|
||||
curMat.Image = kvp.Value
|
||||
imgExists = True
|
||||
End If
|
||||
Next
|
||||
If Not imgExists Then
|
||||
LoadedImages.Add(imgfile, curMat.Image)
|
||||
End If
|
||||
End If
|
||||
End If
|
||||
End If
|
||||
|
||||
End Select
|
||||
Loop
|
||||
|
||||
srMtl.Close()
|
||||
End Sub
|
||||
|
||||
Public Shared Sub ToFile(fileName As String, obj As Object3D)
|
||||
Dim fs As New FileStream(fileName, FileMode.Create, FileAccess.ReadWrite)
|
||||
Dim sw As New StreamWriter(fs, Text.Encoding.ASCII)
|
||||
Dim imgDirName As String = Path.GetFileNameWithoutExtension(fileName)
|
||||
Dim imgDirFull As String = Path.Combine(Path.GetDirectoryName(fileName), Path.GetFileNameWithoutExtension(fileName))
|
||||
|
||||
For Each kvp As KeyValuePair(Of String, Material) In obj.Materials
|
||||
Dim mat As Material = kvp.Value
|
||||
Dim name As String = "_" & ObjFile.GetIndexOfMaterialInList(obj, mat)
|
||||
sw.WriteLine($"newmtl {name}")
|
||||
|
||||
If mat.Color IsNot Nothing Then
|
||||
sw.WriteLine($"kd {(mat.Color.Value.R / 255).ToString.Replace(",", ".")} {(mat.Color.Value.G / 255).ToString.Replace(",", ".")} {(mat.Color.Value.B / 255).ToString.Replace(",", ".")}")
|
||||
End If
|
||||
|
||||
If mat.Opacity IsNot Nothing Then
|
||||
sw.WriteLine($"d {mat.Opacity.Value.ToString.Replace(",", ".")}")
|
||||
End If
|
||||
|
||||
If mat.Image IsNot Nothing Then
|
||||
Dim imgFile As String = name & ".png"
|
||||
|
||||
If Not Directory.Exists(imgDirFull) Then Directory.CreateDirectory(imgDirFull)
|
||||
mat.Image.Save(Path.Combine(imgDirFull, imgFile), Imaging.ImageFormat.Png)
|
||||
|
||||
sw.WriteLine($"map_kd {Path.Combine(imgDirName, imgFile)}")
|
||||
End If
|
||||
Next
|
||||
|
||||
sw.Flush()
|
||||
fs.Close()
|
||||
End Sub
|
||||
|
||||
End Class
|
||||
|
||||
End Namespace
|
||||
11
Pilz.Simple3DFileParser/Model/Face.cs
Normal file
11
Pilz.Simple3DFileParser/Model/Face.cs
Normal file
@@ -0,0 +1,11 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Pilz.S3DFileParser
|
||||
{
|
||||
public class Face
|
||||
{
|
||||
public List<Point> Points { get; private set; } = new List<Point>();
|
||||
public Material Material { get; set; } = null;
|
||||
public object Tag { get; set; } = null;
|
||||
}
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
Public Class Face
|
||||
Public ReadOnly Property Points As New List(Of Point)
|
||||
Public Property Material As Material = Nothing
|
||||
Public Property Tag As Object = Nothing
|
||||
End Class
|
||||
10
Pilz.Simple3DFileParser/Model/Interfaces.cs
Normal file
10
Pilz.Simple3DFileParser/Model/Interfaces.cs
Normal file
@@ -0,0 +1,10 @@
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Pilz.S3DFileParser
|
||||
{
|
||||
public interface IToObject3D
|
||||
{
|
||||
Object3D ToObject3D();
|
||||
Task<Object3D> ToObject3DAsync();
|
||||
}
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
Public Interface IToObject3D
|
||||
|
||||
Function ToObject3D() As Object3D
|
||||
Function ToObject3DAsync() As Task(Of Object3D)
|
||||
|
||||
End Interface
|
||||
35
Pilz.Simple3DFileParser/Model/Material.cs
Normal file
35
Pilz.Simple3DFileParser/Model/Material.cs
Normal file
@@ -0,0 +1,35 @@
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using global::System.Numerics;
|
||||
|
||||
namespace Pilz.S3DFileParser
|
||||
{
|
||||
public class Material : IComparable
|
||||
{
|
||||
public Image Image { get; set; } = null;
|
||||
public Color? Color { get; set; } = default;
|
||||
public float? Opacity { get; set; } = default;
|
||||
public Vector2 Wrap { get; set; } = new Vector2(10497f, 10497f);
|
||||
public Vector2 Scale { get; set; } = new Vector2(1.0f, 1.0f);
|
||||
public object Tag { get; set; } = null;
|
||||
|
||||
public int CompareTo(object obj)
|
||||
{
|
||||
if (obj is object)
|
||||
{
|
||||
if (ReferenceEquals(obj, this))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
Imports System.Numerics
|
||||
|
||||
Public Class Material
|
||||
Implements IComparable
|
||||
|
||||
Public Property Image As Image = Nothing
|
||||
Public Property Color As Color? = Nothing
|
||||
Public Property Opacity As Single? = Nothing
|
||||
Public Property Wrap As New Vector2(10497, 10497)
|
||||
Public Property Scale As New Vector2(1.0F, 1.0F)
|
||||
Public Property Tag As Object = Nothing
|
||||
|
||||
Public Function CompareTo(obj As Object) As Integer Implements IComparable.CompareTo
|
||||
If obj IsNot Nothing Then
|
||||
If obj Is Me Then
|
||||
Return 0
|
||||
Else
|
||||
Return -1
|
||||
End If
|
||||
Else
|
||||
Return 1
|
||||
End If
|
||||
End Function
|
||||
|
||||
End Class
|
||||
50
Pilz.Simple3DFileParser/Model/Mesh.cs
Normal file
50
Pilz.Simple3DFileParser/Model/Mesh.cs
Normal file
@@ -0,0 +1,50 @@
|
||||
using System.Collections.Generic;
|
||||
using global::System.Numerics;
|
||||
|
||||
namespace Pilz.S3DFileParser
|
||||
{
|
||||
public class Mesh
|
||||
{
|
||||
public List<Vertex> Vertices { get; private set; } = new List<Vertex>();
|
||||
public List<Normal> Normals { get; private set; } = new List<Normal>();
|
||||
public List<UV> UVs { get; private set; } = new List<UV>();
|
||||
public List<VertexColor> VertexColors { get; private set; } = new List<VertexColor>();
|
||||
public List<Face> Faces { get; private set; } = new List<Face>();
|
||||
|
||||
public void CenterModel()
|
||||
{
|
||||
CenterModel(new[] { this });
|
||||
}
|
||||
|
||||
public static void CenterModel(IEnumerable<Mesh> meshes)
|
||||
{
|
||||
int avgX = 0;
|
||||
int avgY = 0;
|
||||
int avgZ = 0;
|
||||
long vertsCount = 0L;
|
||||
foreach (Mesh m in meshes)
|
||||
{
|
||||
foreach (Vertex v in m.Vertices)
|
||||
{
|
||||
avgX = (int)(avgX + v.X);
|
||||
avgY = (int)(avgY + v.Y);
|
||||
avgZ = (int)(avgZ + v.Z);
|
||||
}
|
||||
|
||||
vertsCount += m.Vertices.Count;
|
||||
}
|
||||
|
||||
var avg = new Vector3(avgX, avgY, avgZ);
|
||||
avg /= new Vector3(vertsCount);
|
||||
foreach (Mesh m in meshes)
|
||||
{
|
||||
foreach (Vertex v in m.Vertices)
|
||||
{
|
||||
v.X -= avg.X;
|
||||
v.Y -= avg.Y;
|
||||
v.Z -= avg.Z;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
Imports System.Numerics
|
||||
|
||||
Public Class Mesh
|
||||
|
||||
Public ReadOnly Property Vertices As New List(Of Vertex)
|
||||
Public ReadOnly Property Normals As New List(Of Normal)
|
||||
Public ReadOnly Property UVs As New List(Of UV)
|
||||
Public ReadOnly Property VertexColors As New List(Of VertexColor)
|
||||
Public ReadOnly Property Faces As New List(Of Face)
|
||||
|
||||
Public Sub CenterModel()
|
||||
CenterModel({Me})
|
||||
End Sub
|
||||
|
||||
Public Shared Sub CenterModel(meshes As IEnumerable(Of Mesh))
|
||||
Dim avgX As Integer = 0
|
||||
Dim avgY As Integer = 0
|
||||
Dim avgZ As Integer = 0
|
||||
Dim vertsCount As Long = 0
|
||||
|
||||
For Each m As Mesh In meshes
|
||||
For Each v As Vertex In m.Vertices
|
||||
avgX += v.X
|
||||
avgY += v.Y
|
||||
avgZ += v.Z
|
||||
Next
|
||||
vertsCount += m.Vertices.Count
|
||||
Next
|
||||
|
||||
Dim avg As New Vector3(avgX, avgY, avgZ)
|
||||
avg /= New Vector3(vertsCount)
|
||||
|
||||
For Each m As Mesh In meshes
|
||||
For Each v As Vertex In m.Vertices
|
||||
v.X -= avg.X
|
||||
v.Y -= avg.Y
|
||||
v.Z -= avg.Z
|
||||
Next
|
||||
Next
|
||||
End Sub
|
||||
|
||||
End Class
|
||||
16
Pilz.Simple3DFileParser/Model/ModelBoundaries.cs
Normal file
16
Pilz.Simple3DFileParser/Model/ModelBoundaries.cs
Normal file
@@ -0,0 +1,16 @@
|
||||
using global::System.Numerics;
|
||||
|
||||
namespace Pilz.S3DFileParser
|
||||
{
|
||||
public class ModelBoundaries
|
||||
{
|
||||
public readonly Vector3 Upper;
|
||||
public readonly Vector3 Lower;
|
||||
|
||||
public ModelBoundaries(Vector3 upper, Vector3 lower)
|
||||
{
|
||||
Upper = upper;
|
||||
Lower = lower;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
Imports System.Numerics
|
||||
|
||||
Public Class ModelBoundaries
|
||||
Public ReadOnly Upper As Vector3
|
||||
Public ReadOnly Lower As Vector3
|
||||
|
||||
Public Sub New(upper As Vector3, lower As Vector3)
|
||||
Me.Upper = upper
|
||||
Me.Lower = lower
|
||||
End Sub
|
||||
End Class
|
||||
10
Pilz.Simple3DFileParser/Model/Normal.cs
Normal file
10
Pilz.Simple3DFileParser/Model/Normal.cs
Normal file
@@ -0,0 +1,10 @@
|
||||
|
||||
namespace Pilz.S3DFileParser
|
||||
{
|
||||
public class Normal
|
||||
{
|
||||
public float X { get; set; } = 0f;
|
||||
public float Y { get; set; } = 0f;
|
||||
public float Z { get; set; } = 0f;
|
||||
}
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
Public Class Normal
|
||||
Public Property X As Single = 0
|
||||
Public Property Y As Single = 0
|
||||
Public Property Z As Single = 0
|
||||
End Class
|
||||
217
Pilz.Simple3DFileParser/Model/Object3D.cs
Normal file
217
Pilz.Simple3DFileParser/Model/Object3D.cs
Normal file
@@ -0,0 +1,217 @@
|
||||
using System.Collections.Generic;
|
||||
using global::System.Numerics;
|
||||
|
||||
namespace Pilz.S3DFileParser
|
||||
{
|
||||
public class Object3D
|
||||
{
|
||||
public List<Mesh> Meshes { get; private set; } = new List<Mesh>();
|
||||
public Dictionary<string, Material> Materials { get; private set; } = new Dictionary<string, Material>();
|
||||
public Shading Shading { get; set; } = new Shading();
|
||||
|
||||
public void ScaleModel(float factor)
|
||||
{
|
||||
foreach (Mesh m in Meshes)
|
||||
{
|
||||
foreach (Vertex v in m.Vertices)
|
||||
{
|
||||
v.X *= factor;
|
||||
v.Y *= factor;
|
||||
v.Z *= factor;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void OffsetModel(Vector3 off)
|
||||
{
|
||||
foreach (Mesh m in Meshes)
|
||||
{
|
||||
foreach (Vertex v in m.Vertices)
|
||||
{
|
||||
v.X += off.X;
|
||||
v.Y += off.Y;
|
||||
v.Z += off.Z;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public ModelBoundaries GetBoundaries()
|
||||
{
|
||||
float? maxX = default;
|
||||
float? maxY = default;
|
||||
float? maxZ = default;
|
||||
float? minX = default;
|
||||
float? minY = default;
|
||||
float? minZ = default;
|
||||
foreach (Mesh m in Meshes)
|
||||
{
|
||||
foreach (Vertex vert in m.Vertices)
|
||||
{
|
||||
if (maxX is null || vert.X > maxX)
|
||||
maxX = (float?)vert.X;
|
||||
if (maxY is null || vert.Y > maxY)
|
||||
maxY = (float?)vert.Y;
|
||||
if (maxZ is null || vert.Z > maxZ)
|
||||
maxZ = (float?)vert.Z;
|
||||
if (minX is null || vert.X < minX)
|
||||
minX = (float?)vert.X;
|
||||
if (minY is null || vert.Y < minY)
|
||||
minY = (float?)vert.Y;
|
||||
if (minZ is null || vert.Z < minZ)
|
||||
minZ = (float?)vert.Z;
|
||||
}
|
||||
}
|
||||
|
||||
if (maxX is null)
|
||||
maxX = 0;
|
||||
if (maxY is null)
|
||||
maxY = 0;
|
||||
if (maxZ is null)
|
||||
maxZ = 0;
|
||||
if (minX is null)
|
||||
minX = 0;
|
||||
if (minY is null)
|
||||
minY = 0;
|
||||
if (minZ is null)
|
||||
minZ = 0;
|
||||
return new ModelBoundaries(new Vector3((float)maxX, (float)maxY, (float)maxZ), new Vector3((float)minX, (float)minY, (float)minZ));
|
||||
}
|
||||
|
||||
public void SetNullVertices()
|
||||
{
|
||||
var newVert = new Vertex() { X = 0d, Y = 0d, Z = 0d };
|
||||
int nullCounter;
|
||||
foreach (Mesh m in Meshes)
|
||||
{
|
||||
nullCounter = 0;
|
||||
foreach (Face f in m.Faces)
|
||||
{
|
||||
foreach (Point p in f.Points)
|
||||
{
|
||||
if (p.Vertex is null)
|
||||
{
|
||||
p.Vertex = newVert;
|
||||
nullCounter += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (nullCounter > 0)
|
||||
{
|
||||
m.Vertices.Add(newVert);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void SetNullUVs()
|
||||
{
|
||||
var newUV = new UV() { U = 0f, V = 0f };
|
||||
int nullCounter;
|
||||
foreach (Mesh m in Meshes)
|
||||
{
|
||||
nullCounter = 0;
|
||||
foreach (Face f in m.Faces)
|
||||
{
|
||||
foreach (Point p in f.Points)
|
||||
{
|
||||
if (p.UV is null)
|
||||
{
|
||||
p.UV = newUV;
|
||||
nullCounter += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (nullCounter > 0)
|
||||
{
|
||||
m.UVs.Add(newUV);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void SetNullNormals()
|
||||
{
|
||||
var newNormal = new Normal() { X = 0f, Y = 0f, Z = 1f };
|
||||
int nullCounter;
|
||||
foreach (Mesh m in Meshes)
|
||||
{
|
||||
nullCounter = 0;
|
||||
foreach (Face f in m.Faces)
|
||||
{
|
||||
foreach (Point p in f.Points)
|
||||
{
|
||||
if (p.Normal is null)
|
||||
{
|
||||
p.Normal = newNormal;
|
||||
nullCounter += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (nullCounter > 0)
|
||||
{
|
||||
m.Normals.Add(newNormal);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void RemoveUnusedMaterials()
|
||||
{
|
||||
// Dim usedMats As New List(Of Material)
|
||||
// Dim unusedMats As New List(Of String)
|
||||
|
||||
// For Each f As Face In Faces
|
||||
// If Not usedMats.Contains(f.Material) Then
|
||||
// usedMats.Add(f.Material)
|
||||
// End If
|
||||
// Next
|
||||
|
||||
// For Each kvp As KeyValuePair(Of String, Material) In Materials
|
||||
// If Not usedMats.Contains(kvp.Value) Then
|
||||
// unusedMats.Add(kvp.Key)
|
||||
// End If
|
||||
// Next
|
||||
|
||||
// For Each k As String In unusedMats
|
||||
// Materials.Remove(k)
|
||||
// Next
|
||||
}
|
||||
|
||||
public Object3D ToOneMesh()
|
||||
{
|
||||
var newObject3D = new Object3D();
|
||||
var newMesh = new Mesh();
|
||||
foreach (KeyValuePair<string, Material> mat in Materials)
|
||||
newObject3D.Materials.Add(mat.Key, mat.Value);
|
||||
foreach (Mesh m in Meshes)
|
||||
{
|
||||
foreach (Vertex v in m.Vertices)
|
||||
newMesh.Vertices.Add(v);
|
||||
foreach (VertexColor vc in m.VertexColors)
|
||||
newMesh.VertexColors.Add(vc);
|
||||
foreach (Normal n in m.Normals)
|
||||
newMesh.Normals.Add(n);
|
||||
foreach (UV uv in m.UVs)
|
||||
newMesh.UVs.Add(uv);
|
||||
foreach (Face f in m.Faces)
|
||||
newMesh.Faces.Add(f);
|
||||
}
|
||||
|
||||
newObject3D.Meshes.Add(newMesh);
|
||||
return newObject3D;
|
||||
}
|
||||
|
||||
public void CenterModel()
|
||||
{
|
||||
Mesh.CenterModel(Meshes);
|
||||
}
|
||||
|
||||
public static void CenterModel(IEnumerable<Object3D> objs)
|
||||
{
|
||||
var meshes = new List<Mesh>();
|
||||
foreach (Object3D obj in objs)
|
||||
meshes.AddRange(obj.Meshes);
|
||||
Mesh.CenterModel(meshes);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,195 +0,0 @@
|
||||
Imports System.IO
|
||||
Imports System.Numerics
|
||||
|
||||
Public Class Object3D
|
||||
|
||||
Public ReadOnly Property Meshes As New List(Of Mesh)
|
||||
Public ReadOnly Property Materials As New Dictionary(Of String, Material)
|
||||
Public Property Shading As New Shading
|
||||
|
||||
Public Sub ScaleModel(factor As Single)
|
||||
For Each m As Mesh In Meshes
|
||||
For Each v As Vertex In m.Vertices
|
||||
v.X *= factor
|
||||
v.Y *= factor
|
||||
v.Z *= factor
|
||||
Next
|
||||
Next
|
||||
End Sub
|
||||
|
||||
Public Sub OffsetModel(off As Vector3)
|
||||
For Each m As Mesh In Meshes
|
||||
For Each v As Vertex In m.Vertices
|
||||
v.X += off.X
|
||||
v.Y += off.Y
|
||||
v.Z += off.Z
|
||||
Next
|
||||
Next
|
||||
End Sub
|
||||
|
||||
Public Function GetBoundaries() As ModelBoundaries
|
||||
Dim maxX As Single? = Nothing
|
||||
Dim maxY As Single? = Nothing
|
||||
Dim maxZ As Single? = Nothing
|
||||
Dim minX As Single? = Nothing
|
||||
Dim minY As Single? = Nothing
|
||||
Dim minZ As Single? = Nothing
|
||||
|
||||
For Each m As Mesh In Meshes
|
||||
For Each vert As Vertex In m.Vertices
|
||||
If maxX Is Nothing OrElse vert.X > maxX Then maxX = vert.X
|
||||
If maxY Is Nothing OrElse vert.Y > maxY Then maxY = vert.Y
|
||||
If maxZ Is Nothing OrElse vert.Z > maxZ Then maxZ = vert.Z
|
||||
If minX Is Nothing OrElse vert.X < minX Then minX = vert.X
|
||||
If minY Is Nothing OrElse vert.Y < minY Then minY = vert.Y
|
||||
If minZ Is Nothing OrElse vert.Z < minZ Then minZ = vert.Z
|
||||
Next
|
||||
Next
|
||||
|
||||
If maxX Is Nothing Then maxX = 0
|
||||
If maxY Is Nothing Then maxY = 0
|
||||
If maxZ Is Nothing Then maxZ = 0
|
||||
If minX Is Nothing Then minX = 0
|
||||
If minY Is Nothing Then minY = 0
|
||||
If minZ Is Nothing Then minZ = 0
|
||||
|
||||
Return New ModelBoundaries(New Vector3(maxX, maxY, maxZ),
|
||||
New Vector3(minX, minY, minZ))
|
||||
End Function
|
||||
|
||||
Public Sub SetNullVertices()
|
||||
Dim newVert As New Vertex With {.X = 0, .Y = 0, .Z = 0}
|
||||
Dim nullCounter As Integer
|
||||
|
||||
For Each m As Mesh In Meshes
|
||||
nullCounter = 0
|
||||
|
||||
For Each f As Face In m.Faces
|
||||
For Each p As Point In f.Points
|
||||
If p.Vertex Is Nothing Then
|
||||
p.Vertex = newVert
|
||||
nullCounter += 1
|
||||
End If
|
||||
Next
|
||||
Next
|
||||
|
||||
If nullCounter > 0 Then
|
||||
m.Vertices.Add(newVert)
|
||||
End If
|
||||
Next
|
||||
End Sub
|
||||
|
||||
Public Sub SetNullUVs()
|
||||
Dim newUV As New UV With {.U = 0, .V = 0}
|
||||
Dim nullCounter As Integer
|
||||
|
||||
For Each m As Mesh In Meshes
|
||||
nullCounter = 0
|
||||
|
||||
For Each f As Face In m.Faces
|
||||
For Each p As Point In f.Points
|
||||
If p.UV Is Nothing Then
|
||||
p.UV = newUV
|
||||
nullCounter += 1
|
||||
End If
|
||||
Next
|
||||
Next
|
||||
|
||||
If nullCounter > 0 Then
|
||||
m.UVs.Add(newUV)
|
||||
End If
|
||||
Next
|
||||
End Sub
|
||||
|
||||
Public Sub SetNullNormals()
|
||||
Dim newNormal As New Normal With {.X = 0, .Y = 0, .Z = 1}
|
||||
Dim nullCounter As Integer
|
||||
|
||||
For Each m As Mesh In Meshes
|
||||
nullCounter = 0
|
||||
|
||||
For Each f As Face In m.Faces
|
||||
For Each p As Point In f.Points
|
||||
If p.Normal Is Nothing Then
|
||||
p.Normal = newNormal
|
||||
nullCounter += 1
|
||||
End If
|
||||
Next
|
||||
Next
|
||||
|
||||
If nullCounter > 0 Then
|
||||
m.Normals.Add(newNormal)
|
||||
End If
|
||||
Next
|
||||
End Sub
|
||||
|
||||
Public Sub RemoveUnusedMaterials()
|
||||
'Dim usedMats As New List(Of Material)
|
||||
'Dim unusedMats As New List(Of String)
|
||||
|
||||
'For Each f As Face In Faces
|
||||
' If Not usedMats.Contains(f.Material) Then
|
||||
' usedMats.Add(f.Material)
|
||||
' End If
|
||||
'Next
|
||||
|
||||
'For Each kvp As KeyValuePair(Of String, Material) In Materials
|
||||
' If Not usedMats.Contains(kvp.Value) Then
|
||||
' unusedMats.Add(kvp.Key)
|
||||
' End If
|
||||
'Next
|
||||
|
||||
'For Each k As String In unusedMats
|
||||
' Materials.Remove(k)
|
||||
'Next
|
||||
End Sub
|
||||
|
||||
Public Function ToOneMesh() As Object3D
|
||||
Dim newObject3D As New Object3D
|
||||
Dim newMesh As New Mesh
|
||||
|
||||
For Each mat As KeyValuePair(Of String, Material) In Materials
|
||||
newObject3D.Materials.Add(mat.Key, mat.Value)
|
||||
Next
|
||||
|
||||
For Each m As Mesh In Meshes
|
||||
For Each v As Vertex In m.Vertices
|
||||
newMesh.Vertices.Add(v)
|
||||
Next
|
||||
|
||||
For Each vc As VertexColor In m.VertexColors
|
||||
newMesh.VertexColors.Add(vc)
|
||||
Next
|
||||
|
||||
For Each n As Normal In m.Normals
|
||||
newMesh.Normals.Add(n)
|
||||
Next
|
||||
|
||||
For Each uv As UV In m.UVs
|
||||
newMesh.UVs.Add(uv)
|
||||
Next
|
||||
|
||||
For Each f As Face In m.Faces
|
||||
newMesh.Faces.Add(f)
|
||||
Next
|
||||
Next
|
||||
|
||||
newObject3D.Meshes.Add(newMesh)
|
||||
Return newObject3D
|
||||
End Function
|
||||
|
||||
Public Sub CenterModel()
|
||||
Mesh.CenterModel(Meshes)
|
||||
End Sub
|
||||
|
||||
Public Shared Sub CenterModel(objs As IEnumerable(Of Object3D))
|
||||
Dim meshes As New List(Of Mesh)
|
||||
|
||||
For Each obj As Object3D In objs
|
||||
meshes.AddRange(obj.Meshes)
|
||||
Next
|
||||
|
||||
Mesh.CenterModel(meshes)
|
||||
End Sub
|
||||
|
||||
End Class
|
||||
11
Pilz.Simple3DFileParser/Model/Point.cs
Normal file
11
Pilz.Simple3DFileParser/Model/Point.cs
Normal file
@@ -0,0 +1,11 @@
|
||||
|
||||
namespace Pilz.S3DFileParser
|
||||
{
|
||||
public class Point
|
||||
{
|
||||
public Vertex Vertex { get; set; } = null;
|
||||
public UV UV { get; set; } = null;
|
||||
public VertexColor VertexColor { get; set; } = null;
|
||||
public Normal Normal { get; set; } = null;
|
||||
}
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
Public Class Point
|
||||
Public Property Vertex As Vertex = Nothing
|
||||
Public Property UV As UV = Nothing
|
||||
Public Property VertexColor As VertexColor = Nothing
|
||||
Public Property Normal As Normal = Nothing
|
||||
End Class
|
||||
12
Pilz.Simple3DFileParser/Model/Shading.cs
Normal file
12
Pilz.Simple3DFileParser/Model/Shading.cs
Normal file
@@ -0,0 +1,12 @@
|
||||
using System;
|
||||
using System.Drawing;
|
||||
|
||||
namespace Pilz.S3DFileParser
|
||||
{
|
||||
public class Shading
|
||||
{
|
||||
public Color AmbientColor { get; set; } = Color.FromArgb(Convert.ToInt32(0xFFFFFFFF));
|
||||
public Color DiffuseColor { get; set; } = Color.FromArgb(Convert.ToInt32(0xFF7F7F7F));
|
||||
public Vertex DiffusePosition { get; set; } = null;
|
||||
}
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
Public Class Shading
|
||||
Public Property AmbientColor As Color = Color.FromArgb(&HFFFFFFFF)
|
||||
Public Property DiffuseColor As Color = Color.FromArgb(&HFF7F7F7F)
|
||||
Public Property DiffusePosition As Vertex = Nothing
|
||||
End Class
|
||||
9
Pilz.Simple3DFileParser/Model/UV.cs
Normal file
9
Pilz.Simple3DFileParser/Model/UV.cs
Normal file
@@ -0,0 +1,9 @@
|
||||
|
||||
namespace Pilz.S3DFileParser
|
||||
{
|
||||
public class UV
|
||||
{
|
||||
public float U { get; set; } = 0f;
|
||||
public float V { get; set; } = 0f;
|
||||
}
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
Public Class UV
|
||||
Public Property U As Single = 0
|
||||
Public Property V As Single = 0
|
||||
End Class
|
||||
9
Pilz.Simple3DFileParser/Model/UpAxis.cs
Normal file
9
Pilz.Simple3DFileParser/Model/UpAxis.cs
Normal file
@@ -0,0 +1,9 @@
|
||||
|
||||
namespace Pilz.S3DFileParser
|
||||
{
|
||||
public enum UpAxis
|
||||
{
|
||||
Y,
|
||||
Z
|
||||
}
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
Public Enum UpAxis
|
||||
Y
|
||||
Z
|
||||
End Enum
|
||||
10
Pilz.Simple3DFileParser/Model/Vertex.cs
Normal file
10
Pilz.Simple3DFileParser/Model/Vertex.cs
Normal file
@@ -0,0 +1,10 @@
|
||||
|
||||
namespace Pilz.S3DFileParser
|
||||
{
|
||||
public class Vertex
|
||||
{
|
||||
public double X { get; set; } = 0d;
|
||||
public double Y { get; set; } = 0d;
|
||||
public double Z { get; set; } = 0d;
|
||||
}
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
Public Class Vertex
|
||||
Public Property X As Double = 0
|
||||
Public Property Y As Double = 0
|
||||
Public Property Z As Double = 0
|
||||
End Class
|
||||
11
Pilz.Simple3DFileParser/Model/VertexColor.cs
Normal file
11
Pilz.Simple3DFileParser/Model/VertexColor.cs
Normal file
@@ -0,0 +1,11 @@
|
||||
|
||||
namespace Pilz.S3DFileParser
|
||||
{
|
||||
public class VertexColor
|
||||
{
|
||||
public float R { get; set; } = 1f;
|
||||
public float G { get; set; } = 1f;
|
||||
public float B { get; set; } = 1f;
|
||||
public float A { get; set; } = 1f;
|
||||
}
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
Public Class VertexColor
|
||||
Public Property R As Single = 1
|
||||
Public Property G As Single = 1
|
||||
Public Property B As Single = 1
|
||||
Public Property A As Single = 1
|
||||
End Class
|
||||
11
Pilz.Simple3DFileParser/My Project/Application.Designer.cs
generated
Normal file
11
Pilz.Simple3DFileParser/My Project/Application.Designer.cs
generated
Normal file
@@ -0,0 +1,11 @@
|
||||
// ------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// Dieser Code wurde von einem Tool generiert.
|
||||
// Laufzeitversion:4.0.30319.42000
|
||||
//
|
||||
// Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn
|
||||
// der Code erneut generiert wird.
|
||||
// </auto-generated>
|
||||
// ------------------------------------------------------------------------------
|
||||
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
'------------------------------------------------------------------------------
|
||||
' <auto-generated>
|
||||
' Dieser Code wurde von einem Tool generiert.
|
||||
' Laufzeitversion:4.0.30319.42000
|
||||
'
|
||||
' Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn
|
||||
' der Code erneut generiert wird.
|
||||
' </auto-generated>
|
||||
'------------------------------------------------------------------------------
|
||||
|
||||
Option Strict On
|
||||
Option Explicit On
|
||||
|
||||
35
Pilz.Simple3DFileParser/My Project/AssemblyInfo.cs
Normal file
35
Pilz.Simple3DFileParser/My Project/AssemblyInfo.cs
Normal file
@@ -0,0 +1,35 @@
|
||||
using global::System;
|
||||
using global::System.Reflection;
|
||||
using global::System.Runtime.InteropServices;
|
||||
|
||||
// Allgemeine Informationen über eine Assembly werden über die folgenden
|
||||
// Attribute gesteuert. Ändern Sie diese Attributwerte, um die Informationen zu ändern,
|
||||
// die einer Assembly zugeordnet sind.
|
||||
|
||||
// Werte der Assemblyattribute überprüfen
|
||||
|
||||
[assembly: AssemblyTitle("SimpleFileParser")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyCompany("Pilzinsel64")]
|
||||
[assembly: AssemblyProduct("SM64 ROM Manager")]
|
||||
[assembly: AssemblyCopyright("Copyright © Pilzinsel64 2018")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// Die folgende GUID bestimmt die ID der Typbibliothek, wenn dieses Projekt für COM verfügbar gemacht wird.
|
||||
[assembly: Guid("21610485-a96f-4808-bf2e-bbf06c65eba1")]
|
||||
|
||||
// Versionsinformationen für eine Assembly bestehen aus den folgenden vier Werten:
|
||||
//
|
||||
// Hauptversion
|
||||
// Nebenversion
|
||||
// Buildnummer
|
||||
// Revision
|
||||
//
|
||||
// Sie können alle Werte angeben oder Standardwerte für die Build- und Revisionsnummern verwenden,
|
||||
// übernehmen, indem Sie "*" eingeben:
|
||||
// <Assembly: AssemblyVersion("1.0.*")>
|
||||
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
Imports System
|
||||
Imports System.Reflection
|
||||
Imports System.Runtime.InteropServices
|
||||
|
||||
' Allgemeine Informationen über eine Assembly werden über die folgenden
|
||||
' Attribute gesteuert. Ändern Sie diese Attributwerte, um die Informationen zu ändern,
|
||||
' die einer Assembly zugeordnet sind.
|
||||
|
||||
' Werte der Assemblyattribute überprüfen
|
||||
|
||||
<Assembly: AssemblyTitle("SimpleFileParser")>
|
||||
<Assembly: AssemblyDescription("")>
|
||||
<Assembly: AssemblyCompany("Pilzinsel64")>
|
||||
<Assembly: AssemblyProduct("SM64 ROM Manager")>
|
||||
<Assembly: AssemblyCopyright("Copyright © Pilzinsel64 2018")>
|
||||
<Assembly: AssemblyTrademark("")>
|
||||
|
||||
<Assembly: ComVisible(False)>
|
||||
|
||||
'Die folgende GUID bestimmt die ID der Typbibliothek, wenn dieses Projekt für COM verfügbar gemacht wird.
|
||||
<Assembly: Guid("21610485-a96f-4808-bf2e-bbf06c65eba1")>
|
||||
|
||||
' Versionsinformationen für eine Assembly bestehen aus den folgenden vier Werten:
|
||||
'
|
||||
' Hauptversion
|
||||
' Nebenversion
|
||||
' Buildnummer
|
||||
' Revision
|
||||
'
|
||||
' Sie können alle Werte angeben oder Standardwerte für die Build- und Revisionsnummern verwenden,
|
||||
' übernehmen, indem Sie "*" eingeben:
|
||||
' <Assembly: AssemblyVersion("1.0.*")>
|
||||
|
||||
<Assembly: AssemblyVersion("1.0.0.0")>
|
||||
<Assembly: AssemblyFileVersion("1.0.0.0")>
|
||||
192
Pilz.Simple3DFileParser/My Project/MyNamespace.Static.1.Designer.cs
generated
Normal file
192
Pilz.Simple3DFileParser/My Project/MyNamespace.Static.1.Designer.cs
generated
Normal file
@@ -0,0 +1,192 @@
|
||||
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using Microsoft.VisualBasic;
|
||||
|
||||
/* TODO ERROR: Skipped IfDirectiveTrivia *//* TODO ERROR: Skipped DisabledTextTrivia *//* TODO ERROR: Skipped EndIfDirectiveTrivia */
|
||||
/* TODO ERROR: Skipped IfDirectiveTrivia *//* TODO ERROR: Skipped DisabledTextTrivia *//* TODO ERROR: Skipped ElifDirectiveTrivia *//* TODO ERROR: Skipped DisabledTextTrivia *//* TODO ERROR: Skipped ElifDirectiveTrivia */
|
||||
/* TODO ERROR: Skipped DefineDirectiveTrivia *//* TODO ERROR: Skipped DefineDirectiveTrivia *//* TODO ERROR: Skipped DefineDirectiveTrivia *//* TODO ERROR: Skipped DefineDirectiveTrivia */
|
||||
/* TODO ERROR: Skipped ElifDirectiveTrivia *//* TODO ERROR: Skipped DisabledTextTrivia *//* TODO ERROR: Skipped ElifDirectiveTrivia *//* TODO ERROR: Skipped DisabledTextTrivia *//* TODO ERROR: Skipped ElifDirectiveTrivia *//* TODO ERROR: Skipped DisabledTextTrivia *//* TODO ERROR: Skipped ElifDirectiveTrivia *//* TODO ERROR: Skipped DisabledTextTrivia *//* TODO ERROR: Skipped ElifDirectiveTrivia *//* TODO ERROR: Skipped DisabledTextTrivia *//* TODO ERROR: Skipped EndIfDirectiveTrivia */
|
||||
/* TODO ERROR: Skipped IfDirectiveTrivia */
|
||||
namespace Pilz.S3DFileParser.My
|
||||
{
|
||||
|
||||
/* TODO ERROR: Skipped IfDirectiveTrivia */
|
||||
[System.CodeDom.Compiler.GeneratedCode("MyTemplate", "11.0.0.0")]
|
||||
[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
|
||||
|
||||
/* TODO ERROR: Skipped IfDirectiveTrivia *//* TODO ERROR: Skipped DisabledTextTrivia *//* TODO ERROR: Skipped ElifDirectiveTrivia */
|
||||
internal partial class MyApplication : Microsoft.VisualBasic.ApplicationServices.ApplicationBase
|
||||
{
|
||||
/* TODO ERROR: Skipped ElifDirectiveTrivia *//* TODO ERROR: Skipped DisabledTextTrivia *//* TODO ERROR: Skipped EndIfDirectiveTrivia */
|
||||
}
|
||||
|
||||
/* TODO ERROR: Skipped EndIfDirectiveTrivia */
|
||||
/* TODO ERROR: Skipped IfDirectiveTrivia */
|
||||
[System.CodeDom.Compiler.GeneratedCode("MyTemplate", "11.0.0.0")]
|
||||
[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
|
||||
|
||||
/* TODO ERROR: Skipped IfDirectiveTrivia */
|
||||
internal partial class MyComputer : Microsoft.VisualBasic.Devices.Computer
|
||||
{
|
||||
/* TODO ERROR: Skipped ElifDirectiveTrivia *//* TODO ERROR: Skipped DisabledTextTrivia *//* TODO ERROR: Skipped EndIfDirectiveTrivia */
|
||||
[DebuggerHidden()]
|
||||
[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
|
||||
public MyComputer() : base()
|
||||
{
|
||||
}
|
||||
}
|
||||
/* TODO ERROR: Skipped EndIfDirectiveTrivia */
|
||||
[HideModuleName()]
|
||||
[System.CodeDom.Compiler.GeneratedCode("MyTemplate", "11.0.0.0")]
|
||||
internal static class MyProject
|
||||
{
|
||||
|
||||
/* TODO ERROR: Skipped IfDirectiveTrivia */
|
||||
[System.ComponentModel.Design.HelpKeyword("My.Computer")]
|
||||
internal static MyComputer Computer
|
||||
{
|
||||
[DebuggerHidden()]
|
||||
get
|
||||
{
|
||||
return m_ComputerObjectProvider.GetInstance;
|
||||
}
|
||||
}
|
||||
|
||||
private readonly static ThreadSafeObjectProvider<MyComputer> m_ComputerObjectProvider = new ThreadSafeObjectProvider<MyComputer>();
|
||||
/* TODO ERROR: Skipped EndIfDirectiveTrivia */
|
||||
/* TODO ERROR: Skipped IfDirectiveTrivia */
|
||||
[System.ComponentModel.Design.HelpKeyword("My.Application")]
|
||||
internal static MyApplication Application
|
||||
{
|
||||
[DebuggerHidden()]
|
||||
get
|
||||
{
|
||||
return m_AppObjectProvider.GetInstance;
|
||||
}
|
||||
}
|
||||
|
||||
private readonly static ThreadSafeObjectProvider<MyApplication> m_AppObjectProvider = new ThreadSafeObjectProvider<MyApplication>();
|
||||
/* TODO ERROR: Skipped EndIfDirectiveTrivia */
|
||||
/* TODO ERROR: Skipped IfDirectiveTrivia */
|
||||
[System.ComponentModel.Design.HelpKeyword("My.User")]
|
||||
internal static Microsoft.VisualBasic.ApplicationServices.User User
|
||||
{
|
||||
[DebuggerHidden()]
|
||||
get
|
||||
{
|
||||
return m_UserObjectProvider.GetInstance;
|
||||
}
|
||||
}
|
||||
|
||||
private readonly static ThreadSafeObjectProvider<Microsoft.VisualBasic.ApplicationServices.User> m_UserObjectProvider = new ThreadSafeObjectProvider<Microsoft.VisualBasic.ApplicationServices.User>();
|
||||
/* TODO ERROR: Skipped ElifDirectiveTrivia *//* TODO ERROR: Skipped DisabledTextTrivia *//* TODO ERROR: Skipped EndIfDirectiveTrivia */
|
||||
/* TODO ERROR: Skipped IfDirectiveTrivia *//* TODO ERROR: Skipped DisabledTextTrivia *//* TODO ERROR: Skipped EndIfDirectiveTrivia */
|
||||
/* TODO ERROR: Skipped IfDirectiveTrivia */
|
||||
[System.ComponentModel.Design.HelpKeyword("My.WebServices")]
|
||||
internal static MyWebServices WebServices
|
||||
{
|
||||
[DebuggerHidden()]
|
||||
get
|
||||
{
|
||||
return m_MyWebServicesObjectProvider.GetInstance;
|
||||
}
|
||||
}
|
||||
|
||||
[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
|
||||
[MyGroupCollection("System.Web.Services.Protocols.SoapHttpClientProtocol", "Create__Instance__", "Dispose__Instance__", "")]
|
||||
internal sealed class MyWebServices
|
||||
{
|
||||
[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
|
||||
[DebuggerHidden()]
|
||||
public override bool Equals(object o)
|
||||
{
|
||||
return base.Equals(o);
|
||||
}
|
||||
|
||||
[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
|
||||
[DebuggerHidden()]
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return base.GetHashCode();
|
||||
}
|
||||
|
||||
[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
|
||||
[DebuggerHidden()]
|
||||
internal new Type GetType()
|
||||
{
|
||||
return typeof(MyWebServices);
|
||||
}
|
||||
|
||||
[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
|
||||
[DebuggerHidden()]
|
||||
public override string ToString()
|
||||
{
|
||||
return base.ToString();
|
||||
}
|
||||
|
||||
[DebuggerHidden()]
|
||||
private static T Create__Instance__<T>(T instance) where T : new()
|
||||
{
|
||||
if (instance == null)
|
||||
{
|
||||
return new T();
|
||||
}
|
||||
else
|
||||
{
|
||||
return instance;
|
||||
}
|
||||
}
|
||||
|
||||
[DebuggerHidden()]
|
||||
private void Dispose__Instance__<T>(ref T instance)
|
||||
{
|
||||
instance = default;
|
||||
}
|
||||
|
||||
[DebuggerHidden()]
|
||||
[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
|
||||
public MyWebServices() : base()
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
private readonly static ThreadSafeObjectProvider<MyWebServices> m_MyWebServicesObjectProvider = new ThreadSafeObjectProvider<MyWebServices>();
|
||||
/* TODO ERROR: Skipped EndIfDirectiveTrivia */
|
||||
/* TODO ERROR: Skipped IfDirectiveTrivia *//* TODO ERROR: Skipped DisabledTextTrivia *//* TODO ERROR: Skipped EndIfDirectiveTrivia */
|
||||
[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
|
||||
[System.Runtime.InteropServices.ComVisible(false)]
|
||||
internal sealed class ThreadSafeObjectProvider<T> where T : new()
|
||||
{
|
||||
internal T GetInstance
|
||||
{
|
||||
/* TODO ERROR: Skipped IfDirectiveTrivia */
|
||||
[DebuggerHidden()]
|
||||
get
|
||||
{
|
||||
var Value = m_Context.Value;
|
||||
if (Value == null)
|
||||
{
|
||||
Value = new T();
|
||||
m_Context.Value = Value;
|
||||
}
|
||||
|
||||
return Value;
|
||||
}
|
||||
/* TODO ERROR: Skipped ElseDirectiveTrivia *//* TODO ERROR: Skipped DisabledTextTrivia *//* TODO ERROR: Skipped EndIfDirectiveTrivia */
|
||||
}
|
||||
|
||||
[DebuggerHidden()]
|
||||
[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
|
||||
public ThreadSafeObjectProvider() : base()
|
||||
{
|
||||
}
|
||||
|
||||
/* TODO ERROR: Skipped IfDirectiveTrivia */
|
||||
private readonly Microsoft.VisualBasic.MyServices.Internal.ContextValue<T> m_Context = new Microsoft.VisualBasic.MyServices.Internal.ContextValue<T>();
|
||||
/* TODO ERROR: Skipped ElseDirectiveTrivia *//* TODO ERROR: Skipped DisabledTextTrivia *//* TODO ERROR: Skipped EndIfDirectiveTrivia */
|
||||
}
|
||||
}
|
||||
}
|
||||
/* TODO ERROR: Skipped EndIfDirectiveTrivia */
|
||||
253
Pilz.Simple3DFileParser/My Project/MyNamespace.Static.2.Designer.cs
generated
Normal file
253
Pilz.Simple3DFileParser/My Project/MyNamespace.Static.2.Designer.cs
generated
Normal file
@@ -0,0 +1,253 @@
|
||||
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
// See Compiler::LoadXmlSolutionExtension
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Xml.Linq;
|
||||
using Microsoft.VisualBasic;
|
||||
using Microsoft.VisualBasic.CompilerServices;
|
||||
|
||||
namespace Pilz.S3DFileParser.My
|
||||
{
|
||||
[Embedded()]
|
||||
[DebuggerNonUserCode()]
|
||||
[System.Runtime.CompilerServices.CompilerGenerated()]
|
||||
[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
|
||||
internal sealed class InternalXmlHelper
|
||||
{
|
||||
[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
|
||||
private InternalXmlHelper()
|
||||
{
|
||||
}
|
||||
|
||||
public static string get_Value(IEnumerable<XElement> source)
|
||||
{
|
||||
foreach (XElement item in source)
|
||||
return item.Value;
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void set_Value(IEnumerable<XElement> source, string value)
|
||||
{
|
||||
foreach (XElement item in source)
|
||||
{
|
||||
item.Value = value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public static string get_AttributeValue(IEnumerable<XElement> source, XName name)
|
||||
{
|
||||
foreach (XElement item in source)
|
||||
return Conversions.ToString(item.Attribute(name));
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void set_AttributeValue(IEnumerable<XElement> source, XName name, string value)
|
||||
{
|
||||
foreach (XElement item in source)
|
||||
{
|
||||
item.SetAttributeValue(name, value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public static string get_AttributeValue(XElement source, XName name)
|
||||
{
|
||||
return Conversions.ToString(source.Attribute(name));
|
||||
}
|
||||
|
||||
public static void set_AttributeValue(XElement source, XName name, string value)
|
||||
{
|
||||
source.SetAttributeValue(name, value);
|
||||
}
|
||||
|
||||
[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
|
||||
public static XAttribute CreateAttribute(XName name, object value)
|
||||
{
|
||||
if (value is null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return new XAttribute(name, value);
|
||||
}
|
||||
|
||||
[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
|
||||
public static XAttribute CreateNamespaceAttribute(XName name, XNamespace ns)
|
||||
{
|
||||
var a = new XAttribute(name, ns.NamespaceName);
|
||||
a.AddAnnotation(ns);
|
||||
return a;
|
||||
}
|
||||
|
||||
[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
|
||||
public static object RemoveNamespaceAttributes(string[] inScopePrefixes, XNamespace[] inScopeNs, List<XAttribute> attributes, object obj)
|
||||
{
|
||||
if (obj is object)
|
||||
{
|
||||
XElement elem = obj as XElement;
|
||||
if (elem is object)
|
||||
{
|
||||
return RemoveNamespaceAttributes(inScopePrefixes, inScopeNs, attributes, elem);
|
||||
}
|
||||
else
|
||||
{
|
||||
IEnumerable elems = obj as IEnumerable;
|
||||
if (elems is object)
|
||||
{
|
||||
return RemoveNamespaceAttributes(inScopePrefixes, inScopeNs, attributes, elems);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
|
||||
public static IEnumerable RemoveNamespaceAttributes(string[] inScopePrefixes, XNamespace[] inScopeNs, List<XAttribute> attributes, IEnumerable obj)
|
||||
{
|
||||
if (obj is object)
|
||||
{
|
||||
IEnumerable<XElement> elems = obj as IEnumerable<XElement>;
|
||||
if (elems is object)
|
||||
{
|
||||
return elems.Select(new RemoveNamespaceAttributesClosure(inScopePrefixes, inScopeNs, attributes).ProcessXElement);
|
||||
}
|
||||
else
|
||||
{
|
||||
return obj.Cast<object>().Select(new RemoveNamespaceAttributesClosure(inScopePrefixes, inScopeNs, attributes).ProcessObject);
|
||||
}
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
[DebuggerNonUserCode()]
|
||||
[System.Runtime.CompilerServices.CompilerGenerated()]
|
||||
[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
|
||||
private sealed class RemoveNamespaceAttributesClosure
|
||||
{
|
||||
private readonly string[] m_inScopePrefixes;
|
||||
private readonly XNamespace[] m_inScopeNs;
|
||||
private readonly List<XAttribute> m_attributes;
|
||||
|
||||
[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
|
||||
internal RemoveNamespaceAttributesClosure(string[] inScopePrefixes, XNamespace[] inScopeNs, List<XAttribute> attributes)
|
||||
{
|
||||
m_inScopePrefixes = inScopePrefixes;
|
||||
m_inScopeNs = inScopeNs;
|
||||
m_attributes = attributes;
|
||||
}
|
||||
|
||||
[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
|
||||
internal XElement ProcessXElement(XElement elem)
|
||||
{
|
||||
return RemoveNamespaceAttributes(m_inScopePrefixes, m_inScopeNs, m_attributes, elem);
|
||||
}
|
||||
|
||||
[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
|
||||
internal object ProcessObject(object obj)
|
||||
{
|
||||
XElement elem = obj as XElement;
|
||||
if (elem is object)
|
||||
{
|
||||
return RemoveNamespaceAttributes(m_inScopePrefixes, m_inScopeNs, m_attributes, elem);
|
||||
}
|
||||
else
|
||||
{
|
||||
return obj;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
|
||||
public static XElement RemoveNamespaceAttributes(string[] inScopePrefixes, XNamespace[] inScopeNs, List<XAttribute> attributes, XElement e)
|
||||
{
|
||||
if (e is object)
|
||||
{
|
||||
var a = e.FirstAttribute;
|
||||
while (a is object)
|
||||
{
|
||||
var nextA = a.NextAttribute;
|
||||
if (a.IsNamespaceDeclaration)
|
||||
{
|
||||
var ns = a.Annotation<XNamespace>();
|
||||
string prefix = a.Name.LocalName;
|
||||
if (ns is object)
|
||||
{
|
||||
if (inScopePrefixes is object && inScopeNs is object)
|
||||
{
|
||||
int lastIndex = inScopePrefixes.Length - 1;
|
||||
for (int i = 0, loopTo = lastIndex; i <= loopTo; i++)
|
||||
{
|
||||
string currentInScopePrefix = inScopePrefixes[i];
|
||||
var currentInScopeNs = inScopeNs[i];
|
||||
if (prefix.Equals(currentInScopePrefix))
|
||||
{
|
||||
if (ns == currentInScopeNs)
|
||||
{
|
||||
// prefix and namespace match. Remove the unneeded ns attribute
|
||||
a.Remove();
|
||||
}
|
||||
|
||||
// prefix is in scope but refers to something else. Leave the ns attribute.
|
||||
a = null;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (a is object)
|
||||
{
|
||||
// Prefix is not in scope
|
||||
// Now check whether it's going to be in scope because it is in the attributes list
|
||||
|
||||
if (attributes is object)
|
||||
{
|
||||
int lastIndex = attributes.Count - 1;
|
||||
for (int i = 0, loopTo1 = lastIndex; i <= loopTo1; i++)
|
||||
{
|
||||
var currentA = attributes[i];
|
||||
string currentInScopePrefix = currentA.Name.LocalName;
|
||||
var currentInScopeNs = currentA.Annotation<XNamespace>();
|
||||
if (currentInScopeNs is object)
|
||||
{
|
||||
if (prefix.Equals(currentInScopePrefix))
|
||||
{
|
||||
if (ns == currentInScopeNs)
|
||||
{
|
||||
// prefix and namespace match. Remove the unneeded ns attribute
|
||||
a.Remove();
|
||||
}
|
||||
|
||||
// prefix is in scope but refers to something else. Leave the ns attribute.
|
||||
a = null;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (a is object)
|
||||
{
|
||||
// Prefix is definitely not in scope
|
||||
a.Remove();
|
||||
// namespace is not defined either. Add this attributes list
|
||||
attributes.Add(a);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
a = nextA;
|
||||
}
|
||||
}
|
||||
|
||||
return e;
|
||||
}
|
||||
}
|
||||
}
|
||||
14
Pilz.Simple3DFileParser/My Project/MyNamespace.Static.3.Designer.cs
generated
Normal file
14
Pilz.Simple3DFileParser/My Project/MyNamespace.Static.3.Designer.cs
generated
Normal file
@@ -0,0 +1,14 @@
|
||||
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
|
||||
namespace Microsoft.VisualBasic
|
||||
{
|
||||
[Embedded()]
|
||||
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Module | AttributeTargets.Assembly, Inherited = false)]
|
||||
[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
|
||||
[System.Runtime.CompilerServices.CompilerGenerated()]
|
||||
internal sealed class Embedded : Attribute
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -1,63 +0,0 @@
|
||||
'------------------------------------------------------------------------------
|
||||
' <auto-generated>
|
||||
' Dieser Code wurde von einem Tool generiert.
|
||||
' Laufzeitversion:4.0.30319.42000
|
||||
'
|
||||
' Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn
|
||||
' der Code erneut generiert wird.
|
||||
' </auto-generated>
|
||||
'------------------------------------------------------------------------------
|
||||
|
||||
Option Strict On
|
||||
Option Explicit On
|
||||
|
||||
Imports System
|
||||
|
||||
Namespace My.Resources
|
||||
|
||||
'Diese Klasse wurde von der StronglyTypedResourceBuilder automatisch generiert
|
||||
'-Klasse über ein Tool wie ResGen oder Visual Studio automatisch generiert.
|
||||
'Um einen Member hinzuzufügen oder zu entfernen, bearbeiten Sie die .ResX-Datei und führen dann ResGen
|
||||
'mit der /str-Option erneut aus, oder Sie erstellen Ihr VS-Projekt neu.
|
||||
'''<summary>
|
||||
''' Eine stark typisierte Ressourcenklasse zum Suchen von lokalisierten Zeichenfolgen usw.
|
||||
'''</summary>
|
||||
<Global.System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0"), _
|
||||
Global.System.Diagnostics.DebuggerNonUserCodeAttribute(), _
|
||||
Global.System.Runtime.CompilerServices.CompilerGeneratedAttribute(), _
|
||||
Global.Microsoft.VisualBasic.HideModuleNameAttribute()> _
|
||||
Friend Module Resources
|
||||
|
||||
Private resourceMan As Global.System.Resources.ResourceManager
|
||||
|
||||
Private resourceCulture As Global.System.Globalization.CultureInfo
|
||||
|
||||
'''<summary>
|
||||
''' Gibt die zwischengespeicherte ResourceManager-Instanz zurück, die von dieser Klasse verwendet wird.
|
||||
'''</summary>
|
||||
<Global.System.ComponentModel.EditorBrowsableAttribute(Global.System.ComponentModel.EditorBrowsableState.Advanced)> _
|
||||
Friend ReadOnly Property ResourceManager() As Global.System.Resources.ResourceManager
|
||||
Get
|
||||
If Object.ReferenceEquals(resourceMan, Nothing) Then
|
||||
Dim temp As Global.System.Resources.ResourceManager = New Global.System.Resources.ResourceManager("Pilz.S3DFileParser.Resources", GetType(Resources).Assembly)
|
||||
resourceMan = temp
|
||||
End If
|
||||
Return resourceMan
|
||||
End Get
|
||||
End Property
|
||||
|
||||
'''<summary>
|
||||
''' Überschreibt die CurrentUICulture-Eigenschaft des aktuellen Threads für alle
|
||||
''' Ressourcenzuordnungen, die diese stark typisierte Ressourcenklasse verwenden.
|
||||
'''</summary>
|
||||
<Global.System.ComponentModel.EditorBrowsableAttribute(Global.System.ComponentModel.EditorBrowsableState.Advanced)> _
|
||||
Friend Property Culture() As Global.System.Globalization.CultureInfo
|
||||
Get
|
||||
Return resourceCulture
|
||||
End Get
|
||||
Set
|
||||
resourceCulture = value
|
||||
End Set
|
||||
End Property
|
||||
End Module
|
||||
End Namespace
|
||||
@@ -1,73 +0,0 @@
|
||||
'------------------------------------------------------------------------------
|
||||
' <auto-generated>
|
||||
' Dieser Code wurde von einem Tool generiert.
|
||||
' Laufzeitversion:4.0.30319.42000
|
||||
'
|
||||
' Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn
|
||||
' der Code erneut generiert wird.
|
||||
' </auto-generated>
|
||||
'------------------------------------------------------------------------------
|
||||
|
||||
Option Strict On
|
||||
Option Explicit On
|
||||
|
||||
|
||||
Namespace My
|
||||
|
||||
<Global.System.Runtime.CompilerServices.CompilerGeneratedAttribute(), _
|
||||
Global.System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "15.9.0.0"), _
|
||||
Global.System.ComponentModel.EditorBrowsableAttribute(Global.System.ComponentModel.EditorBrowsableState.Advanced)> _
|
||||
Partial Friend NotInheritable Class MySettings
|
||||
Inherits Global.System.Configuration.ApplicationSettingsBase
|
||||
|
||||
Private Shared defaultInstance As MySettings = CType(Global.System.Configuration.ApplicationSettingsBase.Synchronized(New MySettings()),MySettings)
|
||||
|
||||
#Region "Automatische My.Settings-Speicherfunktion"
|
||||
#If _MyType = "WindowsForms" Then
|
||||
Private Shared addedHandler As Boolean
|
||||
|
||||
Private Shared addedHandlerLockObject As New Object
|
||||
|
||||
<Global.System.Diagnostics.DebuggerNonUserCodeAttribute(), Global.System.ComponentModel.EditorBrowsableAttribute(Global.System.ComponentModel.EditorBrowsableState.Advanced)> _
|
||||
Private Shared Sub AutoSaveSettings(sender As Global.System.Object, e As Global.System.EventArgs)
|
||||
If My.Application.SaveMySettingsOnExit Then
|
||||
My.Settings.Save()
|
||||
End If
|
||||
End Sub
|
||||
#End If
|
||||
#End Region
|
||||
|
||||
Public Shared ReadOnly Property [Default]() As MySettings
|
||||
Get
|
||||
|
||||
#If _MyType = "WindowsForms" Then
|
||||
If Not addedHandler Then
|
||||
SyncLock addedHandlerLockObject
|
||||
If Not addedHandler Then
|
||||
AddHandler My.Application.Shutdown, AddressOf AutoSaveSettings
|
||||
addedHandler = True
|
||||
End If
|
||||
End SyncLock
|
||||
End If
|
||||
#End If
|
||||
Return defaultInstance
|
||||
End Get
|
||||
End Property
|
||||
End Class
|
||||
End Namespace
|
||||
|
||||
Namespace My
|
||||
|
||||
<Global.Microsoft.VisualBasic.HideModuleNameAttribute(), _
|
||||
Global.System.Diagnostics.DebuggerNonUserCodeAttribute(), _
|
||||
Global.System.Runtime.CompilerServices.CompilerGeneratedAttribute()> _
|
||||
Friend Module MySettingsProperty
|
||||
|
||||
<Global.System.ComponentModel.Design.HelpKeywordAttribute("My.Settings")> _
|
||||
Friend ReadOnly Property Settings() As Global.Pilz.S3DFileParser.My.MySettings
|
||||
Get
|
||||
Return Global.Pilz.S3DFileParser.My.MySettings.Default
|
||||
End Get
|
||||
End Property
|
||||
End Module
|
||||
End Namespace
|
||||
15
Pilz.Simple3DFileParser/Other/Exceptions.cs
Normal file
15
Pilz.Simple3DFileParser/Other/Exceptions.cs
Normal file
@@ -0,0 +1,15 @@
|
||||
using System;
|
||||
|
||||
namespace Pilz.S3DFileParser.Exceptions
|
||||
{
|
||||
public class MaterialException : Exception
|
||||
{
|
||||
public MaterialException() : base()
|
||||
{
|
||||
}
|
||||
|
||||
public MaterialException(string message) : base(message)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
Namespace Exceptions
|
||||
|
||||
Public Class MaterialException
|
||||
Inherits Exception
|
||||
|
||||
Public Sub New()
|
||||
MyBase.New
|
||||
End Sub
|
||||
Public Sub New(message As String)
|
||||
MyBase.New(message)
|
||||
End Sub
|
||||
End Class
|
||||
|
||||
End Namespace
|
||||
30
Pilz.Simple3DFileParser/Other/Extensions.cs
Normal file
30
Pilz.Simple3DFileParser/Other/Extensions.cs
Normal file
@@ -0,0 +1,30 @@
|
||||
using System.Drawing;
|
||||
|
||||
namespace Pilz.S3DFileParser
|
||||
{
|
||||
internal static class Extensions
|
||||
{
|
||||
public static object GetPropertyValue(this object @base, string propertyName)
|
||||
{
|
||||
return @base?.GetType().GetProperty(propertyName, System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Static)?.GetValue(@base);
|
||||
}
|
||||
|
||||
public static bool IsTheSameAs(this Bitmap @base, Bitmap image)
|
||||
{
|
||||
if (@base.Size != image.Size)
|
||||
return false;
|
||||
for (int y = 0, loopTo = @base.Height - 1; y <= loopTo; y++)
|
||||
{
|
||||
for (int x = 0, loopTo1 = @base.Width - 1; x <= loopTo1; x++)
|
||||
{
|
||||
var p1 = @base.GetPixel(x, y);
|
||||
var p2 = image.GetPixel(x, y);
|
||||
if (p1 != p2)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
Imports System.IO
|
||||
Imports System.Runtime.CompilerServices
|
||||
|
||||
Friend Module Extensions
|
||||
|
||||
<Extension>
|
||||
Public Function GetPropertyValue(base As Object, propertyName As String) As Object
|
||||
Return base?.GetType.GetProperty(propertyName, Reflection.BindingFlags.Public Or Reflection.BindingFlags.NonPublic Or Reflection.BindingFlags.Instance Or Reflection.BindingFlags.Static)?.GetValue(base)
|
||||
End Function
|
||||
|
||||
<Extension>
|
||||
Public Function IsTheSameAs(base As Bitmap, image As Bitmap) As Boolean
|
||||
If base.Size <> image.Size Then Return False
|
||||
|
||||
For y As Integer = 0 To base.Height - 1
|
||||
For x As Integer = 0 To base.Width - 1
|
||||
Dim p1 As Color = base.GetPixel(x, y)
|
||||
Dim p2 As Color = image.GetPixel(x, y)
|
||||
If p1 <> p2 Then Return False
|
||||
Next
|
||||
Next
|
||||
|
||||
Return True
|
||||
End Function
|
||||
|
||||
End Module
|
||||
144
Pilz.Simple3DFileParser/Other/LoaderModule.cs
Normal file
144
Pilz.Simple3DFileParser/Other/LoaderModule.cs
Normal file
@@ -0,0 +1,144 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using global::Assimp.Unmanaged;
|
||||
|
||||
namespace Pilz.S3DFileParser
|
||||
{
|
||||
public class File3DLoaderModule
|
||||
{
|
||||
public delegate Object3D LoaderAction(string fileName, LoaderOptions options);
|
||||
|
||||
public delegate void ExporterAction(Object3D obj, string fileName);
|
||||
|
||||
private static File3DLoaderModule[] _LoaderModules = null;
|
||||
private static File3DLoaderModule[] _ExporterModules = null;
|
||||
private readonly Delegate method = null;
|
||||
|
||||
public string Name { get; private set; }
|
||||
public IReadOnlyDictionary<string, string> SupportedFormats { get; private set; }
|
||||
|
||||
public File3DLoaderModule(string name, LoaderAction method, IReadOnlyDictionary<string, string> supportedFormats)
|
||||
{
|
||||
Name = name;
|
||||
this.method = method;
|
||||
SupportedFormats = supportedFormats;
|
||||
}
|
||||
|
||||
public File3DLoaderModule(string name, ExporterAction method, IReadOnlyDictionary<string, string> supportedFormats)
|
||||
{
|
||||
Name = name;
|
||||
this.method = method;
|
||||
SupportedFormats = supportedFormats;
|
||||
}
|
||||
|
||||
public Task InvokeAsync(Object3D obj, string fileName)
|
||||
{
|
||||
return Task.Run(() => Invoke(obj, fileName));
|
||||
}
|
||||
|
||||
public void Invoke(Object3D obj, string fileName)
|
||||
{
|
||||
method.Method.Invoke(null, new object[] { obj, fileName });
|
||||
}
|
||||
|
||||
public Task<Object3D> InvokeAsync(string fileName, LoaderOptions options)
|
||||
{
|
||||
return Task.Run(() => Invoke(fileName, options));
|
||||
}
|
||||
|
||||
public Object3D Invoke(string fileName, LoaderOptions options)
|
||||
{
|
||||
return (Object3D)method.Method.Invoke(null, new object[] { fileName, options });
|
||||
}
|
||||
|
||||
public static File3DLoaderModule[] LoaderModules
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_LoaderModules is null)
|
||||
{
|
||||
_LoaderModules = GetLoaderModules();
|
||||
}
|
||||
|
||||
return _LoaderModules;
|
||||
}
|
||||
}
|
||||
|
||||
public static File3DLoaderModule[] ExporterModules
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_ExporterModules is null)
|
||||
{
|
||||
_ExporterModules = GetExporterModules();
|
||||
}
|
||||
|
||||
return _ExporterModules;
|
||||
}
|
||||
}
|
||||
|
||||
private static File3DLoaderModule[] GetLoaderModules()
|
||||
{
|
||||
var list = new List<File3DLoaderModule>();
|
||||
list.Add(new File3DLoaderModule("Simple File Parser", LoadViaSimpleFileParser, new Dictionary<string, string>() { { "obj", "OBJ" } }));
|
||||
AssimpModule.AssimpLoader.LoadAssimpLibs();
|
||||
var exts = new Dictionary<string, string>();
|
||||
foreach (Assimp.ExportFormatDescription fd in AssimpLibrary.Instance.GetExportFormatDescriptions())
|
||||
{
|
||||
if (!exts.ContainsKey(fd.FileExtension))
|
||||
{
|
||||
exts.Add(fd.FileExtension, fd.FormatId + " - " + fd.Description);
|
||||
}
|
||||
}
|
||||
|
||||
exts.Add("blend", "Blender");
|
||||
list.Add(new File3DLoaderModule("Assimp", LoadViaAssimp, exts));
|
||||
list.Add(new File3DLoaderModule("Aspose.3D", LoadViaAspose3D, new Dictionary<string, string>() { { "obj", "OBJ" }, { "dae", "DAE" }, { "fbx", "FBX" }, { "stl", "STL" }, { "3ds", "3DS" }, { "3d", "3D" }, { "gltf", "glTF" }, { "drc", "DRC" }, { "rvm", "RVM" }, { "pdf", "PDF" }, { "x", "X" }, { "jt", "JT" }, { "dfx", "DFX" }, { "ply", "PLY" }, { "3mf", "3MF" }, { "ase", "ASE" } }));
|
||||
return list.ToArray();
|
||||
}
|
||||
|
||||
private static File3DLoaderModule[] GetExporterModules()
|
||||
{
|
||||
var list = new List<File3DLoaderModule>();
|
||||
list.Add(new File3DLoaderModule("Simple File Parser", ExportViaSimpleFileParser, new Dictionary<string, string>() { { "obj", "OBJ" } }));
|
||||
AssimpModule.AssimpLoader.LoadAssimpLibs();
|
||||
var exts = new Dictionary<string, string>();
|
||||
foreach (Assimp.ExportFormatDescription fd in AssimpLibrary.Instance.GetExportFormatDescriptions())
|
||||
{
|
||||
if (!exts.ContainsKey(fd.FileExtension))
|
||||
exts.Add(fd.FileExtension, fd.FormatId + " - " + fd.Description);
|
||||
}
|
||||
|
||||
list.Add(new File3DLoaderModule("Assimp", ExportViaAssimp, exts));
|
||||
return list.ToArray();
|
||||
}
|
||||
|
||||
private static Object3D LoadViaSimpleFileParser(string fileName, LoaderOptions options)
|
||||
{
|
||||
return ObjModule.ObjFile.FromFile(fileName, options.LoadMaterials, options.UpAxis);
|
||||
}
|
||||
|
||||
private static Object3D LoadViaAssimp(string fileName, LoaderOptions options)
|
||||
{
|
||||
AssimpModule.AssimpLoader.LoadAssimpLibs();
|
||||
return AssimpModule.AssimpLoader.FromFile(fileName, options.LoadMaterials, options.UpAxis);
|
||||
}
|
||||
|
||||
private static Object3D LoadViaAspose3D(string fileName, LoaderOptions options)
|
||||
{
|
||||
return Aspose3DModule.Aspose3DLoader.FromFile(fileName, options.LoadMaterials, options.UpAxis);
|
||||
}
|
||||
|
||||
private static void ExportViaSimpleFileParser(Object3D o, string fileName)
|
||||
{
|
||||
ObjModule.ObjFile.ToFile(fileName, o);
|
||||
}
|
||||
|
||||
private static void ExportViaAssimp(Object3D o, string fileName)
|
||||
{
|
||||
AssimpModule.AssimpLoader.LoadAssimpLibs();
|
||||
AssimpModule.AssimpLoader.ToFile(fileName, o);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,147 +0,0 @@
|
||||
Imports System.Reflection
|
||||
Imports Assimp.Unmanaged
|
||||
|
||||
Public Class File3DLoaderModule
|
||||
|
||||
Public Delegate Function LoaderAction(fileName As String, options As LoaderOptions) As Object3D
|
||||
Public Delegate Sub ExporterAction(obj As Object3D, fileName As String)
|
||||
|
||||
Private Shared _LoaderModules As File3DLoaderModule() = Nothing
|
||||
Private Shared _ExporterModules As File3DLoaderModule() = Nothing
|
||||
|
||||
Private ReadOnly method As [Delegate] = Nothing
|
||||
Public ReadOnly Property Name As String
|
||||
Public ReadOnly Property SupportedFormats As IReadOnlyDictionary(Of String, String)
|
||||
|
||||
Public Sub New(name As String, method As LoaderAction, supportedFormats As IReadOnlyDictionary(Of String, String))
|
||||
Me.Name = name
|
||||
Me.method = method
|
||||
Me.SupportedFormats = supportedFormats
|
||||
End Sub
|
||||
|
||||
Public Sub New(name As String, method As ExporterAction, supportedFormats As IReadOnlyDictionary(Of String, String))
|
||||
Me.Name = name
|
||||
Me.method = method
|
||||
Me.SupportedFormats = supportedFormats
|
||||
End Sub
|
||||
|
||||
Public Function InvokeAsync(obj As Object3D, fileName As String) As Task
|
||||
Return Task.Run(Sub() Invoke(obj, fileName))
|
||||
End Function
|
||||
|
||||
Public Sub Invoke(obj As Object3D, fileName As String)
|
||||
method.Method.Invoke(Nothing, {obj, fileName})
|
||||
End Sub
|
||||
|
||||
Public Function InvokeAsync(fileName As String, options As LoaderOptions) As Task(Of Object3D)
|
||||
Return Task.Run(Function() Invoke(fileName, options))
|
||||
End Function
|
||||
|
||||
Public Function Invoke(fileName As String, options As LoaderOptions) As Object3D
|
||||
Return method.Method.Invoke(Nothing, {fileName, options})
|
||||
End Function
|
||||
|
||||
Public Shared ReadOnly Property LoaderModules As File3DLoaderModule()
|
||||
Get
|
||||
If _LoaderModules Is Nothing Then
|
||||
_LoaderModules = GetLoaderModules()
|
||||
End If
|
||||
Return _LoaderModules
|
||||
End Get
|
||||
End Property
|
||||
|
||||
Public Shared ReadOnly Property ExporterModules As File3DLoaderModule()
|
||||
Get
|
||||
If _ExporterModules Is Nothing Then
|
||||
_ExporterModules = GetExporterModules()
|
||||
End If
|
||||
Return _ExporterModules
|
||||
End Get
|
||||
End Property
|
||||
|
||||
Private Shared Function GetLoaderModules() As File3DLoaderModule()
|
||||
Dim list As New List(Of File3DLoaderModule)
|
||||
|
||||
list.Add(New File3DLoaderModule("Simple File Parser",
|
||||
AddressOf LoadViaSimpleFileParser,
|
||||
New Dictionary(Of String, String) From {{"obj", "OBJ"}}))
|
||||
|
||||
AssimpModule.AssimpLoader.LoadAssimpLibs()
|
||||
Dim exts As New Dictionary(Of String, String)
|
||||
For Each fd As Assimp.ExportFormatDescription In AssimpLibrary.Instance.GetExportFormatDescriptions
|
||||
If Not exts.ContainsKey(fd.FileExtension) Then
|
||||
exts.Add(fd.FileExtension, fd.FormatId & " - " & fd.Description)
|
||||
End If
|
||||
Next
|
||||
exts.Add("blend", "Blender")
|
||||
|
||||
list.Add(New File3DLoaderModule("Assimp",
|
||||
AddressOf LoadViaAssimp,
|
||||
exts))
|
||||
|
||||
list.Add(New File3DLoaderModule("Aspose.3D",
|
||||
AddressOf LoadViaAspose3D,
|
||||
New Dictionary(Of String, String) From {
|
||||
{"obj", "OBJ"},
|
||||
{"dae", "DAE"},
|
||||
{"fbx", "FBX"},
|
||||
{"stl", "STL"},
|
||||
{"3ds", "3DS"},
|
||||
{"3d", "3D"},
|
||||
{"gltf", "glTF"},
|
||||
{"drc", "DRC"},
|
||||
{"rvm", "RVM"},
|
||||
{"pdf", "PDF"},
|
||||
{"x", "X"},
|
||||
{"jt", "JT"},
|
||||
{"dfx", "DFX"},
|
||||
{"ply", "PLY"},
|
||||
{"3mf", "3MF"},
|
||||
{"ase", "ASE"}}))
|
||||
|
||||
Return list.ToArray
|
||||
End Function
|
||||
|
||||
Private Shared Function GetExporterModules() As File3DLoaderModule()
|
||||
Dim list As New List(Of File3DLoaderModule)
|
||||
|
||||
list.Add(New File3DLoaderModule("Simple File Parser",
|
||||
AddressOf ExportViaSimpleFileParser,
|
||||
New Dictionary(Of String, String) From {{"obj", "OBJ"}}))
|
||||
|
||||
AssimpModule.AssimpLoader.LoadAssimpLibs()
|
||||
Dim exts As New Dictionary(Of String, String)
|
||||
For Each fd As Assimp.ExportFormatDescription In AssimpLibrary.Instance.GetExportFormatDescriptions
|
||||
If Not exts.ContainsKey(fd.FileExtension) Then exts.Add(fd.FileExtension, fd.FormatId & " - " & fd.Description)
|
||||
Next
|
||||
|
||||
list.Add(New File3DLoaderModule("Assimp",
|
||||
AddressOf ExportViaAssimp,
|
||||
exts))
|
||||
|
||||
Return list.ToArray
|
||||
End Function
|
||||
|
||||
Private Shared Function LoadViaSimpleFileParser(fileName As String, options As LoaderOptions) As Object3D
|
||||
Return ObjModule.ObjFile.FromFile(fileName, options.LoadMaterials, options.UpAxis)
|
||||
End Function
|
||||
|
||||
Private Shared Function LoadViaAssimp(fileName As String, options As LoaderOptions) As Object3D
|
||||
AssimpModule.AssimpLoader.LoadAssimpLibs()
|
||||
Return AssimpModule.AssimpLoader.FromFile(fileName, options.LoadMaterials, options.UpAxis)
|
||||
End Function
|
||||
|
||||
Private Shared Function LoadViaAspose3D(fileName As String, options As LoaderOptions) As Object3D
|
||||
Return Aspose3DModule.Aspose3DLoader.FromFile(fileName, options.LoadMaterials, options.UpAxis)
|
||||
End Function
|
||||
|
||||
Private Shared Sub ExportViaSimpleFileParser(o As Object3D, fileName As String)
|
||||
ObjModule.ObjFile.ToFile(fileName, o)
|
||||
End Sub
|
||||
|
||||
Private Shared Sub ExportViaAssimp(o As Object3D, fileName As String)
|
||||
AssimpModule.AssimpLoader.LoadAssimpLibs()
|
||||
AssimpModule.AssimpLoader.ToFile(fileName, o)
|
||||
End Sub
|
||||
|
||||
End Class
|
||||
19
Pilz.Simple3DFileParser/Other/LoaderOptions.cs
Normal file
19
Pilz.Simple3DFileParser/Other/LoaderOptions.cs
Normal file
@@ -0,0 +1,19 @@
|
||||
|
||||
namespace Pilz.S3DFileParser
|
||||
{
|
||||
public class LoaderOptions
|
||||
{
|
||||
public bool LoadMaterials { get; set; } = false;
|
||||
public UpAxis UpAxis { get; set; } = UpAxis.Y;
|
||||
|
||||
public LoaderOptions()
|
||||
{
|
||||
}
|
||||
|
||||
public LoaderOptions(bool loadMaterials, UpAxis upAxis)
|
||||
{
|
||||
LoadMaterials = loadMaterials;
|
||||
UpAxis = upAxis;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
Public Class LoaderOptions
|
||||
|
||||
Public Property LoadMaterials As Boolean = False
|
||||
Public Property UpAxis As UpAxis = False
|
||||
|
||||
Public Sub New()
|
||||
End Sub
|
||||
|
||||
Public Sub New(loadMaterials As Boolean, upAxis As UpAxis)
|
||||
Me.LoadMaterials = loadMaterials
|
||||
Me.UpAxis = upAxis
|
||||
End Sub
|
||||
|
||||
End Class
|
||||
@@ -4,7 +4,7 @@
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{AC955819-7910-450C-940C-7C1989483D4B}</ProjectGuid>
|
||||
<ProjectGuid>{1EB1D972-B548-0AFD-1654-B667EBDF09EB}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<StartupObject>
|
||||
</StartupObject>
|
||||
@@ -16,6 +16,8 @@
|
||||
<NuGetPackageImportStamp>
|
||||
</NuGetPackageImportStamp>
|
||||
<TargetFrameworkProfile />
|
||||
<DefaultItemExcludes>$(DefaultItemExcludes);$(ProjectDir)**\*.vb</DefaultItemExcludes>
|
||||
<LangVersion>latest</LangVersion>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
@@ -50,6 +52,7 @@
|
||||
<OptionInfer>On</OptionInfer>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Microsoft.VisualBasic" />
|
||||
<Reference Include="AssimpNet">
|
||||
<HintPath>..\Shared Libs\AssimpNet.dll</HintPath>
|
||||
</Reference>
|
||||
@@ -82,59 +85,62 @@
|
||||
<Import Include="System.Threading.Tasks" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Model\Face.vb" />
|
||||
<Compile Include="Model\Material.vb" />
|
||||
<Compile Include="Model\Mesh.vb" />
|
||||
<Compile Include="Model\ModelBoundaries.vb" />
|
||||
<Compile Include="Model\Normal.vb" />
|
||||
<Compile Include="Model\Point.vb" />
|
||||
<Compile Include="Model\Shading.vb" />
|
||||
<Compile Include="Model\UpAxis.vb" />
|
||||
<Compile Include="Model\UV.vb" />
|
||||
<Compile Include="Model\Vertex.vb" />
|
||||
<Compile Include="Model\VertexColor.vb" />
|
||||
<Compile Include="Other\LoaderModule.vb" />
|
||||
<Compile Include="FileParser\Aspose3DLoader.vb" />
|
||||
<Compile Include="FileParser\AssimpLoader.vb" />
|
||||
<Compile Include="Other\Extensions.vb" />
|
||||
<Compile Include="Model\Interfaces.vb" />
|
||||
<Compile Include="Model\Object3D.vb" />
|
||||
<Compile Include="Other\Exceptions.vb" />
|
||||
<Compile Include="FileParser\Obj.vb" />
|
||||
<Compile Include="My Project\AssemblyInfo.vb" />
|
||||
<Compile Include="My Project\Application.Designer.vb">
|
||||
<Compile Include="My Project\MyNamespace.Static.1.Designer.cs" />
|
||||
<Compile Include="My Project\MyNamespace.Static.2.Designer.cs" />
|
||||
<Compile Include="My Project\MyNamespace.Static.3.Designer.cs" />
|
||||
<Compile Include="Model\Face.cs" />
|
||||
<Compile Include="Model\Material.cs" />
|
||||
<Compile Include="Model\Mesh.cs" />
|
||||
<Compile Include="Model\ModelBoundaries.cs" />
|
||||
<Compile Include="Model\Normal.cs" />
|
||||
<Compile Include="Model\Point.cs" />
|
||||
<Compile Include="Model\Shading.cs" />
|
||||
<Compile Include="Model\UpAxis.cs" />
|
||||
<Compile Include="Model\UV.cs" />
|
||||
<Compile Include="Model\Vertex.cs" />
|
||||
<Compile Include="Model\VertexColor.cs" />
|
||||
<Compile Include="Other\LoaderModule.cs" />
|
||||
<Compile Include="FileParser\Aspose3DLoader.cs" />
|
||||
<Compile Include="FileParser\AssimpLoader.cs" />
|
||||
<Compile Include="Other\Extensions.cs" />
|
||||
<Compile Include="Model\Interfaces.cs" />
|
||||
<Compile Include="Model\Object3D.cs" />
|
||||
<Compile Include="Other\Exceptions.cs" />
|
||||
<Compile Include="FileParser\Obj.cs" />
|
||||
<Compile Include="My Project\AssemblyInfo.cs" />
|
||||
<Compile Include="My Project\Application.Designer.cs">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DependentUpon>Application.myapp</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="My Project\Resources.Designer.vb">
|
||||
<Compile Include="Resources.Designer.cs">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DesignTime>True</DesignTime>
|
||||
<DependentUpon>Resources.resx</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="My Project\Settings.Designer.vb">
|
||||
<Compile Include="Properties\Settings.Designer.cs">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DependentUpon>Settings.settings</DependentUpon>
|
||||
<DesignTimeSharedInput>True</DesignTimeSharedInput>
|
||||
</Compile>
|
||||
<Compile Include="Other\LoaderOptions.vb" />
|
||||
<Compile Include="Other\LoaderOptions.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="My Project\Resources.resx">
|
||||
<Generator>VbMyResourcesResXFileCodeGenerator</Generator>
|
||||
<LastGenOutput>Resources.Designer.vb</LastGenOutput>
|
||||
<CustomToolNamespace>My.Resources</CustomToolNamespace>
|
||||
<EmbeddedResource Include="Resources.resx">
|
||||
<Generator>ResXFileCodeGenerator</Generator>
|
||||
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
|
||||
<CustomToolNamespace>Pilz.S3DFileParser.My.Resources</CustomToolNamespace>
|
||||
<SubType>Designer</SubType>
|
||||
</EmbeddedResource>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="My Project\Application.myapp">
|
||||
<Generator>MyApplicationCodeGenerator</Generator>
|
||||
<LastGenOutput>Application.Designer.vb</LastGenOutput>
|
||||
<LastGenOutput>Application.Designer.cs</LastGenOutput>
|
||||
</None>
|
||||
<None Include="My Project\Settings.settings">
|
||||
<None Include="Properties\Settings.settings">
|
||||
<Generator>SettingsSingleFileGenerator</Generator>
|
||||
<CustomToolNamespace>My</CustomToolNamespace>
|
||||
<LastGenOutput>Settings.Designer.vb</LastGenOutput>
|
||||
<CustomToolNamespace>Pilz.S3DFileParser.My</CustomToolNamespace>
|
||||
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
|
||||
</None>
|
||||
<None Include="App.config" />
|
||||
</ItemGroup>
|
||||
@@ -152,5 +158,5 @@
|
||||
<Version>4.5.0</Version>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.VisualBasic.targets" />
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
</Project>
|
||||
26
Pilz.Simple3DFileParser/Properties/Settings.Designer.cs
generated
Normal file
26
Pilz.Simple3DFileParser/Properties/Settings.Designer.cs
generated
Normal file
@@ -0,0 +1,26 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// Dieser Code wurde von einem Tool generiert.
|
||||
// Laufzeitversion:4.0.30319.42000
|
||||
//
|
||||
// Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn
|
||||
// der Code erneut generiert wird.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace Pilz.S3DFileParser.My {
|
||||
|
||||
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "15.9.0.0")]
|
||||
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
|
||||
|
||||
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
|
||||
|
||||
public static Settings Default {
|
||||
get {
|
||||
return defaultInstance;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
69
Pilz.Simple3DFileParser/Resources.Designer.cs
generated
Normal file
69
Pilz.Simple3DFileParser/Resources.Designer.cs
generated
Normal file
@@ -0,0 +1,69 @@
|
||||
// ------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// Dieser Code wurde von einem Tool generiert.
|
||||
// Laufzeitversion:4.0.30319.42000
|
||||
//
|
||||
// Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn
|
||||
// der Code erneut generiert wird.
|
||||
// </auto-generated>
|
||||
// ------------------------------------------------------------------------------
|
||||
|
||||
using System.Diagnostics;
|
||||
using Microsoft.VisualBasic;
|
||||
|
||||
namespace Pilz.S3DFileParser.My.Resources
|
||||
{
|
||||
|
||||
// Diese Klasse wurde von der StronglyTypedResourceBuilder automatisch generiert
|
||||
// -Klasse über ein Tool wie ResGen oder Visual Studio automatisch generiert.
|
||||
// Um einen Member hinzuzufügen oder zu entfernen, bearbeiten Sie die .ResX-Datei und führen dann ResGen
|
||||
// mit der /str-Option erneut aus, oder Sie erstellen Ihr VS-Projekt neu.
|
||||
/// <summary>
|
||||
/// Eine stark typisierte Ressourcenklasse zum Suchen von lokalisierten Zeichenfolgen usw.
|
||||
/// </summary>
|
||||
[System.CodeDom.Compiler.GeneratedCode("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")]
|
||||
[DebuggerNonUserCode()]
|
||||
[System.Runtime.CompilerServices.CompilerGenerated()]
|
||||
[HideModuleName()]
|
||||
internal static class Resources
|
||||
{
|
||||
private static System.Resources.ResourceManager resourceMan;
|
||||
private static System.Globalization.CultureInfo resourceCulture;
|
||||
|
||||
/// <summary>
|
||||
/// Gibt die zwischengespeicherte ResourceManager-Instanz zurück, die von dieser Klasse verwendet wird.
|
||||
/// </summary>
|
||||
[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static System.Resources.ResourceManager ResourceManager
|
||||
{
|
||||
get
|
||||
{
|
||||
if (ReferenceEquals(resourceMan, null))
|
||||
{
|
||||
var temp = new System.Resources.ResourceManager("Pilz.S3DFileParser.Resources", typeof(Resources).Assembly);
|
||||
resourceMan = temp;
|
||||
}
|
||||
|
||||
return resourceMan;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Überschreibt die CurrentUICulture-Eigenschaft des aktuellen Threads für alle
|
||||
/// Ressourcenzuordnungen, die diese stark typisierte Ressourcenklasse verwenden.
|
||||
/// </summary>
|
||||
[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static System.Globalization.CultureInfo Culture
|
||||
{
|
||||
get
|
||||
{
|
||||
return resourceCulture;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
resourceCulture = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
117
Pilz.Simple3DFileParser/Resources.resx
Normal file
117
Pilz.Simple3DFileParser/Resources.resx
Normal file
@@ -0,0 +1,117 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
</root>
|
||||
Reference in New Issue
Block a user