convert VB to C#

This commit is contained in:
2020-09-24 11:21:53 +02:00
parent 64277916cd
commit fecbeb4659
320 changed files with 17755 additions and 10320 deletions

View 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;
}
}
}

View File

@@ -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

View 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;
}
}
}

View File

@@ -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

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

View File

@@ -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

View 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;
}
}

View File

@@ -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

View File

@@ -0,0 +1,10 @@
using System.Threading.Tasks;
namespace Pilz.S3DFileParser
{
public interface IToObject3D
{
Object3D ToObject3D();
Task<Object3D> ToObject3DAsync();
}
}

View File

@@ -1,6 +0,0 @@
Public Interface IToObject3D
Function ToObject3D() As Object3D
Function ToObject3DAsync() As Task(Of Object3D)
End Interface

View 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;
}
}
}
}

View File

@@ -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

View 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;
}
}
}
}
}

View File

@@ -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

View 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;
}
}
}

View File

@@ -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

View 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;
}
}

View File

@@ -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

View 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);
}
}
}

View File

@@ -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

View 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;
}
}

View File

@@ -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

View 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;
}
}

View File

@@ -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

View File

@@ -0,0 +1,9 @@
namespace Pilz.S3DFileParser
{
public class UV
{
public float U { get; set; } = 0f;
public float V { get; set; } = 0f;
}
}

View File

@@ -1,4 +0,0 @@
Public Class UV
Public Property U As Single = 0
Public Property V As Single = 0
End Class

View File

@@ -0,0 +1,9 @@
namespace Pilz.S3DFileParser
{
public enum UpAxis
{
Y,
Z
}
}

View File

@@ -1,4 +0,0 @@
Public Enum UpAxis
Y
Z
End Enum

View 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;
}
}

View File

@@ -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

View 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;
}
}

View File

@@ -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

View 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>
// ------------------------------------------------------------------------------

View File

@@ -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

View 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")]

View File

@@ -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")>

View 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 */

View 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;
}
}
}

View 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
{
}
}

View File

@@ -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

View File

@@ -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

View File

@@ -0,0 +1,15 @@
using System;
namespace Pilz.S3DFileParser.Exceptions
{
public class MaterialException : Exception
{
public MaterialException() : base()
{
}
public MaterialException(string message) : base(message)
{
}
}
}

View File

@@ -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

View 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;
}
}
}

View File

@@ -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

View 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);
}
}
}

View File

@@ -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

View 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;
}
}
}

View File

@@ -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

View File

@@ -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>

View 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;
}
}
}
}

View 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;
}
}
}
}

View 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>