Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Robot_Toolkit: Fix MeshResults crash on non-planar meshes #453

Merged
merged 4 commits into from
Mar 12, 2021
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
112 changes: 66 additions & 46 deletions Robot_Adapter/CRUD/Read/Results/MeshResults.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,7 @@
using System.Collections.Generic;
using BH.oM.Structure.Results;
using RobotOM;
using System.Collections;
using BH.oM.Geometry.CoordinateSystem;
using System.Linq;
using BH.oM.Data.Requests;
using System.Collections.ObjectModel;
using BH.oM.Analytical.Results;
using BH.oM.Structure.Requests;
Expand Down Expand Up @@ -70,29 +67,30 @@ public IEnumerable<IResult> ReadResults(MeshResultRequest request, ActionConfig
IRobotStructure robotStructureServer = m_RobotApplication.Project.Structure;

List<BH.oM.Structure.Elements.Node> nodes = ReadNodesQuery();
List<BH.oM.Structure.Elements.Panel> panels = new List<oM.Structure.Elements.Panel>();
List<BH.oM.Structure.Elements.FEMesh> feMeshList = new List<oM.Structure.Elements.FEMesh>();

if (request.ObjectIds == null || request.ObjectIds.Count == 0)
{
panels = ReadPanelsLight();
feMeshList = ReadMeshes();
}
else
{
List<object> panelIds = new List<object>();
List<object> meshIds = new List<object>();
foreach (object obj in request.ObjectIds)
{
if (obj is oM.Structure.Elements.Panel)
panels.Add(obj as oM.Structure.Elements.Panel);
if (obj is oM.Structure.Elements.FEMesh)
feMeshList.Add(obj as oM.Structure.Elements.FEMesh);
else
panelIds.Add(obj);
meshIds.Add(obj);
}
if (panelIds.Count > 0)
if (meshIds.Count > 0)
{
panels.AddRange(ReadPanelsLight(CheckAndGetIds<oM.Structure.Elements.FEMesh>(panelIds)));
List<string> idList = CheckAndGetIds<oM.Structure.Elements.FEMesh>(meshIds).Select(x => x.ToString()).ToList();
feMeshList.AddRange(ReadMeshes(idList));
}
}


List<BH.oM.Geometry.Point> nodePointList = nodes.Select(x => Engine.Structure.Query.Position(x)).ToList();
List<Point> nodePointList = nodes.Select(x => Engine.Structure.Query.Position(x)).ToList();

RobotResultQueryParams queryParams = (RobotResultQueryParams)m_RobotApplication.Kernel.CmpntFactory.Create(IRobotComponentType.I_CT_RESULT_QUERY_PARAMS);

Expand Down Expand Up @@ -130,36 +128,58 @@ public IEnumerable<IResult> ReadResults(MeshResultRequest request, ActionConfig
}

List<MeshResult> meshResultsCollection = new List<MeshResult>();
foreach (BH.oM.Structure.Elements.Panel panel in panels)
foreach (BH.oM.Structure.Elements.FEMesh feMesh in feMeshList)
{
Basis orientation = null;
try
{
orientation = request.Orientation ?? panel.LocalOrientation();
}
catch (System.Exception)
Basis orientation = request.Orientation;

if (orientation == null)
{
Engine.Reflection.Compute.RecordWarning($"Could not extract local orientation for Panel with id {GetAdapterId<int>(panel)}. Default orientation will be used for this panel.");
try
{
//Get local orientations for each face
List<Basis> orientations = feMesh.LocalOrientations();

//Check if all orientations are the same
bool sameOrientation = true;

for (int i = 0; i < orientations.Count - 1; i++)
{
sameOrientation &= orientations[i].Z.Angle(orientations[i].Z) < Tolerance.Angle;
if (!sameOrientation)
break;
}

if (sameOrientation && orientations.Count > 0)
orientation = orientations.First();
}
catch (System.Exception)
{
Engine.Reflection.Compute.RecordWarning($"Could not extract local orientation for FEMesh with id {GetAdapterId<int>(feMesh)}. Default orientation will be used for this FEMesh.");
}
}

List<MeshElementResult> meshResults = new List<MeshElementResult>();

RobotSelection panelSelection = robotStructureServer.Selections.Create(IRobotObjectType.I_OT_PANEL);
panelSelection.FromText(GetAdapterId<int>(panel).ToString());
panelSelection.FromText(GetAdapterId<int>(feMesh).ToString());

IEnumerable<string> nodeIdList = feMesh.Nodes.Select(x => x.FindFragment<RobotId>().ToString());
string nodeIds = string.Join(" ", nodeIdList);

PanelFiniteElementIds feIds = panel.FindFragment<PanelFiniteElementIds>();
IEnumerable<string> faceIdList = feMesh.Faces.Select(x => x.FindFragment<RobotId>().ToString());
string faceIds = string.Join(" ", faceIdList);

if (feIds == null)
if (nodeIds == "" || faceIds == "")
{
Engine.Reflection.Compute.RecordWarning($"Could not access finite element ids for panel with id : { GetAdapterId<int>(panel) }. No results will be extracted for this element.");
Engine.Reflection.Compute.RecordWarning($"Could not access finite element ids for FEMesh with id : { GetAdapterId<int>(feMesh) }. No results will be extracted for this element.");
continue;
}

RobotSelection finiteElementSelection = robotStructureServer.Selections.Create(IRobotObjectType.I_OT_FINITE_ELEMENT);
finiteElementSelection.FromText(feIds.FiniteElementIds);
finiteElementSelection.FromText(faceIds);

RobotSelection nodeSelection = robotStructureServer.Selections.Create(IRobotObjectType.I_OT_NODE);
nodeSelection.FromText(feIds.NodeIds);
nodeSelection.FromText(nodeIds);

queryParams.Selection.Set(IRobotObjectType.I_OT_PANEL, panelSelection);
queryParams.Selection.Set(IRobotObjectType.I_OT_CASE, caseSelection);
Expand Down Expand Up @@ -207,14 +227,14 @@ public IEnumerable<IResult> ReadResults(MeshResultRequest request, ActionConfig
if (queryParams.IsParamSet(IRobotResultParamType.I_RPT_LOAD_CASE))
idCase = System.Convert.ToInt32(row.GetParam(IRobotResultParamType.I_RPT_LOAD_CASE));

int idPanel = GetAdapterId<int>(panel);
int idFEMesh = GetAdapterId<int>(feMesh);

int idNode = 0;
if (request.Smoothing != MeshResultSmoothingType.ByFiniteElementCentres)
{
//idNode = System.Convert.ToInt32(row.GetParam(IRobotResultParamType.I_RPT_NODE));

BH.oM.Geometry.Point nodePoint = BH.Engine.Geometry.Create.Point(row.GetValue(0), row.GetValue(1), row.GetValue(2));
Point nodePoint = BH.Engine.Geometry.Create.Point(row.GetValue(0), row.GetValue(1), row.GetValue(2));
idNode = GetAdapterId<int>(nodes.ElementAt(nodePointList.IndexOf(BH.Engine.Geometry.Query.ClosestPoint(nodePoint, nodePointList))));
}

Expand All @@ -226,19 +246,19 @@ public IEnumerable<IResult> ReadResults(MeshResultRequest request, ActionConfig
switch (request.ResultType)
{
case MeshResultType.Stresses:
meshResults.Add(GetMeshStress(row, idPanel, idNode, idFiniteElement, idCase, mode, layer, layerPosition, smoothing, orientation));
meshResults.Add(GetMeshStress(row, idFEMesh, idNode, idFiniteElement, idCase, mode, layer, layerPosition, smoothing, orientation));
break;
case MeshResultType.Forces:
meshResults.Add(GetMeshForce(row, idPanel, idNode, idFiniteElement, idCase, mode, layer, layerPosition, smoothing, orientation));
meshResults.Add(GetMeshForce(row, idFEMesh, idNode, idFiniteElement, idCase, mode, layer, layerPosition, smoothing, orientation));
break;
case MeshResultType.VonMises:
meshResults.Add(GetMeshVonMises(row, idPanel, idNode, idFiniteElement, idCase, mode, layer, layerPosition, smoothing, orientation));
meshResults.Add(GetMeshVonMises(row, idFEMesh, idNode, idFiniteElement, idCase, mode, layer, layerPosition, smoothing, orientation));
break;
case MeshResultType.Displacements:
meshResults.Add(GetMeshDisplacement(row, idPanel, idNode, idFiniteElement, idCase, mode, layer, layerPosition, smoothing, (Basis)globalXY));
meshResults.Add(GetMeshDisplacement(row, idFEMesh, idNode, idFiniteElement, idCase, mode, layer, layerPosition, smoothing, (Basis)globalXY));
break;
case MeshResultType.MeshModeShape:
meshResults.Add(GetMeshModeShape(row, idPanel, idNode, idFiniteElement, idCase, mode, layer, layerPosition, smoothing, (Basis)globalXY));
meshResults.Add(GetMeshModeShape(row, idFEMesh, idNode, idFiniteElement, idCase, mode, layer, layerPosition, smoothing, (Basis)globalXY));
break;
}
}
Expand All @@ -253,7 +273,7 @@ public IEnumerable<IResult> ReadResults(MeshResultRequest request, ActionConfig
int modeNumber = resultByCase.Key.ModeNumber;
List<MeshElementResult> resultList = resultByCase.ToList();
resultList.Sort();
MeshResult meshResult = new MeshResult(GetAdapterId<int>(panel), loadCase, modeNumber, timeStep, layer, layerPosition, smoothing, new ReadOnlyCollection<MeshElementResult>(resultList));
MeshResult meshResult = new MeshResult(GetAdapterId<int>(feMesh), loadCase, modeNumber, timeStep, layer, layerPosition, smoothing, new ReadOnlyCollection<MeshElementResult>(resultList));
meshResultsCollection.Add(meshResult);
}
}
Expand All @@ -266,9 +286,9 @@ public IEnumerable<IResult> ReadResults(MeshResultRequest request, ActionConfig
/**** Private Methods ****/
/***************************************************/

private MeshStress GetMeshStress(RobotResultRow row, int idPanel, int idNode, int idFiniteElement, int idCase, int mode, MeshResultLayer layer, double layerPosition, MeshResultSmoothingType smoothing, oM.Geometry.Basis orientation)
private MeshStress GetMeshStress(RobotResultRow row, int idFEMesh, int idNode, int idFiniteElement, int idCase, int mode, MeshResultLayer layer, double layerPosition, MeshResultSmoothingType smoothing, oM.Geometry.Basis orientation)
{
return new MeshStress(idPanel,
return new MeshStress(idFEMesh,
idNode,
idFiniteElement,
idCase,
Expand All @@ -291,9 +311,9 @@ private MeshStress GetMeshStress(RobotResultRow row, int idPanel, int idNode, in

/***************************************************/

private MeshForce GetMeshForce(RobotResultRow row, int idPanel, int idNode, int idFiniteElement, int idCase, int mode, MeshResultLayer layer, double layerPosition, MeshResultSmoothingType smoothing, oM.Geometry.Basis orientation)
private MeshForce GetMeshForce(RobotResultRow row, int idFEMesh, int idNode, int idFiniteElement, int idCase, int mode, MeshResultLayer layer, double layerPosition, MeshResultSmoothingType smoothing, oM.Geometry.Basis orientation)
{
return new MeshForce(idPanel,
return new MeshForce(idFEMesh,
idNode,
idFiniteElement,
idCase,
Expand All @@ -316,9 +336,9 @@ private MeshForce GetMeshForce(RobotResultRow row, int idPanel, int idNode, int

/***************************************************/

private MeshVonMises GetMeshVonMises(RobotResultRow row, int idPanel, int idNode, int idFiniteElement, int idCase, int mode, MeshResultLayer layer, double layerPosition, MeshResultSmoothingType smoothing, oM.Geometry.Basis orientation)
private MeshVonMises GetMeshVonMises(RobotResultRow row, int idFEMesh, int idNode, int idFiniteElement, int idCase, int mode, MeshResultLayer layer, double layerPosition, MeshResultSmoothingType smoothing, oM.Geometry.Basis orientation)
{
return new MeshVonMises(idPanel,
return new MeshVonMises(idFEMesh,
idNode,
idFiniteElement,
idCase,
Expand All @@ -336,7 +356,7 @@ private MeshVonMises GetMeshVonMises(RobotResultRow row, int idPanel, int idNode

/***************************************************/

private MeshDisplacement GetMeshDisplacement(RobotResultRow row, int idPanel, int idNode, int idFiniteElement, int idCase, int mode, MeshResultLayer layer, double layerPosition, MeshResultSmoothingType smoothing, oM.Geometry.Basis orientation)
private MeshDisplacement GetMeshDisplacement(RobotResultRow row, int idFEMesh, int idNode, int idFiniteElement, int idCase, int mode, MeshResultLayer layer, double layerPosition, MeshResultSmoothingType smoothing, oM.Geometry.Basis orientation)
{

Vector u = new Vector
Expand All @@ -346,7 +366,7 @@ private MeshDisplacement GetMeshDisplacement(RobotResultRow row, int idPanel, in
Z = TryGetValue(row, (int)IRobotExtremeValueType.I_EVT_DISPLACEMENT_NODE_UZ),
};

return new MeshDisplacement(idPanel,
return new MeshDisplacement(idFEMesh,
idNode,
idFiniteElement,
idCase,
Expand All @@ -366,15 +386,15 @@ private MeshDisplacement GetMeshDisplacement(RobotResultRow row, int idPanel, in

/***************************************************/

private MeshModeShape GetMeshModeShape(RobotResultRow row, int idPanel, int idNode, int idFiniteElement, int idCase, int mode, MeshResultLayer layer, double layerPosition, MeshResultSmoothingType smoothing, oM.Geometry.Basis orientation)
private MeshModeShape GetMeshModeShape(RobotResultRow row, int idFEMesh, int idNode, int idFiniteElement, int idCase, int mode, MeshResultLayer layer, double layerPosition, MeshResultSmoothingType smoothing, oM.Geometry.Basis orientation)
{

Vector u = new Vector
{
X = TryGetValue(row, 234), // T_EIGEN_UX_1
Y = TryGetValue(row, 235), // T_EIGEN_UY_1
Z = TryGetValue(row, 236), // T_EIGEN_UZ_1
// lagg till rotations
// add rotations
};

Vector r = new Vector
Expand All @@ -384,7 +404,7 @@ private MeshModeShape GetMeshModeShape(RobotResultRow row, int idPanel, int idNo
Z = TryGetValue(row, 239), // T_EIGEN_RZ_1
};

return new MeshModeShape(idPanel,
return new MeshModeShape(idFEMesh,
idNode,
idFiniteElement,
idCase,
Expand Down