Having nailed down the initial steps of creating a plugin, I set out to do some real functional work with the plugin. Being naive, I went off the deep end to begin programming the diaphragm slicer, but was quickly met by a sea of syntax and foreign looking code that was difficult to navigate. I had to go back to what all good programmers do, watching youtube videos.

The Code

The example plugin above will gather all of the load combinations in your ETABs project, populate them in a "datagrid view" and combobox and will report the joint reaction forces at a specific node under the selected load combination. I followed this youtube video, thank you Structure Detailing, the video was very informative and helpful!

The code to make this plugin has been upload on github.

New Syntax

From the video, the syntax of {get; set;} in a C# class appeared multiple times.

public class JointReaction
        public string Name { get; set; }
        public string LoadCase { get; set; }
        public double F1 { get; set; }
        public double F2 { get; set; }
        public double F3 { get; set; }
        public double M1 { get; set; }
        public double M2 { get; set; }
        public double M3 { get; set; }

This notation appears related to "encapsulation" in C# and allows this class to be both private (hidden from other classes and other parts of the program) and public. The JointReaction class is then instantiated in the main Form1.cs code.

           React.Name = Name;
           JReact.LoadCase = LoadCase[0];
           JReact.F1 = F1[0];
           JReact.F2 = F2[0];
           JReact.F3 = F3[0];
           JReact.M1 = M1[0];
           JReact.M2 = M2[0];
           JReact.M3 = M3[0];

Calling the .F1 attribute on the class JReact somehow triggers the {get; set;} notation. I have to dig into more C# to fully understand this {get; set;} notation.

ETABs API - Unclear Returns

API calls to ETABs are foreign to me, how can there be no explicit return?

Take for example the following code:

string Name = "";
            eItemTypeElm ItemTypeElm;
            int NumberResults = 1;
            string[] Obj = null;
            string[] Elm = null;
            string[] LoadCase = null;
            string[] StepType = null;
            double[] StepNum = null;
            double[] F1 = null;
            double[] F2 = null;
            double[] F3 = null;
            double[] M1 = null;
            double[] M2 = null;
            double[] M3 = null;
            int x = -1;
            //Method below acts on a string

            //unsure why eItemTypeElm.Element does not need to be initiated
            //anything that is ref is returned, not input
            x = _SapModel.Results.JointReact("4", eItemTypeElm.Element, ref NumberResults, ref Obj, ref Elm, ref LoadCase, ref StepType, ref StepNum, ref F1, ref F2, ref F3, ref M1, ref M2, ref M3);

The confusing part of this code is that the output of _SapModel.Results.Joint(...), x, is merely an integer, 1. I have no idea how this method writes/returns the values of the results to F1, F2, F3... Anytime I have written methods, I have direct return statement and it would typically be written directly to the output variable, x. If you know what the syntax might look like in C# to make this complicated output, please let me know, I would be interested in learning how to return multiple data types, lists, and values.

FYI, the code above will output the joint reaction forces for the unique node "4" in the ETABs model. These are the values that are populated in the initial video.

DataGridViews - A Ray of Hope for Programming

Data grid views have to be the best thing I have discovered in C#. Coming from python and the miserable experience that was PyQt5 to make a GUI, this is a miracle. The code to make tables is very clean and concise. If I never have to write PyQt5 code again, I will be happy. Side note, I have been meaning to make a post on PyQt5 GUIs with ETABs, another post for a later time. A sample of the mess that is PyQt5:

class TableModel(QtCore.QAbstractTableModel):
    def __init__(self, data):
        super(TableModel, self).__init__()
        self._data = data
        self._headers = ['Frame Size', 'Cnx Type', 'Demand (kip)', 'Capacity (kip)', 'ETABs Frame #']

   def data(self, index, role):
        if role == QtCore.Qt.DisplayRole:
            # See below for the nested-list data structure.
            # .row() indexes into the outer list,
            # .column() indexes into the sub-list
            return self._data[index.row()][index.column()]
        if self._data[index.row()][index.column()] == 'SS/DS cnx NG' and role == QtCore.Qt.BackgroundRole :
            return QBrush(Qt.red)
        if self._data[index.row()][index.column()] == 'No Values' and role == QtCore.Qt.BackgroundRole :
            return QtGui.QColor('#FFA500')
        if self._data[index.row()][index.column()] == 'DS cnx Ok' and role == QtCore.Qt.BackgroundRole :
            return QBrush(Qt.yellow)
    def rowCount(self, index):
        # The length of the outer list.
        return len(self._data)

Now that I have learned the basics of the plugin and the ETABs API, I think I should be able to struggle through my first bit of custom coding.

ETABs C Sharp

Our Sidebar

You can put any information here you'd like.

  • Latest Comments
  • retug on Diaphragm Slicer New and Improved -

    Hi Trenno, I just uploaded a new .dll file to github that has metric units included. Give it a whirl, let me know if you have any trouble on the install. I think it should be as easy as downloading the .dll file and adding the file path to the 

  • Trenno on Diaphragm Slicer New and Improved -

    How's the Metric version coming along? Keen to check it the tool. 

    Could you set it up so that the model is run within the initial steps of routine of the plugin? 

  • retug on Project Management with Deltek -

    Hi Tushar, I've used Seaborn as well, it's a good package. 

    I use Matplotlib for quick and dirty plotting, you just can't beat the amount of documentation and examples you can find out there for it.