diff --git a/FemDesign.Core/Bars/Buckling/BucklingData.cs b/FemDesign.Core/Bars/Buckling/BucklingData.cs index 6a5e075a3..2d6808730 100644 --- a/FemDesign.Core/Bars/Buckling/BucklingData.cs +++ b/FemDesign.Core/Bars/Buckling/BucklingData.cs @@ -130,5 +130,35 @@ public static Bar SetOnTimberBar(Bar bar, BucklingLength flexuralStiff, Buckling return bar; } + + /// + /// Set BucklingData on a concealed bar-element. + /// + /// Action + /// HiddenBar. Concealed bar-element. + /// BucklingLength definition in Flexural Stiff direction. + /// BucklingLength definition in Flexural Weak direction. + /// + public static Reinforcement.ConcealedBar SetOnHiddenBar(Reinforcement.ConcealedBar concealedBar, BucklingLength flexuralStiff, BucklingLength flexuralWeak) + { + concealedBar = concealedBar.DeepClone(); + + if (flexuralStiff.Type != BucklingType.FlexuralStiff) + { + throw new System.ArgumentException("flexuralStiff is not of type FlexuralStiff!"); + } + if (flexuralWeak.Type != BucklingType.FlexuralWeak) + { + throw new System.ArgumentException("flexuralWeak is not of type FlexuralWeak!"); + } + + // add input + BucklingData bucklingData = new BucklingData(); + bucklingData.BucklingLength.Add(flexuralStiff); + bucklingData.BucklingLength.Add(flexuralWeak); + concealedBar.BucklingData = bucklingData; + + return concealedBar; + } } } \ No newline at end of file diff --git a/FemDesign.Core/FemDesign.Core.csproj b/FemDesign.Core/FemDesign.Core.csproj index aec64a23a..247bb3432 100644 --- a/FemDesign.Core/FemDesign.Core.csproj +++ b/FemDesign.Core/FemDesign.Core.csproj @@ -341,7 +341,7 @@ - + diff --git a/FemDesign.Core/Geometry/RectangleType.cs b/FemDesign.Core/Geometry/RectangleType.cs index 1ac0f6db2..b12932831 100644 --- a/FemDesign.Core/Geometry/RectangleType.cs +++ b/FemDesign.Core/Geometry/RectangleType.cs @@ -23,5 +23,19 @@ public partial class RectangleType [XmlAttribute("y_size")] public double DimY { get; set; } + + private RectangleType() + { + + } + + public RectangleType(Point3d baseCorner, Vector3d xDir, Vector3d yDir, double xDim, double yDim) + { + this.BaseCorner = baseCorner; + this.LocalX = xDir; + this.LocalY = yDir; + this.DimX = xDim; + this.DimY = yDim; + } } } diff --git a/FemDesign.Core/Model/Entities.cs b/FemDesign.Core/Model/Entities.cs index f071b19d6..485fda456 100644 --- a/FemDesign.Core/Model/Entities.cs +++ b/FemDesign.Core/Model/Entities.cs @@ -39,7 +39,7 @@ public partial class Entities public List BeamReductionZones { get; set; } [XmlElement("hidden_bar", Order = 9)] - public List HiddenBars { get; set; } = new List(); + public List HiddenBars { get; set; } = new List(); [XmlElement("bar_reinforcement", Order = 10)] public List BarReinforcements { get; set; } = new List(); diff --git a/FemDesign.Core/Model/Model.cs b/FemDesign.Core/Model/Model.cs index 47828bfc8..a10318e9e 100644 --- a/FemDesign.Core/Model/Model.cs +++ b/FemDesign.Core/Model/Model.cs @@ -682,6 +682,45 @@ private bool PtcInModel(Reinforcement.Ptc obj) return false; } + + /// + /// Add Post-tensioned cable to Model. + /// + private void AddConcealedBar(Reinforcement.ConcealedBar obj, bool overwrite) + { + // in model? + bool inModel = this.ConcealedBarInModel(obj); + + // in model, don't overwrite + if (inModel && overwrite == false) + { + throw new System.ArgumentException($"{obj.GetType().FullName} with guid: {obj.Guid} has already been added to model. Are you adding the same element twice?"); + } + + // in model, overwrite + else if (inModel && overwrite == true) + { + this.Entities.HiddenBars.RemoveAll(x => x.Guid == obj.Guid); + } + + // add concealed bar + this.Entities.HiddenBars.Add(obj); + } + + private bool ConcealedBarInModel(Reinforcement.ConcealedBar obj) + { + foreach (Reinforcement.ConcealedBar elem in this.Entities.HiddenBars) + { + if (elem.Guid == obj.Guid) + { + return true; + } + } + return false; + } + + + /// /// Add Fictitious Bar to Model. /// @@ -3472,6 +3511,7 @@ public Model AddSupports(params T[] supports) where T : ISupportElement private void AddEntity(Shells.Slab obj, bool overwrite) => AddSlab(obj, overwrite); private void AddEntity(Shells.Panel obj, bool overwrite) => AddPanel(obj, overwrite); private void AddEntity(Reinforcement.Ptc obj, bool overwrite) => AddPtc(obj, overwrite); + private void AddEntity(Reinforcement.ConcealedBar obj, bool overwrite) => AddConcealedBar(obj, overwrite); private void AddEntity(ModellingTools.Cover obj, bool overwrite) => AddCover(obj, overwrite); diff --git a/FemDesign.Core/Reinforcement/BarReinforcement.cs b/FemDesign.Core/Reinforcement/BarReinforcement.cs index e4eb48c82..83ee7e965 100644 --- a/FemDesign.Core/Reinforcement/BarReinforcement.cs +++ b/FemDesign.Core/Reinforcement/BarReinforcement.cs @@ -101,7 +101,7 @@ public BarReinforcement() } /// - /// Construct stirrup bar reinforcement + /// Construct stirrup bar reinforcement for a normal bar /// public BarReinforcement(Guid baseBar, Wire wire, Stirrups stirrups) { @@ -112,7 +112,7 @@ public BarReinforcement(Guid baseBar, Wire wire, Stirrups stirrups) } /// - /// Construct stirrup bar reinforcement + /// Construct stirrup bar reinforcement for a normal bar /// public BarReinforcement(Bars.Bar bar, Wire wire, Stirrups stirrups) { @@ -121,9 +121,20 @@ public BarReinforcement(Bars.Bar bar, Wire wire, Stirrups stirrups) this.Wire = wire; this.Stirrups = stirrups; } - + /// - /// Construct longitudinal bar reinforcement + /// Construct stirrup bar reinforcement for a concealed bar + /// + public BarReinforcement(ConcealedBar concealedBar, Wire wire, Stirrups stirrups) + { + this.EntityCreated(); + this.BaseBar = new GuidListType(concealedBar.Guid); + this.Wire = wire; + this.Stirrups = stirrups; + } + + /// + /// Construct longitudinal bar reinforcement for a normal bar /// public BarReinforcement(Guid baseBar, Wire wire, LongitudinalBar longBar) { @@ -134,7 +145,7 @@ public BarReinforcement(Guid baseBar, Wire wire, LongitudinalBar longBar) } /// - /// Construct longitudinal bar reinforcement + /// Construct longitudinal bar reinforcement for a normal bar /// public BarReinforcement(Bars.Bar bar, Wire wire, LongitudinalBar longBar) { @@ -144,6 +155,17 @@ public BarReinforcement(Bars.Bar bar, Wire wire, LongitudinalBar longBar) this.LongitudinalBar = longBar; } + /// + /// Construct longitudinal bar reinforcement for a concealed bar + /// + public BarReinforcement(ConcealedBar concealedBar, Wire wire, LongitudinalBar longBar) + { + this.EntityCreated(); + this.BaseBar = new GuidListType(concealedBar.Guid); + this.Wire = wire; + this.LongitudinalBar = longBar; + } + /// /// Add reinforcement to bar. /// Internal method use by GH components and Dynamo nodes. @@ -207,6 +229,50 @@ public static Bars.Bar AddReinforcementToBar(Bars.Bar bar, List + /// Add reinforcement to a concealed bar. + /// + /// + /// + /// Overwrite rebar on bar if a rebar sharing guid already exists on the bar? + public static ConcealedBar AddReinforcementToHiddenBar(ConcealedBar concealedBar, List rebar, bool overwrite) + { + foreach (BarReinforcement item in rebar) + { + // empty base bar - update with current barPart guid + if (item.BaseBar.Guid == Guid.Empty) + { + item.BaseBar.Guid = concealedBar.Guid; + } + + // base bar does not equal current barPart guid - reinforcement probably added to another bar already. + else if (item.BaseBar.Guid != concealedBar.Guid) + { + throw new System.ArgumentException($"{item.GetType().FullName} with guid: {item.Guid} has a base bar guid: {item.BaseBar.Guid} that does not correnspond with the current concealed bar"); + } + + // add reinforcement to current bar + bool exists = concealedBar.Reinforcement.Any(x => x.Guid == item.Guid); + if (exists) + { + if (overwrite) + { + concealedBar.Reinforcement.RemoveAll(x => x.Guid == item.Guid); + concealedBar.Reinforcement.Add(item); + } + else + { + throw new System.ArgumentException($"{item.GetType().FullName} with guid: {item.Guid} has already been added to the concealed bar. Are you adding the same element twice?"); + } + } + else + { + concealedBar.Reinforcement.Add(item); + } + } + return concealedBar; + } + public override string ToString() { return $"{this.GetType().FullName} - {this.Wire}"; diff --git a/FemDesign.Core/Reinforcement/ConcealedBar.cs b/FemDesign.Core/Reinforcement/ConcealedBar.cs new file mode 100644 index 000000000..42f42d35f --- /dev/null +++ b/FemDesign.Core/Reinforcement/ConcealedBar.cs @@ -0,0 +1,95 @@ +// https://strusoft.com/ +using System; +using System.Xml.Serialization; +using System.Collections.Generic; +using System.Linq; +using System.ComponentModel; +using FemDesign.GenericClasses; +using FemDesign.Geometry; + + +namespace FemDesign.Reinforcement +{ + [System.Serializable] + public partial class ConcealedBar: NamedEntityBase, IStructureElement + { + private static int _concealedBarInstances = 0; + protected override int GetUniqueInstanceCount() => ++_concealedBarInstances; + + [XmlElement("rectangle", Order = 1)] + public RectangleType Rectangle { get; set; } + + [XmlElement("start", Order = 2)] + public Point3d Start { get; set; } + + [XmlElement("buckling_data", Order = 3)] + public Bars.Buckling.BucklingData BucklingData { get; set; } + + [XmlElement("end", Order = 4)] + public string End = ""; + + [XmlAttribute("base_shell")] + public Guid BaseShell { get; set; } + + [XmlAttribute("axis_in_longer_side")] + [DefaultValue(true)] + public bool AxisInLongerSide { get; set; } = true; + + + [XmlIgnore] + public List Reinforcement = new List(); + + [XmlIgnore] + public List Stirrups + { + get + { + return this.Reinforcement.Where(x => x.Stirrups != null).ToList(); + } + } + [XmlIgnore] + public List LongitudinalBars + { + get + { + return this.Reinforcement.Where(x => x.LongitudinalBar != null).ToList(); + } + } + + private ConcealedBar() + { + + } + + /// + /// Concealed bar constructor. + /// + /// Base shell element. + /// Rectangle area where the concealed bar is specified. Must be inside the SlabPart region boundary. + /// If true, the axis of the concealed bar is parallel to the longer side of the rectangle, otherwise it is parallel to the shorter side. + /// Structural element identifier. + /// + public ConcealedBar(Shells.Slab slab, RectangleType rectangle, bool axisInLongerSide = true, string identifier = "CB") + { + if (slab.SlabPart.ComplexMaterial.Concrete == null) + { + throw new System.ArgumentException("Slab material must be concrete!"); + } + + this.EntityCreated(); + this.BaseShell = slab.SlabPart.Guid; + this.AxisInLongerSide = axisInLongerSide; + //if(axisInLongerSide) + //{ + // this.Start = rectangle.BaseCorner + new Vector3d(0, rectangle.DimY / 2, 0); + //} + //else + //{ + // this.Start = rectangle.BaseCorner + new Vector3d(rectangle.DimX / 2, 0, 0); + //} + this.Rectangle = rectangle; + this.Identifier = identifier; + } + + } +} diff --git a/FemDesign.Core/Reinforcement/HiddenBar.cs b/FemDesign.Core/Reinforcement/HiddenBar.cs deleted file mode 100644 index 6cd7a122a..000000000 --- a/FemDesign.Core/Reinforcement/HiddenBar.cs +++ /dev/null @@ -1,27 +0,0 @@ -using System; -using System.Xml.Serialization; -using FemDesign.GenericClasses; - - -namespace FemDesign.Reinforcement -{ - [System.Serializable] - public partial class HiddenBar: NamedEntityBase, IStructureElement - { - - private static int _hiddenBarInstances = 0; - protected override int GetUniqueInstanceCount() => ++_hiddenBarInstances; - - [XmlElement("rectangle", Order = 1)] - public Geometry.RectangleType Rectangle { get; set; } - - [XmlElement("buckling_data", Order = 2)] - public Bars.Buckling.BucklingData BucklingData { get; set; } - - [XmlElement("end", Order = 3)] - public string End = ""; - - [XmlAttribute("base_shell")] - public Guid BaseShell { get; set; } - } -} diff --git a/FemDesign.Grasshopper/FemDesign.Grasshopper.csproj b/FemDesign.Grasshopper/FemDesign.Grasshopper.csproj index 510242b5b..73c3b386a 100644 --- a/FemDesign.Grasshopper/FemDesign.Grasshopper.csproj +++ b/FemDesign.Grasshopper/FemDesign.Grasshopper.csproj @@ -232,6 +232,7 @@ + @@ -944,6 +945,7 @@ + diff --git a/FemDesign.Grasshopper/Geometry/Convert.cs b/FemDesign.Grasshopper/Geometry/Convert.cs index 19face516..4fe4947d9 100644 --- a/FemDesign.Grasshopper/Geometry/Convert.cs +++ b/FemDesign.Grasshopper/Geometry/Convert.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Runtime.CompilerServices; using System.Text; using FemDesign.Geometry; using FemDesign.Loads; @@ -71,6 +72,21 @@ internal static Rhino.Geometry.Brep GetRhinoSurface(this ModellingTools.Cover co #endregion + #region Rectangle + + public static FemDesign.Geometry.RectangleType FromRhino(this Rhino.Geometry.Rectangle3d obj) + { + var baseCorner = obj.PointAt(0, 0).FromRhino(); + var dimX = obj.Width; + var dimY = obj.Height; + var localX = obj.Plane.XAxis.FromRhino(); + var localY = obj.Plane.YAxis.FromRhino(); + + var rectangle = new RectangleType(baseCorner, localX, localY, dimX, dimY); + return rectangle; + } + #endregion + #region Edge /// /// Convert a Rhino Curve to one or several Edges. @@ -873,7 +889,7 @@ internal static Rhino.Geometry.Brep ToRhinoBrep(this Region region) #endregion -#region RegionGroup + #region RegionGroup /// /// Get rhino breps of underlying regions /// diff --git a/FemDesign.Grasshopper/Properties/Resources.Designer.cs b/FemDesign.Grasshopper/Properties/Resources.Designer.cs index d7d08c14f..349bceb9f 100644 --- a/FemDesign.Grasshopper/Properties/Resources.Designer.cs +++ b/FemDesign.Grasshopper/Properties/Resources.Designer.cs @@ -260,6 +260,16 @@ internal static System.Drawing.Bitmap CombSettings { } } + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap ConcealedBar { + get { + object obj = ResourceManager.GetObject("ConcealedBar", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + /// /// Looks up a localized resource of type System.Drawing.Bitmap. /// diff --git a/FemDesign.Grasshopper/Properties/Resources.resx b/FemDesign.Grasshopper/Properties/Resources.resx index 1b04624b4..eb906e1a5 100644 --- a/FemDesign.Grasshopper/Properties/Resources.resx +++ b/FemDesign.Grasshopper/Properties/Resources.resx @@ -7293,4 +7293,7 @@ ..\Resources\icons\ModellingToolsDeconstruct.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + ..\Resources\icons\ConcealedBar.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + \ No newline at end of file diff --git a/FemDesign.Grasshopper/Reinforcement/ConcealedBar.cs b/FemDesign.Grasshopper/Reinforcement/ConcealedBar.cs new file mode 100644 index 000000000..c88748272 --- /dev/null +++ b/FemDesign.Grasshopper/Reinforcement/ConcealedBar.cs @@ -0,0 +1,76 @@ +// https://strusoft.com/ +using System; +using System.Collections.Generic; +using Grasshopper.Kernel; +using Rhino.Geometry; +using FemDesign.GenericClasses; +using FemDesign.Reinforcement; + +namespace FemDesign.Grasshopper +{ + public class ConcealedBar : FEM_Design_API_Component + { + public ConcealedBar() : base("ConcealedBar", "ConcealedBar", "Create a Concealed Bar (wire).", "FEM-Design", "Reinforcement") + { + + } + protected override void RegisterInputParams(GH_InputParamManager pManager) + { + pManager.AddRectangleParameter("Rectangle", "Rectangle", "", GH_ParamAccess.item); + pManager.AddGenericParameter("RefConcreteSlab", "RefConcreteSlab", "Concrete slab/wall where the concealed bar should be created", GH_ParamAccess.item); + pManager.AddBooleanParameter("Axis", "Axis", + "True: the axis of the concealed bar will follow the X axis of the rectangle.\n" + + "False: the axis of the concealed bar will follow the Y axis of the rectangle.", GH_ParamAccess.item); + pManager[pManager.ParamCount - 1].Optional = true; + pManager.AddTextParameter("Identifier", "Identifier", "", GH_ParamAccess.item, "CB"); + pManager[pManager.ParamCount - 1].Optional = true; + } + protected override void RegisterOutputParams(GH_OutputParamManager pManager) + { + pManager.AddGenericParameter("ConcealedBar", "ConcealedBar", "ConcealedBar.", GH_ParamAccess.item); + } + protected override void SolveInstance(IGH_DataAccess DA) + { + Rectangle3d rectangle = Rectangle3d.Unset; + if (!DA.GetData("Rectangle", ref rectangle)) return; + + FemDesign.Shells.Slab slab = null; + if (!DA.GetData("RefConcreteSlab", ref slab)) return; + + bool axisLongerDirection = true; + DA.GetData("AxisLongerSide", ref axisLongerDirection); + + string identifier = "CB"; + DA.GetData("Identifier", ref identifier); + + var _rectangle = rectangle.FromRhino(); + + for(int i = 0; i < 4; i++) + { + var pt = rectangle.Corner(i); + var closestPt = slab.Region.ToRhinoBrep().ClosestPoint(pt); + if(closestPt.DistanceTo(pt) >= Tolerance.LengthComparison) + { + throw new Exception($"Rectangle does not lie on the slab region!"); + } + } + + var obj = new FemDesign.Reinforcement.ConcealedBar(slab, _rectangle, axisLongerDirection, identifier); + + if(axisLongerDirection == false) + { + var start = rectangle.PointAt(0.5, 0); + obj.Start = start.FromRhino(); + } + + DA.SetData(0, obj); + } + protected override System.Drawing.Bitmap Icon => FemDesign.Properties.Resources.ConcealedBar; + public override Guid ComponentGuid + { + get { return new Guid("{C03C50FB-33BE-45B5-B48B-ED94C3B8F1C3}"); } + } + + public override GH_Exposure Exposure => GH_Exposure.primary; + } +} \ No newline at end of file diff --git a/FemDesign.Grasshopper/Resources/icons/ConcealedBar.png b/FemDesign.Grasshopper/Resources/icons/ConcealedBar.png new file mode 100644 index 000000000..51c9e7062 Binary files /dev/null and b/FemDesign.Grasshopper/Resources/icons/ConcealedBar.png differ