Skip to content

Commit

Permalink
rhino: changes user attributes from dict to base (#1464)
Browse files Browse the repository at this point in the history
* Changes user info from dict to Base

- also adds name prop on receive, this was missing before

* converter attributes bug fix
  • Loading branch information
clairekuang authored Aug 1, 2022
1 parent 65cdd42 commit 25319b4
Show file tree
Hide file tree
Showing 3 changed files with 138 additions and 113 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -396,14 +396,8 @@ void FlattenConvertedObject(object item)
// assign layer
attributes.LayerIndex = bakeLayer.Index;

// handle user strings
if (obj[UserStrings] is Dictionary<string, object> userStrings)
foreach (var key in userStrings.Keys)
attributes.SetUserString(key, userStrings[key] as string);

// handle user dictionaries
if (obj[UserDictionary] is Dictionary<string, object> dict)
ParseDictionaryToArchivable(attributes.UserDictionary, dict);
// handle user info
SetUserInfo(obj, attributes);

Guid id = Doc.Objects.Add(convertedRH, attributes);

Expand All @@ -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
Expand Down Expand Up @@ -493,17 +500,6 @@ public override async Task<string> 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<string, object>();
ParseArchivableToDictionary(userDict, obj.Attributes.UserDictionary);
converted[UserDictionary] = userDict;

if (obj.HasName) converted["name"] = obj.Name;

if (obj is InstanceObject)
containerName = "Blocks";
else
Expand Down Expand Up @@ -617,89 +613,91 @@ public override async Task<string> SendStream(StreamState state, ProgressViewMod
//return state;
}

/// <summary>
/// Copies an ArchivableDictionary to a Dictionary
/// </summary>
/// <param name="target"></param>
/// <param name="dict"></param>
private void ParseArchivableToDictionary(Dictionary<string, object> target, Rhino.Collections.ArchivableDictionary dict)
private List<string> GetObjectsFromFilter(ISelectionFilter filter)
{
foreach (var key in dict.Keys)
{
var obj = dict[key];
switch (obj)
{
case Rhino.Collections.ArchivableDictionary o:
var nested = new Dictionary<string, object>();
ParseArchivableToDictionary(nested, o);
target[key] = nested;
continue;

case double _:
case bool _:
case int _:
case string _:
case IEnumerable<double> _:
case IEnumerable<bool> _:
case IEnumerable<int> _:
case IEnumerable<string> _:
target[key] = obj;
continue;
var objs = new List<string>();

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;
}


/// <summary>
/// Copies a Dictionary to an ArchivableDictionary
/// Copies a Base to an ArchivableDictionary
/// </summary>
/// <param name="target"></param>
/// <param name="dict"></param>
private void ParseDictionaryToArchivable(Rhino.Collections.ArchivableDictionary target, Dictionary<string, object> 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<string, object> 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<double> o:
target.Set(key, o);
target.Set(prop, o);
continue;

case IEnumerable<bool> o:
target.Set(key, o);
target.Set(prop, o);
continue;

case IEnumerable<int> o:
target.Set(key, o);
target.Set(prop, o);
continue;

case IEnumerable<string> o:
target.Set(key, o);
target.Set(prop, o);
continue;

default:
Expand All @@ -708,42 +706,6 @@ private void ParseDictionaryToArchivable(Rhino.Collections.ArchivableDictionary
}
}

private List<string> GetObjectsFromFilter(ISelectionFilter filter)
{
var objs = new List<string>();

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 ./
Expand Down
Original file line number Diff line number Diff line change
@@ -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
{
Expand Down Expand Up @@ -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";

/// <summary>
/// Attaches user strings, user dictionaries, and object name from a RhinoObject to Base
/// </summary>
/// <param name="obj">The converted Base object to attach info to</param>
/// <param name="nativeObj">The Rhino object containing info</param>
/// <returns></returns>
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;
}

/// <summary>
/// Copies an ArchivableDictionary to a Base
/// </summary>
/// <param name="target"></param>
/// <param name="dict"></param>
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<double> _:
case IEnumerable<bool> _:
case IEnumerable<int> _:
case IEnumerable<string> _:
target[key] = obj;
continue;

default:
continue;
}
}
}
#endregion

#region Units
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -514,7 +519,6 @@ public List<Base> ConvertToSpeckleStr(List<object> objects)
return objects.Select(x => ConvertToSpeckleStr(x)).ToList();
}


public object ConvertToNative(Base @object)
{
object rhinoObj = null;
Expand Down

0 comments on commit 25319b4

Please sign in to comment.