From a0472e3cb47a88350245de1ec0c24e9f130360a0 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 12 Oct 2025 21:13:51 +0000 Subject: [PATCH 01/14] Initial plan From 3a4772cf1e5dd5439f54e287988e79529ef90c10 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 12 Oct 2025 21:22:12 +0000 Subject: [PATCH 02/14] Add fromRobot conversion for cellular/castellated beams Co-authored-by: Chrisshort92 <38885832+Chrisshort92@users.noreply.github.com> --- .../Properties/SectionProfile_General.cs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/Robot_Adapter/Convert/FromRobot/Properties/SectionProfile_General.cs b/Robot_Adapter/Convert/FromRobot/Properties/SectionProfile_General.cs index 4c074321..bbbcae84 100644 --- a/Robot_Adapter/Convert/FromRobot/Properties/SectionProfile_General.cs +++ b/Robot_Adapter/Convert/FromRobot/Properties/SectionProfile_General.cs @@ -95,6 +95,14 @@ public static IProfile FromRobotGeneralProfile(IRobotBarSectionData secData) case IRobotBarSectionShapeType.I_BSST_CAE: sectionProfile = BH.Engine.Spatial.Create.AngleProfile(d, bf, Tw, Tf, r, ri); break; + + case IRobotBarSectionShapeType.I_BSST_SPEC_CASTELLATED_WEB_HEXAGONAL_OPENINGS: + case IRobotBarSectionShapeType.I_BSST_SPEC_CASTELLATED_WEB_ROUND_OPENINGS: + case IRobotBarSectionShapeType.I_BSST_SPEC_CASTELLATED_WEB_HEXAGONAL_OPENINGS_SHIFTED: + BH.Engine.Base.Compute.RecordWarning("Cellular/Castellated beams are not fully supported. Section will be read as a standard I-Section without opening information. Section name: " + secData.Name); + sectionProfile = BH.Engine.Spatial.Create.ISectionProfile(d, bf, Tw, Tf, r, ri); + break; + default: return null; } @@ -251,6 +259,17 @@ private static IProfile NonStandardProfile(IRobotBarSectionShapeType shapeType, sectionProfile = BH.Engine.Spatial.Create.TSectionProfile(h, b, tw, tf); break; + case IRobotBarSectionShapeType.I_BSST_SPEC_CASTELLATED_WEB_HEXAGONAL_OPENINGS: + case IRobotBarSectionShapeType.I_BSST_SPEC_CASTELLATED_WEB_ROUND_OPENINGS: + case IRobotBarSectionShapeType.I_BSST_SPEC_CASTELLATED_WEB_HEXAGONAL_OPENINGS_SHIFTED: + b = nonStdData.GetValue(IRobotBarSectionNonstdDataValue.I_BSNDV_I_B); + h = nonStdData.GetValue(IRobotBarSectionNonstdDataValue.I_BSNDV_I_H); + tw = nonStdData.GetValue(IRobotBarSectionNonstdDataValue.I_BSNDV_I_TW); + tf = nonStdData.GetValue(IRobotBarSectionNonstdDataValue.I_BSNDV_I_TF); + BH.Engine.Base.Compute.RecordWarning("Cellular/Castellated beams are not fully supported. Section will be read as a standard I-Section without opening information."); + sectionProfile = BH.Engine.Spatial.Create.ISectionProfile(h + (2 * tf), b, tw, tf, 0, 0); + break; + default: return null; } From de9dafe99593a304fe18ef68af92dd140d4051a4 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 12 Oct 2025 22:14:19 +0000 Subject: [PATCH 03/14] Implement cellular beam conversion using BHoM cellular opening definitions Co-authored-by: Chrisshort92 <38885832+Chrisshort92@users.noreply.github.com> --- .../Properties/SectionProfile_General.cs | 76 ++++++++++++++++--- 1 file changed, 66 insertions(+), 10 deletions(-) diff --git a/Robot_Adapter/Convert/FromRobot/Properties/SectionProfile_General.cs b/Robot_Adapter/Convert/FromRobot/Properties/SectionProfile_General.cs index bbbcae84..9069ebe8 100644 --- a/Robot_Adapter/Convert/FromRobot/Properties/SectionProfile_General.cs +++ b/Robot_Adapter/Convert/FromRobot/Properties/SectionProfile_General.cs @@ -96,11 +96,40 @@ public static IProfile FromRobotGeneralProfile(IRobotBarSectionData secData) sectionProfile = BH.Engine.Spatial.Create.AngleProfile(d, bf, Tw, Tf, r, ri); break; - case IRobotBarSectionShapeType.I_BSST_SPEC_CASTELLATED_WEB_HEXAGONAL_OPENINGS: case IRobotBarSectionShapeType.I_BSST_SPEC_CASTELLATED_WEB_ROUND_OPENINGS: + { + // Create base I-section profile + IProfile baseProfile = BH.Engine.Spatial.Create.ISectionProfile(d, bf, Tw, Tf, r, ri); + // Create circular opening with diameter and spacing + // Note: Opening parameters are estimated as Robot API may not provide all details + double webDepth = d - 2 * Tf; + double openingDiameter = webDepth * 0.75; // Typical ratio for cellular beams + double spacing = s > 0 ? s : webDepth * 1.5; // Use spacing if available, otherwise estimate + ICellularOpening opening = BH.Engine.Spatial.Create.CircularOpening(openingDiameter, spacing); + // Create perforated profile with the opening + sectionProfile = BH.Engine.Spatial.Create.PerforatedISectionProfile(baseProfile, opening); + if (s <= 0) + BH.Engine.Base.Compute.RecordWarning("Opening spacing not available from Robot. Using estimated value for section: " + secData.Name); + } + break; + + case IRobotBarSectionShapeType.I_BSST_SPEC_CASTELLATED_WEB_HEXAGONAL_OPENINGS: case IRobotBarSectionShapeType.I_BSST_SPEC_CASTELLATED_WEB_HEXAGONAL_OPENINGS_SHIFTED: - BH.Engine.Base.Compute.RecordWarning("Cellular/Castellated beams are not fully supported. Section will be read as a standard I-Section without opening information. Section name: " + secData.Name); - sectionProfile = BH.Engine.Spatial.Create.ISectionProfile(d, bf, Tw, Tf, r, ri); + { + // Create base I-section profile + IProfile baseProfile = BH.Engine.Spatial.Create.ISectionProfile(d, bf, Tw, Tf, r, ri); + // Create hexagonal opening with appropriate dimensions + // Note: Opening parameters are estimated as Robot API may not provide all details + double webDepth = d - 2 * Tf; + double openingHeight = webDepth * 0.8; // Typical ratio for castellated beams + double openingWidth = openingHeight * 0.866; // Hexagon width-to-height ratio + double spacing = s > 0 ? s : webDepth * 1.5; // Use spacing if available, otherwise estimate + ICellularOpening opening = BH.Engine.Spatial.Create.HexagonalOpening(openingHeight, openingWidth, spacing); + // Create perforated profile with the opening + sectionProfile = BH.Engine.Spatial.Create.PerforatedISectionProfile(baseProfile, opening); + if (s <= 0) + BH.Engine.Base.Compute.RecordWarning("Opening spacing not available from Robot. Using estimated value for section: " + secData.Name); + } break; default: @@ -259,15 +288,42 @@ private static IProfile NonStandardProfile(IRobotBarSectionShapeType shapeType, sectionProfile = BH.Engine.Spatial.Create.TSectionProfile(h, b, tw, tf); break; - case IRobotBarSectionShapeType.I_BSST_SPEC_CASTELLATED_WEB_HEXAGONAL_OPENINGS: case IRobotBarSectionShapeType.I_BSST_SPEC_CASTELLATED_WEB_ROUND_OPENINGS: + { + b = nonStdData.GetValue(IRobotBarSectionNonstdDataValue.I_BSNDV_I_B); + h = nonStdData.GetValue(IRobotBarSectionNonstdDataValue.I_BSNDV_I_H); + tw = nonStdData.GetValue(IRobotBarSectionNonstdDataValue.I_BSNDV_I_TW); + tf = nonStdData.GetValue(IRobotBarSectionNonstdDataValue.I_BSNDV_I_TF); + // Create base I-section profile + IProfile baseProfile = BH.Engine.Spatial.Create.ISectionProfile(h + (2 * tf), b, tw, tf, 0, 0); + // Create circular opening + // Note: Opening parameters are estimated as Robot API may not provide all details + double openingDiameter = h * 0.75; + double spacing = h * 1.5; // Typical spacing for cellular beams + ICellularOpening opening = BH.Engine.Spatial.Create.CircularOpening(openingDiameter, spacing); + sectionProfile = BH.Engine.Spatial.Create.PerforatedISectionProfile(baseProfile, opening); + BH.Engine.Base.Compute.RecordWarning("Cellular beam opening parameters are estimated. Verify opening diameter and spacing for accuracy."); + } + break; + + case IRobotBarSectionShapeType.I_BSST_SPEC_CASTELLATED_WEB_HEXAGONAL_OPENINGS: case IRobotBarSectionShapeType.I_BSST_SPEC_CASTELLATED_WEB_HEXAGONAL_OPENINGS_SHIFTED: - b = nonStdData.GetValue(IRobotBarSectionNonstdDataValue.I_BSNDV_I_B); - h = nonStdData.GetValue(IRobotBarSectionNonstdDataValue.I_BSNDV_I_H); - tw = nonStdData.GetValue(IRobotBarSectionNonstdDataValue.I_BSNDV_I_TW); - tf = nonStdData.GetValue(IRobotBarSectionNonstdDataValue.I_BSNDV_I_TF); - BH.Engine.Base.Compute.RecordWarning("Cellular/Castellated beams are not fully supported. Section will be read as a standard I-Section without opening information."); - sectionProfile = BH.Engine.Spatial.Create.ISectionProfile(h + (2 * tf), b, tw, tf, 0, 0); + { + b = nonStdData.GetValue(IRobotBarSectionNonstdDataValue.I_BSNDV_I_B); + h = nonStdData.GetValue(IRobotBarSectionNonstdDataValue.I_BSNDV_I_H); + tw = nonStdData.GetValue(IRobotBarSectionNonstdDataValue.I_BSNDV_I_TW); + tf = nonStdData.GetValue(IRobotBarSectionNonstdDataValue.I_BSNDV_I_TF); + // Create base I-section profile + IProfile baseProfile = BH.Engine.Spatial.Create.ISectionProfile(h + (2 * tf), b, tw, tf, 0, 0); + // Create hexagonal opening + // Note: Opening parameters are estimated as Robot API may not provide all details + double openingHeight = h * 0.8; + double openingWidth = openingHeight * 0.866; + double spacing = h * 1.5; + ICellularOpening opening = BH.Engine.Spatial.Create.HexagonalOpening(openingHeight, openingWidth, spacing); + sectionProfile = BH.Engine.Spatial.Create.PerforatedISectionProfile(baseProfile, opening); + BH.Engine.Base.Compute.RecordWarning("Castellated beam opening parameters are estimated. Verify opening dimensions and spacing for accuracy."); + } break; default: From dab76093d0f52bd9de4e26a440cbbeb1e6f56328 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 12 Oct 2025 22:33:25 +0000 Subject: [PATCH 04/14] Add toRobot conversion for cellular/castellated beams Co-authored-by: Chrisshort92 <38885832+Chrisshort92@users.noreply.github.com> --- .../Properties/SectionProperty_Geometrical.cs | 72 +++++++++++++++++++ 1 file changed, 72 insertions(+) diff --git a/Robot_Adapter/Convert/ToRobot/Properties/SectionProperty_Geometrical.cs b/Robot_Adapter/Convert/ToRobot/Properties/SectionProperty_Geometrical.cs index e1afe5a5..7c8e3cd4 100644 --- a/Robot_Adapter/Convert/ToRobot/Properties/SectionProperty_Geometrical.cs +++ b/Robot_Adapter/Convert/ToRobot/Properties/SectionProperty_Geometrical.cs @@ -209,6 +209,45 @@ private static bool SetRobotTypeAndShapeType(this GeneralisedFabricatedBoxProfil /***************************************************/ + private static bool SetRobotTypeAndShapeType(this PerforatedISectionProfile section, IRobotBarSectionData sectionData) + { + // Check opening type to determine appropriate Robot section type + if (section.Openings != null && section.Openings.Count > 0) + { + ICellularOpening opening = section.Openings[0]; + + // Determine shape type based on opening type + if (opening is CircularOpening) + { + sectionData.Type = IRobotBarSectionType.I_BST_NS_I; + sectionData.ShapeType = IRobotBarSectionShapeType.I_BSST_SPEC_CASTELLATED_WEB_ROUND_OPENINGS; + } + else if (opening is HexagonalOpening) + { + sectionData.Type = IRobotBarSectionType.I_BST_NS_I; + sectionData.ShapeType = IRobotBarSectionShapeType.I_BSST_SPEC_CASTELLATED_WEB_HEXAGONAL_OPENINGS; + } + else + { + // Unknown opening type, fall back to regular I-section + Engine.Base.Compute.RecordWarning($"Cellular opening type {opening.GetType().Name} not recognized. Section will be pushed as standard I-section."); + sectionData.Type = IRobotBarSectionType.I_BST_NS_I; + sectionData.ShapeType = IRobotBarSectionShapeType.I_BSST_USER_I_BISYM; + } + return true; + } + else + { + // No openings, treat as regular I-section + Engine.Base.Compute.RecordWarning("PerforatedISectionProfile has no openings defined. Section will be pushed as standard I-section."); + sectionData.Type = IRobotBarSectionType.I_BST_NS_I; + sectionData.ShapeType = IRobotBarSectionShapeType.I_BSST_USER_I_BISYM; + return true; + } + } + + /***************************************************/ + private static bool SetRobotTypeAndShapeType(this IProfile section, IRobotBarSectionData sectionData) { Engine.Base.Compute.RecordWarning("Profile of type " + section.GetType().Name + " is not yet fully supported for Steel sections. Section with name " + sectionData.Name + " set as explicit section."); @@ -386,6 +425,39 @@ private static bool SetNonStandardSectionData(this GeneralisedFabricatedBoxProfi } /***************************************************/ + + private static bool SetNonStandardSectionData(this PerforatedISectionProfile section, IRobotBarSectionData sectionData, int position = 0) + { + // Extract base profile (should be ISectionProfile) + if (section.BaseProfile is ISectionProfile baseProfile) + { + IRobotBarSectionNonstdData nonStdData = sectionData.CreateNonstd(position); + + // Set I-section dimensions from base profile + nonStdData.SetValue(IRobotBarSectionNonstdDataValue.I_BSNDV_I_B, baseProfile.Width); + nonStdData.SetValue(IRobotBarSectionNonstdDataValue.I_BSNDV_I_H, baseProfile.Height - (2 * baseProfile.FlangeThickness)); + nonStdData.SetValue(IRobotBarSectionNonstdDataValue.I_BSNDV_I_TW, baseProfile.WebThickness); + nonStdData.SetValue(IRobotBarSectionNonstdDataValue.I_BSNDV_I_TF, baseProfile.FlangeThickness); + + // Note: Robot API may not support setting all cellular opening parameters (diameter, spacing, etc.) + // The shape type set in SetRobotTypeAndShapeType identifies it as cellular/castellated + // Opening parameters may need to be set manually in Robot after push + + if (section.Openings != null && section.Openings.Count > 0) + { + Engine.Base.Compute.RecordNote($"Cellular opening parameters (diameter, spacing) cannot be fully pushed to Robot API. Section pushed with base I-section geometry and cellular/castellated type. Verify opening parameters in Robot."); + } + + return true; + } + else + { + Engine.Base.Compute.RecordWarning($"PerforatedISectionProfile base profile is not ISectionProfile. Cannot convert to Robot cellular beam. Section name: {sectionData.Name}"); + return false; + } + } + + /***************************************************/ } } From 1951b4da06a5069680e491bac6b3d1bf200b3aaa Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 12 Oct 2025 23:10:48 +0000 Subject: [PATCH 05/14] Update cellular beam comments with Robot API documentation references Co-authored-by: Chrisshort92 <38885832+Chrisshort92@users.noreply.github.com> --- .../Convert/FromRobot/Properties/SectionProfile_General.cs | 6 ++++++ .../ToRobot/Properties/SectionProperty_Geometrical.cs | 4 ++++ 2 files changed, 10 insertions(+) diff --git a/Robot_Adapter/Convert/FromRobot/Properties/SectionProfile_General.cs b/Robot_Adapter/Convert/FromRobot/Properties/SectionProfile_General.cs index 9069ebe8..bda6316a 100644 --- a/Robot_Adapter/Convert/FromRobot/Properties/SectionProfile_General.cs +++ b/Robot_Adapter/Convert/FromRobot/Properties/SectionProfile_General.cs @@ -98,6 +98,7 @@ public static IProfile FromRobotGeneralProfile(IRobotBarSectionData secData) case IRobotBarSectionShapeType.I_BSST_SPEC_CASTELLATED_WEB_ROUND_OPENINGS: { + // I_BSST_SPEC_CASTELLATED_WEB_ROUND_OPENINGS (51): Section with a castellated web (round openings) // Create base I-section profile IProfile baseProfile = BH.Engine.Spatial.Create.ISectionProfile(d, bf, Tw, Tf, r, ri); // Create circular opening with diameter and spacing @@ -116,6 +117,8 @@ public static IProfile FromRobotGeneralProfile(IRobotBarSectionData secData) case IRobotBarSectionShapeType.I_BSST_SPEC_CASTELLATED_WEB_HEXAGONAL_OPENINGS: case IRobotBarSectionShapeType.I_BSST_SPEC_CASTELLATED_WEB_HEXAGONAL_OPENINGS_SHIFTED: { + // I_BSST_SPEC_CASTELLATED_WEB_HEXAGONAL_OPENINGS (50): Section with a castellated web (hexagonal openings) + // I_BSST_SPEC_CASTELLATED_WEB_HEXAGONAL_OPENINGS_SHIFTED (52): Section with a castellated web (hexagonal openings, with spacer plates) // Create base I-section profile IProfile baseProfile = BH.Engine.Spatial.Create.ISectionProfile(d, bf, Tw, Tf, r, ri); // Create hexagonal opening with appropriate dimensions @@ -290,6 +293,7 @@ private static IProfile NonStandardProfile(IRobotBarSectionShapeType shapeType, case IRobotBarSectionShapeType.I_BSST_SPEC_CASTELLATED_WEB_ROUND_OPENINGS: { + // I_BSST_SPEC_CASTELLATED_WEB_ROUND_OPENINGS (51): Section with a castellated web (round openings) b = nonStdData.GetValue(IRobotBarSectionNonstdDataValue.I_BSNDV_I_B); h = nonStdData.GetValue(IRobotBarSectionNonstdDataValue.I_BSNDV_I_H); tw = nonStdData.GetValue(IRobotBarSectionNonstdDataValue.I_BSNDV_I_TW); @@ -309,6 +313,8 @@ private static IProfile NonStandardProfile(IRobotBarSectionShapeType shapeType, case IRobotBarSectionShapeType.I_BSST_SPEC_CASTELLATED_WEB_HEXAGONAL_OPENINGS: case IRobotBarSectionShapeType.I_BSST_SPEC_CASTELLATED_WEB_HEXAGONAL_OPENINGS_SHIFTED: { + // I_BSST_SPEC_CASTELLATED_WEB_HEXAGONAL_OPENINGS (50): Section with a castellated web (hexagonal openings) + // I_BSST_SPEC_CASTELLATED_WEB_HEXAGONAL_OPENINGS_SHIFTED (52): Section with a castellated web (hexagonal openings, with spacer plates) b = nonStdData.GetValue(IRobotBarSectionNonstdDataValue.I_BSNDV_I_B); h = nonStdData.GetValue(IRobotBarSectionNonstdDataValue.I_BSNDV_I_H); tw = nonStdData.GetValue(IRobotBarSectionNonstdDataValue.I_BSNDV_I_TW); diff --git a/Robot_Adapter/Convert/ToRobot/Properties/SectionProperty_Geometrical.cs b/Robot_Adapter/Convert/ToRobot/Properties/SectionProperty_Geometrical.cs index 7c8e3cd4..47f6e589 100644 --- a/Robot_Adapter/Convert/ToRobot/Properties/SectionProperty_Geometrical.cs +++ b/Robot_Adapter/Convert/ToRobot/Properties/SectionProperty_Geometrical.cs @@ -217,6 +217,10 @@ private static bool SetRobotTypeAndShapeType(this PerforatedISectionProfile sect ICellularOpening opening = section.Openings[0]; // Determine shape type based on opening type + // Robot API definitions: + // I_BSST_SPEC_CASTELLATED_WEB_ROUND_OPENINGS (51): Section with a castellated web (round openings) + // I_BSST_SPEC_CASTELLATED_WEB_HEXAGONAL_OPENINGS (50): Section with a castellated web (hexagonal openings) + // I_BSST_SPEC_CASTELLATED_WEB_HEXAGONAL_OPENINGS_SHIFTED (52): Section with a castellated web (hexagonal openings, with spacer plates) if (opening is CircularOpening) { sectionData.Type = IRobotBarSectionType.I_BST_NS_I; From e077be4a3806f494da9e6e76669522b67f5f55fa Mon Sep 17 00:00:00 2001 From: Christopher Short Date: Wed, 22 Oct 2025 23:05:36 +0100 Subject: [PATCH 06/14] Try both VoidedISection & CircularCellularSection methods --- .../Properties/SectionProfile_General.cs | 28 ++++++++++++------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/Robot_Adapter/Convert/FromRobot/Properties/SectionProfile_General.cs b/Robot_Adapter/Convert/FromRobot/Properties/SectionProfile_General.cs index bda6316a..74a146f8 100644 --- a/Robot_Adapter/Convert/FromRobot/Properties/SectionProfile_General.cs +++ b/Robot_Adapter/Convert/FromRobot/Properties/SectionProfile_General.cs @@ -25,7 +25,10 @@ using RobotOM; using BH.oM.Structure.SectionProperties; using BH.oM.Spatial.ShapeProfiles; +using BH.Engine.Spatial; +using BH.Engine.Structure; using System; +using BH.oM.Spatial.ShapeProfiles.CellularOpenings; namespace BH.Adapter.Robot { @@ -99,42 +102,47 @@ public static IProfile FromRobotGeneralProfile(IRobotBarSectionData secData) case IRobotBarSectionShapeType.I_BSST_SPEC_CASTELLATED_WEB_ROUND_OPENINGS: { // I_BSST_SPEC_CASTELLATED_WEB_ROUND_OPENINGS (51): Section with a castellated web (round openings) + // Create base I-section profile - IProfile baseProfile = BH.Engine.Spatial.Create.ISectionProfile(d, bf, Tw, Tf, r, ri); + IProfile baseProfile = BH.Engine.Spatial.Create.ISectionProfile(d, bf, Tw, Tf, r, ri); + // Create circular opening with diameter and spacing // Note: Opening parameters are estimated as Robot API may not provide all details double webDepth = d - 2 * Tf; double openingDiameter = webDepth * 0.75; // Typical ratio for cellular beams - double spacing = s > 0 ? s : webDepth * 1.5; // Use spacing if available, otherwise estimate - ICellularOpening opening = BH.Engine.Spatial.Create.CircularOpening(openingDiameter, spacing); + // Create perforated profile with the opening - sectionProfile = BH.Engine.Spatial.Create.PerforatedISectionProfile(baseProfile, opening); - if (s <= 0) - BH.Engine.Base.Compute.RecordWarning("Opening spacing not available from Robot. Using estimated value for section: " + secData.Name); + sectionProfile = BH.Engine.Spatial.Create.VoidedISectionProfile(d, openingDiameter, bf, Tw, Tf, r, ri); + } break; case IRobotBarSectionShapeType.I_BSST_SPEC_CASTELLATED_WEB_HEXAGONAL_OPENINGS: - case IRobotBarSectionShapeType.I_BSST_SPEC_CASTELLATED_WEB_HEXAGONAL_OPENINGS_SHIFTED: { // I_BSST_SPEC_CASTELLATED_WEB_HEXAGONAL_OPENINGS (50): Section with a castellated web (hexagonal openings) - // I_BSST_SPEC_CASTELLATED_WEB_HEXAGONAL_OPENINGS_SHIFTED (52): Section with a castellated web (hexagonal openings, with spacer plates) + // Create base I-section profile IProfile baseProfile = BH.Engine.Spatial.Create.ISectionProfile(d, bf, Tw, Tf, r, ri); + SteelSection steelSection = BH.Engine.Structure.Create.SteelSectionFromProfile(baseProfile); + // Create hexagonal opening with appropriate dimensions // Note: Opening parameters are estimated as Robot API may not provide all details double webDepth = d - 2 * Tf; double openingHeight = webDepth * 0.8; // Typical ratio for castellated beams double openingWidth = openingHeight * 0.866; // Hexagon width-to-height ratio double spacing = s > 0 ? s : webDepth * 1.5; // Use spacing if available, otherwise estimate - ICellularOpening opening = BH.Engine.Spatial.Create.HexagonalOpening(openingHeight, openingWidth, spacing); + ICellularOpening opening = BH.Engine.Spatial.Create.HexagonalCellularOpening(openingHeight, openingWidth, spacing); // Create perforated profile with the opening - sectionProfile = BH.Engine.Spatial.Create.PerforatedISectionProfile(baseProfile, opening); + sectionProfile = BH.Engine.Structure.Create.CellularSectionFromBaseSection(steelSection, webDepth, opening); if (s <= 0) BH.Engine.Base.Compute.RecordWarning("Opening spacing not available from Robot. Using estimated value for section: " + secData.Name); } break; + case IRobotBarSectionShapeType.I_BSST_SPEC_CASTELLATED_WEB_HEXAGONAL_OPENINGS_SHIFTED: + // I_BSST_SPEC_CASTELLATED_WEB_HEXAGONAL_OPENINGS_SHIFTED (52): Section with a castellated web (hexagonal openings, with spacer plates) + break; + default: return null; } From 0985623d6cc3de2127e6dc69e2063048edcf3d16 Mon Sep 17 00:00:00 2001 From: Christopher Short Date: Thu, 23 Oct 2025 11:03:20 +0100 Subject: [PATCH 07/14] Progress castellated beam conversions --- .../Properties/SectionProfile_General.cs | 92 +++++++++++-------- 1 file changed, 55 insertions(+), 37 deletions(-) diff --git a/Robot_Adapter/Convert/FromRobot/Properties/SectionProfile_General.cs b/Robot_Adapter/Convert/FromRobot/Properties/SectionProfile_General.cs index 74a146f8..2844f26d 100644 --- a/Robot_Adapter/Convert/FromRobot/Properties/SectionProfile_General.cs +++ b/Robot_Adapter/Convert/FromRobot/Properties/SectionProfile_General.cs @@ -20,15 +20,16 @@ * along with this code. If not, see . */ -using BH.oM.Structure.MaterialFragments; -using BH.oM.Geometry; -using RobotOM; -using BH.oM.Structure.SectionProperties; -using BH.oM.Spatial.ShapeProfiles; using BH.Engine.Spatial; using BH.Engine.Structure; -using System; +using BH.oM.Geometry; +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 { @@ -117,41 +118,10 @@ public static IProfile FromRobotGeneralProfile(IRobotBarSectionData secData) } break; - case IRobotBarSectionShapeType.I_BSST_SPEC_CASTELLATED_WEB_HEXAGONAL_OPENINGS: - { - // I_BSST_SPEC_CASTELLATED_WEB_HEXAGONAL_OPENINGS (50): Section with a castellated web (hexagonal openings) - - // Create base I-section profile - IProfile baseProfile = BH.Engine.Spatial.Create.ISectionProfile(d, bf, Tw, Tf, r, ri); - SteelSection steelSection = BH.Engine.Structure.Create.SteelSectionFromProfile(baseProfile); - - // Create hexagonal opening with appropriate dimensions - // Note: Opening parameters are estimated as Robot API may not provide all details - double webDepth = d - 2 * Tf; - double openingHeight = webDepth * 0.8; // Typical ratio for castellated beams - double openingWidth = openingHeight * 0.866; // Hexagon width-to-height ratio - double spacing = s > 0 ? s : webDepth * 1.5; // Use spacing if available, otherwise estimate - ICellularOpening opening = BH.Engine.Spatial.Create.HexagonalCellularOpening(openingHeight, openingWidth, spacing); - // Create perforated profile with the opening - sectionProfile = BH.Engine.Structure.Create.CellularSectionFromBaseSection(steelSection, webDepth, opening); - if (s <= 0) - BH.Engine.Base.Compute.RecordWarning("Opening spacing not available from Robot. Using estimated value for section: " + secData.Name); - } - break; - - case IRobotBarSectionShapeType.I_BSST_SPEC_CASTELLATED_WEB_HEXAGONAL_OPENINGS_SHIFTED: - // I_BSST_SPEC_CASTELLATED_WEB_HEXAGONAL_OPENINGS_SHIFTED (52): Section with a castellated web (hexagonal openings, with spacer plates) - 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; - } else { //Get profile at start. FOr non tapered section this will be the general definition @@ -181,6 +151,54 @@ public static IProfile FromRobotGeneralProfile(IRobotBarSectionData secData) /***************************************************/ + public static CellularSection FromRobotSpecialProfile(IRobotBarSectionSpecialData secSpecData, IRobotBarSectionData secData) + { + CellularSection sectionProfile = null; + + if (secData.Type == IRobotBarSectionType.I_BST_SPECIAL) + { + 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); + double b2 = secSpecData.GetValue(IRobotBarSectionSpecialDataValue.I_BSSDV_B2); + double tf2 = secSpecData.GetValue(IRobotBarSectionSpecialDataValue.I_BSSDV_TF2); + double d = secSpecData.GetValue(IRobotBarSectionSpecialDataValue.I_BSSDV_D); + double w = secSpecData.GetValue(IRobotBarSectionSpecialDataValue.I_BSSDV_W); + double c = secSpecData.GetValue(IRobotBarSectionSpecialDataValue.I_BSSDV_C); + double a = secSpecData.GetValue(IRobotBarSectionSpecialDataValue.I_BSSDV_A); + double hs = secSpecData.GetValue(IRobotBarSectionSpecialDataValue.I_BSSDV_HS); + double bp = secSpecData.GetValue(IRobotBarSectionSpecialDataValue.I_BSSDV_BP); + double tp = secSpecData.GetValue(IRobotBarSectionSpecialDataValue.I_BSSDV_TP); + + switch (secData.ShapeType) + { + case IRobotBarSectionShapeType.I_BSST_SPEC_CASTELLATED_WEB_ROUND_OPENINGS: + ISectionProfile baseProfile = BH.Engine.Spatial.Create.ISectionProfile(h, b1, tW, tf1, 0, 0); + SteelSection steelSection = BH.Engine.Structure.Create.SteelSectionFromProfile(baseProfile); + ICellularOpening opening = BH.Engine.Spatial.Create.CircularCellularOpening(d, w); + sectionProfile = BH.Engine.Structure.Create.CellularSectionFromBaseSection(steelSection, h, opening); + break; + + case IRobotBarSectionShapeType.I_BSST_SPEC_CASTELLATED_WEB_HEXAGONAL_OPENINGS: + ISectionProfile baseProfileHex = BH.Engine.Spatial.Create.ISectionProfile(h, b1, tW, tf1, 0, 0); + SteelSection steelSectionHex = BH.Engine.Structure.Create.SteelSectionFromProfile(baseProfileHex); + ICellularOpening hexOpening = BH.Engine.Spatial.Create.HexagonalCellularOpening(d, w, c); + sectionProfile = BH.Engine.Structure.Create.CellularSectionFromBaseSection(steelSectionHex, h, hexOpening); + break; + + case IRobotBarSectionShapeType.I_BSST_SPEC_CASTELLATED_WEB_HEXAGONAL_OPENINGS_SHIFTED: + + + } + + return sectionProfile; + } + + } + + /***************************************************/ + private static IProfile NonStandardProfile(IRobotBarSectionShapeType shapeType, IRobotBarSectionNonstdData nonStdData) { double d, t, b, b1, b2, h, tw, tf, tf2; From 3b3c5f8b73ea2c40676a93bd52d00f50319ecf0d Mon Sep 17 00:00:00 2001 From: Christopher Short Date: Thu, 23 Oct 2025 19:09:26 +0100 Subject: [PATCH 08/14] Correct definition for castellated beams --- .../Properties/SectionProfile_General.cs | 87 ++++--------------- .../Properties/SectionProperty_Geometrical.cs | 78 ----------------- 2 files changed, 18 insertions(+), 147 deletions(-) diff --git a/Robot_Adapter/Convert/FromRobot/Properties/SectionProfile_General.cs b/Robot_Adapter/Convert/FromRobot/Properties/SectionProfile_General.cs index 2844f26d..c1acbd06 100644 --- a/Robot_Adapter/Convert/FromRobot/Properties/SectionProfile_General.cs +++ b/Robot_Adapter/Convert/FromRobot/Properties/SectionProfile_General.cs @@ -100,24 +100,6 @@ public static IProfile FromRobotGeneralProfile(IRobotBarSectionData secData) sectionProfile = BH.Engine.Spatial.Create.AngleProfile(d, bf, Tw, Tf, r, ri); break; - case IRobotBarSectionShapeType.I_BSST_SPEC_CASTELLATED_WEB_ROUND_OPENINGS: - { - // I_BSST_SPEC_CASTELLATED_WEB_ROUND_OPENINGS (51): Section with a castellated web (round openings) - - // Create base I-section profile - IProfile baseProfile = BH.Engine.Spatial.Create.ISectionProfile(d, bf, Tw, Tf, r, ri); - - // Create circular opening with diameter and spacing - // Note: Opening parameters are estimated as Robot API may not provide all details - double webDepth = d - 2 * Tf; - double openingDiameter = webDepth * 0.75; // Typical ratio for cellular beams - - // Create perforated profile with the opening - sectionProfile = BH.Engine.Spatial.Create.VoidedISectionProfile(d, openingDiameter, bf, Tw, Tf, r, ri); - - } - break; - default: return null; } @@ -160,14 +142,14 @@ public static CellularSection FromRobotSpecialProfile(IRobotBarSectionSpecialDat 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); + 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); - double w = secSpecData.GetValue(IRobotBarSectionSpecialDataValue.I_BSSDV_W); - double c = secSpecData.GetValue(IRobotBarSectionSpecialDataValue.I_BSSDV_C); - double a = secSpecData.GetValue(IRobotBarSectionSpecialDataValue.I_BSSDV_A); - double hs = secSpecData.GetValue(IRobotBarSectionSpecialDataValue.I_BSSDV_HS); + double d = secSpecData.GetValue(IRobotBarSectionSpecialDataValue.I_BSSDV_D); //Diameter 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 double bp = secSpecData.GetValue(IRobotBarSectionSpecialDataValue.I_BSSDV_BP); double tp = secSpecData.GetValue(IRobotBarSectionSpecialDataValue.I_BSSDV_TP); @@ -183,20 +165,28 @@ public static CellularSection FromRobotSpecialProfile(IRobotBarSectionSpecialDat case IRobotBarSectionShapeType.I_BSST_SPEC_CASTELLATED_WEB_HEXAGONAL_OPENINGS: ISectionProfile baseProfileHex = BH.Engine.Spatial.Create.ISectionProfile(h, b1, tW, tf1, 0, 0); SteelSection steelSectionHex = BH.Engine.Structure.Create.SteelSectionFromProfile(baseProfileHex); - ICellularOpening hexOpening = BH.Engine.Spatial.Create.HexagonalCellularOpening(d, w, c); + ICellularOpening hexOpening = BH.Engine.Spatial.Create.HexagonalCellularOpening(d, w, a); sectionProfile = BH.Engine.Structure.Create.CellularSectionFromBaseSection(steelSectionHex, h, hexOpening); break; case IRobotBarSectionShapeType.I_BSST_SPEC_CASTELLATED_WEB_HEXAGONAL_OPENINGS_SHIFTED: + ISectionProfile baseProfileHexSpace = BH.Engine.Spatial.Create.ISectionProfile(h, b1, tW, tf1, 0, 0); + SteelSection steelSectionHexSpace = BH.Engine.Structure.Create.SteelSectionFromProfile(baseProfileHexSpace); + ICellularOpening hexOpeningSpace = BH.Engine.Spatial.Create.HexagonalCellularOpening(d, w, a, hs); + sectionProfile = BH.Engine.Structure.Create.CellularSectionFromBaseSection(steelSectionHexSpace, h, hexOpeningSpace); + break; - + default: + return null; } - return sectionProfile; } - + else + { return null; + } } + /***************************************************/ private static IProfile NonStandardProfile(IRobotBarSectionShapeType shapeType, IRobotBarSectionNonstdData nonStdData) @@ -317,47 +307,6 @@ private static IProfile NonStandardProfile(IRobotBarSectionShapeType shapeType, sectionProfile = BH.Engine.Spatial.Create.TSectionProfile(h, b, tw, tf); break; - case IRobotBarSectionShapeType.I_BSST_SPEC_CASTELLATED_WEB_ROUND_OPENINGS: - { - // I_BSST_SPEC_CASTELLATED_WEB_ROUND_OPENINGS (51): Section with a castellated web (round openings) - b = nonStdData.GetValue(IRobotBarSectionNonstdDataValue.I_BSNDV_I_B); - h = nonStdData.GetValue(IRobotBarSectionNonstdDataValue.I_BSNDV_I_H); - tw = nonStdData.GetValue(IRobotBarSectionNonstdDataValue.I_BSNDV_I_TW); - tf = nonStdData.GetValue(IRobotBarSectionNonstdDataValue.I_BSNDV_I_TF); - // Create base I-section profile - IProfile baseProfile = BH.Engine.Spatial.Create.ISectionProfile(h + (2 * tf), b, tw, tf, 0, 0); - // Create circular opening - // Note: Opening parameters are estimated as Robot API may not provide all details - double openingDiameter = h * 0.75; - double spacing = h * 1.5; // Typical spacing for cellular beams - ICellularOpening opening = BH.Engine.Spatial.Create.CircularOpening(openingDiameter, spacing); - sectionProfile = BH.Engine.Spatial.Create.PerforatedISectionProfile(baseProfile, opening); - BH.Engine.Base.Compute.RecordWarning("Cellular beam opening parameters are estimated. Verify opening diameter and spacing for accuracy."); - } - break; - - case IRobotBarSectionShapeType.I_BSST_SPEC_CASTELLATED_WEB_HEXAGONAL_OPENINGS: - case IRobotBarSectionShapeType.I_BSST_SPEC_CASTELLATED_WEB_HEXAGONAL_OPENINGS_SHIFTED: - { - // I_BSST_SPEC_CASTELLATED_WEB_HEXAGONAL_OPENINGS (50): Section with a castellated web (hexagonal openings) - // I_BSST_SPEC_CASTELLATED_WEB_HEXAGONAL_OPENINGS_SHIFTED (52): Section with a castellated web (hexagonal openings, with spacer plates) - b = nonStdData.GetValue(IRobotBarSectionNonstdDataValue.I_BSNDV_I_B); - h = nonStdData.GetValue(IRobotBarSectionNonstdDataValue.I_BSNDV_I_H); - tw = nonStdData.GetValue(IRobotBarSectionNonstdDataValue.I_BSNDV_I_TW); - tf = nonStdData.GetValue(IRobotBarSectionNonstdDataValue.I_BSNDV_I_TF); - // Create base I-section profile - IProfile baseProfile = BH.Engine.Spatial.Create.ISectionProfile(h + (2 * tf), b, tw, tf, 0, 0); - // Create hexagonal opening - // Note: Opening parameters are estimated as Robot API may not provide all details - double openingHeight = h * 0.8; - double openingWidth = openingHeight * 0.866; - double spacing = h * 1.5; - ICellularOpening opening = BH.Engine.Spatial.Create.HexagonalOpening(openingHeight, openingWidth, spacing); - sectionProfile = BH.Engine.Spatial.Create.PerforatedISectionProfile(baseProfile, opening); - BH.Engine.Base.Compute.RecordWarning("Castellated beam opening parameters are estimated. Verify opening dimensions and spacing for accuracy."); - } - break; - default: return null; } diff --git a/Robot_Adapter/Convert/ToRobot/Properties/SectionProperty_Geometrical.cs b/Robot_Adapter/Convert/ToRobot/Properties/SectionProperty_Geometrical.cs index 47f6e589..834be457 100644 --- a/Robot_Adapter/Convert/ToRobot/Properties/SectionProperty_Geometrical.cs +++ b/Robot_Adapter/Convert/ToRobot/Properties/SectionProperty_Geometrical.cs @@ -209,49 +209,6 @@ private static bool SetRobotTypeAndShapeType(this GeneralisedFabricatedBoxProfil /***************************************************/ - private static bool SetRobotTypeAndShapeType(this PerforatedISectionProfile section, IRobotBarSectionData sectionData) - { - // Check opening type to determine appropriate Robot section type - if (section.Openings != null && section.Openings.Count > 0) - { - ICellularOpening opening = section.Openings[0]; - - // Determine shape type based on opening type - // Robot API definitions: - // I_BSST_SPEC_CASTELLATED_WEB_ROUND_OPENINGS (51): Section with a castellated web (round openings) - // I_BSST_SPEC_CASTELLATED_WEB_HEXAGONAL_OPENINGS (50): Section with a castellated web (hexagonal openings) - // I_BSST_SPEC_CASTELLATED_WEB_HEXAGONAL_OPENINGS_SHIFTED (52): Section with a castellated web (hexagonal openings, with spacer plates) - if (opening is CircularOpening) - { - sectionData.Type = IRobotBarSectionType.I_BST_NS_I; - sectionData.ShapeType = IRobotBarSectionShapeType.I_BSST_SPEC_CASTELLATED_WEB_ROUND_OPENINGS; - } - else if (opening is HexagonalOpening) - { - sectionData.Type = IRobotBarSectionType.I_BST_NS_I; - sectionData.ShapeType = IRobotBarSectionShapeType.I_BSST_SPEC_CASTELLATED_WEB_HEXAGONAL_OPENINGS; - } - else - { - // Unknown opening type, fall back to regular I-section - Engine.Base.Compute.RecordWarning($"Cellular opening type {opening.GetType().Name} not recognized. Section will be pushed as standard I-section."); - sectionData.Type = IRobotBarSectionType.I_BST_NS_I; - sectionData.ShapeType = IRobotBarSectionShapeType.I_BSST_USER_I_BISYM; - } - return true; - } - else - { - // No openings, treat as regular I-section - Engine.Base.Compute.RecordWarning("PerforatedISectionProfile has no openings defined. Section will be pushed as standard I-section."); - sectionData.Type = IRobotBarSectionType.I_BST_NS_I; - sectionData.ShapeType = IRobotBarSectionShapeType.I_BSST_USER_I_BISYM; - return true; - } - } - - /***************************************************/ - private static bool SetRobotTypeAndShapeType(this IProfile section, IRobotBarSectionData sectionData) { Engine.Base.Compute.RecordWarning("Profile of type " + section.GetType().Name + " is not yet fully supported for Steel sections. Section with name " + sectionData.Name + " set as explicit section."); @@ -427,41 +384,6 @@ private static bool SetNonStandardSectionData(this GeneralisedFabricatedBoxProfi return true; } - - /***************************************************/ - - private static bool SetNonStandardSectionData(this PerforatedISectionProfile section, IRobotBarSectionData sectionData, int position = 0) - { - // Extract base profile (should be ISectionProfile) - if (section.BaseProfile is ISectionProfile baseProfile) - { - IRobotBarSectionNonstdData nonStdData = sectionData.CreateNonstd(position); - - // Set I-section dimensions from base profile - nonStdData.SetValue(IRobotBarSectionNonstdDataValue.I_BSNDV_I_B, baseProfile.Width); - nonStdData.SetValue(IRobotBarSectionNonstdDataValue.I_BSNDV_I_H, baseProfile.Height - (2 * baseProfile.FlangeThickness)); - nonStdData.SetValue(IRobotBarSectionNonstdDataValue.I_BSNDV_I_TW, baseProfile.WebThickness); - nonStdData.SetValue(IRobotBarSectionNonstdDataValue.I_BSNDV_I_TF, baseProfile.FlangeThickness); - - // Note: Robot API may not support setting all cellular opening parameters (diameter, spacing, etc.) - // The shape type set in SetRobotTypeAndShapeType identifies it as cellular/castellated - // Opening parameters may need to be set manually in Robot after push - - if (section.Openings != null && section.Openings.Count > 0) - { - Engine.Base.Compute.RecordNote($"Cellular opening parameters (diameter, spacing) cannot be fully pushed to Robot API. Section pushed with base I-section geometry and cellular/castellated type. Verify opening parameters in Robot."); - } - - return true; - } - else - { - Engine.Base.Compute.RecordWarning($"PerforatedISectionProfile base profile is not ISectionProfile. Cannot convert to Robot cellular beam. Section name: {sectionData.Name}"); - return false; - } - } - - /***************************************************/ } } From 5422b6b440f4f7b709baf63d512129851d50763b Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 23 Oct 2025 18:14:05 +0000 Subject: [PATCH 09/14] Fix cellular beam conversion order - add I_BST_SPECIAL section type check Co-authored-by: Chrisshort92 <38885832+Chrisshort92@users.noreply.github.com> --- .../Properties/SectionProfile_General.cs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/Robot_Adapter/Convert/FromRobot/Properties/SectionProfile_General.cs b/Robot_Adapter/Convert/FromRobot/Properties/SectionProfile_General.cs index c1acbd06..776c4727 100644 --- a/Robot_Adapter/Convert/FromRobot/Properties/SectionProfile_General.cs +++ b/Robot_Adapter/Convert/FromRobot/Properties/SectionProfile_General.cs @@ -104,6 +104,25 @@ public static IProfile FromRobotGeneralProfile(IRobotBarSectionData secData) return null; } } + else if (secData.Type == IRobotBarSectionType.I_BST_SPECIAL) + { + // Handle cellular/castellated beams using special section data + IRobotBarSectionSpecialData secSpecData = secData.Special; + if (secSpecData != null) + { + return FromRobotSpecialProfile(secSpecData, secData); + } + else + { + BH.Engine.Base.Compute.RecordWarning("Special section data not available for cellular beam."); + 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; + } else { //Get profile at start. FOr non tapered section this will be the general definition From 2f28e0c2513df24054fa70731c253436fcca654e Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 23 Oct 2025 18:55:24 +0000 Subject: [PATCH 10/14] Fix type mismatch - handle CellularSection at SectionProperty level Co-authored-by: Chrisshort92 <38885832+Chrisshort92@users.noreply.github.com> --- .../Properties/SectionProfile_General.cs | 14 -------------- .../FromRobot/Properties/SectionProperty.cs | 19 +++++++++++++++++++ 2 files changed, 19 insertions(+), 14 deletions(-) diff --git a/Robot_Adapter/Convert/FromRobot/Properties/SectionProfile_General.cs b/Robot_Adapter/Convert/FromRobot/Properties/SectionProfile_General.cs index 776c4727..a2dec7a5 100644 --- a/Robot_Adapter/Convert/FromRobot/Properties/SectionProfile_General.cs +++ b/Robot_Adapter/Convert/FromRobot/Properties/SectionProfile_General.cs @@ -104,20 +104,6 @@ public static IProfile FromRobotGeneralProfile(IRobotBarSectionData secData) return null; } } - else if (secData.Type == IRobotBarSectionType.I_BST_SPECIAL) - { - // Handle cellular/castellated beams using special section data - IRobotBarSectionSpecialData secSpecData = secData.Special; - if (secSpecData != null) - { - return FromRobotSpecialProfile(secSpecData, secData); - } - else - { - BH.Engine.Base.Compute.RecordWarning("Special section data not available for cellular beam."); - return null; - } - } else if (secData.Type == IRobotBarSectionType.I_BST_COMPLEX) { BH.Engine.Base.Compute.RecordWarning("Complex sections can not currently be read from Robot."); diff --git a/Robot_Adapter/Convert/FromRobot/Properties/SectionProperty.cs b/Robot_Adapter/Convert/FromRobot/Properties/SectionProperty.cs index ed57eba1..318b2e6e 100644 --- a/Robot_Adapter/Convert/FromRobot/Properties/SectionProperty.cs +++ b/Robot_Adapter/Convert/FromRobot/Properties/SectionProperty.cs @@ -39,8 +39,27 @@ public static ISectionProperty FromRobot(this IRobotBarSectionData secData, IMat ISectionProperty prop = null; IProfile profile = null; + try { + // Check for cellular/castellated beams first (I_BST_SPECIAL type) + // These return CellularSection (ISectionProperty) directly, not IProfile + if (secData.Type == IRobotBarSectionType.I_BST_SPECIAL) + { + IRobotBarSectionSpecialData secSpecData = secData.Special; + if (secSpecData != null) + { + prop = FromRobotSpecialProfile(secSpecData, secData); + // Set material on the cellular section + if (prop != null && material != null) + { + prop.Material = material; + } + return prop; + } + } + + // Handle standard profiles (concrete and other geometrical sections) if (secData.IsConcrete) profile = FromRobotConcreteProfile(secData); else From 1884c0d24214fc9a9f71ba64309b3ef2d0f448a3 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 23 Oct 2025 22:21:54 +0000 Subject: [PATCH 11/14] Add better error handling and diagnostics for cellular beam conversion Co-authored-by: Chrisshort92 <38885832+Chrisshort92@users.noreply.github.com> --- .../FromRobot/Properties/SectionProperty.cs | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/Robot_Adapter/Convert/FromRobot/Properties/SectionProperty.cs b/Robot_Adapter/Convert/FromRobot/Properties/SectionProperty.cs index 318b2e6e..25e107c8 100644 --- a/Robot_Adapter/Convert/FromRobot/Properties/SectionProperty.cs +++ b/Robot_Adapter/Convert/FromRobot/Properties/SectionProperty.cs @@ -55,8 +55,18 @@ public static ISectionProperty FromRobot(this IRobotBarSectionData secData, IMat { prop.Material = material; } + + if (prop == null) + { + Engine.Base.Compute.RecordWarning($"Failed to convert special section (cellular/castellated beam) named {robotLabelName}. Section type: {secData.ShapeType}"); + } + return prop; } + else + { + Engine.Base.Compute.RecordWarning($"Special section data not available for section {robotLabelName} of type {secData.Type}"); + } } // Handle standard profiles (concrete and other geometrical sections) @@ -65,9 +75,9 @@ public static ISectionProperty FromRobot(this IRobotBarSectionData secData, IMat else profile = FromRobotGeneralProfile(secData); } - catch (System.Exception) + catch (System.Exception ex) { - + Engine.Base.Compute.RecordWarning($"Exception converting section {robotLabelName}: {ex.Message}"); } if (profile != null) From 37da6734a7a20b0e74650fff20aaf60c310c03f6 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 23 Oct 2025 23:40:44 +0000 Subject: [PATCH 12/14] Fix cellular beam detection - check shape type instead of section type Co-authored-by: Chrisshort92 <38885832+Chrisshort92@users.noreply.github.com> --- .../Properties/SectionProfile_General.cs | 54 +++++++++++++++++++ .../FromRobot/Properties/SectionProperty.cs | 24 ++++++++- 2 files changed, 77 insertions(+), 1 deletion(-) diff --git a/Robot_Adapter/Convert/FromRobot/Properties/SectionProfile_General.cs b/Robot_Adapter/Convert/FromRobot/Properties/SectionProfile_General.cs index a2dec7a5..0bd6880b 100644 --- a/Robot_Adapter/Convert/FromRobot/Properties/SectionProfile_General.cs +++ b/Robot_Adapter/Convert/FromRobot/Properties/SectionProfile_General.cs @@ -138,6 +138,60 @@ 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; diff --git a/Robot_Adapter/Convert/FromRobot/Properties/SectionProperty.cs b/Robot_Adapter/Convert/FromRobot/Properties/SectionProperty.cs index 25e107c8..63e9296f 100644 --- a/Robot_Adapter/Convert/FromRobot/Properties/SectionProperty.cs +++ b/Robot_Adapter/Convert/FromRobot/Properties/SectionProperty.cs @@ -42,8 +42,30 @@ public static ISectionProperty FromRobot(this IRobotBarSectionData secData, IMat try { - // Check for cellular/castellated beams first (I_BST_SPECIAL type) + // Check for cellular/castellated beams by shape type (Robot may report them as I_BST_STANDARD or I_BST_COMPLEX) // 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; + } + + // Check for cellular/castellated beams with I_BST_SPECIAL type (alternative path) if (secData.Type == IRobotBarSectionType.I_BST_SPECIAL) { IRobotBarSectionSpecialData secSpecData = secData.Special; From 17b360e5d1f646a099968aee2388c91a532b47b2 Mon Sep 17 00:00:00 2001 From: Christopher Short Date: Wed, 29 Oct 2025 11:27:11 +0000 Subject: [PATCH 13/14] Update SectionProfile_General.cs --- .../Convert/FromRobot/Properties/SectionProfile_General.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Robot_Adapter/Convert/FromRobot/Properties/SectionProfile_General.cs b/Robot_Adapter/Convert/FromRobot/Properties/SectionProfile_General.cs index 0bd6880b..25b76682 100644 --- a/Robot_Adapter/Convert/FromRobot/Properties/SectionProfile_General.cs +++ b/Robot_Adapter/Convert/FromRobot/Properties/SectionProfile_General.cs @@ -53,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) { @@ -106,6 +109,8 @@ public static IProfile FromRobotGeneralProfile(IRobotBarSectionData secData) } else if (secData.Type == IRobotBarSectionType.I_BST_COMPLEX) { + + BH.Engine.Base.Compute.RecordWarning("Complex sections can not currently be read from Robot."); return null; } From 1ab579a494079be9f7726491519c0ef05bf67b21 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 16 Nov 2025 14:10:55 +0000 Subject: [PATCH 14/14] Fix cellular beam detection for I_BST_COMPLEX type with Special data access Co-authored-by: Chrisshort92 <38885832+Chrisshort92@users.noreply.github.com> --- .../Properties/SectionProfile_General.cs | 77 +++++++++++-------- .../FromRobot/Properties/SectionProperty.cs | 57 +++++++------- 2 files changed, 75 insertions(+), 59 deletions(-) diff --git a/Robot_Adapter/Convert/FromRobot/Properties/SectionProfile_General.cs b/Robot_Adapter/Convert/FromRobot/Properties/SectionProfile_General.cs index 25b76682..ef91a715 100644 --- a/Robot_Adapter/Convert/FromRobot/Properties/SectionProfile_General.cs +++ b/Robot_Adapter/Convert/FromRobot/Properties/SectionProfile_General.cs @@ -201,52 +201,65 @@ public static CellularSection FromRobotSpecialProfile(IRobotBarSectionSpecialDat { CellularSection sectionProfile = null; - if (secData.Type == IRobotBarSectionType.I_BST_SPECIAL) + 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 of openings + 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 - double bp = secSpecData.GetValue(IRobotBarSectionSpecialDataValue.I_BSSDV_BP); - double tp = secSpecData.GetValue(IRobotBarSectionSpecialDataValue.I_BSSDV_TP); - - switch (secData.ShapeType) + + // Validate that we have cellular beam data (check for non-zero opening parameters) + if (d > 0 && w > 0) { - case IRobotBarSectionShapeType.I_BSST_SPEC_CASTELLATED_WEB_ROUND_OPENINGS: - ISectionProfile baseProfile = BH.Engine.Spatial.Create.ISectionProfile(h, b1, tW, tf1, 0, 0); - SteelSection steelSection = BH.Engine.Structure.Create.SteelSectionFromProfile(baseProfile); - ICellularOpening opening = BH.Engine.Spatial.Create.CircularCellularOpening(d, w); - sectionProfile = BH.Engine.Structure.Create.CellularSectionFromBaseSection(steelSection, h, opening); - break; - - case IRobotBarSectionShapeType.I_BSST_SPEC_CASTELLATED_WEB_HEXAGONAL_OPENINGS: - ISectionProfile baseProfileHex = BH.Engine.Spatial.Create.ISectionProfile(h, b1, tW, tf1, 0, 0); - SteelSection steelSectionHex = BH.Engine.Structure.Create.SteelSectionFromProfile(baseProfileHex); - ICellularOpening hexOpening = BH.Engine.Spatial.Create.HexagonalCellularOpening(d, w, a); - sectionProfile = BH.Engine.Structure.Create.CellularSectionFromBaseSection(steelSectionHex, h, hexOpening); - break; - - case IRobotBarSectionShapeType.I_BSST_SPEC_CASTELLATED_WEB_HEXAGONAL_OPENINGS_SHIFTED: - ISectionProfile baseProfileHexSpace = BH.Engine.Spatial.Create.ISectionProfile(h, b1, tW, tf1, 0, 0); - SteelSection steelSectionHexSpace = BH.Engine.Structure.Create.SteelSectionFromProfile(baseProfileHexSpace); - ICellularOpening hexOpeningSpace = BH.Engine.Spatial.Create.HexagonalCellularOpening(d, w, a, hs); - sectionProfile = BH.Engine.Structure.Create.CellularSectionFromBaseSection(steelSectionHexSpace, h, hexOpeningSpace); - break; - - default: - return null; + // 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; } - return sectionProfile; } - else - { return null; + catch (System.Exception ex) + { + Engine.Base.Compute.RecordWarning($"Failed to extract cellular beam from special data: {ex.Message}"); + return null; } } diff --git a/Robot_Adapter/Convert/FromRobot/Properties/SectionProperty.cs b/Robot_Adapter/Convert/FromRobot/Properties/SectionProperty.cs index 63e9296f..3bc4c513 100644 --- a/Robot_Adapter/Convert/FromRobot/Properties/SectionProperty.cs +++ b/Robot_Adapter/Convert/FromRobot/Properties/SectionProperty.cs @@ -42,7 +42,36 @@ public static ISectionProperty FromRobot(this IRobotBarSectionData secData, IMat try { - // Check for cellular/castellated beams by shape type (Robot may report them as I_BST_STANDARD or I_BST_COMPLEX) + // 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 || @@ -65,32 +94,6 @@ public static ISectionProperty FromRobot(this IRobotBarSectionData secData, IMat return prop; } - // Check for cellular/castellated beams with I_BST_SPECIAL type (alternative path) - if (secData.Type == IRobotBarSectionType.I_BST_SPECIAL) - { - IRobotBarSectionSpecialData secSpecData = secData.Special; - if (secSpecData != null) - { - prop = FromRobotSpecialProfile(secSpecData, 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 special section (cellular/castellated beam) named {robotLabelName}. Section type: {secData.ShapeType}"); - } - - return prop; - } - else - { - Engine.Base.Compute.RecordWarning($"Special section data not available for section {robotLabelName} of type {secData.Type}"); - } - } - // Handle standard profiles (concrete and other geometrical sections) if (secData.IsConcrete) profile = FromRobotConcreteProfile(secData);