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);
+
}
}