Esempio n. 1
0
        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);
                }
            }
        }
Esempio n. 2
0
        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);
            }
        }
Esempio n. 3
0
        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);
        }
Esempio n. 6
0
        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);
        }
Esempio n. 7
0
        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));
            }
        }
Esempio n. 9
0
        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);
                }
            }
        }
Esempio n. 10
0
        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);
        }
Esempio n. 12
0
        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);
        }
Esempio n. 13
0
        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);
         }
     }
 }
Esempio n. 18
0
 private string BuildLayerString(Layer CurrentLayer, RhinoSceneHierarchyNode ParentNode)
 {
     return(BuildLayerString(FUniqueNameGenerator.GetTargetName(CurrentLayer), ParentNode));
 }
Esempio n. 19
0
 private bool IsObjectIgnoredBySelection(RhinoObject InObject, RhinoSceneHierarchyNode ParentNode)
 {
     return(!ParentNode.bIsInstanceDefinition &&
            ExportOptions.WriteSelectedObjectsOnly &&
            InObject.IsSelected(/*checkSubObjects=*/ true) == 0);
 }