private void ParseRhinoHierarchy() { RhinoSceneHierarchyNode DummyDocumentNode = SceneRoot; if (bIsInWorksession) { // Rhino worksession adds dummy layers (with non consistent IDs) to all of the linked documents except the active one. // This can cause reimport inconsistencies when the active document changes, as dummies are shuffled and some may be created while others destroyed. // To address this issue we add our own "Current Document Layer" dummy layer, and use the file path as ActorElement name, // that way there are no actors deleted and the Datasmith IDs stay consistent. string DummyLayerName = RhinoDocument.Path; string DummyLayerLabel = RhinoDocument.Name; const int DefaultMaterialIndex = -1; const int DummyLayerIndex = -1; DummyDocumentNode = SceneRoot.AddChild(GenerateDummyNodeInfo(DummyLayerName, DummyLayerLabel, DefaultMaterialIndex, ExportOptions.Xform), DummyLayerIndex); LayerIndexToLayerString.Add(DummyLayerIndex, BuildLayerString(DummyDocumentNode.Info.Label, SceneRoot)); } foreach (var CurrentLayer in RhinoDocument.Layers) { //Only add Layers directly under root, the recursion will do the rest. if (CurrentLayer.ParentLayerId == Guid.Empty) { RhinoSceneHierarchyNode ParentNode = bIsInWorksession && !CurrentLayer.IsReference ? DummyDocumentNode : SceneRoot; RecursivelyParseLayerHierarchy(CurrentLayer, ParentNode); } } }
private void RecursivelyParseLayerHierarchy(Layer CurrentLayer, RhinoSceneHierarchyNode ParentNode) { if (!CurrentLayer.IsVisible || CurrentLayer.IsDeleted) { return; } int MaterialIndex = CurrentLayer.RenderMaterialIndex; Transform ParentTransform = ParentNode.bIsRoot ? ExportOptions.Xform : ParentNode.Info.WorldTransform; RhinoSceneHierarchyNodeInfo NodeInfo = GenerateNodeInfo(CurrentLayer, ParentNode.bIsInstanceDefinition, MaterialIndex, ParentTransform); RhinoSceneHierarchyNode CurrentNode = ParentNode.AddChild(NodeInfo, CurrentLayer.Index); GuidToHierarchyNodeDictionary.Add(CurrentLayer.Id, CurrentNode); LayerIndexToLayerString.Add(CurrentLayer.Index, BuildLayerString(CurrentLayer, ParentNode)); AddMaterialIndexMapping(CurrentLayer.RenderMaterialIndex); RhinoObject[] ObjectsInLayer = RhinoDocument.Objects.FindByLayer(CurrentLayer); RecursivelyParseObjectInstance(ObjectsInLayer, CurrentNode); Layer[] ChildrenLayer = CurrentLayer.GetChildren(); if (ChildrenLayer != null) { foreach (var ChildLayer in ChildrenLayer) { RecursivelyParseLayerHierarchy(ChildLayer, CurrentNode); } } if (CurrentNode.GetChildrenCount() == 0) { // This layer is empty, remove it. ParentNode.RemoveChild(CurrentNode); } }
public static string EvaluateAttributeUserText(RhinoSceneHierarchyNode InNode, string ValueFormula) { if (!ValueFormula.StartsWith("%<") || !ValueFormula.EndsWith(">%")) { // Nothing to evaluate, just return the string as-is. return(ValueFormula); } RhinoObject NodeObject = InNode.Info.RhinoModelComponent as RhinoObject; RhinoObject ParentObject = null; RhinoSceneHierarchyNode CurrentNode = InNode; while (CurrentNode.LinkedNode != null) { CurrentNode = CurrentNode.LinkedNode; ParentObject = CurrentNode.Info.RhinoModelComponent as RhinoObject; } // In case this is an instance of a block sub-object, the ID held in the formula may not have been updated // with the definition object ID. We need to replace the ID with the definition object ID, otherwise the formula // will not evaluate correctly. if (InNode.LinkedNode != null && !InNode.LinkedNode.bIsRoot) { int IdStartIndex = ValueFormula.IndexOf("(\"") + 2; int IdEndIndex = ValueFormula.IndexOf("\")"); if (IdStartIndex >= 0 && IdEndIndex > IdStartIndex) { ValueFormula = ValueFormula.Remove(IdStartIndex, IdEndIndex - IdStartIndex); ValueFormula = ValueFormula.Insert(IdStartIndex, NodeObject.Id.ToString()); } } return(RhinoApp.ParseTextField(ValueFormula, NodeObject, ParentObject)); }
private static void AddActorToParent(FDatasmithFacadeActor InDatasmithActor, RhinoSceneHierarchyNode InNode, FDatasmithFacadeScene InDatasmithScene) { if (InNode.Parent.bIsRoot) { InDatasmithScene.AddActor(InDatasmithActor); } else { InNode.Parent.DatasmithActor.AddChild(InDatasmithActor); } }
private static FDatasmithFacadeActor ParseEmptyActor(RhinoSceneHierarchyNode InNode) { string HashedName = FDatasmithFacadeElement.GetStringHash(InNode.Info.Name); FDatasmithFacadeActor DatasmithActor = new FDatasmithFacadeActor(HashedName); DatasmithActor.SetLabel(InNode.Info.Label); float[] MatrixArray = InNode.Info.WorldTransform.ToFloatArray(false); DatasmithActor.SetWorldTransform(MatrixArray); return(DatasmithActor); }
private int GetMaterialIndexFromAttributes(RhinoSceneHierarchyNode HierarchyNode, ObjectAttributes Attributes) { if (Attributes.MaterialSource == ObjectMaterialSource.MaterialFromObject) { return(Attributes.MaterialIndex); } else if (HierarchyNode.Info != null) { return(HierarchyNode.Info.MaterialIndex); } // Return default material index return(-1); }
private void InstanciateDefinition(RhinoSceneHierarchyNode ParentNode, RhinoSceneHierarchyNode DefinitionNode) { ParentNode.LinkToNode(DefinitionNode); for (int ChildIndex = 0; ChildIndex < DefinitionNode.GetChildrenCount(); ++ChildIndex) { RhinoSceneHierarchyNode DefinitionChildNode = DefinitionNode.GetChild(ChildIndex); int MaterialIndex = GetObjectMaterialIndex(DefinitionChildNode.Info.RhinoModelComponent as RhinoObject, ParentNode.Info); RhinoSceneHierarchyNodeInfo ChildNodeInfo = GenerateInstanceNodeInfo(ParentNode.Info, DefinitionChildNode.Info, MaterialIndex); RhinoSceneHierarchyNode InstanceChildNode = ParentNode.AddChild(ChildNodeInfo); InstanciateDefinition(InstanceChildNode, DefinitionChildNode); } }
private static string GetDatasmithActorLayers(RhinoSceneHierarchyNode InNode, DatasmithRhinoSceneParser SceneParser) { bool bIsSameAsParentLayer = !(InNode.Info.bHasRhinoLayer || (InNode.Parent.bIsRoot && InNode.Info.RhinoModelComponent == null) || //This is a dummy document layer. (InNode.Parent?.Info.RhinoModelComponent as RhinoObject)?.ObjectType == ObjectType.InstanceReference); if (bIsSameAsParentLayer && InNode.Parent?.DatasmithActor != null) { return(InNode.Parent.DatasmithActor.GetLayer()); } else { return(SceneParser.GetNodeLayerString(InNode)); } }
private void RecursivelyParseObjectInstance(RhinoObject[] InObjects, RhinoSceneHierarchyNode ParentNode) { foreach (RhinoObject CurrentObject in InObjects) { if (CurrentObject == null || IsObjectIgnoredBySelection(CurrentObject, ParentNode) || IsUnsupportedObject(CurrentObject)) { // Skip the object. continue; } RhinoSceneHierarchyNode DefinitionRootNode = null; if (CurrentObject.ObjectType == ObjectType.InstanceReference) { InstanceObject CurrentInstance = CurrentObject as InstanceObject; DefinitionRootNode = GetOrCreateDefinitionRootNode(CurrentInstance.InstanceDefinition); if (DefinitionRootNode.GetChildrenCount() == 0) { // Don't instantiate empty definitions. continue; } } int MaterialIndex = GetObjectMaterialIndex(CurrentObject, ParentNode.Info); RhinoSceneHierarchyNodeInfo ObjectNodeInfo = GenerateNodeInfo(CurrentObject, ParentNode.bIsInstanceDefinition, MaterialIndex, ParentNode.Info.WorldTransform); RhinoSceneHierarchyNode ObjectNode; if (ParentNode.bIsRoot && ParentNode.bIsInstanceDefinition) { // The objects inside a Block definitions may be defined in a different layer than the one we are currently in. ObjectNode = ParentNode.AddChild(ObjectNodeInfo, GetOrCreateLayerIndexHierarchy(CurrentObject.Attributes.LayerIndex)); } else { ObjectNode = ParentNode.AddChild(ObjectNodeInfo); } GuidToHierarchyNodeDictionary.Add(CurrentObject.Id, ObjectNode); AddObjectMaterialReference(CurrentObject, MaterialIndex); if (DefinitionRootNode != null) { InstanciateDefinition(ObjectNode, DefinitionRootNode); } } }
private string BuildLayerString(string LayerName, RhinoSceneHierarchyNode ParentNode) { string CurrentLayerName = LayerName.Replace(',', '_'); if (!ParentNode.bIsRoot) { Layer ParentLayer = ParentNode.Info.RhinoModelComponent as Layer; // If ParentLayer is null, then the parent node is a dummy document layer and we are in a worksession. int ParentLayerIndex = ParentLayer == null ? -1 : ParentLayer.Index; if (LayerIndexToLayerString.TryGetValue(ParentLayerIndex, out string ParentLayerString)) { return(string.Format("{0}_{1}", ParentLayerString, CurrentLayerName)); } } return(CurrentLayerName); }
private static FDatasmithFacadeActor ParseLightActor(RhinoSceneHierarchyNode InNode) { LightObject RhinoLightObject = InNode.Info.RhinoModelComponent as LightObject; FDatasmithFacadeActor ParsedDatasmithActor = SetupLightActor(InNode.Info, RhinoLightObject.LightGeometry); if (ParsedDatasmithActor != null) { float[] MatrixArray = InNode.Info.WorldTransform.ToFloatArray(false); ParsedDatasmithActor.SetWorldTransform(MatrixArray); } else { // #ueent_todo: Log non supported light type. ParsedDatasmithActor = ParseEmptyActor(InNode); } return(ParsedDatasmithActor); }
private RhinoSceneHierarchyNode GetOrCreateDefinitionRootNode(InstanceDefinition InInstanceDefinition) { RhinoSceneHierarchyNode InstanceRootNode; //If a hierarchy node does not exist for this instance definition, create one. if (!InstanceDefinitionHierarchyNodeDictionary.TryGetValue(InInstanceDefinition, out InstanceRootNode)) { const bool bIsInstanceDefinition = true; const int MaterialIndex = -1; RhinoSceneHierarchyNodeInfo DefinitionNodeInfo = GenerateNodeInfo(InInstanceDefinition, bIsInstanceDefinition, MaterialIndex, Transform.Identity); InstanceRootNode = new RhinoSceneHierarchyNode(/*bInIsInstanceDefinition=*/ true, DefinitionNodeInfo); InstanceDefinitionHierarchyNodeDictionary.Add(InInstanceDefinition, InstanceRootNode); RhinoObject[] InstanceObjects = InInstanceDefinition.GetObjects(); RecursivelyParseObjectInstance(InstanceObjects, InstanceRootNode); } return(InstanceRootNode); }
public string GetNodeLayerString(RhinoSceneHierarchyNode Node) { StringBuilder Buider = new StringBuilder(); foreach (int LayerIndex in Node.LayerIndices) { if (LayerIndexToLayerString.TryGetValue(LayerIndex, out string LayerString)) { if (Buider.Length == 0) { Buider.Append(LayerString); } else { Buider.Append("," + LayerString); } } } return(Buider.ToString()); }
private static FDatasmithFacadeActor ParseMeshActor(RhinoSceneHierarchyNode InNode, DatasmithRhinoSceneParser InSceneParser, DatasmithMeshInfo InMeshInfo) { string HashedActorName = FDatasmithFacadeActor.GetStringHash("A:" + InNode.Info.Name); FDatasmithFacadeActorMesh DatasmithActorMesh = new FDatasmithFacadeActorMesh(HashedActorName); DatasmithActorMesh.SetLabel(InNode.Info.Label); Transform OffsetTransform = Transform.Translation(InMeshInfo.PivotOffset); Transform WorldTransform = Transform.Multiply(InNode.Info.WorldTransform, OffsetTransform); DatasmithActorMesh.SetWorldTransform(WorldTransform.ToFloatArray(false)); string MeshName = FDatasmithFacadeElement.GetStringHash(InMeshInfo.Name); DatasmithActorMesh.SetMesh(MeshName); if (InNode.Info.bOverrideMaterial) { RhinoMaterialInfo MaterialInfo = InSceneParser.GetMaterialInfoFromMaterialIndex(InNode.Info.MaterialIndex); DatasmithActorMesh.AddMaterialOverride(MaterialInfo.Name, 0); } return(DatasmithActorMesh); }
private static void ExportHierarchyNode(FDatasmithFacadeScene DatasmithScene, RhinoSceneHierarchyNode Node, DatasmithRhinoSceneParser SceneParser) { FDatasmithFacadeActor ExportedActor = null; if (Node.Info.bHasRhinoObject) { RhinoObject CurrentObject = Node.Info.RhinoModelComponent as RhinoObject; if (CurrentObject.ObjectType == ObjectType.InstanceReference || CurrentObject.ObjectType == ObjectType.Point) { // The Instance Reference node is exported as an empty actor under which we create the instanced block. // Export points as empty actors as well. ExportedActor = ParseEmptyActor(Node); } else if (CurrentObject.ObjectType == ObjectType.Light) { ExportedActor = ParseLightActor(Node); } else if (SceneParser.ObjectIdToMeshInfoDictionary.TryGetValue(CurrentObject.Id, out DatasmithMeshInfo MeshInfo)) { // If the node's object has a mesh associated to it, export it as a MeshActor. ExportedActor = ParseMeshActor(Node, SceneParser, MeshInfo); } else { //#ueent_todo Log non-exported object in DatasmithExport UI (Writing to Rhino Console is extremely slow). } } else { // This node has no RhinoObject (likely a layer), export an empty Actor. ExportedActor = ParseEmptyActor(Node); } if (ExportedActor != null) { // Add common additional data to the actor, and add it to the hierarchy. Node.SetDatasmithActor(ExportedActor); AddTagsToDatasmithActor(ExportedActor, Node); AddMetadataToDatasmithActor(ExportedActor, Node, DatasmithScene); ExportedActor.SetLayer(GetDatasmithActorLayers(Node, SceneParser)); AddActorToParent(ExportedActor, Node, DatasmithScene); } }
private static void AddMetadataToDatasmithActor(FDatasmithFacadeActor InDatasmithActor, RhinoSceneHierarchyNode InNode, FDatasmithFacadeScene InDatasmithScene) { if (!InNode.Info.bHasRhinoObject) { return; } RhinoObject NodeObject = InNode.Info.RhinoModelComponent as RhinoObject; NameValueCollection UserStrings = NodeObject.Attributes.GetUserStrings(); if (UserStrings != null && UserStrings.Count > 0) { string[] Keys = UserStrings.AllKeys; FDatasmithFacadeMetaData DatasmithMetaData = new FDatasmithFacadeMetaData(InDatasmithActor.GetName() + "_DATA"); DatasmithMetaData.SetLabel(InDatasmithActor.GetLabel()); DatasmithMetaData.SetAssociatedElement(InDatasmithActor); for (int KeyIndex = 0; KeyIndex < Keys.Length; ++KeyIndex) { string CurrentKey = Keys[KeyIndex]; string EvaluatedValue = FDatasmithRhinoUtilities.EvaluateAttributeUserText(InNode, UserStrings.Get(CurrentKey)); DatasmithMetaData.AddPropertyString(CurrentKey, EvaluatedValue); } InDatasmithScene.AddMetaData(DatasmithMetaData); } }
private static void AddTagsToDatasmithActor(FDatasmithFacadeActor InDatasmithActor, RhinoSceneHierarchyNode InNode) { if (!InNode.bIsRoot && InNode.Info.Tags != null) { foreach (string CurrentTag in InNode.Info.Tags) { InDatasmithActor.AddTag(CurrentTag); } } }
private string BuildLayerString(Layer CurrentLayer, RhinoSceneHierarchyNode ParentNode) { return(BuildLayerString(FUniqueNameGenerator.GetTargetName(CurrentLayer), ParentNode)); }
private bool IsObjectIgnoredBySelection(RhinoObject InObject, RhinoSceneHierarchyNode ParentNode) { return(!ParentNode.bIsInstanceDefinition && ExportOptions.WriteSelectedObjectsOnly && InObject.IsSelected(/*checkSubObjects=*/ true) == 0); }