public static SpeckleObject ToSpeckle(this GsaLoadNode dummyObject) { var typeName = dummyObject.GetType().Name; var gsaLoads = Helper.GetNewFromCache <GSA0DLoad, GsaLoadNode>(); if (gsaLoads.Count() == 0) { return(new SpeckleObject()); } gsaLoads = gsaLoads.Where(l => l.Index.ValidNonZero()).ToList(); var keyword = GsaRecord.GetKeyword <GsaLoadNode>(); var nodeKeyword = GsaRecord.GetKeyword <GsaNode>(); var loadCaseKeyword = GsaRecord.GetKeyword <GsaLoadCase>(); //The 0D loads are split into two groups: //1. Those which are grouped by Application ID - n:1 ratio (where n <= 6) between GSA objects and Speckle objects //2. Those which are sent out individually - 1:1 ratio between GSA objects and Speckle objects //To avoid complication regarding merging with existing objects: if a 0D load was previously received from Speckle (i.e. it has an application ID) //and it was manually changed from GLOBAL to referencing an axis, then ignore the application ID when sending out (i.e. lump it with group #2) var group1 = gsaLoads.Where(l => !string.IsNullOrEmpty(l.ApplicationId) && l.GlobalAxis); var group2 = gsaLoads.Except(group1); var nodeIndicesReferenced = new List <int>(); var structural0DLoads = new List <Structural0DLoad>(); var gsaNodes = Initialiser.GsaKit.GSASenderObjects.Get <GSANode>(); Add0dLoadsWithAppId(nodeKeyword, loadCaseKeyword, group1, gsaNodes, ref structural0DLoads, ref nodeIndicesReferenced); Add0dLoadsWithoutAppId(keyword, nodeKeyword, loadCaseKeyword, group2, gsaNodes, ref structural0DLoads, ref nodeIndicesReferenced); var forceSendNodes = gsaNodes.Where(n => nodeIndicesReferenced.Any(nir => nir == n.GSAId)).ToList(); foreach (var fsn in forceSendNodes) { fsn.ForceSend = true; } var loads = structural0DLoads.Select(sl => new GSA0DLoad() { Value = sl }).ToList(); if (loads.Count() > 0) { Initialiser.GsaKit.GSASenderObjects.AddRange(loads); } return((loads.Count() > 0) ? new SpeckleObject() : new SpeckleNull()); }