A long time coming... a professional level plugin for ETABs, or at least a whole lot better than the python diaphragm slicer.

User Input



This plugin will allow you to slice up your diaphragm in any direction you want, allowing you to see shear and moment along the length of the areas.

User Input

Start Point

This is the point at which you want to start the slicing. Only select an individual point, or the program will show you an error message


Select any number of objects, ensure all selected area objects share the same Z coordinate.

Input Vector

For slicing in the X direction, input X = 1, Y =0, ensure you input a positive integer. Input field will be limited to numbers and at this moment does allow for negative numbers.

Select Load Case

Pressing the Gather Cases button will retrieve all of the load cases in your current project, be sure to select one from the drop down box, this will be the outputted results from the section cut analysis

Number of Section

Input an integer between 2 and 1000, this will be the number of points that populate shear and moment diagrams

After all of these items are input, click on the run analysis button to view the results.

Reviewing the Results

3 Plots will generate after the program has run, shear (kips), moment (kip*ft), and a plot that shows how the program generated the cuts of your diaphragm for QA of your input.

The plots are all hoverable, allowing you to zoom and review results. In addition, a tabular data table is populated with location (ft), shear and moment being available to be copied and pasted in your favorite spreadsheet.

I have posted the code up on github. I hope to get this addin up on CSI's website in the future. If you have done this before, drop a comment below on how to do this. 

If you want to take this for test run, let me know below. I have yet to try this out in full production, I am sure there are bugs that need to be worked out.

The Coding

Now that the rough documentation is complete, let's dig into the fun stuff.

First thing that strikes me is that python is still freaking awesome! I was able to do this work in python in 233 lines of code and 1 file. This C# addin weighs in at around 1200 lines and 12 files. That's crazy in my opinion! Python is great for whipping up quick ideas.

Where is the variable explorer in Visual Studio Code?!?

Why in the world is there not a built in variable explorer in visual studio code similar to spyder for python. I never realized how great the variable explorer was until you were reviewing many many lines of nested list/array data. I found myself watching a lot of variables in visual studio code, super slow and tedious.

It looks like there might be a way to view large lists of data in visual studio code with a separate addin, but I did not dig into this in depth.


I ran into some trouble with the API when trying to make section cuts with the database tables methods. I had code that worked in ETABs v19, the OG diaphragm slicer, but the code python code would not work in v20 and the C# code I was trying to write would not work in v20 either. Turns out, the database tables headers between v20 and v19 were updated and no longer matched the visual column headers in the section cut tables. After some painful debugging we got this fixed. You can read more about my struggles here.

Matrices in C#

I use matrices in this program to convert back and forth from global coordinates to local coordinates and needed a matrix program if it was available. After some googling, it looked like mathnet.numerics was the most popular matrix package in C#, even above a c# clone of numpy it appears (package used in python to do matrix math). The mathnet package works, but is a bit clunky and I found the documentation hard to read and understand. Eventually, I was able to create a matrix and invert a matrix. Another odd one, it did not support matrix multiplication, I had to do that by hand!

Some of the weird syntax:

 public class GlobalCoordinateSystem
        public List<double> RefPnt { get; set; }
        public List<double> Vector { get; set; }
        public double hyp { get; set; }
        public double[,] R { get; set; }
        public string inverseMatrixText { get; set; }
        public Matrix<double> R_Matrix { get; set; }
        public double[,] R_Inv { get; set; }
        //This is the constructor, redefine the point?
        public GlobalCoordinateSystem(List<double> xyz, List<double> vector)
            RefPnt = xyz;
            hyp = Math.Sqrt((vector[0] * vector[0] + vector[1] * vector[1]));
            Vector = vector;
            R = new double[,] { { vector[0] / hyp, -vector[1] / hyp, 0 }, { vector[1] / hyp, vector[0] / hyp, 0 }, { 0, 0, 1 } };
            R_Matrix = Matrix<double>.Build.DenseOfArray(R);
            R_Inv = R_Matrix.Inverse().ToArray();

        public void glo_to_loc(GlobalCoordinateSystem globalCoords)
            double[] part1 = new double[] { X - globalCoords.RefPnt[0], Y - globalCoords.RefPnt[1], Z - globalCoords.RefPnt[2] };

            //the class will now have new attribute of local coordinates point.LocalCoords[0] = the X local coordinate system
            LocalCoords = new List<double>() { globalCoords.R_Inv[0, 0] * part1[0] + globalCoords.R_Inv[0, 1] * part1[1] + globalCoords.R_Inv[0, 2] * part1[2] ,
            globalCoords.R_Inv[1, 0] * part1[0] + globalCoords.R_Inv[1, 1] * part1[1] + globalCoords.R_Inv[1, 2] * part1[2],
            globalCoords.R_Inv[2, 0] * part1[0] + globalCoords.R_Inv[2, 1] * part1[1] + globalCoords.R_Inv[2, 2] * part1[2]};
        public void loc_to_glo(GlobalCoordinateSystem globalCoords)
            //this is the ref point
            double[] part1 = new double[] { X, Y, Z };

            //the class will now have new attribute of local coordinates point.LocalCoords[0] = the X local coordinate system
            GlobalCoords = new List<double>() { (globalCoords.R[0, 0] * X + globalCoords.R[0, 1] * Y + globalCoords.R[0, 2] * Z) + globalCoords.RefPnt[0],
            (globalCoords.R[1, 0] * X + globalCoords.R[1, 1] * Y + globalCoords.R[1, 2] * Z) + globalCoords.RefPnt[1],
            (globalCoords.R[2, 0] * X + globalCoords.R[2, 1] * Y + globalCoords.R[2, 2] * Z) + 0}; //unsure why this the way to do this. review in the future. should be the line below, without the 0
            //(globalCoords.R[2, 0] * X + globalCoords.R[2, 1] * Y + globalCoords.R[2, 2] * Z) + globalCoords.RefPnt[2]};

Another point, I need to review why my Z coordinate kept messing up in this process.

C# Plotting

I settled on a plotting package called live charts in C#. This package seemed to be the go-to package back in 2018, but it seems like maybe it has stopped being supported by its developers. Again, documentation was kinda hard to find and when it was able to found, it was hard to understand. More struggling and pain to get to the pretty graphs. I do like the graphs are live, zoomable and interactive. The out-of-the-box microsoft graphs had much less of the interactiveability built into them.

UI Development

I went through a few differing versions of UIs and finally called it good enough where it was. My favorite color is orange, so I wanted to through some orange in the plots, hopefully the plots are not too painful on the eyes.

I also set up a linear gradient brush on the background because why not, it seems like most modern UI's are using color gradients.

A few snips of UI in development

A bit too generic, looks like every other windows form

A bit too much orange

Just right, enough flair to know this guy knows what he's doing, but not too visually distracting:

Eventually I want to get back into this and make rounded buttons and pretty up the tabular data, but I wanted to be done with this project and called it quits at good enough.

Coding for the UI was actually pretty enjoyable in C#, there are a lot of good videos out there on how to make your form look good.

This bit of code makes the linear gradient in the background:

private void Form1_Paint(object send, PaintEventArgs e)
            Graphics mgraphics = e.Graphics;
            Pen pen = new Pen(Color.FromArgb(255, 140, 105), 1);
            Rectangle area = new Rectangle(0, 0, this.Width - 1, this.Height - 1);

            System.Drawing.Drawing2D.LinearGradientBrush lGB2 = new System.Drawing.Drawing2D.LinearGradientBrush(area, Color.FromArgb(255, 255, 255), Color.FromArgb(159, 159, 159), LinearGradientMode.Vertical);
            mgraphics.FillRectangle(lGB2, area);
            mgraphics.DrawRectangle(pen, area);

Please take this for a spin and let me know if you have any feedback!

EDIT 04/19/2023:

The section cut tool is only correct slices in the left right direction! (loading in the X global direction typically) I discovered this after using this on a real project. 

From ETABs documentation:

How is the plane of the section cut defined when drawn in a 3D view?
Expanded Question: When a section cut is drawn in a 3D view, only the X and Y coordinates are provided. How is the section-cut plane defined?

Answer: When using the Draw > Draw Section Cut command, forces are reported in the section-cut coordinate system which is defined by three axes (1,2,Z) as follows:

Section-cut 1 axis is located within the plane parallel to the global X-Y plane, and rotates counterclockwise from the global X axis according to the user-defined parameter Angle (X to 1).
Section-cut 2 axis is also located within the plane parallel to the global X-Y plane, though it is oriented 90° counterclockwise from the section-cut 1 axis.
Section-cut Z axis is parallel to the global Z axis.

I will need to update the code to pull right combination of either F1 or F2. This should not be too difficult to do.

ETABs Diaphragm Design C Sharp

at least for python, jupyter notebooks (extension in VS CODE) does show you variable values 

Awesome work S&T!

Firstly, I'd recommend if you're going to feature the tool on CSI's website then maybe incorporate metric units (aka real units!) 

Secondly, I'm wondering if there would be a way to set up the workflow using something akin to RAM Concept design strips. Perhaps the strip width would have to be manually input but at least your slicer could take sections at given internals along a predefined vector (maybe it's a null frame or simply a vector between two joints?) 

What we really need is CSI to incorporate some of this stuff into the base program. Just pier labels horizontally...

Thanks Trenno.

I will work to get metric units incorporated, that's a great idea.

On your second point, I think something like that could be done, it's just a bit awkward with how CSI currently has it setup. In order to make section cuts, I need to unlock the model, apply all of the generated section cuts and then re-run the model. I would think that this could all be done with some post processing and it would eliminate the clunkiness of unlocking the model and rerunning the analysis.

As always, appreciate the feedback!

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? 

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 GetSelectedObjects.dll location in your etabs addin page.

I hope to work on it this weekend as well for a few other quality of life updates.

Our Sidebar

You can put any information here you'd like.

  • Latest Comments
  • Liz_Larsen on R2R - Update V1.1.0 -

    Great job! We've been wanting a tool like this for so long that I'd considered making it myself. During my research, I stumbled across this blog right around the time you were looking for testers a few months ago. 

    I'll be sure to spread the word about this amazing tool. Thanks …

  • retug on ETABs API - More Examples (Database Tables) -

    Hi rajavardhan, are you not able to delete selected frames and walls based on section properties through the ETABs program itself? Or through the API? I could put together a few quick examples for you with the API if needed.

  • rajavardhan on ETABs API - More Examples (Database Tables) -

    Hi, I am not able to select frames and walls based on section properties in etabs v21 and then delete selected frames and walls..can anyone suggest me the code to do it use Excel VBA code