From 25319b4c7bb840710d6ebd10a7a67d0b7e25bd48 Mon Sep 17 00:00:00 2001 From: Claire Kuang Date: Mon, 1 Aug 2022 13:33:57 +0100 Subject: [PATCH] rhino: changes user attributes from dict to base (#1464) * Changes user info from dict to Base - also adds name prop on receive, this was missing before * converter attributes bug fix --- .../UI/ConnectorBindingsRhino.cs | 160 +++++++----------- .../ConverterRhinoGh.Utils.cs | 77 ++++++++- .../ConverterRhinoGh.cs | 14 +- 3 files changed, 138 insertions(+), 113 deletions(-) diff --git a/ConnectorRhino/ConnectorRhino/ConnectorRhinoShared/UI/ConnectorBindingsRhino.cs b/ConnectorRhino/ConnectorRhino/ConnectorRhinoShared/UI/ConnectorBindingsRhino.cs index dc94db59f6..d83ff4c0d8 100644 --- a/ConnectorRhino/ConnectorRhino/ConnectorRhinoShared/UI/ConnectorBindingsRhino.cs +++ b/ConnectorRhino/ConnectorRhino/ConnectorRhinoShared/UI/ConnectorBindingsRhino.cs @@ -396,14 +396,8 @@ void FlattenConvertedObject(object item) // assign layer attributes.LayerIndex = bakeLayer.Index; - // handle user strings - if (obj[UserStrings] is Dictionary userStrings) - foreach (var key in userStrings.Keys) - attributes.SetUserString(key, userStrings[key] as string); - - // handle user dictionaries - if (obj[UserDictionary] is Dictionary dict) - ParseDictionaryToArchivable(attributes.UserDictionary, dict); + // handle user info + SetUserInfo(obj, attributes); Guid id = Doc.Objects.Add(convertedRH, attributes); @@ -428,6 +422,19 @@ void FlattenConvertedObject(object item) } } + private void SetUserInfo(Base obj, ObjectAttributes attributes) + { + if (obj[UserStrings] is Base userStrings) + foreach (var key in userStrings.GetMemberNames()) + attributes.SetUserString(key, userStrings[key] as string); + + if (obj[UserDictionary] is Base userDictionary) + ParseDictionaryToArchivable(attributes.UserDictionary, userDictionary); + + var name = obj["name"] as string; + if (name != null) attributes.Name = name; + } + #endregion #region sending @@ -493,17 +500,6 @@ public override async Task SendStream(StreamState state, ProgressViewMod continue; } - // attach user strings, dictionaries, and name - var userStrings = obj.Attributes.GetUserStrings(); - var userStringDict = userStrings.AllKeys.ToDictionary(k => k, k => userStrings[k]); - converted[UserStrings] = userStringDict; - - var userDict = new Dictionary(); - ParseArchivableToDictionary(userDict, obj.Attributes.UserDictionary); - converted[UserDictionary] = userDict; - - if (obj.HasName) converted["name"] = obj.Name; - if (obj is InstanceObject) containerName = "Blocks"; else @@ -617,89 +613,91 @@ public override async Task SendStream(StreamState state, ProgressViewMod //return state; } - /// - /// Copies an ArchivableDictionary to a Dictionary - /// - /// - /// - private void ParseArchivableToDictionary(Dictionary target, Rhino.Collections.ArchivableDictionary dict) + private List GetObjectsFromFilter(ISelectionFilter filter) { - foreach (var key in dict.Keys) - { - var obj = dict[key]; - switch (obj) - { - case Rhino.Collections.ArchivableDictionary o: - var nested = new Dictionary(); - ParseArchivableToDictionary(nested, o); - target[key] = nested; - continue; - - case double _: - case bool _: - case int _: - case string _: - case IEnumerable _: - case IEnumerable _: - case IEnumerable _: - case IEnumerable _: - target[key] = obj; - continue; + var objs = new List(); - default: - continue; - } + switch (filter.Slug) + { + case "manual": + return filter.Selection; + case "all": + objs = Doc.Objects.Where(obj => obj.Visible).Select(obj => obj.Id.ToString()).ToList(); + objs.AddRange(Doc.NamedViews.Select(o => o.Name).ToList()); + break; + case "layer": + foreach (var layerPath in filter.Selection) + { + Layer layer = Doc.GetLayer(layerPath); + if (layer != null && layer.IsVisible) + { + var layerObjs = Doc.Objects.FindByLayer(layer)?.Select(o => o.Id.ToString()); + if (layerObjs != null) + objs.AddRange(layerObjs); + } + } + break; + case "project-info": + if (filter.Selection.Contains("Named Views")) + objs.AddRange(Doc.NamedViews.Select(o => o.Name).ToList()); + break; + default: + //RaiseNotification("Filter type is not supported in this app. Why did the developer implement it in the first place?"); + break; } + + return objs; } + /// - /// Copies a Dictionary to an ArchivableDictionary + /// Copies a Base to an ArchivableDictionary /// /// /// - private void ParseDictionaryToArchivable(Rhino.Collections.ArchivableDictionary target, Dictionary dict) + private void ParseDictionaryToArchivable(Rhino.Collections.ArchivableDictionary target, Base @base) { - foreach (var key in dict.Keys) + foreach (var prop in @base.GetMemberNames()) { - var obj = dict[key]; + var obj = @base[prop]; switch (obj) { - case Dictionary o: + case Base o: var nested = new Rhino.Collections.ArchivableDictionary(); ParseDictionaryToArchivable(nested, o); - target.Set(key, nested); + target.Set(prop, nested); continue; case double o: - target.Set(key, o); + target.Set(prop, o); continue; case bool o: - target.Set(key, o); + target.Set(prop, o); continue; case int o: - target.Set(key, o); + target.Set(prop, o); continue; case string o: - target.Set(key, o); + target.Set(prop, o); continue; case IEnumerable o: - target.Set(key, o); + target.Set(prop, o); continue; case IEnumerable o: - target.Set(key, o); + target.Set(prop, o); continue; case IEnumerable o: - target.Set(key, o); + target.Set(prop, o); continue; case IEnumerable o: - target.Set(key, o); + target.Set(prop, o); continue; default: @@ -708,42 +706,6 @@ private void ParseDictionaryToArchivable(Rhino.Collections.ArchivableDictionary } } - private List GetObjectsFromFilter(ISelectionFilter filter) - { - var objs = new List(); - - switch (filter.Slug) - { - case "manual": - return filter.Selection; - case "all": - objs = Doc.Objects.Where(obj => obj.Visible).Select(obj => obj.Id.ToString()).ToList(); - objs.AddRange(Doc.NamedViews.Select(o => o.Name).ToList()); - break; - case "layer": - foreach (var layerPath in filter.Selection) - { - Layer layer = Doc.GetLayer(layerPath); - if (layer != null && layer.IsVisible) - { - var layerObjs = Doc.Objects.FindByLayer(layer)?.Select(o => o.Id.ToString()); - if (layerObjs != null) - objs.AddRange(layerObjs); - } - } - break; - case "project-info": - if (filter.Selection.Contains("Named Views")) - objs.AddRange(Doc.NamedViews.Select(o => o.Name).ToList()); - break; - default: - //RaiseNotification("Filter type is not supported in this app. Why did the developer implement it in the first place?"); - break; - } - - return objs; - } - private string RemoveInvalidDynamicPropChars(string str) { // remove ./ diff --git a/Objects/Converters/ConverterRhinoGh/ConverterRhinoGhShared/ConverterRhinoGh.Utils.cs b/Objects/Converters/ConverterRhinoGh/ConverterRhinoGhShared/ConverterRhinoGh.Utils.cs index 68e205b268..f70434d491 100644 --- a/Objects/Converters/ConverterRhinoGh/ConverterRhinoGhShared/ConverterRhinoGh.Utils.cs +++ b/Objects/Converters/ConverterRhinoGh/ConverterRhinoGhShared/ConverterRhinoGh.Utils.cs @@ -1,16 +1,17 @@ -using Grasshopper.Kernel.Types; -using Objects.Geometry; -using Objects.Primitive; -using Objects.Other; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Drawing; + using Rhino; -using Rhino.Geometry; using Rhino.DocObjects; +using Grasshopper.Kernel.Types; + using Speckle.Core.Kits; using Speckle.Core.Models; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Reflection; +using Objects.Geometry; +using Objects.Primitive; +using Objects.Other; namespace Objects.Converter.RhinoGh { @@ -46,6 +47,64 @@ private string GetCommitInfo() #region app props public static string RhinoPropName = "RhinoProps"; + private static string UserStrings = "userStrings"; + private static string UserDictionary = "userDictionary"; + + /// + /// Attaches user strings, user dictionaries, and object name from a RhinoObject to Base + /// + /// The converted Base object to attach info to + /// The Rhino object containing info + /// + public void GetUserInfo(Base obj, ObjectAttributes attributes) + { + var userStringsBase = new Base(); + var userDictionaryBase = new Base(); + + var userStrings = attributes.GetUserStrings(); + userStrings.AllKeys.ToList().ForEach(k => userStringsBase[k] = userStrings[k]); + ParseArchivableToDictionary(userDictionaryBase, attributes.UserDictionary); + + obj[UserStrings] = userStringsBase; + obj[UserDictionary] = userDictionaryBase; + + if (!string.IsNullOrEmpty(attributes.Name)) obj["name"] = attributes.Name; + } + + /// + /// Copies an ArchivableDictionary to a Base + /// + /// + /// + private void ParseArchivableToDictionary(Base target, Rhino.Collections.ArchivableDictionary dict) + { + foreach (var key in dict.Keys) + { + var obj = dict[key]; + switch (obj) + { + case Rhino.Collections.ArchivableDictionary o: + var nested = new Base(); + ParseArchivableToDictionary(nested, o); + target[key] = nested; + continue; + + case double _: + case bool _: + case int _: + case string _: + case IEnumerable _: + case IEnumerable _: + case IEnumerable _: + case IEnumerable _: + target[key] = obj; + continue; + + default: + continue; + } + } + } #endregion #region Units diff --git a/Objects/Converters/ConverterRhinoGh/ConverterRhinoGhShared/ConverterRhinoGh.cs b/Objects/Converters/ConverterRhinoGh/ConverterRhinoGhShared/ConverterRhinoGh.cs index 1399709360..66715468b4 100644 --- a/Objects/Converters/ConverterRhinoGh/ConverterRhinoGhShared/ConverterRhinoGh.cs +++ b/Objects/Converters/ConverterRhinoGh/ConverterRhinoGhShared/ConverterRhinoGh.cs @@ -122,6 +122,7 @@ public Base ConvertToSpeckle(object @object) RenderMaterial material = null; RH.Mesh displayMesh = null; DisplayStyle style = null; + ObjectAttributes attributes = null; Base @base = null; Base schema = null; if (@object is RhinoObject ro) @@ -131,10 +132,12 @@ public Base ConvertToSpeckle(object @object) if (ro.Attributes.GetUserString(SpeckleSchemaKey) != null) // schema check - this will change in the near future schema = ConvertToSpeckleBE(ro) ?? ConvertToSpeckleStr(ro); - + + attributes = ro.Attributes; + // Fast way to get the displayMesh, try to get the mesh rhino shows on the viewport when available. // This will only return a mesh if the object has been displayed in any mode other than Wireframe. - if(ro is BrepObject || ro is ExtrusionObject) + if (ro is BrepObject || ro is ExtrusionObject) displayMesh = GetRhinoRenderMesh(ro); if (!(@object is InstanceObject)) // block instance check @@ -297,12 +300,14 @@ public Base ConvertToSpeckle(object @object) throw new NotSupportedException(); } + if (@base is null) return @base; + + if (attributes != null) + GetUserInfo(@base, attributes); if (material != null) @base["renderMaterial"] = material; - if (style != null) @base["displayStyle"] = style; - if (schema != null) { schema["renderMaterial"] = material; @@ -514,7 +519,6 @@ public List ConvertToSpeckleStr(List objects) return objects.Select(x => ConvertToSpeckleStr(x)).ToList(); } - public object ConvertToNative(Base @object) { object rhinoObj = null;