using FeMM.Grasshopper.Helpers;
using Grasshopper.Kernel;
using Grasshopper.Kernel.Data;
using Grasshopper.Kernel.Types;
using St7API;
using System;
using System.Collections.Generic;
using System.Text;
namespace FeMM.Grasshopper.Components.ST2R
{
public class St7ReadBeamGlobalDispComponent : GH_Component
{
private bool _run = false;
public St7ReadBeamGlobalDispComponent()
: base(
"Read Beam Global Displacement",
"ReadBeamDisp",
"Reads beam displacement results",
CategoryNameConstants.CATEGORY_F2R,
CategoryNameConstants.SUBCATEGORY_ST2R_BAKE)
{ }
public override void CreateAttributes()
{
var buttonAttributes =
new ComponentAttributes.ComponentOneButtonAttributes(this, "Read");
buttonAttributes.ButtonPressed += () =>
{
_run = true;
ExpireSolution(true);
};
m_attributes = buttonAttributes;
}
protected override void RegisterInputParams(GH_InputParamManager p)
{
p.AddIntegerParameter(
"uID", "ID",
"uID of the opened Straus7 model",
GH_ParamAccess.item);
p.AddTextParameter(
"Result File", "Res",
"Path to .NLA / .NLF / .RST result file",
GH_ParamAccess.item);
p.AddIntegerParameter(
"Beam Number", "BeamNum",
"Beam number(s)",
GH_ParamAccess.list);
p.AddIntegerParameter(
"Min Stations", "Min",
"Minimum number of stations",
GH_ParamAccess.item, 5);
}
protected override void RegisterOutputParams(GH_OutputParamManager p)
{
p.AddTextParameter(
"Case Names", "Names",
"Result case / envelope names",
GH_ParamAccess.tree);
p.AddNumberParameter(
"Positions", "P",
"Station positions",
GH_ParamAccess.tree);
p.AddNumberParameter(
"Dx", "Dx",
"Global displacement X",
GH_ParamAccess.tree);
p.AddNumberParameter(
"Dy", "Dy",
"Global displacement Y",
GH_ParamAccess.tree);
p.AddNumberParameter(
"Dz", "Dz",
"Global displacement Z",
GH_ParamAccess.tree);
p.AddNumberParameter(
"Rx", "Rx",
"Global rotation X",
GH_ParamAccess.tree);
p.AddNumberParameter(
"Ry", "Ry",
"Global rotation Y",
GH_ParamAccess.tree);
p.AddNumberParameter(
"Rz", "Rz",
"Global rotation Z",
GH_ParamAccess.tree);
p.AddTextParameter(
"Log", "Log",
"Debug log messages",
GH_ParamAccess.list);
}
protected override void SolveInstance(IGH_DataAccess DA)
{
int uID = 0;
string resultFile = "";
List<int> beamNums = [];
int minStations = 5;
if (!DA.GetData(0, ref uID)) return;
if (!DA.GetData(1, ref resultFile)) return;
if (!DA.GetDataList(2, beamNums)) return;
if (!DA.GetData(3, ref minStations)) return;
List<string> log = [];
if (!_run)
{
DA.SetDataList(8, log);
return;
}
int numPrimary = 0;
int numSecondary = 0;
int err = St7.St7OpenResultFile(
uID,
resultFile,
null,
St7.kUseExistingCombinations,
ref numPrimary,
ref numSecondary);
if (err != 0)
{
log.Add($"Error opening result file: {err}");
DA.SetDataList(8, log);
_run = false;
return;
}
int numLimitEnv = 0, numComboEnv = 0, numFactorEnv = 0;
St7.St7GenerateEnvelopes(
uID, ref numLimitEnv, ref numComboEnv, ref numFactorEnv);
GH_Structure<GH_String> treeNames = new();
GH_Structure<GH_Number> treePos = new();
GH_Structure<GH_Number> treeDx = new();
GH_Structure<GH_Number> treeDy = new();
GH_Structure<GH_Number> treeDz = new();
GH_Structure<GH_Number> treeRx = new();
GH_Structure<GH_Number> treeRy = new();
GH_Structure<GH_Number> treeRz = new();
int beamIndex = 0;
foreach (int beamNum in beamNums)
{
int caseBranchIndex = 0;
void ReadCase(int caseNum, string caseName)
{
int maxStations = 200;
int maxCols = 6; // Dx Dy Dz Rx Ry Rz
double[] pos = new double[maxStations];
double[] res = new double[maxStations * maxCols];
int nStations = 0;
int nCols = 0;
int errBeam = St7.St7GetBeamResultArray(
uID,
St7.rtBeamDisp,
St7.stBeamGlobal,
beamNum,
minStations,
caseNum,
ref nStations,
ref nCols,
pos,
res);
if (errBeam != 0)
{
log.Add(
$"Error reading beam {beamNum} displacement for {caseName}: {errBeam}");
return;
}
GH_Path path = new(beamIndex, caseBranchIndex);
for (int i = 0; i < nStations; i++)
{
int b = i * nCols;
treeNames.Append(new GH_String(caseName), path);
treePos.Append(new GH_Number(pos[i]), path);
treeDx.Append(new GH_Number(res[b + 0]), path);
treeDy.Append(new GH_Number(res[b + 1]), path);
treeDz.Append(new GH_Number(res[b + 2]), path);
treeRx.Append(new GH_Number(res[b + 3]), path);
treeRy.Append(new GH_Number(res[b + 4]), path);
treeRz.Append(new GH_Number(res[b + 5]), path);
}
caseBranchIndex++;
}
// Primary cases
for (int i = 1; i <= numPrimary; i++)
{
var name = new StringBuilder(256);
if (St7.St7GetResultCaseName(
uID, i, name, name.Capacity) == 0)
ReadCase(i, name.ToString().TrimEnd('\0'));
}
// Secondary combinations
for (int i = 1; i <= numSecondary; i++)
{
var name = new StringBuilder(256);
if (St7.St7GetLSACombinationName(
uID, i, name, name.Capacity) == 0)
ReadCase(i + numPrimary,
name.ToString().TrimEnd('\0'));
}
// Envelopes
int baseEnv = numPrimary + numSecondary;
for (int i = 1;
i <= numLimitEnv + numComboEnv + numFactorEnv;
i++)
{
var name = new StringBuilder(256);
if (St7.St7GetResultCaseName(
uID, baseEnv + i, name, name.Capacity) == 0)
ReadCase(baseEnv + i,
name.ToString().TrimEnd('\0'));
}
beamIndex++;
}
DA.SetDataTree(0, treeNames);
DA.SetDataTree(1, treePos);
DA.SetDataTree(2, treeDx);
DA.SetDataTree(3, treeDy);
DA.SetDataTree(4, treeDz);
DA.SetDataTree(5, treeRx);
DA.SetDataTree(6, treeRy);
DA.SetDataTree(7, treeRz);
DA.SetDataList(8, log);
_run = false;
}
protected override System.Drawing.Bitmap Icon => Properties.Resources.St7ReadBeamGlobalDispIcon;
public override Guid ComponentGuid =>
new("8f9a3e32-7e74-4a9a-9c1a-6a2c3a7c4d11");
}
}