/// <summary>
        ///
        /// </summary>
        /// <param name="renderer"></param>
        /// <param name="speckleStream"></param>
        /// <param name="objectIndex"></param>
        /// <param name="block"></param>
        public override void ApplyRuleToObject(Renderer renderer, SpeckleStream speckleStream, int objectIndex, MaterialPropertyBlock block)
        {
            Color colorToApply;

            if (colorLookup.Count == 0)
            {
                colorKey.Clear();
            }

            if (!colorLookup.ContainsKey(speckleStream.Objects[objectIndex].Type))
            {
                colorToApply = gradient.Evaluate(Random.Range(0f, 1f));

                colorLookup.Add(speckleStream.Objects[objectIndex].Type, colorToApply);
                colorKey.Add(new ColorKey(speckleStream.Objects[objectIndex].Type, colorToApply));
            }
            else
            {
                colorLookup.TryGetValue(speckleStream.Objects[objectIndex].Type, out colorToApply);
            }

            block.SetColor(colorName, colorToApply);
            renderer.SetPropertyBlock(block);

            renderer.receiveShadows    = receiveShadows;
            renderer.shadowCastingMode = shadowCastingMode;
        }
Beispiel #2
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="renderer"></param>
        /// <param name="speckleStream"></param>
        /// <param name="objectIndex"></param>
        /// <param name="block"></param>
        public override void ApplyRuleToObject(Renderer renderer, SpeckleStream speckleStream, int objectIndex, MaterialPropertyBlock block)
        {
            Color colorToApply;

            if (colorLookup.Count == 0)
            {
                colorKey.Clear();
            }

            List <Layer> layers = speckleStream.Layers;

            for (int i = 0; i < layers.Count; i++)
            {
                if (!colorLookup.ContainsKey(layers[i].Name))
                {
                    colorToApply = gradient.Evaluate(Random.Range(0f, 1f));

                    colorLookup.Add(layers[i].Name, colorToApply);
                    colorKey.Add(new ColorKey(layers[i].Name, colorToApply));
                }

                if (objectIndex >= layers[i].StartIndex && objectIndex < (layers[i].StartIndex + layers[i].ObjectCount))
                {
                    colorLookup.TryGetValue(layers[i].Name, out colorToApply);

                    block.SetColor(colorName, colorToApply);
                    renderer.SetPropertyBlock(block);

                    renderer.receiveShadows    = receiveShadows;
                    renderer.shadowCastingMode = shadowCastingMode;
                }
            }
        }
Beispiel #3
0
        public override void AddSender(string args)
        {
            var client = JsonConvert.DeserializeObject <dynamic>(args);

            clients.Add(client);
            var speckleStream = new SpeckleStream()
            {
                StreamId = (string)client.streamId, Objects = new List <SpeckleObject>()
            };

            speckleStreams.Add(speckleStream);

            var request = new Request
            {
                Operation = Operation.SaveClientState,
                Data      = JsonConvert.SerializeObject(clients)
            };

            var response = dataPipeClient.SendRequest(request);

            if (response.StatusCode != 200)
            {
                return;
            }

            request.Operation = Operation.SaveStreamState;
            request.Data      = JsonConvert.SerializeObject(speckleStreams);
            response          = dataPipeClient.SendRequest(request);

            ISelectionFilter filter = JsonConvert.DeserializeObject(JsonConvert.SerializeObject(client.filter), GetFilterType(client.filter.Type.ToString()));

            GetSelectionFilterObjects(filter, client._id.ToString(), client.streamId.ToString());
        }
Beispiel #4
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="stream"></param>
        private void OnStreamSelected(SpeckleStream stream)
        {
            // (Konrad) It's possible for this to be null since we can hide the comboboxes
            if (stream == null)
            {
                return;
            }

            Layers = Model.GetLayers(stream);
        }
Beispiel #5
0
        /// <summary>
        /// Diffs stream objects based on appId + _id non-matching.
        /// </summary>
        /// <param name="Old"></param>
        /// <param name="New"></param>
        /// <returns></returns>
        private (List <SpeckleObject>, List <SpeckleObject>) DiffStreamStates(SpeckleStream Old, SpeckleStream New)
        {
            var ToDelete = Old.Objects.Where(obj =>
            {
                var appIdMatch = New.Objects.FirstOrDefault(x => x.ApplicationId == obj.ApplicationId);
                var idMatch    = New.Objects.FirstOrDefault(x => x._id == obj._id);
                return((appIdMatch == null) && (idMatch == null));
            }).ToList();

            var ToModOrAdd = New.Objects;

            return(ToDelete, ToModOrAdd);
        }
Beispiel #6
0
        public SpeckleAdapter(SpeckleCore.Account speckleAccount, string speckleStreamId, string speckleStreamName = "Anonymous stream")
        {
            if (string.IsNullOrWhiteSpace(speckleStreamId))
            {
                BH.Engine.Reflection.Compute.RecordError("StreamId can't be null or empty.");
                return;
            }

            SpeckleStream SpeckleStream = new SpeckleStream()
            {
                StreamId = speckleStreamId, Name = speckleStreamName
            };

            SpeckleClient = new SpeckleApiClient()
            {
                BaseUrl = speckleAccount.RestApi, AuthToken = speckleAccount.Token, Stream = SpeckleStream, StreamId = SpeckleStream.StreamId
            };
            SpeckleClient.SetupWebsocket();
        }
Beispiel #7
0
        private void MetadataSender_Elapsed(object sender, ElapsedEventArgs e)
        {
            // we do not need to enque another metadata sending event as the data update superseeds the metadata one.
            if (DataSender.Enabled)
            {
                return;
            }
            ;
            SpeckleStream updateStream = new SpeckleStream()
            {
                Name   = BucketName,
                Layers = BucketLayers
            };

            var updateResult = mySender.StreamUpdateAsync(mySender.StreamId, updateStream).GetAwaiter().GetResult();

            Log += updateResult.Message;
            mySender.BroadcastMessage(new { eventType = "update-meta" });
        }
        public override void AddSender(string args)
        {
            var client = JsonConvert.DeserializeObject <dynamic>(args);

            ClientListWrapper.clients.Add(client);

            // TODO: Add stream to LocalState (do we actually need to??? hm...).
            var myStream = new SpeckleStream()
            {
                StreamId = (string)client.streamId, Objects = new List <SpeckleObject>()
            };

            //foreach( dynamic obj in client.objects )
            //{
            //  var SpkObj = new SpeckleObject() { };
            //  SpkObj.Properties[ "revitUniqueId" ] = obj.id.ToString();
            //  SpkObj.Properties[ "__type" ] = "Sent Object";
            //  myStream.Objects.Add( SpkObj );
            //}

            LocalState.Add(myStream);

            Queue.Add(new Action(() =>
            {
                using (Transaction t = new Transaction(CurrentDoc.Document, "Adding Speckle Sender"))
                {
                    t.Start();
                    SpeckleStateManager.WriteState(CurrentDoc.Document, LocalState);
                    SpeckleClientsStorageManager.WriteClients(CurrentDoc.Document, ClientListWrapper);
                    t.Commit();
                }
            }));
            Executor.Raise();


            ISelectionFilter filter = JsonConvert.DeserializeObject(JsonConvert.SerializeObject(client.filter), GetFilterType(client.filter.Type.ToString()));

            GetSelectionFilterObjects(filter, client._id.ToString(), client.streamId.ToString());

            SpeckleTelemetry.RecordStreamCreated("Revit");
        }
        public static Dictionary <string, object> ToDictionary(this SpeckleStream speckleStream)
        {
            var dictionary = new Dictionary <string, object>();

            dictionary.Add("StreamId", speckleStream.StreamId);
            dictionary.Add("Name", speckleStream.Name);
            dictionary.Add("Description", speckleStream.Description);
            dictionary.Add("Layers", speckleStream.Layers?.Select(x => x.Name).ToList());
            //dictionary.Add("TotalObjects", speckleStream.Objects?.Count);
            dictionary.Add("Tags", speckleStream.Tags == null ? new List <string> {
                "null"
            } : speckleStream.Tags);
            dictionary.Add("Parent", speckleStream.Parent == null ? "null" : speckleStream.Parent);
            dictionary.Add("Children", speckleStream.Children == null ? new List <string> {
                "null"
            } : speckleStream.Children);
            dictionary.Add("Ancestors", speckleStream.Ancestors == null ? new List <string> {
                "null"
            } : speckleStream.Ancestors);
            return(dictionary);
        }
Beispiel #10
0
        private void UpdateStreamWithIds(List <Layer> layers, List <SpeckleObject> bucketObjects, ref int numErrors)
        {
            // Update stream with payload
            var placeholders = new List <SpeckleObject>();

            foreach (string id in bucketObjects.Select(bo => bo._id))
            {
                placeholders.Add(new SpecklePlaceholder()
                {
                    _id = id
                });
            }

            SpeckleStream updateStream = new SpeckleStream
            {
                Layers         = layers,
                Objects        = placeholders,
                Name           = StreamName,
                BaseProperties = GSA.GetBaseProperties()
            };

            try
            {
                _ = apiClient.StreamUpdateAsync(StreamID, updateStream).Result;
                apiClient.Stream.Layers  = updateStream.Layers.ToList();
                apiClient.Stream.Objects = placeholders;
                GSA.GsaApp.gsaMessenger.CacheMessage(MessageIntent.Display, MessageLevel.Information, "Updated the stream's object list on the server", StreamID);
            }
            catch (Exception ex)
            {
                numErrors++;
                GSA.GsaApp.gsaMessenger.CacheMessage(MessageIntent.Display, MessageLevel.Error, "Updating the stream's object list on the server", StreamID);
                var speckleExceptionContext = ExtractSpeckleExceptionContext(ex);
                var errContext = speckleExceptionContext.Concat(new[] { "Error updating the stream's object list on the server", "StreamId=" + StreamID });
                GSA.GsaApp.gsaMessenger.CacheMessage(MessageIntent.TechnicalLog, MessageLevel.Error, ex, errContext.ToArray());
            }

            return;
        }
Beispiel #11
0
        public override void BakeReceiver(string args)
        {
            var client    = JsonConvert.DeserializeObject <dynamic>(args);
            var apiClient = new SpeckleApiClient((string)client.account.RestApi)
            {
                AuthToken = (string)client.account.Token
            };

            NotifyUi("update-client", JsonConvert.SerializeObject(new
            {
                _id          = (string)client._id,
                loading      = true,
                loadingBlurb = "Getting stream from server..."
            }));

            var previousStream = speckleStreams.FirstOrDefault(s => s.StreamId == (string)client.streamId);
            var stream         = apiClient.StreamGetAsync((string)client.streamId, "").Result.Resource;

            // If it's the first time we bake this stream, create a local shadow copy
            if (previousStream == null)
            {
                previousStream = new SpeckleStream()
                {
                    StreamId = stream.StreamId, Objects = new List <SpeckleObject>()
                };
                speckleStreams.Add(previousStream);
            }

            LocalContext.GetCachedObjects(stream.Objects, (string)client.account.RestApi);
            var payload = stream.Objects.Where(o => o.Type == "Placeholder").Select(obj => obj._id).ToArray();

            // TODO: Orchestrate & save in cache afterwards!
            var objects = apiClient.ObjectGetBulkAsync(payload, "").Result.Resources;

            foreach (var obj in objects)
            {
                stream.Objects[stream.Objects.FindIndex(o => o._id == obj._id)] = obj;
            }
        }
Beispiel #12
0
        public SpeckleAdapter(SpeckleCore.Account speckleAccount, string speckleStreamId)
        {
            Config.UseAdapterId = false;

            AdapterId = BH.Engine.Speckle.Convert.AdapterId;

            SpeckleAccount = speckleAccount;
            SpeckleStream  = new SpeckleStream()
            {
                StreamId = SpeckleStreamId
            };

            SpeckleClient = new SpeckleApiClient()
            {
                BaseUrl = SpeckleAccount.RestApi, AuthToken = SpeckleAccount.Token, Stream = SpeckleStream
            };                                                                                                                                     // hacky, but i don't want to rebuild stuff and fiddle dll loading etc.
            SpeckleClient.SetupWebsocket();


            //if (string.IsNullOrWhiteSpace(speckleStreamId))
            SpeckleStreamId = speckleStreamId;
        }
        private void MetadataSender_Elapsed(object sender, ElapsedEventArgs e)
        {
            if (ManualMode)
            {
                return;
            }
            // we do not need to enque another metadata sending event as the data update superseeds the metadata one.
            if (DataSender.Enabled)
            {
                return;
            }
            ;
            SpeckleStream updateStream = new SpeckleStream()
            {
                Name   = BucketName,
                Layers = BucketLayers
            };

            var updateResult = Client.StreamUpdateAsync(Client.StreamId, updateStream).Result;

            Log += updateResult.Message;
            Client.BroadcastMessage("stream", Client.StreamId, new { eventType = "update-meta" });
        }
Beispiel #14
0
        public async Task <bool> InitializeSender(string documentName, string streamName, BasePropertyUnits units, double tolerance, double angleTolerance,
                                                  IProgress <int> totalProgress, IProgress <int> incrementProgress)
        {
            this.totalProgress     = totalProgress;
            this.incrementProgress = incrementProgress;

            tryCatchWithEvents(() =>
            {
                var streamToCreate = new SpeckleStream()
                {
                    BaseProperties = CreateBaseProperties(units, tolerance, angleTolerance), Name = streamName
                };
                var streamResponse = apiClient.StreamCreateAsync(streamToCreate, timeoutMillisecondsOverride: apiTimeoutOverride).Result;
                apiClient.Stream   = streamResponse.Resource;
                apiClient.StreamId = apiClient.Stream.StreamId;
            },
                               "", "Unable to create stream on the server");

            tryCatchWithEvents(() =>
            {
                var clientResponse = apiClient.ClientCreateAsync(new AppClient()
                {
                    DocumentName = documentName,
                    DocumentType = "GSA",
                    Role         = "Sender",
                    StreamId     = this.StreamId,
                    Online       = true,
                }, timeoutMillisecondsOverride: apiTimeoutOverride).Result;
                apiClient.ClientId = clientResponse.Resource._id;
            }, "", "Unable to create client on the server");

            await InitialiseUser();

            ConnectWebSocket();

            return(true);
        }
Beispiel #15
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="renderer"></param>
        /// <param name="speckleStream"></param>
        /// <param name="objectIndex"></param>
        /// <param name="block"></param>
        public override void ApplyRuleToObject(Renderer renderer, SpeckleStream speckleStream, int objectIndex, MaterialPropertyBlock block)
        {
            Color colorToApply;

            colorToApply = gradient.Evaluate(Random.Range(0f, 1f));



            SpeckleObject data = speckleStream.Objects[objectIndex];

            if (data.Properties.TryGetValue("parameters", out object propertyValue))
            {
                //Debug.Log(propertyValue.ToString());
                var json       = JsonConvert.SerializeObject(propertyValue);
                var dictionary = JsonConvert.DeserializeObject <Dictionary <string, string> >(json);
                if (dictionary.TryGetValue("Comments", out string propertyValue1))
                {
                    if (ColorUtility.TryParseHtmlString("#" + propertyValue1, out colorToApply))
                    {
                    }
                }
            }


            if (colorLookup.Count == 0)
            {
                colorKey.Clear();
            }


            block.SetColor(colorName, colorToApply);
            renderer.SetPropertyBlock(block);

            renderer.receiveShadows    = receiveShadows;
            renderer.shadowCastingMode = shadowCastingMode;
        }
Beispiel #16
0
        /// <summary>
        /// This function will bake the objects in the given receiver. Behaviour:
        /// 1) Fresh bake: objects are created
        /// 2) Diff bake: old objects are deleted, any overlapping objects (by applicationId) are either edited or left alone if not marked as having been user modified, new objects are created.
        /// </summary>
        /// <param name="args">Serialised client coming from the ui.</param>
        public override void BakeReceiver(string args)
        {
            var client    = JsonConvert.DeserializeObject <dynamic>(args);
            var apiClient = new SpeckleApiClient((string)client.account.RestApi)
            {
                AuthToken = (string)client.account.Token
            };

            apiClient.ClientType = "Revit";

            //dispatch on the cef window to let progress bar update
            SpeckleWindow.Dispatcher.Invoke(() =>
            {
                NotifyUi("update-client", JsonConvert.SerializeObject(new
                {
                    _id          = (string)client._id,
                    loading      = true,
                    loadingBlurb = "Getting stream from server..."
                }));
            }, System.Windows.Threading.DispatcherPriority.Background);



            var previousStream = LocalState.FirstOrDefault(s => s.StreamId == (string)client.streamId);
            var stream         = apiClient.StreamGetAsync((string)client.streamId, "").Result.Resource;

            InjectScaleInKits(GetScale((string)stream.BaseProperties.units));
            var test = stream.BaseProperties.unitsDictionary;

            if (test != null)
            {
                var secondTest = JsonConvert.DeserializeObject <Dictionary <string, string> >(JsonConvert.SerializeObject(test));
                InjectUnitDictionaryInKits(secondTest);
            }
            else
            {
                InjectUnitDictionaryInKits(null); // make sure it's not there to potentially muddy the waters on other conversions
            }
            // If it's the first time we bake this stream, create a local shadow copy
            if (previousStream == null)
            {
                previousStream = new SpeckleStream()
                {
                    StreamId = stream.StreamId, Objects = new List <SpeckleObject>()
                };
                LocalState.Add(previousStream);
            }

            LocalContext.GetCachedObjects(stream.Objects, (string)client.account.RestApi);
            var payload = stream.Objects.Where(o => o.Type == "Placeholder").Select(obj => obj._id).ToArray();

            // TODO: Orchestrate & save in cache afterwards!
            var objects = apiClient.ObjectGetBulkAsync(payload, "").Result.Resources;

            foreach (var obj in objects)
            {
                stream.Objects[stream.Objects.FindIndex(o => o._id == obj._id)] = obj;
            }

            var(toDelete, ToAddOrMod) = DiffStreamStates(previousStream, stream);

            SpeckleWindow.Dispatcher.Invoke(() =>
            {
                NotifyUi("update-client", JsonConvert.SerializeObject(new
                {
                    _id          = (string)client._id,
                    loading      = true,
                    loadingBlurb = "Deleting " + toDelete.Count() + " objects.",
                    objects      = stream.Objects
                }));
            }, System.Windows.Threading.DispatcherPriority.Background);



            // DELETION OF OLD OBJECTS
            if (toDelete.Count() > 0)
            {
                Queue.Add(new Action(() =>
                {
                    using (Transaction t = new Transaction(CurrentDoc.Document, "Speckle Delete (" + (string)client.streamId + ")"))
                    {
                        t.Start();
                        foreach (var obj in toDelete)
                        {
                            var myObj = previousStream.Objects.FirstOrDefault(o => o._id == obj._id);
                            if (myObj != null)
                            {
                                var elem = CurrentDoc.Document.GetElement(myObj.Properties["revitUniqueId"] as string);
                                CurrentDoc.Document.Delete(elem.Id);
                            }
                        }
                        t.Commit();
                    }
                }));
                Executor.Raise();
            }

            // ADD/MOD/LEAVE ALONE EXISTING OBJECTS

            //if the conversion completely fails, it outputs a speckleerror and it's put in here
            var errors = new List <SpeckleError>();

            //this instead will store errors swallowed by the erroreater class
            Globals.ConversionErrors = new List <SpeckleError>();
            var tempList = new List <SpeckleObject>();

            Queue.Add(new Action(() =>
            {
                using (var t = new Transaction(CurrentDoc.Document, "Speckle Bake"))
                {
                    t.Start();

                    int i = 0;
                    foreach (var mySpkObj in ToAddOrMod)
                    {
                        SpeckleWindow.Dispatcher.Invoke(() =>
                        {
                            NotifyUi("update-client", JsonConvert.SerializeObject(new
                            {
                                _id     = (string)client._id,
                                loading = true,
                                isLoadingIndeterminate = false,
                                loadingProgress        = 1f * i / ToAddOrMod.Count * 100,
                                loadingBlurb           = string.Format("Creating/updating objects: {0} / {1}", i, ToAddOrMod.Count)
                            }));
                        }, System.Windows.Threading.DispatcherPriority.Background);



                        object res;

                        var failOpts = t.GetFailureHandlingOptions();
                        failOpts.SetFailuresPreprocessor(new ErrorEater());
                        t.SetFailureHandlingOptions(failOpts);

                        try
                        {
                            res = SpeckleCore.Converter.Deserialise(obj: mySpkObj, excludeAssebmlies: new string[] { "SpeckleCoreGeometryDynamo", "SpeckleCoreGeometryRevit" });

                            // The converter returns either the converted object, or the original speckle object if it failed to deserialise it.
                            // Hence, we need to create a shadow copy of the baked element only if deserialisation was succesful.
                            if (res is Element)
                            {
                                // creates a shadow copy of the baked object to store in our local state.
                                var myObject = new SpeckleObject()
                                {
                                    Properties = new Dictionary <string, object>()
                                };
                                myObject._id                         = mySpkObj._id;
                                myObject.ApplicationId               = mySpkObj.ApplicationId;
                                myObject.Properties["__type"]        = mySpkObj.Type;
                                myObject.Properties["revitUniqueId"] = ((Element)res).UniqueId;
                                myObject.Properties["revitId"]       = ((Element)res).Id.ToString();
                                myObject.Properties["userModified"]  = false;

                                tempList.Add(myObject);
                            }

                            // TODO: Handle scenario when one object creates more objects.
                            // ie: SpeckleElements wall with a base curve that is a polyline/polycurve
                            if (res is System.Collections.IEnumerable)
                            {
                                int k  = 0;
                                var xx = ((IEnumerable <object>)res).Cast <Element>();
                                foreach (var elm in xx)
                                {
                                    var myObject                         = new SpeckleObject();
                                    myObject._id                         = mySpkObj._id;
                                    myObject.ApplicationId               = mySpkObj.ApplicationId;
                                    myObject.Properties["__type"]        = mySpkObj.Type;
                                    myObject.Properties["revitUniqueId"] = ((Element)elm).UniqueId;
                                    myObject.Properties["revitId"]       = ((Element)elm).Id.ToString();
                                    myObject.Properties["userModified"]  = false;
                                    myObject.Properties["orderIndex"]    = k++; // keeps track of which elm it actually is

                                    tempList.Add(myObject);
                                }
                            }

                            //if( res is SpeckleObject || res == null ) failedToBake++;

                            if (res is SpeckleError)
                            {
                                errors.Add(res as SpeckleError);
                            }
                        }
                        catch (Exception e)
                        {
                            //if(e.Message.Contains("missing"))
                            //failedToBake++;
                            errors.Add(new SpeckleError {
                                Message = e.Message
                            });
                        }


                        i++;
                    }
                    t.Commit();
                }
            }));
            Executor.Raise();


            Queue.Add(new Action(() =>
            {
                SpeckleWindow.Dispatcher.Invoke(() =>
                {
                    NotifyUi("update-client", JsonConvert.SerializeObject(new
                    {
                        _id     = (string)client._id,
                        loading = true,
                        isLoadingIndeterminate = true,
                        loadingBlurb           = string.Format("Updating shadow state.")
                    }));
                }, System.Windows.Threading.DispatcherPriority.Background);



                // set the local state stream's object list, and inject it in the kits, persist it in the doc
                previousStream.Objects = tempList;
                InjectStateInKits();
                using (var t = new Transaction(CurrentDoc.Document, "Speckle State Save"))
                {
                    t.Start();
                    Storage.SpeckleStateManager.WriteState(CurrentDoc.Document, LocalState);
                    t.Commit();
                }

                string errorMsg     = "";
                int failedToConvert = errors.Count();

                //other conversion errors that we are catching
                var additionalErrors = GetAndClearConversionErrors();

                if (additionalErrors != null && additionalErrors.Count > 0)
                {
                    errors.AddRange(additionalErrors);
                }
                errors.AddRange(Globals.ConversionErrors);

                //remove duplicates
                errors = errors.GroupBy(x => x.Message).Select(x => x.First()).ToList();

                if (errors.Any())
                {
                    errorMsg += string.Format("There {0} {1} error{2} ",
                                              errors.Count() == 1 ? "is" : "are",
                                              errors.Count(),
                                              errors.Count() == 1 ? "" : "s");
                    if (failedToConvert > 0)
                    {
                        errorMsg += string.Format("and {0} objects that failed to convert ",
                                                  failedToConvert,
                                                  failedToConvert == 1 ? "" : "s");
                    }

                    errorMsg += "<nobr>" + Globals.GetRandomSadFace() + "</nobr>";
                }

                //if(errors.Any())
                //{
                //  errorMsg += "" +
                //  //errors += "<v-divider></v-divider>" +
                //  "<v-layout row wrap><v-flex xs12>";
                //  //"<strong>Missing families:</strong>&nbsp;&nbsp;";

                //  foreach( var err in errors)
                //  {
                //    errorMsg += $"<code>{err.Message}</code>&nbsp;";
                //  }

                //  errorMsg += "</v-flex></v-layout>";
                //}

                SpeckleWindow.Dispatcher.Invoke(() =>
                {
                    NotifyUi("update-client", JsonConvert.SerializeObject(new
                    {
                        _id     = (string)client._id,
                        loading = false,
                        isLoadingIndeterminate = true,
                        loadingBlurb           = string.Format("Done."),
                        errorMsg,
                        errors
                    }));
                }, System.Windows.Threading.DispatcherPriority.Background);
            }));

            Executor.Raise();
        }
Beispiel #17
0
        public async void SendStaggeredUpdate(bool force = false)
        {
            if (Paused && !force)
            {
                Context.NotifySpeckleFrame("client-expired", StreamId, "");
                return;
            }
            else
            {
                // create a clone
                var cloneResult = Client.StreamCloneAsync(StreamId).Result;
                Client.Stream.Children.Add(cloneResult.Clone.StreamId);

                Client.BroadcastMessage("stream", StreamId, new { eventType = "update-children" });
            }

            if (IsSendingUpdate)
            {
                Expired = true;
                return;
            }

            IsSendingUpdate = true;

            Context.NotifySpeckleFrame("client-is-loading", StreamId, "");

            var objs = RhinoDoc.ActiveDoc.Objects.FindByUserString("spk_" + this.StreamId, "*", false).OrderBy(obj => obj.Attributes.LayerIndex);

            Context.NotifySpeckleFrame("client-progress-message", StreamId, "Converting " + objs.Count() + " objects...");

            // layer list creation
            var pLayers = new List <SpeckleCore.Layer>();
            int lindex = -1, count = 0, orderIndex = 0;

            foreach (RhinoObject obj in objs)
            {
                Rhino.DocObjects.Layer layer = RhinoDoc.ActiveDoc.Layers[obj.Attributes.LayerIndex];
                if (lindex != obj.Attributes.LayerIndex)
                {
                    var spkLayer = new SpeckleCore.Layer()
                    {
                        Name        = layer.FullPath,
                        Guid        = layer.Id.ToString(),
                        ObjectCount = 1,
                        StartIndex  = count,
                        OrderIndex  = orderIndex++,
                        Properties  = new LayerProperties()
                        {
                            Color = new SpeckleCore.SpeckleBaseColor()
                            {
                                A = 1, Hex = System.Drawing.ColorTranslator.ToHtml(layer.Color)
                            },
                        }
                    };

                    pLayers.Add(spkLayer);
                    lindex = obj.Attributes.LayerIndex;
                }
                else
                {
                    var spkl = pLayers.FirstOrDefault(pl => pl.Name == layer.FullPath);
                    spkl.ObjectCount++;
                }

                count++;
            }

            // convert objects
            var convertedObjects = new List <SpeckleObject>();

            foreach (RhinoObject obj in objs)
            {
                var myObj = Converter.Serialise(obj.Geometry);
                myObj.ApplicationId = obj.Id.ToString();
                convertedObjects.Add(myObj);
            }

            LocalContext.PruneExistingObjects(convertedObjects, Client.BaseUrl);

            List <SpeckleObject> persistedObjects = new List <SpeckleObject>();

            if (convertedObjects.Count(obj => obj.Type == "Placeholder") != convertedObjects.Count)
            {
                // create the update payloads
                count = 0;
                var  objectUpdatePayloads = new List <List <SpeckleObject> >();
                long totalBucketSize      = 0;
                long currentBucketSize    = 0;
                var  currentBucketObjects = new List <SpeckleObject>();
                var  allObjects           = new List <SpeckleObject>();
                foreach (SpeckleObject convertedObject in convertedObjects)
                {
                    if (count++ % 100 == 0)
                    {
                        Context.NotifySpeckleFrame("client-progress-message", StreamId, "Converted " + count + " objects out of " + objs.Count() + ".");
                    }

                    // size checking & bulk object creation payloads creation
                    long size = Converter.getBytes(convertedObject).Length;
                    currentBucketSize += size;
                    totalBucketSize   += size;
                    currentBucketObjects.Add(convertedObject);

                    // Object is too big?
                    if (size > 2e6)
                    {
                        Context.NotifySpeckleFrame("client-error", StreamId, JsonConvert.SerializeObject("This stream contains a super big object. These will fail. Sorry for the bad error message - we're working on improving this."));
                        currentBucketObjects.Remove(convertedObject);
                    }

                    if (currentBucketSize > 5e5) // restrict max to ~500kb; should it be user config? anyway these functions should go into core. at one point.
                    {
                        Debug.WriteLine("Reached payload limit. Making a new one, current  #: " + objectUpdatePayloads.Count);
                        objectUpdatePayloads.Add(currentBucketObjects);
                        currentBucketObjects = new List <SpeckleObject>();
                        currentBucketSize    = 0;
                    }
                }

                // add in the last bucket
                if (currentBucketObjects.Count > 0)
                {
                    objectUpdatePayloads.Add(currentBucketObjects);
                }

                Debug.WriteLine("Finished, payload object update count is: " + objectUpdatePayloads.Count + " total bucket size is (kb) " + totalBucketSize / 1000);

                // create bulk object creation tasks
                int k = 0;
                List <ResponseObject> responses = new List <ResponseObject>();
                foreach (var payload in objectUpdatePayloads)
                {
                    Context.NotifySpeckleFrame("client-progress-message", StreamId, String.Format("Sending payload {0} out of {1}", k++, objectUpdatePayloads.Count));
                    try
                    {
                        var objResponse = await Client.ObjectCreateAsync(payload);

                        responses.Add(objResponse);
                        persistedObjects.AddRange(objResponse.Resources);

                        int m = 0;
                        foreach (var oL in payload)
                        {
                            oL._id = objResponse.Resources[m++]._id;
                        }

                        // push sent objects in the cache non-blocking
                        Task.Run(() =>
                        {
                            foreach (var oL in payload)
                            {
                                if (oL.Type != "Placeholder")
                                {
                                    LocalContext.AddSentObject(oL, Client.BaseUrl);
                                }
                            }
                        });
                    }
                    catch (Exception err)
                    {
                        Context.NotifySpeckleFrame("client-error", Client.Stream.StreamId, JsonConvert.SerializeObject(err.Message));
                        Context.NotifySpeckleFrame("client-done-loading", StreamId, "");
                        IsSendingUpdate = false;
                        return;
                    }
                }
            }
            else
            {
                persistedObjects = convertedObjects;
            }

            Context.NotifySpeckleFrame("client-progress-message", StreamId, "Updating stream...");

            // finalise layer creation
            foreach (var layer in pLayers)
            {
                layer.Topology = "0-" + layer.ObjectCount + " ";
            }

            // create placeholders for stream update payload
            List <SpeckleObject> placeholders = new List <SpeckleObject>();

            //foreach ( var myResponse in responses )
            foreach (var obj in persistedObjects)
            {
                placeholders.Add(new SpecklePlaceholder()
                {
                    _id = obj._id
                });
            }

            // create stream update payload
            SpeckleStream streamUpdatePayload = new SpeckleStream();

            streamUpdatePayload.Layers  = pLayers;
            streamUpdatePayload.Objects = placeholders;
            streamUpdatePayload.Name    = Client.Stream.Name;

            // set some base properties (will be overwritten)
            var baseProps = new Dictionary <string, object>();

            baseProps["units"]                 = RhinoDoc.ActiveDoc.ModelUnitSystem.ToString();
            baseProps["tolerance"]             = RhinoDoc.ActiveDoc.ModelAbsoluteTolerance;
            baseProps["angleTolerance"]        = RhinoDoc.ActiveDoc.ModelAngleToleranceRadians;
            streamUpdatePayload.BaseProperties = baseProps;

            // update the stream
            ResponseBase response = null;

            try
            {
                response = await Client.StreamUpdateAsync(Client.Stream.StreamId, streamUpdatePayload);
            }
            catch (Exception err)
            {
                Context.NotifySpeckleFrame("client-error", Client.Stream.StreamId, JsonConvert.SerializeObject(err.Message));
                IsSendingUpdate = false;
                return;
            }

            // emit  events, etc.
            Client.Stream.Layers  = streamUpdatePayload.Layers.ToList();
            Client.Stream.Objects = placeholders;

            Context.NotifySpeckleFrame("client-metadata-update", StreamId, Client.Stream.ToJson());
            Context.NotifySpeckleFrame("client-done-loading", StreamId, "");

            Client.BroadcastMessage("stream", StreamId, new { eventType = "update-global" });

            IsSendingUpdate = false;
            if (Expired)
            {
                DataSender.Start();
            }
            Expired = false;
        }
Beispiel #18
0
        // TODO: Orchestration
        // Create buckets, send sequentially, notify ui re upload progress
        // NOTE: Problems with local context and cache: we seem to not sucesffuly pass through it
        // perhaps we're not storing the right sent object (localcontext.addsentobject)
        public override void UpdateSender(string args)
        {
            var client    = JsonConvert.DeserializeObject <dynamic>(args);
            var apiClient = new SpeckleApiClient((string)client.account.RestApi)
            {
                AuthToken = (string)client.account.Token
            };

            var convertedObjects = new List <SpeckleObject>();
            var placeholders     = new List <SpeckleObject>();

            var units = CurrentDoc.Document.GetUnits().GetFormatOptions(UnitType.UT_Length).DisplayUnits.ToString().ToLower().Replace("dut_", "");

            InjectScaleInKits(GetScale(units)); // this is used for feet to sane units conversion.

            int  i = 0;
            long currentBucketSize = 0;
            var  errors            = "";
            var  failedSend        = 0;
            var  failedConvert     = 0;

            foreach (var obj in client.objects)
            {
                NotifyUi("update-client", JsonConvert.SerializeObject(new
                {
                    _id     = (string)client._id,
                    loading = true,
                    isLoadingIndeterminate = false,
                    loadingProgress        = 1f * i++ / client.objects.Count * 100,
                    loadingBlurb           = string.Format("Converting and uploading objects: {0} / {1}", i, client.objects.Count)
                }));

                try
                {
                    var revitElement = CurrentDoc.Document.GetElement((string)obj.properties["revitUniqueId"]);

                    var conversionResult = SpeckleCore.Converter.Serialise(new List <object>()
                    {
                        revitElement
                    });
                    var byteCount = Converter.getBytes(conversionResult).Length;
                    currentBucketSize += byteCount;

                    if (byteCount > 2e6)
                    {
                        var problemId = revitElement.Id;
                    }

                    convertedObjects.AddRange(conversionResult);

                    if (currentBucketSize > 5e5 || i >= client.objects.Count) // aim for roughly 500kb uncompressed
                    {
                        LocalContext.PruneExistingObjects(convertedObjects, apiClient.BaseUrl);

                        try
                        {
                            var chunkResponse = apiClient.ObjectCreateAsync(convertedObjects).Result.Resources;
                            int m             = 0;
                            foreach (var objConverted in convertedObjects)
                            {
                                objConverted._id = chunkResponse[m++]._id;
                                placeholders.Add(new SpecklePlaceholder()
                                {
                                    _id = objConverted._id
                                });
                                if (objConverted.Type != "Placeholder")
                                {
                                    LocalContext.AddSentObject(objConverted, apiClient.BaseUrl);
                                }
                            }
                        }
                        catch (Exception e)
                        {
                            failedSend += convertedObjects.Count;
                            NotifyUi("update-client", JsonConvert.SerializeObject(new
                            {
                                _id    = (string)client._id,
                                errors = "Failed to send " + failedSend + " objects."
                            }));
                        }
                        currentBucketSize = 0;
                        convertedObjects  = new List <SpeckleObject>(); // reset the chunkness
                    }
                }
                catch (Exception e)
                {
                    failedConvert++;
                    NotifyUi("update-client", JsonConvert.SerializeObject(new
                    {
                        _id    = (string)client._id,
                        errors = "Failed to convert " + failedConvert + " objects."
                    }));
                }
            }

            if (failedConvert > 0)
            {
                errors += String.Format("Failed to convert a total of {0} objects. ", failedConvert);
            }
            if (failedSend > 0)
            {
                errors += String.Format("Failed to send a total of {0} objects. ", failedSend);
            }

            var myStream = new SpeckleStream()
            {
                Objects = placeholders
            };

            var ug        = UnitUtils.GetUnitGroup(UnitType.UT_Length);
            var baseProps = new Dictionary <string, object>();

            baseProps["units"] = units;

            baseProps["unitsDictionary"] = GetAndClearUnitDictionary();

            myStream.BaseProperties = baseProps;
            //myStream.BaseProperties = JsonConvert.SerializeObject(baseProps);

            NotifyUi("update-client", JsonConvert.SerializeObject(new
            {
                _id     = (string)client._id,
                loading = true,
                isLoadingIndeterminate = true,
                loadingBlurb           = "Updating stream."
            }));

            var response = apiClient.StreamUpdateAsync((string)client.streamId, myStream).Result;

            NotifyUi("update-client", JsonConvert.SerializeObject(new
            {
                _id          = (string)client._id,
                loading      = false,
                loadingBlurb = "Done sending.",
                errors
            }));
        }
        // NOTE: This is actually triggered when clicking "Push!"
        // TODO: Orchestration
        // Create buckets, send sequentially, notify ui re upload progress
        // NOTE: Problems with local context and cache: we seem to not sucesffuly pass through it
        // perhaps we're not storing the right sent object (localcontext.addsentobject)
        public override void PushSender(string args)
        {
            var client = JsonConvert.DeserializeObject <dynamic>(args);

            //if it's a category or property filter we need to refresh the list of objects
            //if it's a selection filter just use the objects that were stored previously
            ISelectionFilter            filter  = JsonConvert.DeserializeObject(JsonConvert.SerializeObject(client.filter), GetFilterType(client.filter.Type.ToString()));
            IEnumerable <SpeckleObject> objects = new List <SpeckleObject>();

            objects = GetSelectionFilterObjects(filter, client._id.ToString(), client.streamId.ToString());

            var apiClient = new SpeckleApiClient((string)client.account.RestApi)
            {
                AuthToken = (string)client.account.Token
            };

            var convertedObjects = new List <SpeckleObject>();
            var placeholders     = new List <SpeckleObject>();

            var units = CurrentDoc.Document.GetUnits().GetFormatOptions(UnitType.UT_Length).DisplayUnits.ToString().ToLowerInvariant().Replace("dut_", "");

            InjectScaleInKits(GetScale(units)); // this is used for feet to sane units conversion.

            int  i = 0;
            long currentBucketSize = 0;
            var  errorMsg          = "";
            var  failedToConvert   = 0;
            var  errors            = new List <SpeckleError>();

            foreach (var obj in objects)
            {
                NotifyUi("update-client", JsonConvert.SerializeObject(new
                {
                    _id     = (string)client._id,
                    loading = true,
                    isLoadingIndeterminate = false,
                    loadingProgress        = 1f * i++ / objects.Count() * 100,
                    loadingBlurb           = string.Format("Converting and uploading objects: {0} / {1}", i, objects.Count())
                }));

                var     id           = 0;
                Element revitElement = null;
                try
                {
                    revitElement = CurrentDoc.Document.GetElement((string)obj.Properties["revitUniqueId"]);
                    id           = revitElement.Id.IntegerValue;
                }
                catch (Exception e)
                {
                    errors.Add(new SpeckleError {
                        Message = "Could not retrieve element", Details = e.Message
                    });
                    continue;
                }

                try
                {
                    var conversionResult = SpeckleCore.Converter.Serialise(new List <object>()
                    {
                        revitElement
                    });
                    var byteCount = Converter.getBytes(conversionResult).Length;
                    currentBucketSize += byteCount;

                    if (byteCount > 2e6)
                    {
                        errors.Add(new SpeckleError {
                            Message = "Element is too big to be sent", Details = $"Element {id} is bigger than 2MB, it will be skipped"
                        });
                        continue;
                    }

                    convertedObjects.AddRange(conversionResult);

                    if (currentBucketSize > 5e5 || i >= objects.Count()) // aim for roughly 500kb uncompressed
                    {
                        LocalContext.PruneExistingObjects(convertedObjects, apiClient.BaseUrl);

                        try
                        {
                            var chunkResponse = apiClient.ObjectCreateAsync(convertedObjects).Result.Resources;
                            int m             = 0;
                            foreach (var objConverted in convertedObjects)
                            {
                                objConverted._id = chunkResponse[m++]._id;
                                placeholders.Add(new SpecklePlaceholder()
                                {
                                    _id = objConverted._id
                                });
                                if (objConverted.Type != "Placeholder")
                                {
                                    LocalContext.AddSentObject(objConverted, apiClient.BaseUrl);
                                }
                            }
                        }
                        catch (Exception e)
                        {
                            errors.Add(new SpeckleError {
                                Message = $"Failed to send {convertedObjects.Count} objects", Details = e.Message
                            });
                        }
                        currentBucketSize = 0;
                        convertedObjects  = new List <SpeckleObject>(); // reset the chunkness
                    }
                }
                catch (Exception e)
                {
                    failedToConvert++;
                    errors.Add(new SpeckleError {
                        Message = $"Failed to convert {revitElement.Name}", Details = $"Element id: {id}"
                    });

                    //NotifyUi("update-client", JsonConvert.SerializeObject(new
                    //{
                    //  _id = (string)client._id,
                    //  errors = "Failed to convert " + failedConvert + " objects."
                    //}));
                }
            }

            if (errors.Any())
            {
                if (failedToConvert > 0)
                {
                    errorMsg += string.Format("Failed to convert {0} objects ",
                                              failedToConvert,
                                              failedToConvert == 1 ? "" : "s");
                }
                else
                {
                    errorMsg += string.Format("There {0} {1} error{2} ",
                                              errors.Count() == 1 ? "is" : "are",
                                              errors.Count(),
                                              errors.Count() == 1 ? "" : "s");
                }


                errorMsg += "<nobr>" + Globals.GetRandomSadFace() + "</nobr>";
            }

            var myStream = new SpeckleStream()
            {
                Objects = placeholders
            };

            var ug        = UnitUtils.GetUnitGroup(UnitType.UT_Length);
            var baseProps = new Dictionary <string, object>();

            baseProps["units"] = units;

            baseProps["unitsDictionary"] = GetAndClearUnitDictionary();

            myStream.BaseProperties = baseProps;
            //myStream.BaseProperties =  JsonConvert.SerializeObject(baseProps);

            NotifyUi("update-client", JsonConvert.SerializeObject(new
            {
                _id     = (string)client._id,
                loading = true,
                isLoadingIndeterminate = true,
                loadingBlurb           = "Updating stream."
            }));

            var response = apiClient.StreamUpdateAsync((string)client.streamId, myStream).Result;

            var plural = objects.Count() == 1 ? "" : "s";

            NotifyUi("update-client", JsonConvert.SerializeObject(new
            {
                _id          = (string)client._id,
                loading      = false,
                loadingBlurb = "",
                message      = $"Done sending {objects.Count()} object{plural}.",
                errorMsg,
                errors
            }));

            SpeckleTelemetry.RecordStreamUpdated("Revit");
        }
Beispiel #20
0
        private void DataSender_Elapsed(object sender, ElapsedEventArgs e)
        {
            if (MetadataSender.Enabled)
            {
                //  start the timer again, as we need to make sure we're updating
                DataSender.Start();
                return;
            }

            this.Message = String.Format("Converting {0} \n objects", BucketObjects.Count);

            var convertedObjects = Converter.Serialise(BucketObjects).Select(obj =>
            {
                if (ObjectCache.ContainsKey(obj.Hash))
                {
                    return new SpecklePlaceholder()
                    {
                        Hash = obj.Hash, _id = ObjectCache[obj.Hash]._id
                    }
                }
                ;
                return(obj);
            }).ToList();

            this.Message = String.Format("Creating payloads");

            long totalBucketSize   = 0;
            long currentBucketSize = 0;
            List <List <SpeckleObject> > objectUpdatePayloads = new List <List <SpeckleObject> >();
            List <SpeckleObject>         currentBucketObjects = new List <SpeckleObject>();
            List <SpeckleObject>         allObjects           = new List <SpeckleObject>();

            foreach (SpeckleObject convertedObject in convertedObjects)
            {
                long size = Converter.getBytes(convertedObject).Length;
                currentBucketSize += size;
                totalBucketSize   += size;
                currentBucketObjects.Add(convertedObject);

                if (currentBucketSize > 5e5) // restrict max to ~500kb; should it be user config? anyway these functions should go into core. at one point.
                {
                    Debug.WriteLine("Reached payload limit. Making a new one, current  #: " + objectUpdatePayloads.Count);
                    objectUpdatePayloads.Add(currentBucketObjects);
                    currentBucketObjects = new List <SpeckleObject>();
                    currentBucketSize    = 0;
                }
            }

            // add  the last bucket
            if (currentBucketObjects.Count > 0)
            {
                objectUpdatePayloads.Add(currentBucketObjects);
            }

            Debug.WriteLine("Finished, payload object update count is: " + objectUpdatePayloads.Count + " total bucket size is (kb) " + totalBucketSize / 1000);

            if (objectUpdatePayloads.Count > 100)
            {
                this.AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "This is a humongous update, in the range of ~50mb. For now, create more streams instead of just one massive one! Updates will be faster and snappier, and you can combine them back together at the other end easier.");
                return;
            }

            int k = 0;
            List <ResponseObject> responses = new List <ResponseObject>();

            foreach (var payload in objectUpdatePayloads)
            {
                this.Message = String.Format("Sending payload\n{0} / {1}", k++, objectUpdatePayloads.Count);

                responses.Add(mySender.ObjectCreateAsync(payload).GetAwaiter().GetResult());
            }

            this.Message = "Updating stream...";

            // create placeholders for stream update payload
            List <SpeckleObject> placeholders = new List <SpeckleObject>();

            foreach (var myResponse in responses)
            {
                foreach (var obj in myResponse.Resources)
                {
                    placeholders.Add(new SpecklePlaceholder()
                    {
                        _id = obj._id
                    });
                }
            }

            SpeckleStream updateStream = new SpeckleStream()
            {
                Layers  = BucketLayers,
                Name    = BucketName,
                Objects = placeholders
            };

            // set some base properties (will be overwritten)
            var baseProps = new Dictionary <string, object>();

            baseProps["units"]          = Rhino.RhinoDoc.ActiveDoc.ModelUnitSystem.ToString();
            baseProps["tolerance"]      = Rhino.RhinoDoc.ActiveDoc.ModelAbsoluteTolerance;
            baseProps["angleTolerance"] = Rhino.RhinoDoc.ActiveDoc.ModelAngleToleranceRadians;
            updateStream.BaseProperties = baseProps;

            var response = mySender.StreamUpdateAsync(mySender.StreamId, updateStream);

            mySender.BroadcastMessage(new { eventType = "update-global" });

            // put the objects in the cache
            int l = 0;

            foreach (var obj in placeholders)
            {
                ObjectCache[convertedObjects[l].Hash] = placeholders[l];
                l++;
            }

            Log += response.Result.Message;
            AddRuntimeMessage(GH_RuntimeMessageLevel.Remark, "Data sent at " + DateTime.Now);
            Message = "Data sent\n@" + DateTime.Now.ToString("hh:mm:ss");
        }
 /// <summary>
 ///
 /// </summary>
 /// <param name="renderer"></param>
 /// <param name="speckleStream"></param>
 /// <param name="objectIndex"></param>
 /// <param name="block"></param>
 public abstract void ApplyRuleToObject(Renderer renderer, SpeckleStream speckleStream, int objectIndex, MaterialPropertyBlock block);
 /// <summary>
 ///
 /// </summary>
 /// <param name="stream"></param>
 /// <returns></returns>
 public List <Layer> GetLayers(SpeckleStream stream)
 {
     return(stream.Layers);
 }
Beispiel #23
0
        /// <summary>
        /// <para>Creates a stream.</para>
        /// <para>Please note this is not the best way to do it for large payloads!</para>
        /// </summary>
        /// <param name="account"></param>
        /// <returns></returns>
        static string CreateStream(Account account)
        {
            Console.WriteLine("Hello Speckle! We will now create a sample stream.");

            Console.WriteLine("Please enter a stream name:");
            var name = Console.ReadLine();

            var myStream = new SpeckleStream()
            {
                Objects     = new List <SpeckleObject>(),
                Name        = name != "" ? name : "Console test stream",
                Description = "This stream was created from a .net console program. Easy peasy.",
                Tags        = new List <string> {
                    "example", "console-test"
                }
            };


            Console.WriteLine("Creating and converting sample data... ");
            var sampleSize = 10;

            var myNodes = new List <Node>();

            for (int i = 0; i < sampleSize; i++)
            {
                myNodes.Add(new Node {
                    id = i, x = i, y = i + 1, z = i + 2
                });
                myStream.Objects.Add(myNodes[i]);
                Console.WriteLine("Added " + i + " nodes");
            }

            var myQuads = new List <Quad>();

            for (int i = 0; i < sampleSize; i++)
            {
                myQuads.Add(new Quad
                {
                    id        = i,
                    nodes     = myNodes.GetRange(0, i).ToArray(),
                    vx        = 42,
                    iteration = 42,
                    tau       = 1337 // obviously bogus numbers
                });

                myStream.Objects.Add(myQuads[i]);
                Console.WriteLine("Added " + i + " quads");
            }

            Console.WriteLine("Done.\n");
            Console.WriteLine(String.Format("Saving stream to {0} using {1}'s account. This might take a bit.", account.RestApi, account.Email));

            // create an api client
            var client = new SpeckleApiClient(account.RestApi, false, "console_app");

            client.AuthToken = account.Token;

            try
            {
                // save the stream.
                var result = client.StreamCreateAsync(myStream).Result;

                // profit
                Console.WriteLine(String.Format("Succesfully created a stream! It's id is {0}. Rock on! Check it out at {1}/streams/{0}", result.Resource.StreamId, account.RestApi));
                Console.WriteLine("Press any key to continue.");

                System.Diagnostics.Process.Start(String.Format("{1}/streams/{0}", result.Resource.StreamId, account.RestApi));
                Console.ReadLine();
                return(result.Resource.StreamId);
            }
            catch (Exception e)
            {
                Console.WriteLine("Bummer - something went wrong:");
                Console.WriteLine(e.Message);
                Console.WriteLine("Press any key to continue.");
                Console.ReadLine();
                return(null);
            }
        }
Beispiel #24
0
        protected override void SolveInstance(IGH_DataAccess DA)
        {
            if (mySender == null)
            {
                return;
            }

            if (this.EnableRemoteControl)
            {
                this.Message = "JobQueue: " + JobQueue.Count;
            }

            StreamId = mySender.StreamId;

            DA.SetData(0, Log);
            DA.SetData(1, mySender.StreamId);

            if (!mySender.IsConnected)
            {
                return;
            }

            if (WasSerialised && FirstSendUpdate)
            {
                FirstSendUpdate = false;
                return;
            }

            this.State = "Expired";

            // All flags are good to start an update
            if (!this.EnableRemoteControl && !this.ManualMode)
            {
                UpdateData();
                return;
            }
            //
            else if (!this.EnableRemoteControl && this.ManualMode)
            {
                AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "State is expired, update push is required.");
                return;
            }

            #region RemoteControl

            // Code below deals with the remote control functionality.
            // Proceed at your own risk.
            if (JobQueue.Count == 0)
            {
                SetDefaultState();
                AddRuntimeMessage(GH_RuntimeMessageLevel.Remark, "Updated default state for remote control.");
                return;
            }

            // prepare solution and exit
            if (!SolutionPrepared && JobQueue.Count != 0)
            {
                System.Collections.DictionaryEntry t = JobQueue.Cast <DictionaryEntry>().ElementAt(0);
                Document.ScheduleSolution(1, PrepareSolution);
                return;
            }

            // send out solution and exit
            if (SolutionPrepared)
            {
                SolutionPrepared = false;
                var BucketObjects    = GetData();
                var BucketLayers     = GetLayers();
                var convertedObjects = Converter.Serialise(BucketObjects).Select(obj =>
                {
                    if (ObjectCache.ContainsKey(obj.Hash))
                    {
                        return new SpecklePlaceholder()
                        {
                            Hash = obj.Hash, _id = ObjectCache[obj.Hash]._id
                        }
                    }
                    ;
                    return(obj);
                });


                // theoretically this should go through the same flow as in DataSenderElapsed(), ie creating
                // buckets for staggered updates, etc. but we're lazy to untangle that logic for now

                var responseClone  = mySender.StreamCloneAsync(this.StreamId).Result;
                var responseStream = new SpeckleStream();

                responseStream.IsComputedResult = true;

                responseStream.Objects = convertedObjects.ToList();
                responseStream.Layers  = BucketLayers;

                List <SpeckleInput>  speckleInputs  = null;
                List <SpeckleOutput> speckleOutputs = null;
                GetSpeckleParams(ref speckleInputs, ref speckleOutputs);

                responseStream.GlobalMeasures = new { input = speckleInputs, output = speckleOutputs };

                // go unblocking
                var responseCloneUpdate = mySender.StreamUpdateAsync(responseClone.Clone.StreamId, responseStream).ContinueWith(tres =>
                {
                    mySender.SendMessage(CurrentJobClient, new { eventType = "compute-response", streamId = responseClone.Clone.StreamId });
                });


                JobQueue.RemoveAt(0);
                this.Message = "JobQueue: " + JobQueue.Count;

                if (JobQueue.Count != 0)
                {
                    Rhino.RhinoApp.MainApplicationWindow.Invoke(ExpireComponentAction);
                }
            }

            #endregion
        }
        // TODO: This method, or an abstracted version of it, should move to Speckle Core.
        public async void SendStaggeredUpdate(bool force = false)
        {
            if (Paused && !force)
            {
                Context.NotifySpeckleFrame("client-expired", StreamId, "");
                return;
            }

            if (IsSendingUpdate)
            {
                Expired = true;
                return;
            }

            IsSendingUpdate = true;

            Context.NotifySpeckleFrame("client-is-loading", StreamId, "");

            var objs = RhinoDoc.ActiveDoc.Objects.FindByUserString("spk_" + this.StreamId, "*", false).OrderBy(obj => obj.Attributes.LayerIndex);

            Context.NotifySpeckleFrame("client-progress-message", StreamId, "Converting " + objs.Count() + " objects...");

            List <SpeckleCore.Layer>     pLayers              = new List <SpeckleCore.Layer>();
            List <SpeckleObject>         convertedObjects     = new List <SpeckleObject>();
            List <List <SpeckleObject> > objectUpdatePayloads = new List <List <SpeckleObject> >();

            long totalBucketSize   = 0;
            long currentBucketSize = 0;
            List <SpeckleObject> currentBucketObjects = new List <SpeckleObject>();
            List <SpeckleObject> allObjects           = new List <SpeckleObject>();

            int lindex = -1, count = 0, orderIndex = 0;

            foreach (RhinoObject obj in objs)
            {
                // layer list creation
                Rhino.DocObjects.Layer layer = RhinoDoc.ActiveDoc.Layers[obj.Attributes.LayerIndex];
                if (lindex != obj.Attributes.LayerIndex)
                {
                    var spkLayer = new SpeckleCore.Layer()
                    {
                        Name        = layer.FullPath,
                        Guid        = layer.Id.ToString(),
                        ObjectCount = 1,
                        StartIndex  = count,
                        OrderIndex  = orderIndex++,
                        Properties  = new LayerProperties()
                        {
                            Color = new SpeckleCore.SpeckleBaseColor()
                            {
                                A = 1, Hex = System.Drawing.ColorTranslator.ToHtml(layer.Color)
                            },
                        }
                    };

                    pLayers.Add(spkLayer);
                    lindex = obj.Attributes.LayerIndex;
                }
                else
                {
                    var spkl = pLayers.FirstOrDefault(pl => pl.Name == layer.FullPath);
                    spkl.ObjectCount++;
                }

                count++;

                // object conversion
                SpeckleObject convertedObject;

                convertedObject = Converter.Serialise(obj.Geometry);
                convertedObject.ApplicationId = obj.Id.ToString();
                allObjects.Add(convertedObject);

                if (count % 10 == 0)
                {
                    Context.NotifySpeckleFrame("client-progress-message", StreamId, "Converted " + count + " objects out of " + objs.Count() + ".");
                }

                // check cache and see what the response from the server is when sending placeholders
                // in the ObjectCreateBulkAsyncRoute
                if (Context.SpeckleObjectCache.ContainsKey(convertedObject.Hash))
                {
                    convertedObject = new SpecklePlaceholder()
                    {
                        Hash = convertedObject.Hash, _id = Context.SpeckleObjectCache[convertedObject.Hash]._id, ApplicationId = Context.SpeckleObjectCache[convertedObject.Hash].ApplicationId
                    };
                }

                // size checking & bulk object creation payloads creation
                long size = Converter.getBytes(convertedObject).Length;
                currentBucketSize += size;
                totalBucketSize   += size;
                currentBucketObjects.Add(convertedObject);

                if (currentBucketSize > 2e6)
                {
                    // means we're around fooking bazillion mb of an upload. FAIL FAIL FAIL
                    Context.NotifySpeckleFrame("client-error", StreamId, JsonConvert.SerializeObject("This stream contains a super big object. These are not supported yet :("));
                    Context.NotifySpeckleFrame("client-done-loading", StreamId, "");
                    IsSendingUpdate = false;
                    return;
                }

                if (currentBucketSize > 5e5) // restrict max to ~500kb; should it be user config? anyway these functions should go into core. at one point.
                {
                    Debug.WriteLine("Reached payload limit. Making a new one, current  #: " + objectUpdatePayloads.Count);
                    objectUpdatePayloads.Add(currentBucketObjects);
                    currentBucketObjects = new List <SpeckleObject>();
                    currentBucketSize    = 0;
                }

                // catch overflows early
                if (totalBucketSize >= 50e6)
                {
                    Context.NotifySpeckleFrame("client-error", StreamId, JsonConvert.SerializeObject("This is a humongous update, in the range of ~50mb. For now, create more streams instead of just one massive one! Updates will be faster and snappier, and you can combine them back together at the other end easier. " + totalBucketSize / 1000 + "(kb)"));
                    IsSendingUpdate = false;
                    Context.NotifySpeckleFrame("client-done-loading", StreamId, "");
                    return;
                }
            }

            // last bucket
            if (currentBucketObjects.Count > 0)
            {
                objectUpdatePayloads.Add(currentBucketObjects);
            }

            Debug.WriteLine("Finished, payload object update count is: " + objectUpdatePayloads.Count + " total bucket size is (kb) " + totalBucketSize / 1000);

            if (objectUpdatePayloads.Count > 100 || totalBucketSize >= 50e6)
            {
                // means we're around fooking bazillion mb of an upload. FAIL FAIL FAIL
                Context.NotifySpeckleFrame("client-error", StreamId, JsonConvert.SerializeObject("This is a humongous update, in the range of ~50mb. For now, create more streams instead of just one massive one! Updates will be faster and snappier, and you can combine them back together at the other end easier. " + totalBucketSize / 1000 + "(kb)"));
                IsSendingUpdate = false;
                Context.NotifySpeckleFrame("client-done-loading", StreamId, "");
                return;
            }

            // create bulk object creation tasks
            int k = 0;
            List <ResponseObject> responses = new List <ResponseObject>();

            foreach (var payload in objectUpdatePayloads)
            {
                Context.NotifySpeckleFrame("client-progress-message", StreamId, String.Format("Sending payload {0} out of {1}", k++, objectUpdatePayloads.Count));
                try
                {
                    responses.Add(await Client.ObjectCreateAsync(payload));
                }
                catch (Exception err)
                {
                    Context.NotifySpeckleFrame("client-error", Client.Stream.StreamId, JsonConvert.SerializeObject(err.Message));
                    Context.NotifySpeckleFrame("client-done-loading", StreamId, "");
                    IsSendingUpdate = false;
                    return;
                }
            }

            Context.NotifySpeckleFrame("client-progress-message", StreamId, "Updating stream...");

            // finalise layer creation
            foreach (var layer in pLayers)
            {
                layer.Topology = "0-" + layer.ObjectCount + " ";
            }

            // create placeholders for stream update payload
            List <SpeckleObject> placeholders = new List <SpeckleObject>();
            int m = 0;

            foreach (var myResponse in responses)
            {
                foreach (var obj in myResponse.Resources)
                {
                    placeholders.Add(new SpecklePlaceholder()
                    {
                        _id = obj._id, ApplicationId = allObjects[m++].ApplicationId
                    });
                }
            }

            // create stream update payload
            SpeckleStream streamUpdatePayload = new SpeckleStream();

            streamUpdatePayload.Layers  = pLayers;
            streamUpdatePayload.Objects = placeholders;
            streamUpdatePayload.Name    = Client.Stream.Name;

            // set some base properties (will be overwritten)
            var baseProps = new Dictionary <string, object>();

            baseProps["units"]                 = RhinoDoc.ActiveDoc.ModelUnitSystem.ToString();
            baseProps["tolerance"]             = RhinoDoc.ActiveDoc.ModelAbsoluteTolerance;
            baseProps["angleTolerance"]        = RhinoDoc.ActiveDoc.ModelAngleToleranceRadians;
            streamUpdatePayload.BaseProperties = baseProps;

            // push it to the server yo!
            ResponseBase response = null;

            try
            {
                response = await Client.StreamUpdateAsync(Client.Stream.StreamId, streamUpdatePayload);
            }
            catch (Exception err)
            {
                Context.NotifySpeckleFrame("client-error", Client.Stream.StreamId, JsonConvert.SerializeObject(err.Message));
                IsSendingUpdate = false;
                return;
            }

            // put the objects in the cache
            int l = 0;

            foreach (var obj in streamUpdatePayload.Objects)
            {
                obj._id = placeholders[l]._id;
                Context.SpeckleObjectCache[allObjects[l].Hash] = placeholders[l];
                l++;
            }

            // emit  events, etc.
            Client.Stream.Layers  = streamUpdatePayload.Layers.ToList();
            Client.Stream.Objects = placeholders;

            Context.NotifySpeckleFrame("client-metadata-update", StreamId, Client.Stream.ToJson());
            Context.NotifySpeckleFrame("client-done-loading", StreamId, "");

            Client.BroadcastMessage(new { eventType = "update-global" });

            IsSendingUpdate = false;
            if (Expired)
            {
                DataSender.Start();
            }
            Expired = false;
        }
Beispiel #26
0
        static async Task TestStreams(SpeckleApiClient myClient)
        {
            string streamId       = "lol";
            string secondStreamId = "hai";

            var myPoint = new SpecklePoint()
            {
                Value = new List <double>()
                {
                    1, 2, 3
                }
            };
            var mySecondPoint = new SpecklePoint()
            {
                Value = new List <double>()
                {
                    23, 33, 12
                }
            };
            var myCircle = new SpeckleCircle()
            {
                Radius = 21
            };


            myPoint.Properties = new Dictionary <string, object>();
            myPoint.Properties.Add("Really", mySecondPoint);

            myCircle.Properties = new Dictionary <string, object>();
            myCircle.Properties.Add("a property", "Hello!");
            myCircle.Properties.Add("point", myPoint);

            SpeckleStream myStream = new SpeckleStream()
            {
                Name    = "Hello World My Little Stream",
                Objects = new List <SpeckleObject>()
                {
                    myCircle, myPoint
                }
            };

            SpeckleStream secondStream = new SpeckleStream()
            {
                Name    = "Second Little Stream",
                Objects = new List <SpeckleObject>()
                {
                    myCircle, mySecondPoint
                }
            };

            Console.WriteLine();
            try
            {
                Console.WriteLine("Creating a stream.");
                var Response = await myClient.StreamCreateAsync(myStream);

                Console.WriteLine("OK: " + Response.Resource.ToJson());

                streamId = Response.Resource.StreamId;
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }

            Console.WriteLine();
            try
            {
                Console.WriteLine("Creating a second stream.");
                var Response = await myClient.StreamCreateAsync(secondStream);

                Console.WriteLine("OK: " + Response.Resource.ToJson());

                secondStreamId = Response.Resource.StreamId;
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }


            Console.WriteLine();
            try
            {
                Console.WriteLine("Diffing two streams!");
                var Response = await myClient.StreamDiffAsync(streamId, secondStreamId);

                Console.WriteLine("OK: " + Response.Message);
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }

            Console.WriteLine();
            try
            {
                Console.WriteLine("Getting a stream.");
                var Response = await myClient.StreamGetAsync(streamId, null);

                Console.WriteLine("OK: " + Response.Resource.ToJson());
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }

            Console.WriteLine();
            try
            {
                Console.WriteLine("Getting a stream's objects.");
                var Response = await myClient.StreamGetObjectsAsync(streamId, null);

                Console.WriteLine("OK: " + Response.Resources.Count);
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }

            Console.WriteLine();
            try
            {
                Console.WriteLine("Updating a stream.");
                var Response = await myClient.StreamUpdateAsync(streamId, new SpeckleStream()
                {
                    Name = "I hate api testing", ViewerLayers = new List <object>()
                    {
                        new { test = "test" }
                    }
                });

                Console.WriteLine("OK: " + Response.Message);
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }

            Console.WriteLine();
            try
            {
                Console.WriteLine("Getting a stream field.");
                var Response = await myClient.StreamGetAsync(streamId, "fields=viewerLayers,name,owner");

                Console.WriteLine("OK: " + Response.Resource.ToJson());
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }

            Console.WriteLine();
            try
            {
                Console.WriteLine("Getting all users's streams.");
                var Response = await myClient.StreamsGetAllAsync();

                Console.WriteLine("OK: " + Response.Resources.Count);
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }


            Console.WriteLine();
            try
            {
                Console.WriteLine("Cloning a stream.");
                var Response = await myClient.StreamCloneAsync(streamId);

                Console.WriteLine("OK: " + Response.Message);
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }

            Console.WriteLine();
            try
            {
                Console.WriteLine("Deleting a stream: " + streamId);
                var Response = await myClient.StreamDeleteAsync(streamId);

                Console.WriteLine("OK: " + Response.Message);
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }
        }
Beispiel #27
0
        // Send objects to Speckle server. Triggered on "Push!".
        // Create buckets, send sequentially, notify ui re upload progress
        public override void PushSender(string args)
        {
            var client = JsonConvert.DeserializeObject <dynamic>(args);

            //if it's a category or property filter we need to refresh the list of objects
            //if it's a selection filter just use the objects that were stored previously
            ISelectionFilter            filter  = JsonConvert.DeserializeObject(JsonConvert.SerializeObject(client.filter), GetFilterType(client.filter.Type.ToString()));
            IEnumerable <SpeckleObject> objects = new List <SpeckleObject>();

            objects = GetSelectionFilterObjects(filter, client._id.ToString(), client.streamId.ToString());

            var apiClient = new SpeckleApiClient((string)client.account.RestApi)
            {
                AuthToken = (string)client.account.Token
            };
            var task = Task.Run(async() => { await apiClient.IntializeUser(); });

            task.Wait();
            apiClient.ClientType = "AutoCAD";

            var convertedObjects = new List <SpeckleObject>();
            var placeholders     = new List <SpeckleObject>();

            var units = AutocadDataService.GetLengthUnit();
            //InjectScaleInKits(GetScale(units)); // this is used for feet to sane units conversion.

            int  i = 0;
            long currentBucketSize = 0;
            var  errorMsg          = "";
            var  failedToConvert   = 0;
            var  errors            = new List <SpeckleError>();

            foreach (var obj in objects)
            {
                NotifyUi("update-client", JsonConvert.SerializeObject(new
                {
                    _id     = (string)client._id,
                    loading = true,
                    isLoadingIndeterminate = false,
                    loadingProgress        = 1f * i++ / objects.Count() * 100,
                    loadingBlurb           = string.Format("Converting and uploading objects: {0} / {1}", i, objects.Count())
                }));

                long          handle        = 0;
                SpeckleObject speckleObject = null;

                try
                {
                    handle        = (long)obj.Properties["autocadhandle"];
                    speckleObject = AutocadDataService.GetObject(handle);
                    if (speckleObject == null)
                    {
                        errors.Add(new SpeckleError {
                            Message = "Could not retrieve element", Details = string.Empty
                        });
                        continue;
                    }
                }
                catch (Exception e)
                {
                    errors.Add(new SpeckleError {
                        Message = "Could not retrieve element", Details = e.Message
                    });
                    continue;
                }

                try
                {
                    var conversionResult = new List <SpeckleObject> {
                        speckleObject
                    };
                    var byteCount = Converter.getBytes(conversionResult).Length;
                    currentBucketSize += byteCount;

                    if (byteCount > 2e6)
                    {
                        errors.Add(new SpeckleError {
                            Message = "Element is too big to be sent", Details = $"Element {handle} is bigger than 2MB, it will be skipped"
                        });
                        continue;
                    }

                    convertedObjects.AddRange(conversionResult);

                    if (currentBucketSize > 5e5 || i >= objects.Count()) // aim for roughly 500kb uncompressed
                    {
                        LocalContext.PruneExistingObjects(convertedObjects, apiClient.BaseUrl);

                        try
                        {
                            var chunkResponse = apiClient.ObjectCreateAsync(convertedObjects).Result.Resources;
                            int m             = 0;
                            foreach (var objConverted in convertedObjects)
                            {
                                objConverted._id = chunkResponse[m++]._id;
                                placeholders.Add(new SpecklePlaceholder()
                                {
                                    _id = objConverted._id
                                });
                                if (objConverted.Type != "Placeholder")
                                {
                                    LocalContext.AddSentObject(objConverted, apiClient.BaseUrl);
                                }
                            }
                        }
                        catch (Exception e)
                        {
                            errors.Add(new SpeckleError {
                                Message = $"Failed to send {convertedObjects.Count} objects", Details = e.Message
                            });
                        }
                        currentBucketSize = 0;
                        convertedObjects  = new List <SpeckleObject>(); // reset the chunkness
                    }
                }
                catch (Exception e)
                {
                    failedToConvert++;
                    errors.Add(new SpeckleError {
                        Message = $"Failed to convert element", Details = $"Element handle: {handle}"
                    });

                    //NotifyUi("update-client", JsonConvert.SerializeObject(new
                    //{
                    //  _id = (string)client._id,
                    //  errors = "Failed to convert " + failedConvert + " objects."
                    //}));
                }
            }

            if (errors.Any())
            {
                if (failedToConvert > 0)
                {
                    errorMsg += string.Format("Failed to convert {0} objects ",
                                              failedToConvert,
                                              failedToConvert == 1 ? "" : "s");
                }
                else
                {
                    errorMsg += string.Format("There {0} {1} error{2} ",
                                              errors.Count() == 1 ? "is" : "are",
                                              errors.Count(),
                                              errors.Count() == 1 ? "" : "s");
                }
            }

            var myStream = new SpeckleStream()
            {
                Objects = placeholders
            };

            var baseProps = new Dictionary <string, object>();

            baseProps["units"] = units;

            //baseProps["unitsDictionary"] = GetAndClearUnitDictionary();

            myStream.BaseProperties = baseProps;

            NotifyUi("update-client", JsonConvert.SerializeObject(new
            {
                _id     = (string)client._id,
                loading = true,
                isLoadingIndeterminate = true,
                loadingBlurb           = "Updating stream."
            }));

            apiClient.Stream = myStream;
            var response = apiClient.StreamUpdateAsync((string)client.streamId, myStream).Result;

            var plural = objects.Count() == 1 ? "" : "s";

            NotifyUi("update-client", JsonConvert.SerializeObject(new
            {
                _id          = (string)client._id,
                loading      = false,
                loadingBlurb = "",
                message      = $"Done sending {objects.Count()} object{plural}.",
                errorMsg,
                errors
            }));
        }
        /// <summary>
        /// Sends the update to the server.
        /// </summary>
        private void SendUpdate()
        {
            if (MetadataSender.Enabled)
            {
                // start the timer again, as we need to make sure we're updating
                DataSender.Start();
                return;
            }

            if (IsSendingUpdate)
            {
                return;
            }

            IsSendingUpdate = true;

            Message = String.Format("Converting {0} \n objects", BucketObjects.Count);

            var convertedObjects = Converter.Serialise(BucketObjects).ToList();

            Message = String.Format("Creating payloads");

            LocalContext.PruneExistingObjects(convertedObjects, Client.BaseUrl);

            List <SpeckleObject> persistedObjects = new List <SpeckleObject>();

            if (convertedObjects.Count(obj => obj.Type == "Placeholder") != convertedObjects.Count)
            {
                // create the update payloads
                int  count = 0;
                var  objectUpdatePayloads = new List <List <SpeckleObject> >();
                long totalBucketSize      = 0;
                long currentBucketSize    = 0;
                var  currentBucketObjects = new List <SpeckleObject>();
                var  allObjects           = new List <SpeckleObject>();
                foreach (SpeckleObject convertedObject in convertedObjects)
                {
                    if (count++ % 100 == 0)
                    {
                        Message = "Converted " + count + " objects out of " + convertedObjects.Count() + ".";
                    }

                    // size checking & bulk object creation payloads creation
                    long size = Converter.getBytes(convertedObject).Length;
                    currentBucketSize += size;
                    totalBucketSize   += size;
                    currentBucketObjects.Add(convertedObject);

                    // Object is too big?
                    if (size > 2e6)
                    {
                        AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "This stream contains a super big object. These will fail. Sorry for the bad error message - we're working on improving this.");

                        currentBucketObjects.Remove(convertedObject);
                    }

                    if (currentBucketSize > 5e5) // restrict max to ~500kb; should it be user config? anyway these functions should go into core. at one point.
                    {
                        Debug.WriteLine("Reached payload limit. Making a new one, current  #: " + objectUpdatePayloads.Count);
                        objectUpdatePayloads.Add(currentBucketObjects);
                        currentBucketObjects = new List <SpeckleObject>();
                        currentBucketSize    = 0;
                    }
                }

                // add in the last bucket
                if (currentBucketObjects.Count > 0)
                {
                    objectUpdatePayloads.Add(currentBucketObjects);
                }

                Debug.WriteLine("Finished, payload object update count is: " + objectUpdatePayloads.Count + " total bucket size is (kb) " + totalBucketSize / 1000);

                // create bulk object creation tasks
                int k = 0;
                List <ResponseObject> responses = new List <ResponseObject>();
                foreach (var payload in objectUpdatePayloads)
                {
                    Message = String.Format("{0}/{1}", k++, objectUpdatePayloads.Count);

                    try
                    {
                        var objResponse = Client.ObjectCreateAsync(payload).Result;
                        responses.Add(objResponse);
                        persistedObjects.AddRange(objResponse.Resources);

                        int m = 0;
                        foreach (var oL in payload)
                        {
                            oL._id = objResponse.Resources[m++]._id;
                        }

                        // push sent objects in the cache non-blocking
                        Task.Run(() =>
                        {
                            foreach (var oL in payload)
                            {
                                if (oL.Type != "Placeholder")
                                {
                                    LocalContext.AddSentObject(oL, Client.BaseUrl);
                                }
                            }
                        });
                    }
                    catch (Exception err)
                    {
                        AddRuntimeMessage(GH_RuntimeMessageLevel.Error, err.Message);
                        return;
                    }
                }
            }
            else
            {
                persistedObjects = convertedObjects;
            }

            // create placeholders for stream update payload
            List <SpeckleObject> placeholders = new List <SpeckleObject>();

            //foreach ( var myResponse in responses )
            foreach (var obj in persistedObjects)
            {
                placeholders.Add(new SpecklePlaceholder()
                {
                    _id = obj._id
                });
            }

            SpeckleStream updateStream = new SpeckleStream()
            {
                Layers  = BucketLayers,
                Name    = BucketName,
                Objects = placeholders
            };

            // set some base properties (will be overwritten)
            var baseProps = new Dictionary <string, object>();

            baseProps["units"]          = Rhino.RhinoDoc.ActiveDoc.ModelUnitSystem.ToString();
            baseProps["tolerance"]      = Rhino.RhinoDoc.ActiveDoc.ModelAbsoluteTolerance;
            baseProps["angleTolerance"] = Rhino.RhinoDoc.ActiveDoc.ModelAngleToleranceRadians;
            updateStream.BaseProperties = baseProps;

            var response = Client.StreamUpdateAsync(Client.StreamId, updateStream).Result;

            Client.BroadcastMessage("stream", Client.StreamId, new { eventType = "update-global" });

            Log += response.Message;
            AddRuntimeMessage(GH_RuntimeMessageLevel.Remark, "Data sent at " + DateTime.Now);
            Message = "Data sent\n@" + DateTime.Now.ToString("hh:mm:ss");

            IsSendingUpdate = false;
            State           = "Ok";
        }
Beispiel #29
0
        /// <summary>
        /// Creates a stream with many objects. Use this as a reference for how to save arbitrarily large numbers of objects.
        /// </summary>
        /// <param name="numObjects">how many objects to create.</param>
        static void CreateStreamWithManyObjects(int numObjects)
        {
            if (numObjects > 50000)
            {
                Console.WriteLine("Let's think about this: is this the best way to do it? Y/N");
                var answer = Console.ReadLine();
                if (answer == "N")
                {
                    return;
                }
                else
                {
                    Console.WriteLine("oh well, ok... will go ahead.");
                }
            }

            var nodes = new List <Node>();

            for (int i = 0; i < numObjects; i++)
            {
                nodes.Add(new Node {
                    x = i, y = i % 2, z = i % 3
                });
            }

            var account      = GetAccount();
            var savedObjects = SaveManyObjects(account, nodes);

            var client = new SpeckleApiClient(account.RestApi, false, "console_app");

            client.AuthToken = account.Token;

            Console.WriteLine("Please enter a stream name:");
            var name = Console.ReadLine();

            var myStream = new SpeckleStream()
            {
                Objects     = savedObjects.Cast <SpeckleObject>().ToList(),
                Name        = name != "" ? name : "Console test stream",
                Description = "This stream was created from a .net console program. Easy peasy.",
                Tags        = new List <string> {
                    "example", "console-test"
                },
            };

            try
            {
                // save the stream.
                var result = client.StreamCreateAsync(myStream).Result;

                // profit
                Console.WriteLine(String.Format("Succesfully created a stream! It's id is {0}. Rock on! Check it out at {1}/streams/{0}", result.Resource.StreamId, account.RestApi));
                Console.WriteLine("Press any key to continue.");

                System.Diagnostics.Process.Start(String.Format("{1}/streams/{0}", result.Resource.StreamId, account.RestApi));
                Console.ReadLine();
            }
            catch (Exception e)
            {
                Console.WriteLine("Bummer - something went wrong:");
                Console.WriteLine(e.Message);
                Console.WriteLine("Press any key to continue.");
                Console.ReadLine();
            }
        }