public override bool ExportToFile(IOModel model, string filename) { var tempFile = Path.Combine(Path.GetDirectoryName(filename), "_proxy.obj"); var tempMtlFile = Path.Combine(Path.GetDirectoryName(filename), "_proxy.mtl"); var objExporter = new ObjExporter(_settings, _callback); var objData = objExporter.ExportToFile(model, tempFile); AssimpContext context = new AssimpContext(); context.SetConfig(new NormalSmoothingAngleConfig(90.0f)); Scene scene = context.ImportFile(tempFile); switch (_exporter) { case Exporter.Collada: { context.ExportFile(scene, filename, "collada"); // Open up exported collada file and fix all texture filenames to relative XDocument exported = XDocument.Load(filename); foreach (var node in exported.Root.DescendantNodes()) { if (node is XElement) { var element = (XElement)node; if (element.Name.LocalName == "init_from" && element.Value.EndsWith(".png")) { element.Value = Path.GetFileName(element.Value); } } } exported.Save(filename); } break; case Exporter.GLTF2: context.ExportFile(scene, filename, "gltf2"); break; case Exporter.X3d: context.ExportFile(scene, filename, "x3d"); break; } File.Delete(tempFile); File.Delete(tempMtlFile); return(true); }
public bool ExportObject(FileInfo file) { using (var exporter = new AssimpContext()) { return(exporter.ExportFile(Scene, file.FullName, "obj", PostProcessSteps.ValidateDataStructure)); } }
public void Export(IFile outputFile, IModel model) { var outputPath = outputFile.FullName; var outputExtension = outputFile.Extension; var inputFile = outputFile.CloneWithExtension(".glb"); var inputPath = inputFile.FullName; var inputExtension = inputFile.Extension; var ctx = new AssimpContext(); string exportFormatId; { var supportedImportFormatExtensions = ctx.GetSupportedImportFormats(); Asserts.True(supportedImportFormatExtensions.Contains(inputExtension), $"'{inputExtension}' is not a supported import format!"); var supportedExportFormats = ctx.GetSupportedExportFormats(); var exportFormatIds = supportedExportFormats .Where(exportFormat => outputExtension == $".{exportFormat.FileExtension}") .Select(exportFormat => exportFormat.FormatId); Asserts.True(exportFormatIds.Any(), $"'{outputExtension}' is not a supported export format!"); exportFormatId = exportFormatIds.First(); } var sc = ctx.ImportFile(inputPath); var success = ctx.ExportFile(sc, outputPath, exportFormatId); Asserts.True(success, "Failed to export model."); }
public static bool SaveToGltf(this Scene model, string path, string fileName) { try { using (var importer = new AssimpContext()) { string outputFilePath = $"{path}/{fileName}.gltf"; if (importer.ExportFile(model, outputFilePath, "gltf2")) { // Replace the buffer path to a relative one. string gltf = File.ReadAllText(outputFilePath); gltf = gltf.Replace(path + '/', ""); File.WriteAllText(outputFilePath, gltf); return(true); } else { return(false); } } } catch (Exception e) { //Logger.LogException("Error in saving gltf: ", e); return(false); } }
public bool ExportCollada(FileInfo file) { using (var exporter = new AssimpContext()) { return(exporter.ExportFile(Scene, file.FullName, "collada", PostProcessSteps.ValidateDataStructure)); //collada or obj } }
public static void ExportToFile(HavokAnimationData anim, string filePath, string assimpFileFormatStr) { var scene = ExportToScene(anim); using (var x = new AssimpContext()) { x.ExportFile(scene, filePath, assimpFileFormatStr); } }
public void TestExportToFile() { String path = Path.Combine(TestHelper.RootPath, "TestFiles\\ExportedTriangle.obj"); //Create a very simple scene a single node with a mesh that has a single face, a triangle and a default material Scene scene = new Scene(); scene.RootNode = new Node("Root"); Mesh triangle = new Mesh("", PrimitiveType.Triangle); triangle.Vertices.Add(new Vector3D(1, 0, 0)); triangle.Vertices.Add(new Vector3D(5, 5, 0)); triangle.Vertices.Add(new Vector3D(10, 0, 0)); triangle.Faces.Add(new Face(new int[] { 0, 1, 2 })); triangle.MaterialIndex = 0; scene.Meshes.Add(triangle); scene.RootNode.MeshIndices.Add(0); Material mat = new Material(); mat.Name = "MyMaterial"; scene.Materials.Add(mat); //Export the scene then read it in and compare! AssimpContext context = new AssimpContext(); Assert.IsTrue(context.ExportFile(scene, path, "obj")); Scene importedScene = context.ImportFile(path); Assert.IsTrue(importedScene.MeshCount == scene.MeshCount); Assert.IsTrue(importedScene.MaterialCount == 2); //Always has the default material, should also have our material //Compare the meshes Mesh importedTriangle = importedScene.Meshes[0]; Assert.IsTrue(importedTriangle.VertexCount == triangle.VertexCount); for (int i = 0; i < importedTriangle.VertexCount; i++) { Assert.IsTrue(importedTriangle.Vertices[i].Equals(triangle.Vertices[i])); } Assert.IsTrue(importedTriangle.FaceCount == triangle.FaceCount); for (int i = 0; i < importedTriangle.FaceCount; i++) { Face importedFace = importedTriangle.Faces[i]; Face face = triangle.Faces[i]; for (int j = 0; j < importedFace.IndexCount; j++) { Assert.IsTrue(importedFace.Indices[j] == face.Indices[j]); } } }
public void TestImportExportFile() { String colladaPath = Path.Combine(TestHelper.RootPath, "TestFiles\\duck.dae"); String plyPath = Path.Combine(TestHelper.RootPath, "TestFiles\\duck.ply"); AssimpContext context = new AssimpContext(); Scene ducky = context.ImportFile(colladaPath); context.ExportFile(ducky, plyPath, "ply"); }
static void Main(string[] args) { if (!args.Any()) { Log("No input files defined! Just drag and drop files onto CBRE.SMFConverter.exe", ConsoleColor.Red); } else { AssimpContext context = new AssimpContext(); foreach (string file in args) { try { string directory = Path.GetDirectoryName(file).Replace('\\', '/'); if (directory.Length > 0 && directory.Last() != '/') { directory += "/"; } Scene scene = new Scene(); Node rootNode = new Node("rootnode"); scene.RootNode = rootNode; using (var fileStream = new FileStream(file, FileMode.Open)) { using (var reader = new BinaryReader(fileStream)) { // header UInt16 mapVersion = reader.ReadUInt16(); if (mapVersion != 1) { Log($"[{file}] Warning: mapVersion != 1 ({mapVersion})", ConsoleColor.Yellow); } byte mapFlags = reader.ReadByte(); ReadNode(file, directory, reader, scene, rootNode); string resultFilename = Path.GetFileNameWithoutExtension(file) + ".x"; context.ExportFile(scene, resultFilename, "x"); Log($"[{file}] Complete!", ConsoleColor.Green); } } } catch (Exception e) { Log($"[{file}] Error: {e.Message}\n{e.StackTrace}", ConsoleColor.Red); } } Log("Done! Press any key to continue", ConsoleColor.Cyan); } Console.ReadKey(); }
public void TestImportExportImportFile() { String colladaPath = Path.Combine(TestHelper.RootPath, "TestFiles/duck.dae"); String plyPath = Path.Combine(TestHelper.RootPath, "TestFiles/output/duck2.dae"); AssimpContext context = new AssimpContext(); Scene ducky = context.ImportFile(colladaPath); context.ExportFile(ducky, plyPath, "collada"); Scene ducky2 = context.ImportFile(plyPath); Assert.IsNotNull(ducky2); }
public void TestExportBadFormatId() { AssimpContext importer = new AssimpContext(); NormalSmoothingAngleConfig config = new NormalSmoothingAngleConfig(66.0f); importer.SetConfig(config); LogStream logStream = new LogStream(delegate(string msg, string userData) { Console.WriteLine(msg); }); logStream.Attach(); Scene collada = importer.ImportFile(Path.Combine(TestHelper.RootPath, "TestFiles/duck.dae")); bool success = importer.ExportFile(collada, Path.Combine(TestHelper.RootPath, "TestFiles/output/exportedCollada.dae"), "dae"); Assert.IsFalse(success); success = importer.ExportFile(collada, Path.Combine(TestHelper.RootPath, "TestFiles/output/exportedCollada.dae"), "collada"); Assert.IsTrue(success); }
public void SaveFromObject(List <Vertex> vertices, List <int> faces, string MeshName, string FileName) { Scene scene = new Scene(); scene.RootNode = new Node("Root"); Mesh mesh = new Mesh(MeshName, PrimitiveType.Triangle); List <Vector3D> textureCoords0 = new List <Vector3D>(); List <Vector3D> textureCoords1 = new List <Vector3D>(); List <Vector3D> textureCoords2 = new List <Vector3D>(); List <Color4D> vertexColors = new List <Color4D>(); foreach (Vertex v in vertices) { mesh.Vertices.Add(new Vector3D(v.pos.X, v.pos.Y, v.pos.Z)); mesh.Normals.Add(new Vector3D(v.nrm.X, v.nrm.Y, v.nrm.Z)); textureCoords0.Add(new Vector3D(v.uv0.X, v.uv0.Y, 0)); textureCoords1.Add(new Vector3D(v.uv1.X, v.uv1.Y, 0)); textureCoords2.Add(new Vector3D(v.uv2.X, v.uv2.Y, 0)); vertexColors.Add(new Color4D(v.col.X, v.col.Y, v.col.Z, v.col.W)); mesh.TextureCoordinateChannels[0] = textureCoords0; mesh.TextureCoordinateChannels[1] = textureCoords1; mesh.TextureCoordinateChannels[2] = textureCoords2; mesh.VertexColorChannels[0] = vertexColors; } for (int f = 0; f < faces.Count; f++) { mesh.Faces.Add(new Face(new int[] { faces[f++], faces[f++], faces[f] })); } mesh.MaterialIndex = 0; mesh.TextureCoordinateChannels.SetValue(textureCoords0, 0); scene.Meshes.Add(mesh); scene.RootNode.MeshIndices.Add(0); Material material = new Material(); material.Name = "NewMaterial"; scene.Materials.Add(material); using (var v = new AssimpContext()) { v.ExportFile(scene, FileName, "obj"); } }
/// <summary> /// /// </summary> /// <param name="filePath"></param> /// <param name="rootJOBJ"></param> public static void ExportFile(string filePath, HSD_JOBJ rootJOBJ, ModelExportSettings settings = null, Dictionary <int, string> boneLabels = null) { ModelExporter mex = new ModelExporter(); AssimpContext importer = new AssimpContext(); Dictionary <string, string> extToId = new Dictionary <string, string>(); foreach (var v in importer.GetSupportedExportFormats()) { if (!extToId.ContainsKey("." + v.FileExtension)) { extToId.Add("." + v.FileExtension, v.FormatId); } } PostProcessSteps postProcess = PostProcessSteps.FlipWindingOrder; if (settings.Optimize) { postProcess |= PostProcessSteps.JoinIdenticalVertices; } if (settings.FlipUVs) { postProcess |= PostProcessSteps.FlipUVs; } settings.Directory = System.IO.Path.GetDirectoryName(filePath) + "\\"; if (System.IO.Path.GetExtension(filePath).ToLower() == ".dae") { var sc = mex.WriteRootNode(rootJOBJ, settings, boneLabels); /*var scn = Scene.ToUnmanagedScene(sc); * scn = AssimpLibrary.Instance.ApplyPostProcessing(scn, postProcess); * var scene = Scene.FromUnmanagedScene(scn); * Scene.FreeUnmanagedScene(scn);*/ ExportCustomDAE(filePath, sc, settings); } else { importer.ExportFile(mex.WriteRootNode(rootJOBJ, settings, boneLabels), filePath, extToId[System.IO.Path.GetExtension(filePath)], postProcess); } importer.Dispose(); }
private static void Convert(string PMO_Path, string PAM_Path) { Stream pmoStream = File.OpenRead(PMO_Path); Stream pamStream = File.OpenRead(PAM_Path); Pmo pmo = Pmo.Read(pmoStream); Pam pam = Pam.Read(pamStream); Assimp.Scene nScene = GetPMOScene(pmo); List <Assimp.Animation> FBXAnims = PAMtoFBXAnim(pmo, pam); nScene.Animations.AddRange(FBXAnims); pmoStream.Close(); pamStream.Close(); using var ctx = new AssimpContext(); ctx.ExportFile(nScene, "Test.fbx", "fbx"); }
public void SaveFromModel(STGenericModel model, string FileName, List <STGenericTexture> Textures, STSkeleton skeleton = null, List <int> NodeArray = null) { Scene scene = new Scene(); scene.RootNode = new Node("RootNode"); SaveSkeleton(skeleton, scene.RootNode); SaveMaterials(scene, model, FileName, Textures); SaveMeshes(scene, model, skeleton, FileName, NodeArray); using (var v = new AssimpContext()) { string ext = System.IO.Path.GetExtension(FileName); string formatID = "collada"; if (ext == ".obj") { formatID = "obj"; } if (ext == ".3ds") { formatID = "3ds"; } if (ext == ".dae") { formatID = "collada"; } if (ext == ".ply") { formatID = "ply"; } if (v.ExportFile(scene, FileName, formatID, PostProcessSteps.ValidateDataStructure)) { MessageBox.Show($"Exported {FileName} Successfuly!"); } else { MessageBox.Show($"Failed to export {FileName}!"); } } }
private void SaveScene(string FileName, Scene scene, List <STGenericObject> Meshes) { using (var v = new AssimpContext()) { string ext = System.IO.Path.GetExtension(FileName); string formatID = "collada"; if (ext == ".obj") { formatID = "obj"; } if (ext == ".3ds") { formatID = "3ds"; } if (ext == ".dae") { formatID = "collada"; } if (ext == ".ply") { formatID = "ply"; } bool ExportSuccessScene = v.ExportFile(scene, FileName, formatID, PostProcessSteps.FlipUVs); if (ExportSuccessScene) { if (ext == ".dae") { WriteExtraSkinningInfo(FileName, scene, Meshes); } MessageBox.Show($"Exported {FileName} Successfuly!"); } else { MessageBox.Show($"Failed to export {FileName}!"); } } }
public static void ExportModel(SrdFile srd, string exportName) { // Setup the scene for the root of our model Scene scene = new Scene(); // Get all our various data scene.Materials.AddRange(GetMaterials(srd)); scene.Meshes.AddRange(GetMeshes(srd, scene.Materials)); scene.RootNode = GetNodeTree(srd, scene.Materials, scene.Meshes); AssimpContext exportContext = new AssimpContext(); var exportFormats = exportContext.GetSupportedExportFormats(); foreach (var format in exportFormats) { if (format.FileExtension == "gltf") { exportContext.ExportFile(scene, exportName + '.' + format.FileExtension, format.FormatId); break; } } }
/// <summary> /// Exports an assimp scene as a .obj formatted file to filepath. /// </summary> /// <param name="scene"></param> /// <param name="filepath"></param> public void ExportOBJ(Scene scene, string savePath) { if (scene != null && scene.HasMeshes == true) { AssimpContext exporter = new AssimpContext(); exporter.ExportFile(scene, "savePath", "objnomtl"); //ExportDataBlob blob = exporter.ExportToBlob(scene, "objnomtl");//"objnomtl" "Wavefront OBJ format without material file" // Debug.Log(blob); //Debug.Log(savePath); //if(blob.HasData == true) // { /* if (File.Exists(savePath)) * { * File.Delete(savePath); #if UNITY_EDITOR * * File.Delete(savePath + ".meta"); #endif * } * else * { * Debug.Log(true); * }*/ //File.Create(savePath); //File.WriteAllBytes(savePath, blob.Data); // } // else // { // Debug.LogError("No data to export."); // } //} // else // { // Debug.Log("Scene to export does not contain any meshes or is null."); } }
public void ExportAssImp(string fileName, string modelType, ExportSettings settings) { fileName = Path.GetFullPath(fileName); // Get absolute path instead of relative string outDir = Path.GetDirectoryName(fileName); string fileNameNoExt = Path.GetFileNameWithoutExtension(fileName); fileName = Path.Combine(outDir, fileNameNoExt + ".dae"); Scene outScene = new Scene(); outScene.RootNode = new Node("RootNode"); Materials.FillScene(outScene, Textures, outDir); Shapes.FillScene(outScene, VertexData.Attributes, Joints.FlatSkeleton, SkinningEnvelopes.InverseBindMatrices); Scenegraph.FillScene(outScene, Joints.FlatSkeleton, settings.UseSkeletonRoot); Scenegraph.CorrectMaterialIndices(outScene, Materials); Textures.DumpTextures(outDir); foreach (Mesh mesh in outScene.Meshes) { // Assimp has a JoinIdenticalVertices post process step, but we can't use that or the skinning info we manually add won't take it into account. RemoveDuplicateVertices(mesh); } AssimpContext cont = new AssimpContext(); cont.ExportFile(outScene, fileName, "collada", PostProcessSteps.ValidateDataStructure); //if (SkinningEnvelopes.Weights.Count == 0) // return; // There's no skinning information, so we can stop here // Now we need to add some skinning info, since AssImp doesn't do it for some bizarre reason StreamWriter test = new StreamWriter(fileName + ".tmp"); StreamReader dae = File.OpenText(fileName); while (!dae.EndOfStream) { string line = dae.ReadLine(); if (line == " <library_visual_scenes>") { AddControllerLibrary(outScene, test); test.WriteLine(line); test.Flush(); } else if (line.Contains("<node")) { Regex reg = new Regex("^( +)<node id=\"([^\"]+)\" +name=\"[^\"]+\" +type=\"NODE\">$"); Match match = reg.Match(line); if (match.Success) { string indentation = match.Groups[1].Value; string joint_name = match.Groups[2].Value; if (Joints.FlatSkeleton.Exists(x => x.Name == joint_name)) { string jointLine = indentation + $"<node id=\"{joint_name}\" name=\"{joint_name}\" sid=\"{joint_name}\" type=\"JOINT\">"; test.WriteLine(jointLine); } else { test.WriteLine(line); } } else { test.WriteLine(line); } test.Flush(); } else if (line.Contains("<material id=\"")) { Regex reg = new Regex("^ <material id=\"([^\"]+)\" name=\"[^\"]+\">$"); Match match = reg.Match(line); if (match.Success) { string mat_name_sanitized = match.Groups[1].Value; int mat_index = Materials.GetMaterialIndexFromSanitizedMaterialName(mat_name_sanitized); string mat_name = Materials.m_Materials[mat_index].Name; string matLine = $" <material id=\"{mat_name_sanitized}\" name=\"{mat_name}\">"; test.WriteLine(matLine); } else { test.WriteLine(line); } test.Flush(); } else if (line.Contains("</visual_scene>")) { foreach (Mesh mesh in outScene.Meshes) { test.WriteLine($" <node id=\"{ mesh.Name }\" name=\"{ mesh.Name }\" type=\"NODE\">"); test.WriteLine($" <instance_controller url=\"#{ mesh.Name }-skin\">"); test.WriteLine(" <skeleton>#skeleton_root</skeleton>"); test.WriteLine(" <bind_material>"); test.WriteLine(" <technique_common>"); test.WriteLine($" <instance_material symbol=\"{ Materials.m_Materials[mesh.MaterialIndex].Name }\" target=\"#{ Materials.m_Materials[mesh.MaterialIndex].Name.Replace("(", "_").Replace(")", "_") }\" />"); test.WriteLine(" </technique_common>"); test.WriteLine(" </bind_material>"); test.WriteLine(" </instance_controller>"); test.WriteLine(" </node>"); test.Flush(); } test.WriteLine(line); test.Flush(); } else { test.WriteLine(line); test.Flush(); } } test.Close(); dae.Close(); File.Copy(fileName + ".tmp", fileName, true); File.Delete(fileName + ".tmp"); }
public static void ExportColladaFile(this Scene aiScene, string path) { using (var aiContext = new AssimpContext()) aiContext.ExportFile(aiScene, path, "collada", PostProcessSteps.JoinIdenticalVertices | PostProcessSteps.FlipUVs | PostProcessSteps.GenerateSmoothNormals); }
private static bool PackModels(ProcessorInfo info, BinPacking <int> texturePacker) { using (AssimpContext importer = new AssimpContext()) { ExportFormatDescription[] exportFormatDescriptions = importer.GetSupportedExportFormats(); ExportFormatDescription exportFormat = exportFormatDescriptions.FirstOrDefault(x => x.FormatId == info.modelExportFormatId); if (exportFormat == null) { Log.Line(LogType.Error, "Model export format {0} is not supported!", info.modelExportFormatId); Log.Line(LogType.Info, "Supported formats are:"); foreach (ExportFormatDescription e in exportFormatDescriptions) { Log.Line(LogType.Info, "{0} ({1})", e.FormatId, e.Description); } return(false); } Log.Line(LogType.Info, "Shifting uv(w) positions of {0} models to their new location", info.models.Length); if (info.mergeModels) { Log.Line(LogType.Info, "Going to merge models"); } Scene mergedScene = new Scene { RootNode = new Assimp.Node(), Materials = { new Material() } }; for (int i = 0; i < info.models.Length; i++) { string modelPath = info.models[i]; Scene model = importer.ImportFile(modelPath); if (!model.HasMeshes) { Log.Line(LogType.Warning, "There are no meshes in model file '{0}'", modelPath); continue; } Log.Line(LogType.Info, "Processing {0} meshes from model file '{1}'", model.MeshCount, modelPath); foreach (Mesh mesh in model.Meshes) { Log.Line(LogType.Debug, "Found {0} uv(w) channels in mesh '{1}'", mesh.TextureCoordinateChannelCount, mesh.Name); // TODO: Add support for offsetting uvs per mesh instead of per model file // Thus having 1 texture per mesh instead of having 1 texture per model file Block <int> block = texturePacker.blocks.First(x => x.data == i); Log.Line(LogType.Debug, "Using texture at index {0} for this model", Array.IndexOf(texturePacker.blocks, block)); float scaleX = (block.w - info.padding * 2) / (float)texturePacker.root.w; float scaleY = (block.h - info.padding * 2) / (float)texturePacker.root.h; float offsetX = (block.fit.x + info.padding) / (float)texturePacker.root.w; float offsetY = (block.fit.y + info.padding) / (float)texturePacker.root.h; offsetY = 1 - offsetY - scaleY; // This is because the uv 0,0 is in the bottom left Log.Line(LogType.Debug, "Calculated scaling multipliers: x: {0}; y: {1}", scaleX, scaleY); Log.Line(LogType.Debug, "Calculated offsets: x: {0}; y: {1}", offsetX, offsetY); for (int uvwChannel = 0; uvwChannel < mesh.TextureCoordinateChannelCount; uvwChannel++) { List <Vector3D> uvw = mesh.TextureCoordinateChannels[uvwChannel]; if (uvw == null || uvw.Count == 0) { continue; } for (int n = 0; n < uvw.Count; n++) { uvw[n] = new Vector3D( uvw[n].X * scaleX + offsetX, uvw[n].Y * scaleY + offsetY, uvw[n].Z); } mesh.TextureCoordinateChannels[uvwChannel] = uvw; } if (info.mergeModels) { mergedScene.RootNode.MeshIndices.Add(mergedScene.MeshCount); mesh.MaterialIndex = 0; mergedScene.Meshes.Add(mesh); mergedScene.Animations.AddRange(model.Animations); Log.Line(LogType.Info, "Merged mesh {0} into output model", mesh.Name); } } if (!info.mergeModels) { string savePath; if (!string.IsNullOrEmpty(info.outputFilesPrefix.Trim())) { savePath = Path.Combine(info.outputDir, string.Format("{0}-model-{1}.{2}", info.outputFilesPrefix, Path.GetFileNameWithoutExtension(modelPath), exportFormat.FileExtension)); } else { savePath = Path.Combine(info.outputDir, string.Format("model-{0}.{1}", Path.GetFileNameWithoutExtension(modelPath), exportFormat.FileExtension)); } Log.Line(LogType.Info, "Saving edited model to '{0}'", savePath); importer.ExportFile(model, savePath, exportFormat.FormatId); } } if (info.mergeModels) { string savePath; if (!string.IsNullOrEmpty(info.outputFilesPrefix.Trim())) { savePath = Path.Combine(info.outputDir, string.Format("{0}-models-merged.{1}", info.outputFilesPrefix, exportFormat.FileExtension)); } else { savePath = Path.Combine(info.outputDir, string.Format("models-merged.{0}", exportFormat.FileExtension)); } Log.Line(LogType.Info, "Saving merged model to '{0}'", savePath); importer.ExportFile(mergedScene, savePath, exportFormat.FormatId); } } return(true); }
public void TestImportExportImportFile() { String colladaPath = Path.Combine(TestHelper.RootPath, "TestFiles\\duck.dae"); String plyPath = Path.Combine(TestHelper.RootPath, "TestFiles\\duck2.dae"); AssimpContext context = new AssimpContext(); Scene ducky = context.ImportFile(colladaPath); context.ExportFile(ducky, plyPath, "collada"); Scene ducky2 = context.ImportFile(plyPath); Assert.IsNotNull(ducky2); }
public void TestExportToFile() { String path = Path.Combine(TestHelper.RootPath, "TestFiles\\ExportedTriangle.obj"); //Create a very simple scene a single node with a mesh that has a single face, a triangle and a default material Scene scene = new Scene(); scene.RootNode = new Node("Root"); Mesh triangle = new Mesh("", PrimitiveType.Triangle); triangle.Vertices.Add(new Vector3D(1, 0, 0)); triangle.Vertices.Add(new Vector3D(5, 5, 0)); triangle.Vertices.Add(new Vector3D(10, 0, 0)); triangle.Faces.Add(new Face(new int[] { 0, 1, 2 })); triangle.MaterialIndex = 0; scene.Meshes.Add(triangle); scene.RootNode.MeshIndices.Add(0); Material mat = new Material(); mat.Name = "MyMaterial"; scene.Materials.Add(mat); //Export the scene then read it in and compare! AssimpContext context = new AssimpContext(); Assert.IsTrue(context.ExportFile(scene, path, "obj")); Scene importedScene = context.ImportFile(path); Assert.IsTrue(importedScene.MeshCount == scene.MeshCount); Assert.IsTrue(importedScene.MaterialCount == 2); //Always has the default material, should also have our material //Compare the meshes Mesh importedTriangle = importedScene.Meshes[0]; Assert.IsTrue(importedTriangle.VertexCount == triangle.VertexCount); for(int i = 0; i < importedTriangle.VertexCount; i++) { Assert.IsTrue(importedTriangle.Vertices[i].Equals(triangle.Vertices[i])); } Assert.IsTrue(importedTriangle.FaceCount == triangle.FaceCount); for(int i = 0; i < importedTriangle.FaceCount; i++) { Face importedFace = importedTriangle.Faces[i]; Face face = triangle.Faces[i]; for(int j = 0; j < importedFace.IndexCount; j++) { Assert.IsTrue(importedFace.Indices[j] == face.Indices[j]); } } }
public void SaveFromModel(GenericModel model, string FileName) { Scene scene = new Scene(); scene.RootNode = new Node("Root"); Node modelNode = new Node(model.Text); scene.RootNode.Children.Add(modelNode); int MeshIndex = 0; foreach (var obj in model.Nodes[0].Nodes) { var genericObj = (STGenericObject)obj; Node groupNode = new Node(genericObj.Text); Mesh mesh = new Mesh(genericObj.Text, PrimitiveType.Triangle); List <Vector3D> textureCoords0 = new List <Vector3D>(); List <Vector3D> textureCoords1 = new List <Vector3D>(); List <Vector3D> textureCoords2 = new List <Vector3D>(); List <Color4D> vertexColors = new List <Color4D>(); foreach (Vertex v in genericObj.vertices) { mesh.Vertices.Add(new Vector3D(v.pos.X, v.pos.Y, v.pos.Z)); mesh.Normals.Add(new Vector3D(v.nrm.X, v.nrm.Y, v.nrm.Z)); textureCoords0.Add(new Vector3D(v.uv0.X, v.uv0.Y, 0)); textureCoords1.Add(new Vector3D(v.uv1.X, v.uv1.Y, 0)); textureCoords2.Add(new Vector3D(v.uv2.X, v.uv2.Y, 0)); vertexColors.Add(new Color4D(v.col.X, v.col.Y, v.col.Z, v.col.W)); mesh.TextureCoordinateChannels[0] = textureCoords0; mesh.TextureCoordinateChannels[1] = textureCoords1; mesh.TextureCoordinateChannels[2] = textureCoords2; mesh.VertexColorChannels[0] = vertexColors; } List <int> faces = genericObj.lodMeshes[genericObj.DisplayLODIndex].faces; for (int f = 0; f < faces.Count; f++) { mesh.Faces.Add(new Face(new int[] { faces[f++], faces[f++], faces[f] })); } Console.WriteLine(genericObj.faces.Count); Console.WriteLine(genericObj.vertices.Count); Console.WriteLine(genericObj.Text); mesh.MaterialIndex = genericObj.MaterialIndex; mesh.TextureCoordinateChannels.SetValue(textureCoords0, 0); groupNode.MeshIndices.Add(scene.Meshes.Count); scene.Meshes.Add(mesh); MeshIndex++; modelNode.Children.Add(groupNode); } foreach (var mat in model.Nodes[1].Nodes) { var genericMat = (STGenericMaterial)mat; Material material = new Material(); material.Name = genericMat.Name; foreach (var tex in genericMat.TextureMaps) { TextureSlot slot = new TextureSlot(); slot.FilePath = tex.Name; if (tex.Type == STGenericMatTexture.TextureType.Diffuse) { slot.TextureType = TextureType.Diffuse; } else if (tex.Type == STGenericMatTexture.TextureType.Normal) { slot.TextureType = TextureType.Normals; } else if (tex.Type == STGenericMatTexture.TextureType.Specular) { slot.TextureType = TextureType.Specular; } else if (tex.Type == STGenericMatTexture.TextureType.Emission) { slot.TextureType = TextureType.Emissive; } else if (tex.Type == STGenericMatTexture.TextureType.Light) { slot.Mapping = TextureMapping.FromUV - 1; slot.TextureType = TextureType.Lightmap; } else if (tex.Type == STGenericMatTexture.TextureType.Shadow) { slot.Mapping = TextureMapping.FromUV - 1; slot.TextureType = TextureType.Ambient; } else { slot.TextureType = TextureType.Unknown; } if (tex.wrapModeS == 0) { slot.WrapModeU = TextureWrapMode.Wrap; } if (tex.wrapModeS == 1) { slot.WrapModeU = TextureWrapMode.Mirror; } if (tex.wrapModeS == 2) { slot.WrapModeU = TextureWrapMode.Clamp; } if (tex.wrapModeT == 0) { slot.WrapModeU = TextureWrapMode.Wrap; } if (tex.wrapModeT == 1) { slot.WrapModeU = TextureWrapMode.Mirror; } if (tex.wrapModeT == 2) { slot.WrapModeU = TextureWrapMode.Clamp; } material.AddMaterialTexture(ref slot); } scene.Materials.Add(material); } using (var v = new AssimpContext()) { string ext = System.IO.Path.GetExtension(FileName); string formatID = "obj"; if (ext == ".obj") { formatID = "obj"; } if (ext == ".fbx") { formatID = "fbx"; } if (ext == ".dae") { formatID = "dae"; } Console.WriteLine(ext); Console.WriteLine(formatID); bool Exported = v.ExportFile(scene, FileName, formatID); if (Exported) { System.Windows.Forms.MessageBox.Show($"Exported {FileName} Successfuly!"); } else { System.Windows.Forms.MessageBox.Show($"Failed to export {FileName}!"); } } }
public void ExportAssImp(string fileName, string modelType, ExportSettings settings) { string outDir = Path.GetDirectoryName(fileName); string fileNameNoExt = Path.GetFileNameWithoutExtension(fileName); fileName = Path.Combine(outDir, fileNameNoExt + ".dae"); Scene outScene = new Scene(); outScene.RootNode = new Node("RootNode"); Scenegraph.FillScene(outScene, Joints.FlatSkeleton, settings.UseSkeletonRoot); Materials.FillScene(outScene, Textures, outDir); Shapes.FillScene(outScene, VertexData.Attributes, Joints.FlatSkeleton, SkinningEnvelopes.InverseBindMatrices); Scenegraph.CorrectMaterialIndices(outScene, Materials); if (SkinningEnvelopes.Weights.Count == 0) { Assimp.Node geomNode = new Node(Path.GetFileNameWithoutExtension(fileName), outScene.RootNode); for (int i = 0; i < Shapes.Shapes.Count; i++) { geomNode.MeshIndices.Add(i); } outScene.RootNode.Children.Add(geomNode); } AssimpContext cont = new AssimpContext(); cont.ExportFile(outScene, fileName, "collada", PostProcessSteps.ValidateDataStructure); if (SkinningEnvelopes.Weights.Count == 0) { return; // There's no skinning information, so we can stop here } // Now we need to add some skinning info, since AssImp doesn't do it for some bizarre reason StreamWriter test = new StreamWriter(fileName + ".tmp"); StreamReader dae = File.OpenText(fileName); while (!dae.EndOfStream) { string line = dae.ReadLine(); if (line == " <library_visual_scenes>") { AddControllerLibrary(outScene, test); test.WriteLine(line); test.Flush(); } else if (line.Contains("<node")) { string[] testLn = line.Split('\"'); string name = testLn[3]; if (Joints.FlatSkeleton.Exists(x => x.Name == name)) { string jointLine = line.Replace(">", $" sid=\"{ name }\" type=\"JOINT\">"); test.WriteLine(jointLine); test.Flush(); } else { test.WriteLine(line); test.Flush(); } } else if (line.Contains("</visual_scene>")) { foreach (Mesh mesh in outScene.Meshes) { test.WriteLine($" <node id=\"{ mesh.Name }\" name=\"{ mesh.Name }\" type=\"NODE\">"); test.WriteLine($" <instance_controller url=\"#{ mesh.Name }-skin\">"); test.WriteLine(" <skeleton>#skeleton_root</skeleton>"); test.WriteLine(" <bind_material>"); test.WriteLine(" <technique_common>"); test.WriteLine($" <instance_material symbol=\"theresonlyone\" target=\"#m{ mesh.MaterialIndex }mat\" />"); test.WriteLine(" </technique_common>"); test.WriteLine(" </bind_material>"); test.WriteLine(" </instance_controller>"); test.WriteLine(" </node>"); test.Flush(); } test.WriteLine(line); test.Flush(); } else if (line.Contains("<matrix")) { string matLine = line.Replace("<matrix>", "<matrix sid=\"matrix\">"); test.WriteLine(matLine); test.Flush(); } else { test.WriteLine(line); test.Flush(); } } test.Close(); dae.Close(); File.Copy(fileName + ".tmp", fileName, true); File.Delete(fileName + ".tmp"); }
public void ExportAssImp(string fileName, string modelType, ExportSettings settings, Arguments cmdargs) { fileName = Path.GetFullPath(fileName); // Get absolute path instead of relative string outDir = Path.GetDirectoryName(fileName); string fileNameNoExt = Path.GetFileNameWithoutExtension(fileName); if (modelType == "obj") { fileName = Path.Combine(outDir, fileNameNoExt + ".obj"); } else { fileName = Path.Combine(outDir, fileNameNoExt + ".dae"); } Scene outScene = new Scene { RootNode = new Node("RootNode") }; Console.WriteLine(); Console.WriteLine("Processing Materials ->"); Materials.FillScene(outScene, Textures, outDir); Console.WriteLine(); Console.WriteLine("Processing Meshes ->"); Shapes.FillScene(outScene, VertexData.Attributes, Joints.FlatSkeleton, SkinningEnvelopes.InverseBindMatrices); Console.WriteLine(); Console.Write("Processing Skeleton"); Scenegraph.FillScene(outScene, Joints.FlatSkeleton, settings.UseSkeletonRoot); Scenegraph.CorrectMaterialIndices(outScene, Materials); Console.WriteLine(); Console.WriteLine(); Console.WriteLine("Processing Textures ->"); Textures.DumpTextures(outDir, fileNameNoExt + "_tex_headers.json", true, cmdargs.readMipmaps); string infPath = Path.Combine(outDir, fileNameNoExt + "_hierarchy.json"); this.Scenegraph.DumpJson(infPath); Console.WriteLine(); Console.WriteLine("Removing Duplicate Verticies ->"); foreach (Mesh mesh in outScene.Meshes) { Console.Write(mesh.Name.Replace('_', ' ') + ": "); // Assimp has a JoinIdenticalVertices post process step, but we can't use that or the skinning info we manually add won't take it into account. RemoveDuplicateVertices(mesh); Console.Write("✓"); Console.WriteLine(); } AssimpContext cont = new AssimpContext(); if (modelType == "obj") { Console.WriteLine("Writing the OBJ file..."); cont.ExportFile(outScene, fileName, "obj");//, PostProcessSteps.ValidateDataStructure); using (System.IO.StreamWriter file = new System.IO.StreamWriter(fileName)) { string mtllibname = fileName.Split(new char[] { '\\', '/' }, StringSplitOptions.RemoveEmptyEntries).Last() + ".mtl"; file.WriteLine(String.Format("mtllib {0}", mtllibname)); foreach (Assimp.Mesh mesh in outScene.Meshes) { foreach (Assimp.Vector3D vertex in mesh.Vertices) { file.WriteLine(String.Format("v {0} {1} {2}", vertex.X, vertex.Y, vertex.Z)); } } foreach (Assimp.Mesh mesh in outScene.Meshes) { foreach (Assimp.Vector3D normal in mesh.Normals) { file.WriteLine(String.Format("vn {0} {1} {2}", normal.X, normal.Y, normal.Z)); } } foreach (Assimp.Mesh mesh in outScene.Meshes) { if (mesh.HasTextureCoords(0)) { foreach (Assimp.Vector3D uv in mesh.TextureCoordinateChannels[0]) { file.WriteLine(String.Format("vt {0} {1}", uv.X, uv.Y)); } } } int vertex_offset = 1; foreach (Assimp.Mesh mesh in outScene.Meshes) { string material_name = outScene.Materials[mesh.MaterialIndex].Name; file.WriteLine(String.Format("usemtl {0}", material_name)); foreach (Assimp.Face face in mesh.Faces) { file.Write("f "); foreach (int index in face.Indices) { file.Write(index + vertex_offset); if (mesh.HasTextureCoords(0)) { file.Write("/"); file.Write(index + vertex_offset); } if (!mesh.HasTextureCoords(0) && mesh.HasNormals) { file.Write("//"); file.Write(index + vertex_offset); } else if (mesh.HasNormals) { file.Write("/"); file.Write(index + vertex_offset); } file.Write(" "); } file.Write("\n"); } vertex_offset += mesh.VertexCount; } } return; } else { cont.ExportFile(outScene, fileName, "collada", PostProcessSteps.ValidateDataStructure); } //if (SkinningEnvelopes.Weights.Count == 0) // return; // There's no skinning information, so we can stop here // Now we need to add some skinning info, since AssImp doesn't do it for some bizarre reason StreamWriter test = new StreamWriter(fileName + ".tmp"); StreamReader dae = File.OpenText(fileName); Console.WriteLine(); Console.Write("Finalizing the Mesh"); while (!dae.EndOfStream) { string line = dae.ReadLine(); if (line == " <library_visual_scenes>") { AddControllerLibrary(outScene, test); test.WriteLine(line); test.Flush(); } else if (line.Contains("<node")) { string[] testLn = line.Split('\"'); string name = testLn[3]; if (Joints.FlatSkeleton.Exists(x => x.Name == name)) { string jointLine = line.Replace(">", $" sid=\"{ name }\" type=\"JOINT\">"); test.WriteLine(jointLine); test.Flush(); } else { test.WriteLine(line); test.Flush(); } } else if (line.Contains("</visual_scene>")) { foreach (Mesh mesh in outScene.Meshes) { string matname = "mat"; bool keepmatnames = false; if (keepmatnames == true) { matname = AssimpMatnameSanitize(mesh.MaterialIndex, outScene.Materials[mesh.MaterialIndex].Name); } else { matname = AssimpMatnameSanitize(mesh.MaterialIndex, Materials.m_Materials[mesh.MaterialIndex].Name); } test.WriteLine($" <node id=\"{ mesh.Name }\" name=\"{ mesh.Name }\" type=\"NODE\">"); test.WriteLine($" <instance_controller url=\"#{ mesh.Name }-skin\">"); test.WriteLine(" <skeleton>#skeleton_root</skeleton>"); test.WriteLine(" <bind_material>"); test.WriteLine(" <technique_common>"); test.WriteLine($" <instance_material symbol=\"m{matname}\" target=\"#{matname}\" />"); test.WriteLine(" </technique_common>"); test.WriteLine(" </bind_material>"); test.WriteLine(" </instance_controller>"); test.WriteLine(" </node>"); test.Flush(); } test.WriteLine(line); test.Flush(); } else if (line.Contains("<matrix")) { string matLine = line.Replace("<matrix>", "<matrix sid=\"matrix\">"); test.WriteLine(matLine); test.Flush(); } else { test.WriteLine(line); test.Flush(); } Console.Write("."); } Console.Write("✓"); Console.WriteLine(); test.Close(); dae.Close(); File.Copy(fileName + ".tmp", fileName, true); File.Delete(fileName + ".tmp"); }
public void SaveFromModel(STGenericModel model, string FileName, List <STGenericTexture> Textures) { Scene scene = new Scene(); scene.RootNode = new Node("RootNode"); int MeshIndex = 0; foreach (var obj in model.Nodes[0].Nodes) { var genericObj = (STGenericObject)obj; Mesh mesh = new Mesh(genericObj.Text, PrimitiveType.Triangle); mesh.MaterialIndex = genericObj.MaterialIndex; List <Vector3D> textureCoords0 = new List <Vector3D>(); List <Vector3D> textureCoords1 = new List <Vector3D>(); List <Vector3D> textureCoords2 = new List <Vector3D>(); List <Color4D> vertexColors = new List <Color4D>(); foreach (Vertex v in genericObj.vertices) { mesh.Vertices.Add(new Vector3D(v.pos.X, v.pos.Y, v.pos.Z)); mesh.Normals.Add(new Vector3D(v.nrm.X, v.nrm.Y, v.nrm.Z)); textureCoords0.Add(new Vector3D(v.uv0.X, v.uv0.Y, 0)); textureCoords1.Add(new Vector3D(v.uv1.X, v.uv1.Y, 0)); textureCoords2.Add(new Vector3D(v.uv2.X, v.uv2.Y, 0)); vertexColors.Add(new Color4D(v.col.X, v.col.Y, v.col.Z, v.col.W)); mesh.TextureCoordinateChannels[0] = textureCoords0; mesh.TextureCoordinateChannels[1] = textureCoords1; mesh.TextureCoordinateChannels[2] = textureCoords2; mesh.VertexColorChannels[0] = vertexColors; } List <int> faces = genericObj.lodMeshes[genericObj.DisplayLODIndex].faces; for (int f = 0; f < faces.Count; f++) { mesh.Faces.Add(new Face(new int[] { faces[f++], faces[f++], faces[f] })); } mesh.TextureCoordinateChannels.SetValue(textureCoords0, 0); scene.Meshes.Add(mesh); MeshIndex++; } string TextureExtension = ".png"; string TexturePath = System.IO.Path.GetDirectoryName(FileName); foreach (var mat in model.Nodes[1].Nodes) { var genericMat = (STGenericMaterial)mat; Material material = new Material(); material.Name = genericMat.Text; foreach (var tex in genericMat.TextureMaps) { TextureSlot slot = new TextureSlot(); string path = System.IO.Path.Combine(TexturePath, tex.Name + TextureExtension); slot.FilePath = path; slot.UVIndex = 0; slot.Flags = 0; slot.TextureIndex = 0; slot.BlendFactor = 1.0f; slot.Mapping = TextureMapping.FromUV; slot.Operation = TextureOperation.Add; if (tex.Type == STGenericMatTexture.TextureType.Diffuse) { slot.TextureType = TextureType.Diffuse; } else if (tex.Type == STGenericMatTexture.TextureType.Normal) { slot.TextureType = TextureType.Normals; } else if (tex.Type == STGenericMatTexture.TextureType.Specular) { slot.TextureType = TextureType.Specular; } else if (tex.Type == STGenericMatTexture.TextureType.Emission) { slot.TextureType = TextureType.Emissive; } else if (tex.Type == STGenericMatTexture.TextureType.Light) { slot.TextureType = TextureType.Lightmap; slot.UVIndex = 2; } else if (tex.Type == STGenericMatTexture.TextureType.Shadow) { slot.TextureType = TextureType.Ambient; slot.UVIndex = 1; } else { slot.TextureType = TextureType.Unknown; } if (tex.wrapModeS == 0) { slot.WrapModeU = TextureWrapMode.Wrap; } if (tex.wrapModeS == 1) { slot.WrapModeU = TextureWrapMode.Mirror; } if (tex.wrapModeS == 2) { slot.WrapModeU = TextureWrapMode.Clamp; } if (tex.wrapModeT == 0) { slot.WrapModeV = TextureWrapMode.Wrap; } if (tex.wrapModeT == 1) { slot.WrapModeV = TextureWrapMode.Mirror; } if (tex.wrapModeT == 2) { slot.WrapModeV = TextureWrapMode.Clamp; } else { slot.WrapModeU = TextureWrapMode.Wrap; slot.WrapModeV = TextureWrapMode.Wrap; } material.AddMaterialTexture(ref slot); } scene.Materials.Add(material); } foreach (var tex in Textures) { string path = System.IO.Path.Combine(TexturePath, tex.Name + TextureExtension); if (!System.IO.File.Exists(path)) { tex.GetBitmap().Save(path); } } using (var v = new AssimpContext()) { string ext = System.IO.Path.GetExtension(FileName); string formatID = "obj"; if (ext == ".obj") { formatID = "obj"; } if (ext == ".fbx") { formatID = "collada"; } if (ext == ".dae") { formatID = "collada"; } if (v.ExportFile(scene, FileName, formatID, PostProcessSteps.ValidateDataStructure)) { System.Windows.Forms.MessageBox.Show($"Exported {FileName} Successfuly!"); } else { System.Windows.Forms.MessageBox.Show($"Failed to export {FileName}!"); } } }
public void ExportMesh(GameObject go, string path) { Vector3 lastPos = go.transform.position; go.transform.position = Vector3.zero; Scene scene = new Scene(); List <string> sameNames = new List <string>(); List <Transform> children = new List <Transform>(); Dictionary <Transform, Node> nodesByTransform = new Dictionary <Transform, Node>(); GetAllChildren(children, go.transform); foreach (Transform child in children) { string nname = child.name; if (sameNames.Contains(nname)) { nname += "_"; } else { sameNames.Add(nname); } Node node = new Node(nname); UnityEngine.Matrix4x4 m = child.localToWorldMatrix.inverse; node.Transform = new Assimp.Matrix4x4( m.m00, m.m01, m.m02, m.m03, m.m10, m.m11, m.m12, m.m13, m.m20, m.m21, m.m22, m.m23, m.m30, m.m31, m.m32, m.m33 ); nodesByTransform.Add(child, node); if (child == go.transform) { Node rootNode = new Node(Path.GetFileNameWithoutExtension(path)); rootNode.Children.Add(node); scene.RootNode = rootNode; } } foreach (Transform child in children) { foreach (Transform c in child) { if (child == go.transform) { scene.RootNode.Children.Add(nodesByTransform[c]); } else { nodesByTransform[child].Children.Add(nodesByTransform[c]); } } } sameNames.Clear(); MeshFilter[] mfs = go.GetComponentsInChildren <MeshFilter>(); SkinnedMeshRenderer[] smrs = go.GetComponentsInChildren <SkinnedMeshRenderer>(); int meshIndex = 0; foreach (var mf in mfs) { PdxShape shape = mf.GetComponent <PdxShape>(); Assimp.Material mat = new Assimp.Material(); mat.Name = shape.shader; TextureSlot diff = new TextureSlot(); diff.FilePath = shape.diffuse; diff.TextureType = TextureType.Diffuse; diff.UVIndex = 0; //mat.TextureDiffuse = diff; mat.AddMaterialTexture(ref diff); TextureSlot norm = new TextureSlot(); norm.FilePath = shape.normal; norm.TextureType = TextureType.Normals; norm.UVIndex = 0; //mat.TextureNormal = norm; mat.AddMaterialTexture(ref norm); TextureSlot spec = new TextureSlot(); spec.FilePath = shape.specular; spec.TextureType = TextureType.Specular; spec.UVIndex = 0; //mat.TextureSpecular = spec; mat.AddMaterialTexture(ref spec); scene.Materials.Add(mat); Assimp.Mesh am = null; am = FromUnityMesh(mf.mesh, "pShape" + meshIndex, go.transform); if (sameNames.Contains(am.Name)) { am.Name += "_"; } else { sameNames.Add(am.Name); } am.MaterialIndex = meshIndex; scene.Meshes.Add(am); nodesByTransform[mf.transform].MeshIndices.Add(meshIndex); meshIndex++; } foreach (var smr in smrs) { PdxShape shape = smr.GetComponent <PdxShape>(); Assimp.Material mat = new Assimp.Material(); mat.Name = shape.shader; TextureSlot diff = new TextureSlot(); diff.FilePath = shape.diffuse; diff.TextureType = TextureType.Diffuse; diff.UVIndex = 0; //mat.TextureDiffuse = diff; mat.AddMaterialTexture(ref diff); TextureSlot norm = new TextureSlot(); norm.FilePath = shape.normal; norm.TextureType = TextureType.Normals; norm.UVIndex = 0; //mat.TextureNormal = norm; mat.AddMaterialTexture(ref norm); TextureSlot spec = new TextureSlot(); spec.FilePath = shape.specular; spec.TextureType = TextureType.Specular; spec.UVIndex = 0; //mat.TextureSpecular = spec; mat.AddMaterialTexture(ref spec); scene.Materials.Add(mat); Assimp.Mesh am = null; UnityEngine.Mesh baked = new UnityEngine.Mesh(); smr.BakeMesh(baked); am = FromUnityMesh(baked /*smr.sharedMesh*/, "pShape" + meshIndex, go.transform); if (sameNames.Contains(am.Name)) { am.Name += "_"; } else { sameNames.Add(am.Name); } am.MaterialIndex = meshIndex; scene.Meshes.Add(am); nodesByTransform[smr.transform].MeshIndices.Add(meshIndex); meshIndex++; } AssimpContext context = new AssimpContext(); bool result = context.ExportFile(scene, path, "obj", PostProcessSteps.MakeLeftHanded | PostProcessSteps.FlipWindingOrder); context.Dispose(); go.transform.position = lastPos; if (result) { EditorController.instance.Status("Object saved as " + path); } else { EditorController.instance.Status("Export failed :(", 2); } }
private void DoExport(Scene scene, string id) { var overwriteWithoutConfirmation = checkBoxNoOverwriteConfirm.Checked; var path = textBoxPath.Text.Trim(); path = (path.Length > 0 ? path : scene.BaseDir); var name = textBoxFileName.Text.Trim(); var fullPath = Path.Combine(path, name); if (!overwriteWithoutConfirmation && Path.GetFullPath(fullPath) == Path.GetFullPath(scene.File)) { if (MessageBox.Show("This will overwrite the current scene's source file. Continue?", "Warning", MessageBoxButtons.YesNo, MessageBoxIcon.Warning) == DialogResult.No) { PushLog("Canceled"); return; } } var copyTextures = checkBoxCopyTexturesToSubfolder.Checked; var relativeTexturePaths = checkBoxUseRelativeTexturePaths.Checked; var includeAnimations = checkBoxIncludeAnimations.Checked; var includeSceneHierarchy = checkBoxIncludeSceneHierarchy.Checked; var textureCopyJobs = new Dictionary <string, string>(); var textureDestinationFolder = textBoxCopyTexturesToFolder.Text; PushLog("*** Export: " + scene.File); if (copyTextures) { try { Directory.CreateDirectory(Path.Combine(path, textureDestinationFolder)); } catch (Exception) { PushLog("Failed to create texture destination directory " + Path.Combine(path, textureDestinationFolder)); return; } } progressBarExport.Style = ProgressBarStyle.Marquee; progressBarExport.MarqueeAnimationSpeed = 5; // Create a shallow copy of the original scene that replaces all the texture paths with their // corresponding output paths, and omits animations if requested. var sourceScene = new Assimp.Scene { }; sourceScene.Textures.AddRange(scene.Raw.Textures); sourceScene.SceneFlags = scene.Raw.SceneFlags; sourceScene.RootNode = scene.Raw.RootNode; sourceScene.Meshes.AddRange(scene.Raw.Meshes); sourceScene.Lights.AddRange(scene.Raw.Lights); sourceScene.Cameras.AddRange(scene.Raw.Cameras); if (includeAnimations) { sourceScene.Animations.AddRange(scene.Raw.Animations); } var uniques = new HashSet <string>(); var textureMapping = new Dictionary <string, string>(); PushLog("Locating all textures"); foreach (var texId in scene.TextureSet.GetTextureIds()) { // TODO(acgessler): Verify if this handles texture replacements and GUID-IDs correctly. var destName = texId; // Broadly skip over embedded (in-memory) textures if (destName.StartsWith("*")) { PushLog("Ignoring embedded texture: " + destName); continue; } // Locate the texture on-disk string diskLocation; try { TextureLoader.ObtainStream(texId, scene.BaseDir, out diskLocation).Close(); } catch (IOException) { PushLog("Failed to locate texture " + texId); continue; } if (copyTextures) { destName = GeUniqueTextureExportPath(path, textureDestinationFolder, diskLocation, uniques); } if (relativeTexturePaths) { textureMapping[texId] = GetRelativePath(path + "\\", destName); } else { textureMapping[texId] = destName; } textureCopyJobs[diskLocation] = destName; PushLog("Texture " + texId + " maps to " + textureMapping[texId]); } foreach (var mat in scene.Raw.Materials) { sourceScene.Materials.Add(CloneMaterial(mat, textureMapping)); } var t = new Thread(() => { using (var v = new AssimpContext()) { PushLog("Exporting using Assimp to " + fullPath + ", using format id: " + id); var result = v.ExportFile(sourceScene, fullPath, id, includeSceneHierarchy ? PostProcessSteps.None : PostProcessSteps.PreTransformVertices); _main.BeginInvoke(new MethodInvoker(() => { progressBarExport.Style = ProgressBarStyle.Continuous; progressBarExport.MarqueeAnimationSpeed = 0; if (!result) { // TODO: get native error message PushLog("Export failure"); MessageBox.Show("Failed to export to " + fullPath, "Export error", MessageBoxButtons.OK, MessageBoxIcon.Error); } else { if (copyTextures) { PushLog("Copying textures"); foreach (var kv in textureCopyJobs) { PushLog(" ... " + kv.Key + " -> " + kv.Value); try { File.Copy(kv.Key, kv.Value, false); } catch (IOException) { if (!File.Exists(kv.Value)) { throw; } if (!overwriteWithoutConfirmation && MessageBox.Show("Texture " + kv.Value + " already exists. Overwrite?", "Overwrite Warning", MessageBoxButtons.YesNo, MessageBoxIcon.Warning) == DialogResult.No) { PushLog("Exists already, skipping"); continue; } PushLog("Exists already, overwriting"); File.Copy(kv.Key, kv.Value, true); } catch (Exception ex) { PushLog(ex.Message); } } } if (checkBoxOpenExportedFile.Checked) { _main.AddTab(fullPath, true, false); } PushLog("Export completed"); } })); } }); t.Start(); }
public void ExportAssImp(string fileName, string outFilepath, string modelType, ExportSettings settings, bool keepmatnames = true) { string outDir = Path.GetDirectoryName(outFilepath); //string fileNameNoExt = Path.GetFileNameWithoutExtension(fileName); fileName = outFilepath;//Path.Combine(outDir, fileNameNoExt + ".dae"); Scene outScene = new Scene(); outScene.RootNode = new Node("RootNode"); Scenegraph.FillScene(outScene, Joints.FlatSkeleton, settings.UseSkeletonRoot); Dictionary <string, int> slots_to_uvindex = Materials.FillScene(outScene, Textures, outDir, keepmatnames); Shapes.FillScene(outScene, VertexData.Attributes, Joints.FlatSkeleton, SkinningEnvelopes.InverseBindMatrices); Scenegraph.CorrectMaterialIndices(outScene, Materials); Textures.DumpTextures(outDir); foreach (Mesh mesh in outScene.Meshes) { Console.WriteLine(String.Format("Texcoord count: {0}", mesh.TextureCoordinateChannelCount)); } if (true) //(SkinningEnvelopes.Weights.Count == 0) { Assimp.Node geomNode = new Node(Path.GetFileNameWithoutExtension(fileName), outScene.RootNode); for (int i = 0; i < Shapes.Shapes.Count; i++) { geomNode.MeshIndices.Add(i); } outScene.RootNode.Children.Add(geomNode); } AssimpContext cont = new AssimpContext(); cont.ExportFile(outScene, fileName, "collada", PostProcessSteps.ValidateDataStructure | PostProcessSteps.JoinIdenticalVertices); //cont.ExportFile(outScene, fileName, "collada"); List <string> a; //if (SkinningEnvelopes.Weights.Count == 0) // return; // There's no skinning information, so we can stop here //return; // adding skinning info is buggy so we won't do it // Now we need to add some skinning info, since AssImp doesn't do it for some bizarre reason bool hasWeights = SkinningEnvelopes.Weights.Count != 0; hasWeights = false; StreamWriter test = new StreamWriter(fileName + ".tmp"); StreamReader dae = File.OpenText(fileName); bool dontWrite = false; while (!dae.EndOfStream) { string line = dae.ReadLine(); //if (SkinningEnvelopes.Weights.Count != 0) { if (hasWeights && line == " <library_visual_scenes>") { AddControllerLibrary(outScene, test); test.WriteLine(line); test.Flush(); } else if (hasWeights && line.Contains("<node")) { string[] testLn = line.Split('\"'); string name = testLn[3]; if (Joints.FlatSkeleton.Exists(x => x.Name == name)) { string jointLine = line.Replace(">", $" sid=\"{ name }\" type=\"JOINT\">"); test.WriteLine(jointLine); test.Flush(); } else { test.WriteLine(line); test.Flush(); } } else if (hasWeights && line.Contains("</visual_scene>")) { foreach (Mesh mesh in outScene.Meshes) { string matname = "mat"; if (keepmatnames == true) { matname = AssimpMatnameSanitize(mesh.MaterialIndex, outScene.Materials[mesh.MaterialIndex].Name); } else { matname = AssimpMatnameSanitize(mesh.MaterialIndex, matname); } test.WriteLine($" <node id=\"{ mesh.Name }\" name=\"{ mesh.Name }\" type=\"NODE\">"); test.WriteLine($" <instance_controller url=\"#{ mesh.Name }-skin\">"); test.WriteLine(" <skeleton>#skeleton_root</skeleton>"); test.WriteLine(" <bind_material>"); test.WriteLine(" <technique_common>"); test.WriteLine($" <instance_material symbol=\"theresonlyone\" target=\"#{matname}\" />"); test.WriteLine(" </technique_common>"); test.WriteLine(" </bind_material>"); test.WriteLine(" </instance_controller>"); test.WriteLine(" </node>"); test.Flush(); } test.WriteLine(line); test.Flush(); } else if (hasWeights && line.Contains("<matrix")) { string matLine = line.Replace("<matrix>", "<matrix sid=\"matrix\">"); test.WriteLine(matLine); test.Flush(); } else if (line.Contains("<library_images>")) { dontWrite = true; Console.WriteLine("Hello Hallo"); } else if (line.Contains("</library_images>")) { dontWrite = false; Console.WriteLine("Hello Hallo2"); // Add our own images here test.WriteLine(" <library_images>"); WriteTexturesToStream(outScene, test); test.WriteLine(line); test.Flush(); } else if (line.Contains("<library_effects>")) { dontWrite = true; Console.WriteLine("Hello Hallo3"); // We get rid of the existing library effects } else if (line.Contains("</library_effects>")) { dontWrite = false; Console.WriteLine("Hello Hallo4"); // Add our own library_effects here test.WriteLine(" <library_effects>"); WriteMaterialsToStream(outScene, test, slots_to_uvindex); test.WriteLine(line); test.Flush(); } else if (!dontWrite) { test.WriteLine(line); test.Flush(); } } test.Close(); dae.Close(); File.Copy(fileName + ".tmp", fileName, true); File.Delete(fileName + ".tmp"); }
public void ToDAEFile(string file_name) { AssimpContext cont = new AssimpContext(); cont.ExportFile(BuildDAEScene(), file_name, "collada", 0); }
private void lvFiles_SelectedIndexChanged(object sender, EventArgs e) { if (lvFiles.SelectedItems.Count <= 0) { pbPreview.Width = 0; pbPreview.Visible = false; rtbPreview.Width = 0; rtbPreview.Visible = false; splitContainer.SplitterDistance = this.Width; lbSelection.Text = String.Empty; return; } if (File.Exists(currentMeshFile)) { File.Delete(currentMeshFile); } if (File.Exists(currentMeshFile + ".mtl")) { File.Delete(currentMeshFile + ".mtl"); } if (glControl != null) { if (glControl.GLrender != null) { glControl.GLrender.ClearAllObjects(); glControl.GLrender.GLControlInstance.Dispose(); } glControl.Dispose(); } ListViewItem Item = lvFiles.SelectedItems[0]; lbSelection.Text = String.Format("Sel {0}", Item.Index + 1); ImageListIndex indx = FileType.GetImageIndex(Path.GetExtension(Item.Text)); if (indx == ImageListIndex.Image) { pbPreview.Width = 399; pbPreview.Visible = true; rtbPreview.Width = 0; rtbPreview.Visible = false; pnlPreview.Visible = false; ArchiveEntry ent = m_Archive.getByName(Path.GetFileNameWithoutExtension(Item.Text)); Image img = null; using (MemoryStream ms = new MemoryStream(ent.getData())) { try { if (Path.GetExtension(Item.Text) == ".tga") { TargaImage tgaImg = new TargaImage(ms); img = tgaImg.Image; } else { img = Image.FromStream(ms); } } catch { } } if (img != null) { pbPreview.Image = img; pbPreview.Width = img.Width; pbPreview.Location = new Point(pbPreview.Location.X, (this.Height / 2) - (img.Height / 2) - 20); splitContainer.SplitterDistance = Math.Max(this.Width - img.Width - 20, 200); } } else if (indx == ImageListIndex.Text) { pbPreview.Width = 0; pbPreview.Visible = false; rtbPreview.Width = 500; rtbPreview.Visible = true; pnlPreview.Visible = false; splitContainer.SplitterDistance = this.Width - 500; rtbPreview.Text = ""; ArchiveEntry ent = m_Archive.getByName(Path.GetFileNameWithoutExtension(Item.Text)); if (ent != null) { rtbPreview.Text = Encoding.Default.GetString(ent.getData()); } } else if (indx == ImageListIndex.Mesh) { pnlPreview.Visible = true; splitContainer.SplitterDistance = this.Width - 500; glControl = new OGLControl(); glControl.Parent = pnlPreview; glControl.Dock = DockStyle.Fill; glContext = new OpenGLContext(glControl); glControl.GLrender.PrimitiveTypes = OpenTK.Graphics.OpenGL.PrimitiveType.Triangles; glControl.GLrender.Camera.ZNear = 0.01f; glControl.GLrender.Camera.ZFar = float.MaxValue; string tempFile = Path.GetTempFileName(); currentMeshFile = Path.ChangeExtension(Path.GetTempFileName(), "obj"); ArchiveEntry ent = m_Archive.getByName(Path.GetFileNameWithoutExtension(Item.Text)); ent.extractTo(tempFile, true); using (AssimpContext context = new AssimpContext()) { Scene mesh = context.ImportFile(tempFile); context.ExportFile(mesh, currentMeshFile, "obj"); } File.Delete(tempFile); Model model = new Model(currentMeshFile); glControl.GLrender.AddModel(model); glControl.GLrender.SelectedModelIndex = 0; } else { pbPreview.Width = 0; pbPreview.Visible = false; rtbPreview.Width = 0; rtbPreview.Visible = false; pnlPreview.Visible = false; } }