Skip to content
Draft
Show file tree
Hide file tree
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
139 changes: 136 additions & 3 deletions Robot_Adapter/Convert/FromRobot/Properties/SectionProfile_General.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,15 @@
* along with this code. If not, see <https://www.gnu.org/licenses/lgpl-3.0.html>.
*/

using BH.oM.Structure.MaterialFragments;
using BH.Engine.Spatial;
using BH.Engine.Structure;
using BH.oM.Geometry;
using RobotOM;
using BH.oM.Structure.SectionProperties;
using BH.oM.Spatial.ShapeProfiles;
using BH.oM.Spatial.ShapeProfiles.CellularOpenings;
using BH.oM.Structure.Elements;
using BH.oM.Structure.MaterialFragments;
using BH.oM.Structure.SectionProperties;
using RobotOM;
using System;

namespace BH.Adapter.Robot
Expand All @@ -49,6 +53,9 @@ public static IProfile FromRobotGeneralProfile(IRobotBarSectionData secData)
double ri = secData.GetValue(IRobotBarSectionDataValue.I_BSDV_RI);
double s = secData.GetValue(IRobotBarSectionDataValue.I_BSDV_S);
double mass = secData.GetValue(IRobotBarSectionDataValue.I_BSDV_WEIGHT);
double dim1 = secData.GetValue(IRobotBarSectionDataValue.I_BSDV_DIM1);
double dim2 = secData.GetValue(IRobotBarSectionDataValue.I_BSDV_DIM2);
double dim3 = secData.GetValue(IRobotBarSectionDataValue.I_BSDV_DIM3);

switch (secData.ShapeType)
{
Expand Down Expand Up @@ -95,12 +102,15 @@ public static IProfile FromRobotGeneralProfile(IRobotBarSectionData secData)
case IRobotBarSectionShapeType.I_BSST_CAE:
sectionProfile = BH.Engine.Spatial.Create.AngleProfile(d, bf, Tw, Tf, r, ri);
break;

default:
return null;
}
}
else if (secData.Type == IRobotBarSectionType.I_BST_COMPLEX)
{


BH.Engine.Base.Compute.RecordWarning("Complex sections can not currently be read from Robot.");
return null;
}
Expand Down Expand Up @@ -131,6 +141,129 @@ public static IProfile FromRobotGeneralProfile(IRobotBarSectionData secData)

}

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

public static CellularSection FromRobotCellularProfile(IRobotBarSectionData secData)
{
CellularSection sectionProfile = null;

// Extract base I-section dimensions from standard section data
double h = secData.GetValue(IRobotBarSectionDataValue.I_BSDV_D); // Total depth
double bf = secData.GetValue(IRobotBarSectionDataValue.I_BSDV_BF); // Flange width
double tw = secData.GetValue(IRobotBarSectionDataValue.I_BSDV_TW); // Web thickness
double tf = secData.GetValue(IRobotBarSectionDataValue.I_BSDV_TF); // Flange thickness
double r = secData.GetValue(IRobotBarSectionDataValue.I_BSDV_RA); // Root radius
double ri = secData.GetValue(IRobotBarSectionDataValue.I_BSDV_RI); // Internal radius

// Extract cellular opening parameters from DIM values
double dim1 = secData.GetValue(IRobotBarSectionDataValue.I_BSDV_DIM1); // Opening diameter (d) or height
double dim2 = secData.GetValue(IRobotBarSectionDataValue.I_BSDV_DIM2); // Opening spacing (H)
double dim3 = secData.GetValue(IRobotBarSectionDataValue.I_BSDV_DIM3); // Opening width (w) for hexagonal

switch (secData.ShapeType)
{
case IRobotBarSectionShapeType.I_BSST_SPEC_CASTELLATED_WEB_ROUND_OPENINGS:
// Circular openings: dim1 = diameter (d), dim2 = spacing (H)
ISectionProfile baseProfile = BH.Engine.Spatial.Create.ISectionProfile(h, bf, tw, tf, r, ri);
SteelSection steelSection = BH.Engine.Structure.Create.SteelSectionFromProfile(baseProfile);
ICellularOpening opening = BH.Engine.Spatial.Create.CircularCellularOpening(dim1, dim2);
sectionProfile = BH.Engine.Structure.Create.CellularSectionFromBaseSection(steelSection, h, opening);
break;

case IRobotBarSectionShapeType.I_BSST_SPEC_CASTELLATED_WEB_HEXAGONAL_OPENINGS:
// Hexagonal openings: dim1 = height (d), dim2 = spacing (H), dim3 = width (w)
ISectionProfile baseProfileHex = BH.Engine.Spatial.Create.ISectionProfile(h, bf, tw, tf, r, ri);
SteelSection steelSectionHex = BH.Engine.Structure.Create.SteelSectionFromProfile(baseProfileHex);
ICellularOpening hexOpening = BH.Engine.Spatial.Create.HexagonalCellularOpening(dim1, dim3, dim2);
sectionProfile = BH.Engine.Structure.Create.CellularSectionFromBaseSection(steelSectionHex, h, hexOpening);
break;

case IRobotBarSectionShapeType.I_BSST_SPEC_CASTELLATED_WEB_HEXAGONAL_OPENINGS_SHIFTED:
// Shifted hexagonal openings: dim1 = height (d), dim2 = spacing (H), dim3 = width (w)
// Note: Spacer height not available in DIM values, using 0 as default
ISectionProfile baseProfileHexShift = BH.Engine.Spatial.Create.ISectionProfile(h, bf, tw, tf, r, ri);
SteelSection steelSectionHexShift = BH.Engine.Structure.Create.SteelSectionFromProfile(baseProfileHexShift);
ICellularOpening hexOpeningShift = BH.Engine.Spatial.Create.HexagonalCellularOpening(dim1, dim3, dim2, 0);
sectionProfile = BH.Engine.Structure.Create.CellularSectionFromBaseSection(steelSectionHexShift, h, hexOpeningShift);
BH.Engine.Base.Compute.RecordNote("Spacer height for shifted hexagonal cellular beam not available from Robot DIM values. Using default value of 0.");
break;

default:
return null;
}

return sectionProfile;
}

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

public static CellularSection FromRobotSpecialProfile(IRobotBarSectionSpecialData secSpecData, IRobotBarSectionData secData)
{
CellularSection sectionProfile = null;

try
{
// Extract cellular beam parameters from special data
// Note: Robot reports cellular beams as I_BST_COMPLEX with I_BSST_UNKNOWN shape type
// but the Special property provides access to cellular parameters via I_BSSDV_* values
double tW = secSpecData.GetValue(IRobotBarSectionSpecialDataValue.I_BSSDV_TW);
double b1 = secSpecData.GetValue(IRobotBarSectionSpecialDataValue.I_BSSDV_B1);
double tf1 = secSpecData.GetValue(IRobotBarSectionSpecialDataValue.I_BSSDV_TF1);
double h = secSpecData.GetValue(IRobotBarSectionSpecialDataValue.I_BSSDV_H); //Final height of section
double b2 = secSpecData.GetValue(IRobotBarSectionSpecialDataValue.I_BSSDV_B2);
double tf2 = secSpecData.GetValue(IRobotBarSectionSpecialDataValue.I_BSSDV_TF2);
double d = secSpecData.GetValue(IRobotBarSectionSpecialDataValue.I_BSSDV_D); //Diameter or height of openings
double w = secSpecData.GetValue(IRobotBarSectionSpecialDataValue.I_BSSDV_W); //Distance between openings
double c = secSpecData.GetValue(IRobotBarSectionSpecialDataValue.I_BSSDV_C); //Cut depth of hexagonal openings (2*c = height of hexagonal opening)
double a = secSpecData.GetValue(IRobotBarSectionSpecialDataValue.I_BSSDV_A); //Spacing of hexagonal openings
double hs = secSpecData.GetValue(IRobotBarSectionSpecialDataValue.I_BSSDV_HS); //Height of spacer for shifted hexagonal openings

// Validate that we have cellular beam data (check for non-zero opening parameters)
if (d > 0 && w > 0)
{
// Determine opening type based on available parameters
// If 'a' (hexagonal spacing) is 0 or very small, assume circular openings
// Otherwise, assume hexagonal openings
ISectionProfile baseProfile = BH.Engine.Spatial.Create.ISectionProfile(h, b1, tW, tf1, 0, 0);
SteelSection steelSection = BH.Engine.Structure.Create.SteelSectionFromProfile(baseProfile);
ICellularOpening opening;

if (a > 0.001) // Hexagonal opening (has spacing parameter 'a')
{
if (hs > 0.001) // Shifted hexagonal with spacer
{
opening = BH.Engine.Spatial.Create.HexagonalCellularOpening(d, w, a, hs);
Engine.Base.Compute.RecordNote($"Converted cellular beam as shifted hexagonal opening: d={d}, w={w}, a={a}, hs={hs}");
}
else // Standard hexagonal
{
opening = BH.Engine.Spatial.Create.HexagonalCellularOpening(d, w, a);
Engine.Base.Compute.RecordNote($"Converted cellular beam as hexagonal opening: d={d}, w={w}, a={a}");
}
}
else // Circular opening (a=0 or very small)
{
opening = BH.Engine.Spatial.Create.CircularCellularOpening(d, w);
Engine.Base.Compute.RecordNote($"Converted cellular beam as circular opening: d={d}, w={w}");
}

sectionProfile = BH.Engine.Structure.Create.CellularSectionFromBaseSection(steelSection, h, opening);
return sectionProfile;
}
else
{
Engine.Base.Compute.RecordWarning($"Special section data available but opening parameters invalid: d={d}, w={w}. Not a cellular beam.");
return null;
}
}
catch (System.Exception ex)
{
Engine.Base.Compute.RecordWarning($"Failed to extract cellular beam from special data: {ex.Message}");
return null;
}
}


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

private static IProfile NonStandardProfile(IRobotBarSectionShapeType shapeType, IRobotBarSectionNonstdData nonStdData)
Expand Down
58 changes: 56 additions & 2 deletions Robot_Adapter/Convert/FromRobot/Properties/SectionProperty.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,16 +39,70 @@ public static ISectionProperty FromRobot(this IRobotBarSectionData secData, IMat

ISectionProperty prop = null;
IProfile profile = null;

try
{
// Check for cellular/castellated beams by trying to access Special data first
// Robot reports cellular beams as I_BST_COMPLEX with I_BSST_UNKNOWN shape type
// but the Special property still provides access to cellular beam parameters via I_BSSDV_* values
IRobotBarSectionSpecialData secSpecData = null;
try
{
secSpecData = secData.Special;
}
catch
{
// Special data not accessible
}

if (secSpecData != null)
{
// Try to convert as cellular beam using special data (I_BSSDV_* values)
prop = FromRobotSpecialProfile(secSpecData, secData);

if (prop != null)
{
// Successfully converted cellular beam
if (material != null)
{
prop.Material = material;
}
return prop;
}
}

// Fallback: Check for cellular/castellated beams by shape type (if Robot reports them properly)
// These return CellularSection (ISectionProperty) directly, not IProfile
if (secData.ShapeType == IRobotBarSectionShapeType.I_BSST_SPEC_CASTELLATED_WEB_ROUND_OPENINGS ||
secData.ShapeType == IRobotBarSectionShapeType.I_BSST_SPEC_CASTELLATED_WEB_HEXAGONAL_OPENINGS ||
secData.ShapeType == IRobotBarSectionShapeType.I_BSST_SPEC_CASTELLATED_WEB_HEXAGONAL_OPENINGS_SHIFTED)
{
// Cellular beams - extract from standard section data with DIM values
prop = FromRobotCellularProfile(secData);

// Set material on the cellular section
if (prop != null && material != null)
{
prop.Material = material;
}

if (prop == null)
{
Engine.Base.Compute.RecordWarning($"Failed to convert cellular/castellated beam named {robotLabelName}. Shape type: {secData.ShapeType}, Section type: {secData.Type}");
}

return prop;
}

// Handle standard profiles (concrete and other geometrical sections)
if (secData.IsConcrete)
profile = FromRobotConcreteProfile(secData);
else
profile = FromRobotGeneralProfile(secData);
}
catch (System.Exception)
catch (System.Exception ex)
{

Engine.Base.Compute.RecordWarning($"Exception converting section {robotLabelName}: {ex.Message}");
}

if (profile != null)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -384,8 +384,6 @@ private static bool SetNonStandardSectionData(this GeneralisedFabricatedBoxProfi
return true;

}

/***************************************************/
}
}

Expand Down