diff --git a/ETABS_Engine/Convert/ToCSI.cs b/ETABS_Engine/Convert/ToCSI.cs index f2522fd2..0240a0f5 100644 --- a/ETABS_Engine/Convert/ToCSI.cs +++ b/ETABS_Engine/Convert/ToCSI.cs @@ -25,7 +25,7 @@ using BH.oM.Structure.Constraints; using BH.oM.Structure.MaterialFragments; using BH.oM.Geometry; - +using System.Linq; namespace BH.Engine.ETABS { @@ -52,39 +52,58 @@ public static void ToCSI(this Constraint6DOF support, ref bool[] restraint, ref /***************************************************/ - public static void ToCSI(this BarRelease release, ref bool[] startRestraint, ref double[] startSpring, ref bool[] endRestraint, ref double[] endSpring) + public static bool ToCSI(this BarRelease release, ref bool[] startRestraint, ref double[] startSpring, ref bool[] endRestraint, ref double[] endSpring) { startRestraint = new bool[6]; startRestraint[0] = release.StartRelease.TranslationX == DOFType.Free; - startRestraint[1] = release.StartRelease.TranslationY == DOFType.Free; - startRestraint[2] = release.StartRelease.TranslationZ == DOFType.Free; + startRestraint[1] = release.StartRelease.TranslationZ == DOFType.Free; + startRestraint[2] = release.StartRelease.TranslationY == DOFType.Free; startRestraint[3] = release.StartRelease.RotationX == DOFType.Free; - startRestraint[4] = release.StartRelease.RotationY == DOFType.Free; - startRestraint[5] = release.StartRelease.RotationZ == DOFType.Free; + startRestraint[4] = release.StartRelease.RotationZ == DOFType.Free; + startRestraint[5] = release.StartRelease.RotationY == DOFType.Free; startSpring = new double[6]; startSpring[0] = release.StartRelease.TranslationalStiffnessX; - startSpring[1] = release.StartRelease.TranslationalStiffnessY; - startSpring[2] = release.StartRelease.TranslationalStiffnessZ; + startSpring[1] = release.StartRelease.TranslationalStiffnessZ; + startSpring[2] = release.StartRelease.TranslationalStiffnessY; startSpring[3] = release.StartRelease.RotationalStiffnessX; - startSpring[4] = release.StartRelease.RotationalStiffnessY; - startSpring[5] = release.StartRelease.RotationalStiffnessZ; + startSpring[4] = release.StartRelease.RotationalStiffnessZ; + startSpring[5] = release.StartRelease.RotationalStiffnessY; endRestraint = new bool[6]; endRestraint[0] = release.EndRelease.TranslationX == DOFType.Free; - endRestraint[1] = release.EndRelease.TranslationY == DOFType.Free; - endRestraint[2] = release.EndRelease.TranslationZ == DOFType.Free; + endRestraint[1] = release.EndRelease.TranslationZ == DOFType.Free; + endRestraint[2] = release.EndRelease.TranslationY == DOFType.Free; endRestraint[3] = release.EndRelease.RotationX == DOFType.Free; - endRestraint[4] = release.EndRelease.RotationY == DOFType.Free; - endRestraint[5] = release.EndRelease.RotationZ == DOFType.Free; + endRestraint[4] = release.EndRelease.RotationZ == DOFType.Free; + endRestraint[5] = release.EndRelease.RotationY == DOFType.Free; endSpring = new double[6]; endSpring[0] = release.EndRelease.TranslationalStiffnessX; - endSpring[1] = release.EndRelease.TranslationalStiffnessY; - endSpring[2] = release.EndRelease.TranslationalStiffnessZ; + endSpring[1] = release.EndRelease.TranslationalStiffnessZ; + endSpring[2] = release.EndRelease.TranslationalStiffnessY; endSpring[3] = release.EndRelease.RotationalStiffnessX; - endSpring[4] = release.EndRelease.RotationalStiffnessY; - endSpring[5] = release.EndRelease.RotationalStiffnessZ; + endSpring[4] = release.EndRelease.RotationalStiffnessZ; + endSpring[5] = release.EndRelease.RotationalStiffnessY; + + bool[] startReleased = startRestraint.Zip(startSpring, (x, y) => x && y == 0).ToArray(); + bool[] endReleased = endRestraint.Zip(endSpring, (x, y) => x && y == 0).ToArray(); + bool success = true; + + if (startReleased[0] && endReleased[0]) + { Engine.Reflection.Compute.RecordWarning($"Unstable releases have not been set, can not release TranslationX for both ends"); success = false; } + if (startReleased[1] && endReleased[1]) + { Engine.Reflection.Compute.RecordWarning($"Unstable releases have not been set, can not release TranslationZ for both ends"); success = false; } + if (startReleased[2] && endReleased[2]) + { Engine.Reflection.Compute.RecordWarning($"Unstable releases have not been set, can not release TranslationY for both ends"); success = false; } + if (startReleased[3] && endReleased[3]) + { Engine.Reflection.Compute.RecordWarning($"Unstable releases have not been set, can not release RotationX for both ends"); success = false; } + if (startReleased[4] && endReleased[4] && (startReleased[2] || endReleased[2])) + { Engine.Reflection.Compute.RecordWarning($"Unstable releases have not been set, can not release TranslationY when RotationZ is released for both ends"); success = false; } + if (startReleased[5] && endReleased[5] && (startReleased[1] || endReleased[1])) + { Engine.Reflection.Compute.RecordWarning($"Unstable releases have not been set, can not release TranslationZ when RotationY is released for both ends"); success = false; } + + return success; } /***************************************************/ diff --git a/ETABS_Engine/ETABS_Engine.csproj b/ETABS_Engine/ETABS_Engine.csproj index 9c2f0cda..c1c35ae3 100644 --- a/ETABS_Engine/ETABS_Engine.csproj +++ b/ETABS_Engine/ETABS_Engine.csproj @@ -166,6 +166,7 @@ + diff --git a/ETABS_Engine/Query/CheckFlipBar.cs b/ETABS_Engine/Query/CheckFlipBar.cs new file mode 100644 index 00000000..bcab6c30 --- /dev/null +++ b/ETABS_Engine/Query/CheckFlipBar.cs @@ -0,0 +1,59 @@ +/* + * This file is part of the Buildings and Habitats object Model (BHoM) + * Copyright (c) 2015 - 2018, the respective contributors. All rights reserved. + * + * Each contributor holds copyright over their respective contributions. + * The project versioning (Git) records all such contribution source information. + * + * + * The BHoM is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3.0 of the License, or + * (at your option) any later version. + * + * The BHoM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this code. If not, see . + */ + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using BH.oM.Structure.Elements; +using BH.oM.Adapters.ETABS.Elements; +using BH.oM.Geometry; + +namespace BH.Engine.ETABS +{ + public static partial class Query + { + + /***************************************************/ + /**** Public Methods ****/ + /***************************************************/ + + public static bool CheckFlipBar(this Bar bar) + { + Point start = bar.StartNode.Position; + Point end = bar.EndNode.Position; + + if (start.Z > end.Z) + return true; + if (start.X > end.X) + return true; + if (start.Y > end.Y) + return true; + + return false; + } + + /***************************************************/ + + } +} \ No newline at end of file diff --git a/Etabs_Adapter/CRUD/Create/Bar.cs b/Etabs_Adapter/CRUD/Create/Bar.cs index 49105165..e8c5b78b 100644 --- a/Etabs_Adapter/CRUD/Create/Bar.cs +++ b/Etabs_Adapter/CRUD/Create/Bar.cs @@ -35,6 +35,11 @@ using BH.Engine.ETABS; using BH.oM.Adapters.ETABS.Elements; using BH.oM.Geometry.ShapeProfiles; +using BH.oM.Geometry; +using System.ComponentModel; +using BH.oM.Adapters.ETABS; +using BH.Engine.Base; +using System; #if Debug17 || Release17 using ETABSv17; #else @@ -57,7 +62,14 @@ private bool CreateObject(Bar bhBar) string name = ""; - + + // Evaluate if the bar is alinged as Etabs wants it + if (bhBar.CheckFlipBar()) + { + FlipEndPoints(bhBar); //CloneBeforePush means this is fine + FlipInsertionPoint(bhBar); //ETABS specific operation + Engine.Reflection.Compute.RecordNote("Some bars has been flipped to comply with ETABS API, asymmetric sections will suffer"); + } ret = m_model.FrameObj.AddByPoint(bhBar.StartNode.CustomData[AdapterIdName].ToString(), bhBar.EndNode.CustomData[AdapterIdName].ToString(), ref name); bhBar.CustomData[AdapterIdName] = name; @@ -109,12 +121,13 @@ private bool CreateObject(Bar bhBar) bool[] restraintEnd = null; double[] springEnd = null; - bhBar.Release.ToCSI(ref restraintStart, ref springStart, ref restraintEnd, ref springEnd); - - if (m_model.FrameObj.SetReleases(name, ref restraintStart, ref restraintEnd, ref springStart, ref springEnd) != 0) + if (bhBar.Release.ToCSI(ref restraintStart, ref springStart, ref restraintEnd, ref springEnd)) { - CreatePropertyWarning("Release", "Bar", name); - ret++; + if (m_model.FrameObj.SetReleases(name, ref restraintStart, ref restraintEnd, ref springStart, ref springEnd) != 0) + { + CreatePropertyWarning("Release", "Bar", name); + ret++; + } } } @@ -132,7 +145,7 @@ private bool CreateObject(Bar bhBar) } else if (bhBar.Offset != null) { - if (m_model.FrameObj.SetEndLengthOffset(name, false, -1 * (bhBar.Offset.Start.X), bhBar.Offset.End.X, 1) != 0) + if (m_model.FrameObj.SetEndLengthOffset(name, false, bhBar.Offset.Start.X, -1 * (bhBar.Offset.End.X), 1) != 0) { CreatePropertyWarning("Length offset", "Bar", name); ret++; @@ -144,6 +157,88 @@ private bool CreateObject(Bar bhBar) /***************************************************/ + [Description("Returns a bar where the endpoints have been flipped without cloning the object")] + private static void FlipEndPoints(Bar bar) + { + // Flip the endpoints + Node tempNode = bar.StartNode; + bar.StartNode = bar.EndNode; + bar.EndNode = tempNode; + + // Flip orientationAngle + bar.OrientationAngle = -bar.OrientationAngle; + if (bar.IsVertical()) + bar.OrientationAngle += Math.PI; + + // Flip Offsets + if (bar.Offset != null) + { + Vector tempV = bar.Offset.Start; + bar.Offset.Start = bar.Offset.End; + bar.Offset.End = tempV; + + bar.Offset.Start.X *= -1; + bar.Offset.End.X *= -1; + + if (!bar.IsVertical()) + { + bar.Offset.Start.Y *= -1; + bar.Offset.End.Y *= -1; + } + } + // mirror the section + // not possible to push to ETABS afterwards if we did + // warning for asymetric sections? + + // Flip Release + if (bar.Release != null) + { + Constraint6DOF tempC = bar.Release.StartRelease; + bar.Release.StartRelease = bar.Release.EndRelease; + bar.Release.EndRelease = tempC; + } + } + + /***************************************************/ + + private static void FlipInsertionPoint(Bar bar) + { + InsertionPoint fragment = bar.FindFragment(); + if (fragment != null) + { + BarInsertionPoint insertionPoint = fragment.BarInsertionPoint; + + switch (insertionPoint) + { + case BarInsertionPoint.BottomLeft: + fragment.BarInsertionPoint = BarInsertionPoint.BottomRight; + break; + case BarInsertionPoint.BottomRight: + fragment.BarInsertionPoint = BarInsertionPoint.BottomLeft; + break; + case BarInsertionPoint.MiddleLeft: + fragment.BarInsertionPoint = BarInsertionPoint.MiddleRight; + break; + case BarInsertionPoint.MiddleRight: + fragment.BarInsertionPoint = BarInsertionPoint.MiddleLeft; + break; + case BarInsertionPoint.TopLeft: + fragment.BarInsertionPoint = BarInsertionPoint.TopRight; + break; + case BarInsertionPoint.TopRight: + fragment.BarInsertionPoint = BarInsertionPoint.TopLeft; + break; + default: + break; + } + bar.Fragments.AddOrReplace(fragment); + } + } + + /***************************************************/ + /****** SectionProperty *******/ + /***************************************************/ + private bool CreateObject(ISectionProperty bhSection) { string propertyName = "None"; @@ -199,7 +294,12 @@ private void SetSection(ConcreteSection section) private void SetSection(ExplicitSection section) { - m_model.PropFrame.SetGeneral(section.Name, section.Material.Name, section.CentreZ * 2, section.CentreY * 2, section.Area, section.Asy, section.Asz, section.J, section.Iy, section.Iz, section.Wply, section.Wplz, section.Wely, section.Wely, section.Rgy, section.Rgz); + m_model.PropFrame.SetGeneral(section.Name, section.Material.Name, section.Vz + section.Vpz, section.Vy + section.Vpy, + section.Area, section.Asz, section.Asy, section.J, + section.Iz, section.Iy, // I22, I33 + section.Welz, section.Wely, // S22, S33 + section.Wplz, section.Wply, // Z22, Z33 + section.Rgz, section.Rgy); // R22, R33 } /***************************************************/ diff --git a/Etabs_Adapter/CRUD/Create/Load.cs b/Etabs_Adapter/CRUD/Create/Load.cs index c49dbbe0..d4c44ab5 100644 --- a/Etabs_Adapter/CRUD/Create/Load.cs +++ b/Etabs_Adapter/CRUD/Create/Load.cs @@ -166,7 +166,19 @@ public void SetLoad(BarUniformlyDistributedLoad barUniformLoad, bool replace) stepReplace = false; } - //moments ? does not exist in old toolkit either! + // Moment + for (int direction = 1; direction <= 3; direction++) + { + int ret = 1; + double val = direction == 1 ? barUniformLoad.Moment.X : direction == 2 ? barUniformLoad.Moment.Y : barUniformLoad.Moment.Z; //note: etabs acts different then stated in API documentstion + + if (val != 0) + { + ret = m_model.FrameObj.SetLoadDistributed(barName, caseName, 2, direction + 3, 0, 1, val, val, "Global", true, stepReplace); + } + + stepReplace = false; + } } } @@ -198,16 +210,27 @@ public void SetLoad(BarVaryingDistributedLoad barLoad, bool replace) foreach (Bar bar in barLoad.Objects.Elements) { + double val1, val2, dist1, dist2; + if (bar.CheckFlipBar()) { - double val1 = barLoad.ForceA.Z; //note: etabs acts different then stated in API documentstion - double val2 = barLoad.ForceB.Z; - double dist1 = barLoad.DistanceFromA; - double dist2 = bar.Length() - barLoad.DistanceFromB; - string caseName = barLoad.Loadcase.CustomData[AdapterIdName].ToString(); - string nodeName = bar.CustomData[AdapterIdName].ToString(); - int direction = 6; // we're doing this for Z axis only right now. - ret = m_model.FrameObj.SetLoadDistributed(bar.CustomData[AdapterIdName].ToString(), caseName, 1, direction, dist1, dist2, val1, val2, "Global", false, replace); + val1 = barLoad.ForceB.Z; //note: etabs acts different then stated in API documentstion + val2 = barLoad.ForceA.Z; + dist1 = barLoad.DistanceFromB; + dist2 = bar.Length() - barLoad.DistanceFromA; } + else + { + val1 = barLoad.ForceA.Z; //note: etabs acts different then stated in API documentstion + val2 = barLoad.ForceB.Z; + dist1 = barLoad.DistanceFromA; + dist2 = bar.Length() - barLoad.DistanceFromB; + } + + string caseName = barLoad.Loadcase.CustomData[AdapterIdName].ToString(); + string nodeName = bar.CustomData[AdapterIdName].ToString(); + int direction = 6; // we're doing this for Z axis only right now. + ret = m_model.FrameObj.SetLoadDistributed(bar.CustomData[AdapterIdName].ToString(), caseName, 1, direction, dist1, dist2, val1, val2, "Global", false, replace); + } }