private static bool Create1DElementResultObjects(string typeName, string axisStr, int num1dPos, string loadTaskKw, string comboKw,
      List<ResultType> resultTypes, List<string> cases, int numAdditionalPoints)
    {
      var gsaResults = new List<GSA1DElementResult>();
      var gsaResultsLock = new object();
      var memberKw = typeof(GSA1DMember).GetGSAKeyword();
      var keyword = typeof(GSA1DElement).GetGSAKeyword();
      var globalAxis = !Initialiser.AppResources.Settings.ResultInLocalAxis;
      

      //Unlike embedding, separate results doesn't necessarily mean that there is a Speckle object created for each 1d element.  There is always though
      //some GWA loaded into the cache
      if (!Initialiser.AppResources.Cache.GetKeywordRecordsSummary(keyword, out var gwa, out var indices, out var applicationIds))
      {
        return false;
      }

      Initialiser.AppResources.Proxy.LoadResults(ResultGroup.Element1d, out int numErrorRows, cases, indices);
      if (numErrorRows > 0)
      {
        Initialiser.AppResources.Messenger.Message(MessageIntent.Display, MessageLevel.Error, "Unable to process " + numErrorRows + " rows of 1D element results");
        Initialiser.AppResources.Messenger.Message(MessageIntent.TechnicalLog, MessageLevel.Error, "Unable to process " + numErrorRows + " rows of 1D element results");
      }

#if DEBUG
      for (int i = 0; i < indices.Count(); i++)
#else
      Parallel.For(0, indices.Count(), i =>
#endif
      {
        var entity = indices[i];
        var applicationId = applicationIds[i];

        try
        {
          var pPieces = gwa[i].ListSplit(Initialiser.AppResources.Proxy.GwaDelimiter);
          if (pPieces[4].ParseElementNumNodes() == 2 && entity != 0)
          { 
            if (Initialiser.AppResources.Proxy.GetResultHierarchy(ResultGroup.Element1d, entity, out var results) && results != null)
            {
              var orderedLoadCases = results.Keys.OrderBy(k => k).ToList();
              foreach (var loadCase in orderedLoadCases)
              {
                if (!SchemaConversion.Helper.FilterResults(results[loadCase], out Dictionary<string, object> sendableResults))
                {
                  continue;
                }
                var elem1dResult = new Structural1DElementResult()
                {
                  IsGlobal = !Initialiser.AppResources.Settings.ResultInLocalAxis,
                  Value = sendableResults,
                  TargetRef = applicationId
                };
                var loadCaseRef = SchemaConversion.Helper.GsaCaseToRef(loadCase, loadTaskKw, comboKw);
                if (!string.IsNullOrEmpty(loadCaseRef))
                {
                  elem1dResult.LoadCaseRef = loadCase;
                }

                lock(gsaResultsLock)
                {
                  gsaResults.Add(new GSA1DElementResult { Value = elem1dResult, GSAId = entity });
                }
              }
            }
          }

        }
        catch (Exception ex)
        {
          var contextDesc = string.Join(" ", typeName, entity);
          Initialiser.AppResources.Messenger.Message(MessageIntent.TechnicalLog, MessageLevel.Error, ex, contextDesc, i.ToString());
        }
      }
#if !DEBUG
      );
#endif
      Initialiser.AppResources.Proxy.ClearResults(ResultGroup.Element1d);
      if (gsaResults.Count > 0)
      {
        Initialiser.GsaKit.GSASenderObjects.AddRange(gsaResults);
      }
      return true;
    }
        public static SpeckleObject ToSpeckle(this GSA1DElementResult dummyObject)
        {
            if (Initialiser.Settings.Element1DResults.Count() == 0)
            {
                return(new SpeckleNull());
            }

            if (Initialiser.Settings.EmbedResults && !Initialiser.GSASenderObjects.ContainsKey(typeof(GSA1DElement)))
            {
                return(new SpeckleNull());
            }

            if (Initialiser.Settings.EmbedResults)
            {
                var elements = Initialiser.GSASenderObjects[typeof(GSA1DElement)].Cast <GSA1DElement>().ToList();

                var entities = elements.Cast <IGSASpeckleContainer>().ToList();

                foreach (var kvp in Initialiser.Settings.Element1DResults)
                {
                    foreach (var loadCase in Initialiser.Settings.ResultCases)
                    {
                        if (!Initialiser.Interface.CaseExist(loadCase))
                        {
                            continue;
                        }

                        foreach (var entity in entities)
                        {
                            var id = entity.GSAId;

                            if (entity.Value.Result == null)
                            {
                                entity.Value.Result = new Dictionary <string, object>();
                            }

                            var resultExport = Initialiser.Interface.GetGSAResult(id, kvp.Value.Item1, kvp.Value.Item2, kvp.Value.Item3, loadCase, Initialiser.Settings.ResultInLocalAxis
                ? "local" : "global", Initialiser.Settings.Result1DNumPosition);

                            if (resultExport == null)
                            {
                                continue;
                            }

                            if (!entity.Value.Result.ContainsKey(loadCase))
                            {
                                entity.Value.Result[loadCase] = new Structural1DElementResult()
                                {
                                    Value = new Dictionary <string, object>()
                                }
                            }
                            ;

                            (entity.Value.Result[loadCase] as Structural1DElementResult).Value[kvp.Key] = resultExport;
                        }
                    }
                }

                // Linear interpolate the line values
                foreach (var entity in entities)
                {
                    var dX = (entity.Value.Value[3] - entity.Value.Value[0]) / (Initialiser.Settings.Result1DNumPosition + 1);
                    var dY = (entity.Value.Value[4] - entity.Value.Value[1]) / (Initialiser.Settings.Result1DNumPosition + 1);
                    var dZ = (entity.Value.Value[5] - entity.Value.Value[2]) / (Initialiser.Settings.Result1DNumPosition + 1);

                    var interpolatedVertices = new List <double>();
                    interpolatedVertices.AddRange((entity.Value.Value as List <double>).Take(3));

                    for (var i = 1; i <= Initialiser.Settings.Result1DNumPosition; i++)
                    {
                        interpolatedVertices.Add(interpolatedVertices[0] + dX * i);
                        interpolatedVertices.Add(interpolatedVertices[1] + dY * i);
                        interpolatedVertices.Add(interpolatedVertices[2] + dZ * i);
                    }

                    interpolatedVertices.AddRange((entity.Value.Value as List <double>).Skip(3).Take(3));

                    entity.Value.ResultVertices = interpolatedVertices;
                }
            }
            else
            {
                Initialiser.GSASenderObjects[typeof(GSA1DElementResult)] = new List <object>();

                var results = new List <GSA1DElementResult>();

                var keyword = HelperClass.GetGSAKeyword(typeof(GSA1DElement));
                var gwa     = Initialiser.Cache.GetGwa(keyword);

                foreach (var kvp in Initialiser.Settings.Element1DResults)
                {
                    foreach (var loadCase in Initialiser.Settings.ResultCases)
                    {
                        if (!Initialiser.Interface.CaseExist(loadCase))
                        {
                            continue;
                        }

                        for (var i = 0; i < gwa.Count(); i++)
                        {
                            var record = gwa[i];

                            var pPieces = record.ListSplit("\t");
                            if (pPieces[4].ParseElementNumNodes() != 2)
                            {
                                continue;
                            }

                            if (!int.TryParse(pPieces[1], out var id))
                            {
                                //Could not extract index
                                continue;
                            }

                            var resultExport = Initialiser.Interface.GetGSAResult(id, kvp.Value.Item1, kvp.Value.Item2, kvp.Value.Item3, loadCase, Initialiser.Settings.ResultInLocalAxis ? "local" : "global", Initialiser.Settings.Result1DNumPosition);

                            if (resultExport == null || resultExport.Count() == 0)
                            {
                                continue;
                            }

                            var existingRes = results.FirstOrDefault(x => x.Value.TargetRef == id.ToString());
                            if (existingRes == null)
                            {
                                var newRes = new Structural1DElementResult()
                                {
                                    Value     = new Dictionary <string, object>(),
                                    TargetRef = HelperClass.GetApplicationId(typeof(GSA1DElement).GetGSAKeyword(), id),
                                    IsGlobal  = !Initialiser.Settings.ResultInLocalAxis,
                                };
                                newRes.Value[kvp.Key] = resultExport;

                                newRes.GenerateHash();

                                results.Add(new GSA1DElementResult()
                                {
                                    Value = newRes
                                });
                            }
                            else
                            {
                                existingRes.Value.Value[kvp.Key] = resultExport;
                            }
                        }
                    }
                }

                Initialiser.GSASenderObjects[typeof(GSA1DElementResult)].AddRange(results);
            }

            return(new SpeckleObject());
        }
    private static void Embed1DResults(string typeName, string axisStr, int num1dPos, string keyword, string loadTaskKw, string comboKw,
      List<ResultType> resultTypes, List<string> cases, int numAdditionalPoints)
    {
      var elements = Initialiser.GsaKit.GSASenderObjects.Get<GSA1DElement>();

      var entities = elements.Cast<GSA1DElement>().ToList();
      var globalAxis = !Initialiser.AppResources.Settings.ResultInLocalAxis;

      Initialiser.AppResources.Proxy.LoadResults(ResultGroup.Element1d, out int numErrorRows, cases, entities.Select(e => e.GSAId).ToList());
      if (numErrorRows > 0)
      {
        Initialiser.AppResources.Messenger.Message(MessageIntent.Display, MessageLevel.Error, "Unable to process " + numErrorRows + " rows of 1D element results");
        Initialiser.AppResources.Messenger.Message(MessageIntent.TechnicalLog, MessageLevel.Error, "Unable to process " + numErrorRows + " rows of 1D element results");
      }

#if DEBUG
      foreach (var e in entities)
#else
      Parallel.ForEach(entities, e =>
#endif
      {
        var i = e.GSAId;
        var obj = e.Value;
        if (Initialiser.AppResources.Proxy.GetResultHierarchy(ResultGroup.Element1d, i, out var results) && results != null)
        {
          var orderedLoadCases = results.Keys.OrderBy(k => k).ToList();
          foreach (var loadCase in orderedLoadCases)
          {
            if (!SchemaConversion.Helper.FilterResults(results[loadCase], out Dictionary<string, object> sendableResults))
            {
              continue;
            }
            var nodeResult = new Structural1DElementResult()
            {
              IsGlobal = !Initialiser.AppResources.Settings.ResultInLocalAxis,
              TargetRef = obj.ApplicationId,
              Value = sendableResults
            };
            var loadCaseRef = SchemaConversion.Helper.GsaCaseToRef(loadCase, loadTaskKw, comboKw);
            if (!string.IsNullOrEmpty(loadCaseRef))
            {
              nodeResult.LoadCaseRef = loadCase;
            }
            if (obj.Result == null)
            {
              //Can't just allocate an empty dictionary as the Result set property won't allow it
              obj.Result = new Dictionary<string, object>() { { loadCase, nodeResult } };
            }
            else
            {
              obj.Result.Add(loadCase, nodeResult);
            }
          }
        }
      }
#if !DEBUG
      );
#endif

      Initialiser.AppResources.Proxy.ClearResults(ResultGroup.Element1d);

      // Linear interpolate the line values
      foreach (var entity in entities)
      {
        var obj = entity.Value;

        var dX = (obj.Value[3] - obj.Value[0]) / (Initialiser.AppResources.Settings.Result1DNumPosition + 1);
        var dY = (obj.Value[4] - obj.Value[1]) / (Initialiser.AppResources.Settings.Result1DNumPosition + 1);
        var dZ = (obj.Value[5] - obj.Value[2]) / (Initialiser.AppResources.Settings.Result1DNumPosition + 1);

        var interpolatedVertices = new List<double>();
        interpolatedVertices.AddRange(obj.Value.Take(3));

        for (var i = 1; i <= Initialiser.AppResources.Settings.Result1DNumPosition; i++)
        {
          interpolatedVertices.Add(interpolatedVertices[0] + dX * i);
          interpolatedVertices.Add(interpolatedVertices[1] + dY * i);
          interpolatedVertices.Add(interpolatedVertices[2] + dZ * i);
        }

        interpolatedVertices.AddRange(obj.Value.Skip(3).Take(3));

        obj.ResultVertices = interpolatedVertices;
      }
    }
Esempio n. 4
0
    public void ParseGWACommand(List<GSA1DElement> elements)
    {
      if (elements.Count() < 1)
      {
        return;
      }
      var elementsListCopy = new List<GSA1DElement>(elements);

      var obj = new Structural1DElementPolyline
      {
        ApplicationId = Helper.GetApplicationId(typeof(GSA1DMember).GetGSAKeyword(), GSAId),

        Value = new List<double>(),
        ElementApplicationId = new List<string>(),

        ElementType = elementsListCopy.First().Value.ElementType,
        PropertyRef = elementsListCopy.First().Value.PropertyRef,
        ZAxis = new List<StructuralVectorThree>(),
        EndRelease = new List<StructuralVectorBoolSix>(),
        Offset = new List<StructuralVectorThree>(),
        ResultVertices = new List<double>()
      };

      if (obj.Properties == null)
      {
        obj.Properties = new Dictionary<string, object>();
      }
      if (!obj.Properties.ContainsKey("structural"))
      {
        obj.Properties.Add("structural", new Dictionary<string, object>());
      }

      var settings = Initialiser.AppResources.Settings;
      var anyElement1dResults = settings.ResultTypes != null && settings.ResultTypes.Any(rt => rt.ToString().ToLower().Contains("1d"));

      Dictionary<string, object> results = null;
      if (anyElement1dResults & settings.StreamSendConfig == StreamContentConfig.ModelWithEmbeddedResults)
      {
        results = new Dictionary<string, object>();
      }

      // Match up coordinates
      var coordinates = new List<Tuple<string, string>>();

      foreach (var e in elementsListCopy)
        coordinates.Add(new Tuple<string, string>(
          string.Join(",", (e.Value.Value as List<double>).Take(3).Select(x => Math.Round(x, 4).ToString())),
          string.Join(",", (e.Value.Value as List<double>).Skip(3).Take(3).Select(x => Math.Round(x, 4).ToString()))
        ));

      // Find start coordinate
      var flatCoordinates = coordinates.SelectMany(x => new List<string>() { x.Item1, x.Item2 }).ToList();
      var uniqueCoordinates = flatCoordinates.Where(x => flatCoordinates.Count(y => y == x) == 1).ToList();

      var current = uniqueCoordinates[0];

      //Because these properties could, depending on how they've been added to the StructuralProperties dictionary,
      //return another instance of the lists instead of a pointer to the lists themselves, temporary variables are used
      //to build up new lists which are assigned as replacements to the property values further down
      if (obj.ElementApplicationId == null)
      {
        obj.ElementApplicationId = new List<string>();
      }
      var elementAppIds = obj.ElementApplicationId ?? new List<string>();
      var gsaIds = new List<int>();
      var zAxes = obj.ZAxis ?? new List<StructuralVectorThree>();
      var endReleases = obj.EndRelease ?? new List<StructuralVectorBoolSix>();
      var offsets = obj.Offset ?? new List<StructuralVectorThree>();
      var resultVertices = obj.ResultVertices ?? new List<double>();

      while (coordinates.Count > 0)
      {
        var matchIndex = 0;
        var reverseCoordinates = false;

        matchIndex = coordinates.FindIndex(x => x.Item1 == current);
        reverseCoordinates = false;
        if (matchIndex == -1)
        {
          matchIndex = coordinates.FindIndex(x => x.Item2 == current);
          reverseCoordinates = true;
        }

        var gsaElement = elementsListCopy[matchIndex];
        var element = (Structural1DElement)gsaElement.Value;

        elementAppIds.Add(element.ApplicationId);
        try
        {
          if (int.TryParse(((Dictionary<string, object>)element.Properties["structural"])["NativeId"].ToString(), out int gsaId))
          gsaIds.Add(gsaId);
        }
        catch { }

        zAxes.Add(element.ZAxis);

        if (obj.Value.Count == 0)
        {
          if (!reverseCoordinates)
          {
            obj.Value.AddRange((element.Value as List<double>).Take(3));
          }
          else
          {
            obj.Value.AddRange((element.Value as List<double>).Skip(3).Take(3));
          }
        }

        if (!reverseCoordinates)
        {
          current = string.Join(",", (element.Value as List<double>).Skip(3).Take(3).Select(x => Math.Round(x, 4).ToString()));
          obj.Value.AddRange((element.Value as List<double>).Skip(3).Take(3));
          endReleases.AddRange(element.EndRelease);
          offsets.AddRange(element.Offset);

          if (anyElement1dResults && settings.StreamSendConfig == StreamContentConfig.ModelWithEmbeddedResults)
          {
            resultVertices.AddRange(element.ResultVertices);
          }
          else
          {
            resultVertices.AddRange((element.Value as List<double>));
          }
        }
        else
        {
          current = string.Join(",", (element.Value as List<double>).Take(3).Select(x => Math.Round(x, 4).ToString()));
          obj.Value.AddRange((element.Value as List<double>).Take(3));
          endReleases.Add((element.EndRelease as List<StructuralVectorBoolSix>).Last());
          endReleases.Add((element.EndRelease as List<StructuralVectorBoolSix>).First());
          offsets.Add((element.Offset as List<StructuralVectorThree>).Last());
          offsets.Add((element.Offset as List<StructuralVectorThree>).First());

          if (anyElement1dResults && settings.StreamSendConfig == StreamContentConfig.ModelWithEmbeddedResults)
          {
            for (var i = (element.ResultVertices.Count - 3); i >= 0; i -= 3)
            {
              resultVertices.AddRange((element.ResultVertices as List<double>).Skip(i).Take(3));
            }
          }
          else
          {
            resultVertices.AddRange((element.Value as List<double>).Skip(3).Take(3));
            resultVertices.AddRange((element.Value as List<double>).Take(3));
          }
        }

        // Result merging
        if (results != null && ((Structural1DElement)gsaElement.Value).Result != null)
        {
          try
          {
            foreach (var loadCase in element.Result.Keys)
            {
              if (!results.ContainsKey(loadCase))
              {
                results[loadCase] = new Structural1DElementResult()
                {
                  Value = new Dictionary<string, object>(),
                  IsGlobal = !Initialiser.AppResources.Settings.ResultInLocalAxis,
                };
              }


              if (element.Result[loadCase] is Structural1DElementResult resultExport)
              {
                foreach (var key in resultExport.Value.Keys)
                {
                  if (!(results[loadCase] as Structural1DElementResult).Value.ContainsKey(key))
                  {
                    (results[loadCase] as Structural1DElementResult).Value[key]
                      = new Dictionary<string, object>(resultExport.Value[key] as Dictionary<string, object>);
                  }
                  else
                  {
                    foreach (var resultKey in ((results[loadCase] as Structural1DElementResult).Value[key] as Dictionary<string, object>).Keys)
                    {
                      var res = (resultExport.Value[key] as Dictionary<string, object>)[resultKey] as List<object>;
                      if (reverseCoordinates)
                      {
                        res.Reverse();
                      }
                      (((results[loadCase] as Structural1DElementResult).Value[key] as Dictionary<string, object>)[resultKey] as List<object>)
                        .AddRange(res);
                    }
                  }
                }
              }
              else
              {
                // UNABLE TO MERGE RESULTS
                results = null;
                break;
              }
            }
          }
          catch
          {
            // UNABLE TO MERGE RESULTS
            results = null;
          }
        }

        coordinates.RemoveAt(matchIndex);
        elementsListCopy.RemoveAt(matchIndex);
      }

      obj.ElementApplicationId = elementAppIds;
      obj.ZAxis = zAxes;
      obj.EndRelease = endReleases;
      obj.Offset = offsets;
      obj.ResultVertices = resultVertices;
      obj.Result = results;

      ((Dictionary<string, object>)obj.Properties["structural"]).Add("NativeIds", gsaIds.Select(gid => gid.ToString()).ToList());

      this.Value = obj;
    }