/// <summary> /// Processes the scene nodes. /// </summary> /// <param name="root">The root.</param> /// <returns></returns> protected virtual ErrorCode ProcessSceneNodes(HxScene.SceneNode root) { if (root == null) { return(ErrorCode.Failed); } SceneNodes.Add(root); SceneNodes.AddRange(root.Items.PreorderDFT(n => { return(true); })); return(ErrorCode.Succeed); }
/// <summary> /// Gets the material from node. Currently only supports <see cref="HxScene.MaterialGeometryNode"/> /// </summary> /// <param name="node">The node.</param> /// <param name="material">The material.</param> /// <returns></returns> protected virtual bool GetMaterialFromNode(HxScene.SceneNode node, out MaterialCore material) { if (node is HxScene.MaterialGeometryNode geo) { material = geo.Material; return(material != null); } else { material = null; return(false); } }
/// <summary> /// Gets the geometry from node. Currently only supports <see cref="HxScene.GeometryNode"/> /// </summary> /// <param name="node">The node.</param> /// <param name="geometry">The geometry.</param> /// <returns></returns> protected virtual bool GetGeometryFromNode(HxScene.SceneNode node, out Geometry3D geometry) { if (node is HxScene.GeometryNode geo) { geometry = geo.Geometry; return(true); } else { geometry = null; return(false); } }
private Node ConstructAssimpNode(HxScene.SceneNode current, Node parent) { var node = new Node(string.IsNullOrEmpty(current.Name) ? "Node" : current.Name, parent) { Transform = current.ModelMatrix.ToAssimpMatrix(configuration.ToSourceMatrixColumnMajor) }; if (current is HxScene.GroupNodeBase group) { foreach (var s in group.Items) { if (s is HxScene.GeometryNode geo) { var key = GetMaterialGeoKey(geo, out var materialIndex, out var geoIndex); if (meshInfos.TryGetValue(key, out var meshInfo)) { node.MeshIndices.Add(meshInfo.MeshIndex); } } else if (s is HxScene.GroupNodeBase) { node.Children.Add(ConstructAssimpNode(s, node)); } else { logger.LogWarning("Current node type does not support yet. Type: {}", s.GetType().Name); } } if (group.Metadata != null) { foreach (var metadata in group.Metadata.ToAssimpMetadata()) { node.Metadata.Add(metadata.Key, metadata.Value); } } } else if (current is HxScene.GeometryNode geo) { var key = GetMaterialGeoKey(geo, out var materialIndex, out var geoIndex); if (meshInfos.TryGetValue(key, out var meshInfo)) { node.MeshIndices.Add(meshInfo.MeshIndex); } } else { logger.LogWarning("Current node type does not support yet. Type: {}", current.GetType().Name); } return(node); }
/// <summary> /// Exports to file. /// </summary> /// <param name="filePath">The file path.</param> /// <param name="root">The root.</param> /// <param name="formatId">The format identifier. <see cref="SupportedFormats"/></param> /// <returns></returns> public ErrorCode ExportToFile(string filePath, HxScene.SceneNode root, string formatId) { Clear(); AssimpContext exporter = null; var useExtern = false; if (Configuration.ExternalContext != null) { exporter = Configuration.ExternalContext; useExtern = true; } else { exporter = new AssimpContext(); } if (!exporter.IsExportFormatSupported(Path.GetExtension(filePath))) { return(ErrorCode.Failed | ErrorCode.FileTypeNotSupported); } var scene = CreateScene(root); var postProcessing = configuration.PostProcessing; if (configuration.FlipWindingOrder) { postProcessing |= PostProcessSteps.FlipWindingOrder; } try { if (!exporter.ExportFile(scene, filePath, formatId, postProcessing)) { logger.LogError("Export failed. FilePath: {}; Format: {}", filePath, formatId); return(ErrorCode.Failed); } return(ErrorCode.Succeed); } catch (Exception ex) { logger.LogError(ex.Message); AssimpExceptionOccurred?.Invoke(this, ex); } finally { if (!useExtern) { exporter.Dispose(); } } return(ErrorCode.Failed); }
private Scene CreateScene(HxScene.SceneNode root) { CollectAllGeometriesAndMaterials(root); var scene = new Scene(); //Adds material and meshes into the assimp scene foreach (var material in materialCollection.OrderBy(x => x.Value)) { scene.Materials.Add(OnCreateAssimpMaterial(material.Key)); } scene.RootNode = ConstructAssimpNode(root, null); scene.Meshes.AddRange(meshInfos.Select(x => x.Value.AssimpMesh)); AddAnimationsToScene(scene); return(scene); }
private void SyncNamesWithElement3DAndSceneNode(HxScene.SceneNode node) { foreach (var n in node.Traverse()) { if (n.WrapperSource is Element3D ele) { if (string.IsNullOrEmpty(ele.Name)) { continue; } else if (string.IsNullOrEmpty(node.Name)) { node.Name = ele.Name; } } } }
private void CollectAllGeometriesAndMaterials(HxScene.SceneNode root) { // Collect all geometries and materials foreach (var node in root.Traverse()) { if (GetMaterialFromNode(node, out var material) && !materialCollection.ContainsKey(material)) { materialCollection.Add(material, materialCollection.Count); } if (GetGeometryFromNode(node, out var geometry) && !geometryCollection.ContainsKey(geometry)) { geometryCollection.Add(geometry, geometryCollection.Count); } } foreach (var node in root.Traverse()) { if (node is HxScene.GeometryNode geo) { var info = OnCreateMeshInfo(geo); if (info == null) { logger.LogWarning("Create Mesh info failed. Node Name: {}", geo.Name); continue; } if (!meshInfos.ContainsKey(info.MaterialMeshKey)) { meshInfos.Add(info.MaterialMeshKey, info); } } } if (configuration.EnableParallelProcessing) { Parallel.ForEach(meshInfos, (info) => { info.Value.AssimpMesh = OnCreateAssimpMesh(info.Value); }); } else { foreach (var info in meshInfos) { info.Value.AssimpMesh = OnCreateAssimpMesh(info.Value); } } }
/// <summary> /// Exports to BLOB. /// </summary> /// <param name="root">The root.</param> /// <param name="formatId">The format identifier.</param> /// <param name="blob">The BLOB.</param> /// <returns></returns> public ErrorCode ExportToBlob(HxScene.SceneNode root, string formatId, out ExportDataBlob blob) { Clear(); AssimpContext exporter = null; var useExtern = false; if (Configuration.ExternalContext != null) { exporter = Configuration.ExternalContext; useExtern = true; } else { exporter = new AssimpContext(); } var scene = CreateScene(root); var postProcessing = configuration.PostProcessing; if (configuration.FlipWindingOrder) { postProcessing |= PostProcessSteps.FlipWindingOrder; } blob = null; try { blob = exporter.ExportToBlob(scene, formatId, postProcessing); return(ErrorCode.Succeed); } catch (Exception ex) { logger.LogError(ex.Message); AssimpExceptionOccurred?.Invoke(this, ex); } finally { if (!useExtern) { exporter.Dispose(); } } return(ErrorCode.Failed); }
/// <summary> /// Convert a HelixToolkit scene graph to the assimp scene. /// </summary> /// <param name="root">The HelixToolkit scene graph root node.</param> /// <param name="assimpScene">The assimp scene.</param> /// <returns></returns> public ErrorCode ToAssimpScene(HxScene.SceneNode root, out Scene assimpScene) { Clear(); assimpScene = CreateScene(root); return(ErrorCode.Succeed); }