An introduction to the model module

On this page :


Q. How do I begin?

A . Getting the information that you want from the model module requires that you choose the right path to that information. To begin defining that path, you need to declare a member object.

To declare a member object, you can use the member() function, which can take a member number as its argument. In the following example, the member number 32 is used. The Python Prompt can be launched from your toolbar in Modeling , if you have placed its icon on your toolbar using Toolbar Configuration .

SDS2 Python Prompt
>>> import model
>>> m = model.member(32)
>>> m
<member 32>

Declaring a member object in a Python script (a parametric ) works in much the same way. The example scripts in the final section show you how you can do so using the model module's member() function together with the member module's MemberLocate() function.

Once you've declared a member object, there are various paths that you can use to get information about that member's ends, its framing condition, its input and designed connections, and its materials, holes and bolts. Here are some of these paths:

Paths for members, member ends and framing conditions:
m = model.member(mem_num)
m.xxx, where xxx is an attribute from the member_index or custom_properties
m.Ends[0].xxx, where xxx is an attribute from index_end or member_end
m.Ends[1].xxx (same as above)
m.Ends[0].FramingCondition[0].xxx, where xxx is an attribute from frame_cond
m.Ends[1].FramingCondition[0].xxx (same as above)

If you already understand these paths, you can probably go directly to the documentation on the model module. If you don't understand the above-listed paths, go ahead and look at the model module anyway, then come back to this page and read the questions and answers. After you are done, you will have a better understanding of what these paths can do.


Q. Does the model module have any useful functions or methods?

A . Not very many. In the previous section, I mentioned the member() function. In the next section, I will show you the selected_member() function.

Another function that you might find useful is members() , which by default, if you do not enter an argument, returns a list [ ] of all members in your current Job.

model.members(arg)
arg = 0 returns a list of all members in your current Job
arg = 1 returns a list of all members in your current view
arg = 2 returns a list of all selected members
arg = 3 returns a list of all selected member ends
arg = 4 returns a list of all members locked by this process

When the model module became writable, no longer read-only, a variety of new functions were added to the module:

LocateSingle()       LocateMultiple()      GetSelection()
set_ssize_maker()    set_piecemark_maker()
ChangeOneMaterial()
LockOnlyThis()   LockConnectedMembers()   Unlock()    Reload()
WriteOnlyThis()     WriteGraphical()
ParametricIndexToName()
EraseMember()
GetWeightAndCenterOfMass()
Select()       Deselect()     IsMember()      IsEnd()     IsMaterial()
IsHole()     IsBolt()     IsWeld()
DoPolygonsIntersect()    HasPolygons()    ConnectionFailError()
MaterialOnMembers()   BoltsOnMembers()    WeldsOnMembers()
IntersectsAnyItem()    IntersectingItems()


Q. How do I query the attributes of a member?

A . In Modeling , with a member selected, type the following at the Python Prompt . To produce the examples shown on this page, the selected member was a beam connected to a column flange with bolted-bolted clip angles.

SDS2 Python Prompt
>>> import model
>>> m = model.selected_member()
>>> m
<member 32>
>>> dir(m)

The results you get from the dir() query will depend on the member that you have selected and the version of SDS2 program you are running. Here are the results that I got:

SDS2 Python Prompt
>>> dir(m)
['_as_tuple', 'a_max_unbrcd', 'analysis', 'approval_status', 'asn_hash', 'asn_pcmk', 'auto_stitch_number', 'auto_stitch_space', 'automatic_double_brace_gap', 'automatic_erection_pinhole', 'bolt_cnt', 'bolts', 'bound_blf', 'bound_trb', 'br_alt_end', 'br_bolt_stag', 'br_neutral_axis', 'br_one_gage', 'brace_draw', 'camber', 'category', 'composite', 'compression_check', 'create_3d', 'custom_properties', 'dbl_angle', 'deck_direction', 'detail_complete', 'down_loaded', 'dtl_length', 'ead_fail', 'ead_group', 'ead_mem_typ', 'ead_struct_num', 'econ_idx', 'ends', 'erected', 'erected_date', 'erection_pinhole', 'estimate', 'existing', 'exploded', 'exploded_loc', 'fabricated', 'fabrication_approved', 'fabrication_complete', 'fabrication_projected', 'force_pcmk', 'frame_from_all', 'galvanizing', 'graphic_altered', 'group_num', 'guid_analysis', 'guid_design', 'guid_manufacturing', 'has_camber', 'has_user_def_conn', 'held_date', 'held_desc', 'idx_mtrl', 'idx_pcmk', 'jst_base_len', 'jst_clr_span', 'jst_overall', 'last_quant', 'last_rev_level', 'last_revised', 'linked_mem', 'llv', 'material_count', 'materials', 'max_unbrcd_len', 'mem_desc', 'mem_link', 'mem_slope', 'mem_stat', 'member_hold', 'member_type', 'min_guss_thick', 'misc_type', 'model_complete', 'mt_origin', 'mtrl_bend_angle', 'mtrl_bend_rad', 'mtrl_camber', 'mtrl_cnt', 'mtrl_grade', 'mtrl_rolled_offset', 'mtrl_twist', 'needs_detail', 'node_num', 'node_stat', 'nom_dpth_idx', 'num_studs', 'number', 'offset', 'on_sheet', 'param_cnt', 'param_idx', 'pcmk_frozen', 'piecemark', 'piecemark_refcount', 'plane_rot', 'plot', 'quantity', 'received_approval', 'received_at_site', 'ref_xform', 'rev_level', 'revised', 'roll_type', 'rotation', 'route1', 'route2', 'route3', 'route4', 'sect_modulus', 'section_size', 'sent_for_approval', 'seq_num', 'ship_complete', 'ship_projected', 'shipped', 'slab_spacing', 'stitch_pl_spa', 'stress_inc', 'stud_dia', 'swap_ends', 'system_piecemark', 'toeio', 'unique_id', 'user_site', 'usr_def_k', 'usr_min_gus', 'weld_cnt', 'welds', 'wkpt_level', 'wkpt_slope', 'wkpt_stbk_chg', 'wl_offset', 'zone']

The results shown above are packed in a Python list [ ]. That is, the information is enclosed in brackets [ ] and the items within the brackets are separated by commas. You can unpack the first item in a list by using list_name[0 ], the second item by using list_name[1] , and so on. In the following example, list_name is dir(m). The same unpacking technique can also be applied to a tuple ( ).

SDS2 Python Prompt
>>> dir(m)[0]
'_as_tuple'
>>> dir(m)[1]
'a_max_unbrcd'
>>> dir(m)[2]
'analysis'

To see the value assigned to a particular attribute, you can do the following. For this example, the attribute member_type tells me the type of the member, the attribute composite tells me that the beam is not a composite beam, and the attribute section_size tells me the member's section size.

SDS2 Python Prompt
>>> m.member_type
model.Beam
>>> m.composite
False
>>> m.section_size
'W18x40'

Here's a way, using the built-in Python function get_attr() , to return the values assigned to each of the attributes of the member m . I've added comments (preceded by the # symbol) to help you better cross reference the attribute names associated with the returned value. Only the first four of the 141 returned values are shown here.

SDS2 Python Prompt
>>> for attr in dir(m):
. . .       getattr(m, attr)
. . .
(32, -1, -1, -1, -1, -1)    # _as_tuple
False      # a_max_unbrcd
True       # analysis
model.NotSubmitted    # approval_status

Of course, the comments shown above are bogus -- I just "typed them in" -- they weren't returned at the actual Python Prompt . In the example that follows, I actually instruct the Python Prompt to return the attribute-value pair, wrapped up in a tuple (attribute name, attribute value). Don't be confused by my changing the variable attr in the previous example to a in this example. I made that change just to show you that I could, and to demonstrate that attr is nothing more than a variable. In the example below, only the first four of the returned tuples are shown; when I did this in real life, 141 tuples were returned.

SDS2 Python Prompt
>>> for a in dir(m):
. . .       a, getattr(m, a)
. . .
('_as_tuple', (32, -1, -1, -1, -1, -1))
('a_max_unbrcd', False)
('analysis', True)
('approval_status', model.NotSubmitted)

Q. Why are there two forms of model module attributes?

A . Originally, there was only the base form of model module attributes, which is returned when you use built-in Python functions such as dir(), as described in the previous sections. At a later date, aliases of these base form attributes were added. These aliases were written in CamelCase form to match equivalent fields in the Report Writer database . Both forms are listed in the model module documentation. This means that member_type and Type are functionally the same, as are composite and Composite , and section_size and SectionSize .

SDS2 Python Prompt
>>> m                 # defined here or here
<member 32>
>>> m.member_type
model.Beam
>>> m.Type
model.Beam
>>> m.composite
False
>>> m.Composite
False
>>> m.section_size
'W18x40'
>>> m.SectionSize
'W18x40'

Good news: The attributes in the Advanced Selection dictionary are a subset of the attributes in the model module. You may, at times, find it easier to use the Advanced Selection dictionary since it is organized based on Modeling 's GUI interface. That is, attributes are categorized and arranged based on the location of corresponding fields on windows in Modeling . For example, refer to the dictionary's documentation for Type , Composite , and SectionSize . Another advantage of the Advanced Selection dictionary is that it has more examples, although those examples are tailored to Advanced Selecion , rather than to the writing of parametrics . Conversely, users of Advanced Selection may, at times, find it advantageous to consult the model module documentation since it lists the complete list of attributes.


Q. How do I query member end information?

A . Note, from the following example, that m.Ends returns a list [ ] of the two member end objects, where the left end ( m.Ends[0] ) is listed first and the right end ( m.Ends[1] ) is listed second. You can use dir(m.Ends[0]) to query a member's left-end attributes, dir(m.Ends[1]) to query a member's right-end attributes.

SDS2 Python Prompt
>>> m                 # defined here or here
<member 32>
>>> m.Ends
[<left end of member 32>, <right end of member 32>]
>>> m.Ends[0]
<left end of member 32>
>>> m.Ends[1]
<right end of member 32>
>>> dir(m.Ends[0])
['_as_tuple', 'a_compress', 'a_conn_grd_input', 'a_minus_dim', 'a_moment', 'a_mtrl_stbk', 'a_redistrib_vb', 'a_shear', 'a_tension', 'below_min', 'bolt_grade', 'bolt_jst_end', 'bolt_type', 'btm_op_dim1', 'btm_op_dim2', 'btm_op_dim3', 'btm_op_dim4', 'btm_op_dim5', 'btm_op_dim6', 'btm_op_dim7', 'btm_op_dim8', 'btm_op_type', 'comp_load', 'cond', 'conn', 'conn_fail', 'conn_fail_num_err', 'conn_grd_angle', 'conn_grd_channel', 'conn_grd_input', 'conn_grd_pl', 'conn_grd_roll', 'conn_grd_wtee', 'conn_stbk', 'conn_stbk_flg', 'conn_user', 'custom_properties', 'design_changed', 'design_mthd', 'designed', 'di_angle', 'dist_support', 'dsgn_user_def', 'dsgn_web_dbl', 'end_prep', 'epl_ext_dimension', 'ext_epl_to_flgs', 'field_clear', 'field_clear_flag', 'flg_end_cut', 'force_conn', 'framing_sit', 'graphical_conn', 'hbrace_weld', 'input', 'joist_ext_btm', 'joist_ext_top', 'loc_x_', 'loc_y_', 'loc_z_', 'location', 'locked_end', 'max_comp', 'max_moment', 'max_shear', 'max_tension', 'member_grew', 'min_conn', 'minus_dim', 'mom_bolt_dia', 'mom_bolt_type', 'moment', 'mtrl_stbk', 'needs_node', 'needs_snode', 'nm_bolt_dia', 'node_opp', 'nodes', 'non_aisc_conn', 'non_eq_gus_thick', 'non_sqr_cut', 'non_std_bolt', 'ofs_wkpt_canted', 'priority_priorities', 'process', 'proj_rot', 'redistrib_vb', 'rot', 'rotation', 's_seat_loc', 's_seat_reqd', 'seismic_guss_conn', 'shear_load', 'shear_min', 'special_disp', 'spt_thickness', 'sq_cut', 'std_dtl', 'std_dtl_type', 'story_shear', 'supported', 'supporting', 'tension_load', 'top_chord_ext', 'top_op_dim1', 'top_op_dim2', 'top_op_dim3', 'top_op_dim4', 'top_op_dim5', 'top_op_dim6', 'top_op_dim7', 'top_op_dim8', 'top_op_type', 'use_mod_mb', 'user_mom_bolt_dia', 'user_mom_bolt_type', 'user_nm_bolt_dia', 'user_nm_bolt_type', 'web_dblr_pl', 'web_end_cut', 'wkpt_setbk']

As you can see, a member's end also has a great number of attributes. Since m is a beam, lets check out the attributes a_shear ( AutoShearLoad ) and max_shear ( MaxShearWithoutFailing ).

SDS2 Python Prompt
>>> m.Ends[0].a_shear
True
>>> m.Ends[0].max_shear
55.3000000

Of course, if you try this in your own model, you may get different values than those that are shown here, since the member that you select will likely have different properties than the beam that I selected . To verify that the results you get are what they should be, you can open that beam's edit window .

Member end attributes in the Advanced Selection dictionary can found in the sections for Left/Right End , Connection type , Connection specifications , Setbacks , Moment , Loads , End preparations and Framing Condition .

Member end attributes in the model module documentation can be found in the index_end , member_end , frame_cond , auto_plate , clip_angle , column_plate , conn_info , end_plate , horiz_brace , seated_type , shear_type , splice_plate and vert_brace sections.


Q. How do I query member framing condition information?

A . You can use dir(m.Ends[0].FramingCondition[0]) to query a member's left end framing condition attributes, dir(m.Ends[1].FramingCondition[0]) to query a member's right end framing condition attributes.

SDS2 Python Prompt
>>> m                 # defined here or here
<member 32>
>>> m.Ends[0].FramingCondition
(<framing condition 0 of left end of member 32>, None, None, None)
>>> m.Ends[0].FramingCondition[0]
<framing condition 0 of left end of member 32>
>>> dir(m.ends[0].FramingCondition[0])
['_as_tuple', 'conn_disp', 'custom_properties', 'from_matt', 'from_memt', 'ignore_node', 'offset', 'perp', 'splice', 'to_matt', 'to_memt', 'web']

Now I try to_memt ( MemberTypeFramingTo ) and to_matt ( MaterialTypeFramingTo ). To save a little typing time, I use cond instead of FramingCondition .

SDS2 Python Prompt
>>> m.ends[0].cond[0]).to_memt
model.Column
>>> m.ends[0].cond[0]).to_matt
model.WideFlange

Recall from our earlier discussion that [0] is used to unpack the first item in a list [ ]. The same applies to a tuple ( ). Do not use m.Ends[1].FramingCondition[1] to return the right end framing condition; use m.Ends[1].FramingCondition[0] . This is because the member end framing condition object is the first item in the tuple that is returned for m.Ends[1].FramingCondition . In the following example, m.Ends[1].FramingCondition[1] returns nothing since None is the second item in the tuple.

SDS2 Python Prompt

>>> m.Ends[1].FramingCondition
(<framing condition 0 of right end of member 32>, None, None, None)
>>> m.Ends[1].FramingCondition[1]
>>>
>>> m.Ends[1].FramingCondition[0]
<framing condition 0 of right end of member 32>

Framing condition attributes in the Advanced Selection dictionary can be found in the Framing Condition section.

Framing condition attributes in the model module documentation can be found in the frame_cond section.


Q. How can I find information about a member's materials?

A . You can begin by discovering the numbers of the materials that the member, m , is composed of.

SDS2 Python Prompt
>>> m                 # defined here or here
<member 32>
>>> m.MemberNumber
32
>>> m.materials
[<material 0 of member 32>, <material 1 of member 32>, <material 2 of member 32>, <material 3 of member 32>, <material 4 of member 32>]

In the above example, m.materials returns a list [ ] of five member material objects. The first member material object that is reported, which is indexted as material 0 , is the beam's main material. The other four materials, materials 1 , 2 , 3 and 4 , are clip angles. I'm going to find out some information about the member main material using the attributes MainMaterial and MaterialGrade and MinorMark and ConnectionMaterial and MaterialType .

SDS2 Python Prompt
>>> m.materials[0].MainMaterial
True
>>> m.materials[0].MaterialGrade
'A992'
>>> m.materials[0].MinorMark
'B_96'
>>> m.materials[0].ConnectionMaterial
False
>>> m.materials[0].MaterialType
model.WideFlange

I'm getting tired of writing m.materials all the time. So, to test m.materials[1] , which I know is a clip angle, I'm going to assign mt as a variable.

SDS2 Python Prompt
>>> m
<member 32>
>>> mt = m.materials[1]
>>> mt
<material 1 of member 32>
>>> mt.MainMaterial
False
>>> mt.MaterialGrade
'A36'
>>> mt.MinorMark
'a92'
>>> mt.ConnectionMaterial
True
>>> mt.MaterialType
model.Angle

Member material attributes in the Advanced Selection dictionary can be found in the Standard Part and General Information sections. Material attributes that are particular to specific material types can be found in the Rolled Section , Rectangular Plate , Round Plate , Bent Plate , Rolled Plate , Flat Plate Layout , Bent Plate Layout , Round Bar , Square Bar , Flat Bar , Grating , Grating Tread , Decking , Shear Stud and Clevis sections in the Advanced Selection dictionary. Also, two of the attributes discussed in the next section -- HoleGroupCount and HoleCount -- are, in actuality, general material properties.

Member material attributes in the model module documentation can be found in the material_info , sub_mtrl , custom_properties , clevis_info , deck_info , grate_info , grate_tread and shear_stud sections.


Q. How can I find information about a material's holes?

A . For this demonstration, I am using the variable mt , which was assigned to m.materials[1] in the previous example (directly above). I begin by looking at some material properties, rather than individual hole properties. The clip angle is a bolted-bolted clip angle, so it is expected that it will have a HoleGroupCount of 2 groups, one group for shop bolting the clip angle to the supported beam, a second group for field bolting it to the supporting column. The clip angle has a HoleCount of 6 holes, three holes in each hole group.

SDS2 Python Prompt
>>> m                 # defined here or here
<member 32>
>>> mt
<material 1 of member 32>
>>> mt.HoleGroupCount
2
>>> mt.HoleCount
6

You can also find out information about individual holes, each of which has its own number. In this example, I find out whether hole 0 was SystemGenerated , its Diameter , and its Type . Note that mt.Hole and mt.holes are equivalent expressions.

SDS2 Python Prompt
>>> mt.Hole
[<hole 0 on material 1 of member 32>, <hole 1 on material 1 of member 32>, <hole 0 on material 1 of member 32>, <hole 0 on material 1 of member 32>, <hole 0 on material 1 of member 32>]
>>> mt.holes
[<hole 0 on material 1 of member 32>, <hole 1 on material 1 of member 32>, <hole 0 on material 1 of member 32>, <hole 0 on material 1 of member 32>, <hole 0 on material 1 of member 32>]
>>> mt.Hole[0].SystemGenerated
True
>>> mt.Hole[0].Diameter
0.8125
>>> mt.Hole[0].Type
0

A hole Type of 0 is a standard round hole.

Member material hole attributes in the Advanced Selection dictionary can be found in the Holes section.

Member material hole attributes in the model module documentation can be found in the hole_data section.


Q. How can I find information about a member's bolts?

A . Most bolt properties are attributes of member bolt objects, but in this next example I look at the BoltCount , which is a member object attribute, and which returns a count of the shop bolts and field bolts that belong to the member, m . Note that the count matches the number of bolts that are enumerated in the list that is returned when I type m.Bolt or the equivalent expression m.bolts .

SDS2 Python Prompt
>>> m                 # defined here or here
<member 32>
>>> m.BoltCount
21
>>> m.Bolt
[<bolt 0 of member 32>, <bolt 1 of member 32>, <bolt 2 of member 32>, <bolt 3 of member 32>, <bolt 4 of member 32>, <bolt 5 of member 32>, <bolt 6 of member 32>, <bolt 7 of member 32>, <bolt 8 of member 32>, <bolt 9 of member 32>, <bolt 10 of member 32>, <bolt 11 of member 32>, <bolt 12 of member 32>, <bolt 13 of member 32>, <bolt 14 of member 32>, <bolt 15 of member 32>, <bolt 16 of member 32>, <bolt 17 of member 32>, <bolt 18 of member 32>, <bolt 19 of member 32>, <bolt 20 of member 32>]
>>> len(m.Bolt)
21

Now I am going to find out the values assigned for particular attributes of bolt number 0 of the member m . The attributes I am interested in are IsFieldBolt , Diameter and BoltTypeDescription .

SDS2 Python Prompt
>>> m.Bolt[0].IsFieldBolt
False
>>> m.Bolt[0].Diameter
0.75
>>> m.Bolt[0].BoltTypeDescription
'A325N'

Member bolt attributes in the Advanced Selection dictionary can be found in the Bolts section.

Member bolt attributes in the model module documentation can be found in the mem_bolt section.


Q. How do I find information about a member's end connection?

A . A member has two end connection, one on its left end ( Ends[0] ), the other on its right end ( Ends[1] ). Also, the connection that connection design creates (the m.Ends[0].Designed connection) may, in some respects, be different than the connection that the user specified on the member edit window (the m.Ends[0].Input connection). To ensure that the input connection and the designed connection are as close as possible, you need to Process and Create Solids after having changed the input settings.

I want to know the connection type ( TypeDescription ) of the Input connection and the Designed connection on the left end ( Ends[0] ) of the member, m .

SDS2 Python Prompt
>>> m                 # defined here or here
<member 32>
>>> m.Ends[0].Input
<input connection of left end of member 32>
>>> m.Ends[0].Designed
<designed connection of left end of member 32>
>>> m.Ends[0].Input.TypeDescription
model.AutoStandard
>>> m.Ends[0].Designed.TypeDescription
model.ClipAngle

I'm also interested in knowing if the designed connection bolts ( IsBolted ) to the beam web ( AttachToSupported ) and if it is a wide gage clip angle ( IsWideGage ).

SDS2 Python Prompt
>>> m.Ends[0].Designed.IsBolted
True
>>>m.Ends[0].Designed.AttachToSupported
True
>>>m.Ends[0].Designed.IsWideGage
True

Member end designed connection and input connection attributes in the Advanced Selection dictionary can be found in the Conn Type , Conn Spec and Left/Right End sections of the Advanced Selection dictionary.

Member end designed connection and input connection attributes in the model module documentation can be found in the auto_plate , clip_angle , column_plate , conn_info , end_plate , horiz_brace , seated_type , shear_type , splice_plate and vert_brace sections.


Q. How can I create a script that returns model attributes:

A . The easiest way to answer that question is with some examples.

Here's a parametric that you can Run to output the Type and SectionSize of a member that you select. Note that the model function member uses the member number that is returned by using the member module attribute MemberNumber . Also, the member is selected using the member module function MemberLocate .

# Outputs the member type and section size of the member that you select.
import member
import model
from param import ClearSelection
ClearSelection()
mem = member.MemberLocate( "Select a member" )
mem_num = mem.MemberNumber
m = model.member(mem_num)
print("Member type and section size:", m.Type, ",", m.SectionSize)
ClearSelection()

This next script outputs the " Shear load " on the left end of a beam and prints whether it is " Auto " ( AutoShearLoad ) along with the maximum shear capacity of the connection as it is currently designed ( MaxShearWithoutFailing ). Notice that, in this script, import member was changed to from member import MemberLocate -- click here for an explanation.

# Outputs shear load information on a beam that you select.
from member import MemberLocate
import model
from param import ClearSelection
ClearSelection()
mem = MemberLocate( "Select a beam" )
m = model.member(mem.MemberNumber)
if mem.Type != "Beam":
    print("You need to select a beam.")
else:
    print("Shear load:", m.Ends[0].ShearLoad)
    print("Shear load is auto:", m.Ends[0].AutoShearLoad)
    print("Maximum shear:", m.Ends[0].MaxShearWithoutFailing)
ClearSelection()

The following script prints the material type of each of the selected member's submaterials. The built-in Python function len() is used with m.materials in the expression len(m.materials) to return the total number of the member's materials. The while statement is constructed so that the loop ends when ii is no longer less than the total number of the member's materials. The model module attribute Piecemark returns the piecemark of the selected member. The model module attribute MaterialType is used, in this script, to return each of that member's submaterials (its ii'th material, each in turn). As was discussed in the section on finding out information about a member's materials , the first material reported (when ii = 0) is the member's main material.

# Prints material types of each submaterial of a member.
import model
import member
from param import ClearSelection
ClearSelection()
mem = member.MemberLocate( "Select any member" )
m = model.member(mem.MemberNumber)
print("Member ", m.Piecemark)
ii = 0
while ii < len(m.materials):
    m_mtrl = m.materials[ii]
    print(" Material type ", m_mtrl.MaterialType)
    ii += 1
ClearSelection()
#Example output:
# Member B_36
#  Material type WideFlange
#  Material type Angle
#  Material type Angle
#  Material type Angle
#  Material type Angle

The following script generates output for those members that you select which have user defined connections. The member module function MultiMemberLocate promts the user to " Select some members " in the model. A pair of for statements, the second indented under the first, iterate over the list of selected members and their ends. Since the attribute UserDefinedConnectionIndex will throw an attribute error if the input type connection is not user defined, the script includes an if statement that checks to see if a connection is user defined, then prints the user defined coneection's index number, the member number of the member with the user defined connection, and whether the connection is on the member's left end or its right end.

# Prints the indexes and locations of user defined connections.
import model
from member import MultiMemberLocate
from param import ClearSelection
ClearSelection()
mem_list = MultiMemberLocate("Select some members")
for mem in mem_list:
        if end.Input.TypeDescription == "UserDefined":
            print("UDC on", end, "is", end.Input.UserDefinedConnectionIndex)
ClearSelection()

# Example output:
# UDC on <right end of member number 12> is 2