JWock82 / Pynite

A 3D structural engineering finite element library for Python.
MIT License
454 stars 93 forks source link

Visualize Local Coordinate Systems on Members in Finite Element Model Visualization #190

Open Jeroen124 opened 6 months ago

Jeroen124 commented 6 months ago

Currently, I am working with standards that have predefined coordinate systems with the Y-axis pointing upwards. This specific orientation is critical for our analyses and understanding of structural behavior according to these standards. However, our current visualization tool lacks the functionality to explicitly display local coordinate systems for each member according to this convention. This limitation makes it challenging to ensure that all members are correctly oriented as per the standards, potentially leading to errors in analysis or interpretation.

I know we should follow the pynite conventions for local coordinate systems: https://pynite.readthedocs.io/en/latest/member.html

I propose the addition of a feature that allows for the visualization of local coordinate systems for each member within the finite element model. This feature would visually represent the local X, Y, and Z axes at an appropriate point (such as the midpoint), with distinct colors for each axis (e.g., red for X, green for Y, blue for Z) to clearly indicate directionality. There should be options to customize the length of these axes for clear visibility without overwhelming the model's appearance, and the ability to toggle this display feature on or off as needed by the user.

maybe we can update the renderer?

renderer.show_local_coordinate = true

Small code idea to kickstart the feature:

def plot_member_coordinate_system(self, member):
    # Midpoint calculation and axis direction determination is done here
    midpoint = [(member.i_node.X + member.j_node.X) / 2,
                (member.i_node.Y + member.j_node.Y) / 2,
                (member.i_node.Z + member.j_node.Z) / 2]

    # Directions for local axes 
    local_x_direction = [member.j_node.X - member.i_node.X,
                         member.j_node.Y - member.i_node.Y,
                         member.j_node.Z - member.i_node.Z]

    local_z_direction = [0, 0, 1]  # Always horizontal

    # Calculate local_y_direction using cross product of x and z directions
    local_y_direction = [
        local_x_direction[1] * local_z_direction[2] - local_x_direction[2] * local_z_direction[1],
        local_x_direction[2] * local_z_direction[0] - local_x_direction[0] * local_z_direction[2],
        local_x_direction[0] * local_z_direction[1] - local_x_direction[1] * local_z_direction[0]
    ]

    # Size of coordinate system
    axis_length = 1  

A quick example of what it could look like: image

Jeroen124 commented 6 months ago

Maybe also add a function to rotate a member 90 degrees? Right hand rule around x-axis

JWock82 commented 6 months ago

These are great ideas. I'd like to get them implemented. For the past few weeks I've been in the process of migrating the visualization code from VTK to pyvista (which is still VTK based) in an effort to simplify the visualization code. VTK by itself is a very difficult API to deal with. It's made improvements to visualization slow to implement. Pyvista will greatly simplify Pynite's visualization code base. Once I've finished migrating the code over, I'll be ready to start looking into more ways to improve visualization.

angelmusonda commented 6 months ago

For the time being, I believe PyNite already provides a way of rotating a member around its longitudinal (x) axis. Thei_node and the aux_node are used to define the direction of the member's z-axis. Hence, a member can be rotated by correctly specifying an auxiliary node. And since the auxiliary node can be visualised, then one can roughly visualise the orientation of the member, i.e the x and z axes.