/// <summary>
        /// Workflow for casting a Base into a GH_Structure, taking into account potential Convertions. Pass Converter as null if you don't care for conversion.
        /// </summary>
        /// <param name="Converter"></param>
        /// <param name="base"></param>
        /// <returns></returns>
        public static GH_Structure <IGH_Goo> ConvertToTree(ISpeckleConverter Converter, Base @base, Action <GH_RuntimeMessageLevel, string> onError = null)
        {
            var data = new GH_Structure <IGH_Goo>();

            // Use the converter
            // case 1: it's an item that has a direct conversion method, eg a point
            if (Converter != null && Converter.CanConvertToNative(@base))
            {
                var converted = Converter.ConvertToNative(@base);
                data.Append(TryConvertItemToNative(converted, Converter));
            }
            // We unpack automatically since we auto-wrapped it initially
            // case 2: it's a wrapper Base
            //       2a: if there's only one member unpack it
            //       2b: otherwise return dictionary of unpacked members
            else if (@base.IsWrapper())
            {
                var treeBuilder = new TreeBuilder(Converter)
                {
                    ConvertToNative = Converter != null
                };
                data = treeBuilder.Build(@base[@base.GetDynamicMembers().ElementAt(0)]);
            }
            // Simple pass the SpeckleBase
            else
            {
                onError(GH_RuntimeMessageLevel.Remark, "This object needs to be expanded.");
                data.Append(new GH_SpeckleBase(@base));
            }
            return(data);
        }
Example #2
0
        // Recurses through the commit object and flattens it. Returns list of Base objects with their bake layers
        private List <Tuple <Base, string> > FlattenCommitObject(object obj, ISpeckleConverter converter, string layer, StreamState state, ref int count, bool foundConvertibleMember = false)
        {
            var objects = new List <Tuple <Base, string> >();

            if (obj is Base @base)
            {
                if (converter.CanConvertToNative(@base))
                {
                    objects.Add(new Tuple <Base, string>(@base, layer));
                    return(objects);
                }
                else
                {
                    int totalMembers = @base.GetDynamicMembers().Count();
                    foreach (var prop in @base.GetDynamicMembers())
                    {
                        count++;

                        // get bake layer name
                        string objLayerName = prop.StartsWith("@") ? prop.Remove(0, 1) : prop;
                        string acLayerName  = $"{layer}${objLayerName}";

                        var nestedObjects = FlattenCommitObject(@base[prop], converter, acLayerName, state, ref count, foundConvertibleMember);
                        if (nestedObjects.Count > 0)
                        {
                            objects.AddRange(nestedObjects);
                            foundConvertibleMember = true;
                        }
                    }
                    if (!foundConvertibleMember && count == totalMembers) // this was an unsupported geo
                    {
                        converter.Report.Log($"Skipped not supported type: { @base.speckle_type }. Object {@base.id} not baked.");
                    }
                    return(objects);
                }
            }

            if (obj is List <object> list)
            {
                count = 0;
                foreach (var listObj in list)
                {
                    objects.AddRange(FlattenCommitObject(listObj, converter, layer, state, ref count));
                }
                return(objects);
            }

            if (obj is IDictionary dict)
            {
                count = 0;
                foreach (DictionaryEntry kvp in dict)
                {
                    objects.AddRange(FlattenCommitObject(kvp.Value, converter, layer, state, ref count));
                }
                return(objects);
            }

            return(objects);
        }
        /// <summary>
        /// Recurses through the commit object and flattens it.
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="converter"></param>
        /// <returns>List of Base objects with their bake layers</returns>
        private List <Tuple <Base, string> > FlattenCommitObject(object obj, ISpeckleConverter converter, string layer, StreamState state)
        {
            var objects = new List <Tuple <Base, string> >();

            if (obj is Base @base)
            {
                if (converter.CanConvertToNative(@base))
                {
                    objects.Add(new Tuple <Base, string>(@base, layer));
                    return(objects);
                }
                else
                {
                    if (@base.GetDynamicMembers().Count() == 0) // this was an unsupported geo
                    {
                        state.Errors.Add(new Exception($"Recieving {@base.speckle_type} objects is not supported. Object {@base.id} not baked."));
                    }

                    foreach (var prop in @base.GetDynamicMembers())
                    {
                        // get acad bake layer name
                        string objLayerName;
                        if (prop.StartsWith("@"))
                        {
                            objLayerName = prop.Remove(0, 1);
                        }
                        else
                        {
                            objLayerName = prop;
                        }
                        string acLayerName = $"{layer}${objLayerName}";

                        objects.AddRange(FlattenCommitObject(@base[prop], converter, acLayerName, state));
                    }
                    return(objects);
                }
            }

            if (obj is List <object> list)
            {
                foreach (var listObj in list)
                {
                    objects.AddRange(FlattenCommitObject(listObj, converter, layer, state));
                }
                return(objects);
            }

            if (obj is IDictionary dict)
            {
                foreach (DictionaryEntry kvp in dict)
                {
                    objects.AddRange(FlattenCommitObject(kvp.Value, converter, layer, state));
                }
                return(objects);
            }

            return(objects);
        }
Example #4
0
        public static IGH_Goo TryConvertItemToNative(object value, ISpeckleConverter converter)
        {
            if (value == null)
            {
                return(null);
            }

            if (value is IGH_Goo)
            {
                value = value.GetType().GetProperty("Value")?.GetValue(value);
            }

            if (value is Base @base && converter.CanConvertToNative(@base))
            {
                var converted = converter.ConvertToNative(@base);
                var geomgoo   = GH_Convert.ToGoo(converted);
                if (geomgoo != null)
                {
                    return(geomgoo);
                }
                var goo = new GH_ObjectWrapper {
                    Value = converted
                };
                return(goo);
            }

            if (value is Base @base2)
            {
                var goo = new GH_SpeckleBase {
                    Value = @base2
                };
                return(goo);
            }

            if (value.GetType().IsSimpleType())
            {
                return(GH_Convert.ToGoo(value));
            }

            if (value is Enum)
            {
                var i = (Enum)value;
                return(new GH_ObjectWrapper {
                    Value = i
                });
            }
            return(null);
        }
Example #5
0
        /// <summary>
        /// Recurses through the commit object and flattens it.
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="converter"></param>
        /// <returns></returns>
        private List <Base> FlattenCommitObject(object obj, ISpeckleConverter converter)
        {
            List <Base> objects = new List <Base>();

            if (obj is Base @base)
            {
                if (converter.CanConvertToNative(@base))
                {
                    objects.Add(@base);

                    return(objects);
                }
                else
                {
                    foreach (var prop in @base.GetDynamicMembers())
                    {
                        objects.AddRange(FlattenCommitObject(@base[prop], converter));
                    }
                    return(objects);
                }
            }

            if (obj is List <object> list)
            {
                foreach (var listObj in list)
                {
                    objects.AddRange(FlattenCommitObject(listObj, converter));
                }
                return(objects);
            }

            if (obj is IDictionary dict)
            {
                foreach (DictionaryEntry kvp in dict)
                {
                    objects.AddRange(FlattenCommitObject(kvp.Value, converter));
                }
                return(objects);
            }

            else
            {
                converter.Report.Log($"Skipped object of type {obj.GetType()}, not supported.");
            }

            return(objects);
        }
Example #6
0
        /// <summary>
        /// Try to convert a given object into native (Grasshopper) format.
        /// </summary>
        /// <param name="value">Object to convert</param>
        /// <param name="converter">Converter instance to use.</param>
        /// <param name="recursive">Indicates if any non-convertible <see cref="Base"/> instances should be traversed too.</param>
        /// <returns>An <see cref="IGH_Goo"/> instance holding the converted object. </returns>
        public static IGH_Goo TryConvertItemToNative(object value, ISpeckleConverter converter, bool recursive = false)
        {
            if (converter == null)
            {
                return(new GH_ObjectWrapper(value));
            }
            if (value == null)
            {
                return(null);
            }

            if (value is IGH_Goo)
            {
                value = value.GetType().GetProperty("Value")?.GetValue(value);
            }

            if (value is Base @base)
            {
                if (converter.CanConvertToNative(@base))
                {
                    try
                    {
                        var converted = converter.ConvertToNative(@base);
                        var geomgoo   = GH_Convert.ToGoo(converted);
                        if (geomgoo != null)
                        {
                            return(geomgoo);
                        }
                        var goo = new GH_ObjectWrapper {
                            Value = converted
                        };
                        return(goo);
                    }
                    catch (Exception e)
                    {
                        converter.ConversionErrors.Add(new Exception($"Could not convert {@base}", e));
                    }
                }
                if (recursive)
                {
                    // Object is base but cannot convert directly, traverse!!!
                    var x = TraverseAndConvertToNative(@base, converter);
                    return(new GH_SpeckleBase(x));
                }
            }

            if (value is Base @base2)
            {
                return new GH_SpeckleBase {
                           Value = @base2
                }
            }
            ;


            if (value.GetType().IsSimpleType())
            {
                return(GH_Convert.ToGoo(value));
            }

            if (value is Enum)
            {
                var i = (Enum)value;
                return(new GH_ObjectWrapper {
                    Value = i
                });
            }
            return(new GH_ObjectWrapper(value));
        }