Challenge

Week - 12 - Creating the locator, writing and reading the node data

Objective

The purpose of this challenge is to generate 3 more macros that can help the user simplify repetitive tasks at the time of placing locators and welds, finding similar geometries, and processing nodes inside and outside of HM.

Problem statement

There are 3 problems for this challenge:

1. Write a macro to create and separate welds, X-Locators, Y-Locators, and Z-locators into different components.

2. Write a macro to find repeated bodies in an assembly.

3. Write a macro to read nodes from a text file and then create them in the HM session. Also, write the nodes' coordinates on a text file after selecting them in the graphic interface.

"Welds and locators procedures"

# Create a procedure to form weldings by taking as input the nodes to join in different parts:
# Clear all marks, make "Welds" the current component
# Create a panel to select the nodes that will make up the weld
# Create the weld using the selected nodes
# Clear all marks

proc weld {} {
*clearmarkall 1 ; *clearmarkall 2
*currentcollector components "Welds"
*createmarkpanel nodes 2 "Select the nodes where you want to create the welding"
*rigidlinkinodecalandcreate 2 0 0 123456
*clearmarkall 1
}

# Create a procedure to form x-locators by taking as input the nodes to join in different parts
# Clear marks 1 and 2
# Make X locator the current component
# Make a panel to select the first node on the 1st part and set it to variable "a"
# Make a panel to select the second node on the 2nd part and set it to variable "b"
# Create a rigid taking the value form a and b, locking translational and rotational
# degrees of freedom in X

proc xlocator {} {
*clearmarkall 1 ; *clearmarkall 2
*currentcollector components "X_locator"
*createlistbypathpanel nodes 1 "Select the first node where you want to create the x-locator"
set a [hm_getlist nodes 1]
*createlistbypathpanel nodes 2 "Select the second node where you want to create the x-locator"
set b [hm_getlist nodes 2]
*rigid $a $b 156
}

# Create a procedure to form Y-locators by taking as input the nodes to join in different parts
# Clear marks 1 and 2
# Make Y locator the current component
# Make a panel to select the first node on the 1st part and set it to variable "a"
# Make a panel to select the second node on the 2nd part and set it to variable "b"
# Create a rigid taking the value form a and b, locking translational and rotational
# degrees of freedom in Y

proc ylocator {} {
*clearmarkall 1 ; *clearmarkall 2
*currentcollector components "Y_locator"
*createlistbypathpanel nodes 1 "Select the first node where you want to create the y-locator"
set a [hm_getlist nodes 1]
*createlistbypathpanel nodes 2 "Select the second node where you want to create the y-locator"
set b [hm_getlist nodes 2]
*rigid $a $b 246
}

# Create a procedure to form z-locators by taking as input the nodes to join in different parts
# Clear marks 1 and 2
# Make Y locator the current component
# Make a panel to select the first node on the 1st part and set it to variable "a"
# Make a panel to select the second node on the 2nd part and set it to variable "b"
# Create a rigid taking the value form a and b, locking translational and rotational
# degrees of freedom in Z

proc zlocator {} {
*clearmarkall 1 ; *clearmarkall 2
*currentcollector components "Z_locator"
*createlistbypathpanel nodes 1 "Select the first node where you want to create the z-locator"
set a [hm_getlist nodes 1]
*createlistbypathpanel nodes 2 "Select the second node where you want to create the z-locator"
set b [hm_getlist nodes 2]
*rigid $a $b 345
}

# Create a procedure to generate components to store welds, x,y and z locators
# If the length of the selection of component "weld", "X-Locator","Y-Locator" or "Z-Locator" is equal to 0,
# the create the components
proc createcomp {} {
*clearmarkall 1 ; *clearmarkall 2
*createmark component 1 Welds; if {[hm_marklength components 1] == 0} {*createentity component name=Welds color=3}
*createmark component 1 X_locator; if {[hm_marklength components 1] == 0} {*createentity component name=X_locator color=56}
*createmark component 1 Y_locator; if {[hm_marklength components 1] == 0} {*createentity component name=Y_locator color=5}
*createmark component 1 Z_locator; if {[hm_marklength components 1] == 0} {*createentity component name=Z_locator color=6}
}

# Create window to store buttons
set a .window
catch {destroy a}
toplevel $a -class TopClass

# Define the title of the window, size and position
wm title $a "Connectors"
wm geometry $a 220x160+500+250 ; update
wm resizable $a 0 0
wm deiconify $a

# Generate buttons to execute tasks and position them in the previously created window
button $a.01 -text "Component creator" -bg grey -font {times 10 bold} -command {createcomp} ; place $a.01 -x 10 -y 10 -width 200 -height 20
button $a.02 -text "Weld" -bg grey -font {times 10 bold} -command {weld} ; place $a.02 -x 10 -y 40 -width 200 -height 20
button $a.03 -text "X-Locator" -bg grey -font {times 10 bold} -command {xlocator} ; place $a.03 -x 10 -y 70 -width 200 -height 20
button $a.04 -text "Y-Locator" -bg grey -font {times 10 bold} -command {ylocator} ; place $a.04 -x 10 -y 100 -width 200 -height 20
button $a.05 -text "Z-Locator" -bg grey -font {times 10 bold} -command {zlocator} ; place $a.05 -x 10 -y 130 -width 200 -height 20

----------------------------------------

"Detective procedure"

# The procedure starts by clearing all marks that could be in use
# Create a mark including all components
# Then this mark is saved in variable all_comps
# Clear all marks again
# Create a foreach loop for all components contained in "all_comps"
# where the surfaces contained on each component is appended to a list
# called all_comps_surf_count
# Clear all marks again
# Create a panel to choose the target component that one wishes to know about
# Save this component's id in variable target and isolate the component
# then create a mark with the surfaces of the target collector and save this number
# as "target_surf_count"
# Create a variable called match that stores the positions of the input list "all_comps_surf_count}"
# with the target_surf_count
# Create a foreach loop where the components of variable "all_comps"
# with indices equal to the "match" list are turned on

# To run it just type similar in the command window.

proc similar {} {
*clearmarkall 1 ; *clearmarkall 2
*createmark comps 1 "all"
set all_comps [hm_getmark comps 1]

*clearmarkall 1 ; *clearmarkall 2
foreach i $all_comps {
*createmark surfs 1 "by collector" $i
lappend all_comps_surf_count [hm_marklength surfaces 1]
}

*clearmarkall 1 ; *clearmarkall 2
*createmarkpanel comps 1 "Select the component you wish to look for"
set target [hm_getmark comps 1]
*isolateentitybymark 1
puts "Target comp id $target"
*createmark surfs 2 "by collector" $target
set target_surf_count [hm_marklength surfaces 2]

*clearmarkall 1 ; *clearmarkall 2
set match [lsearch -all $all_comps_surf_count $target_surf_count]
puts "Match list surfaces $match"

foreach j $match {
*clearmarkall 1 ; *clearmarkall 2
set comp_id [lindex $all_comps $j]
set comp_name [hm_entityinfo name components $comp_id]
*displaycollectorwithfilter components "on" "$comp_name" 0 1
}
}

-----------------------------------------------------------

"Write and read nodes"

# Create 2 procedures, one to read nodes form a .csv file and generate the nodes,
# and one to write on a .cvs file the coordinates of nodes.

# Set the tool that opens a window to select the desired file in the variable filename
# Set the the result of the tool that opens the window to select the desired file as fileChannelId
# Set a while conditional that as long as the file has not reached the end, the macro creates a node
# with x,y and z coordinates equal to the first, second and third numbers of each line in the read file.
# As soon as the loop ends, the file to read the nodes is closed

proc read_nodes {} {
set filename [tk_getOpenFile -title "Select node info file"]
set fileChannelId [open $filename r]
while {[eof $fileChannelId] == 0} {
puts [set lst_nodeCord [gets $fileChannelId]]
*createnode [lindex $lst_nodeCord 0] [lindex $lst_nodeCord 1] [lindex $lst_nodeCord 2];
}
close $fileChannelId
}

# Clear marks 1 and 2
# Create a nodes list panel and store it in slot 1
# Set this nodes list to variable nodeslist
# Set the variable fileChannelId to the result of the desired location where the nodes are written
# Create a foreach loop where for all the nodes included in list "nodelist", their coordinates information
# gets written until the end of the list is reached
# When the loop ends, close the output file

proc write_nodes {} {
*clearmarkall 1 ; *clearmarkall 2;
*createlistpanel nodes 1
set nodelist [hm_getlist nodes 1]
set fileChannelId [open "write_nodes.csv" w]
foreach i $nodelist {
set info [hm_nodevalue $i]
puts $fileChannelId [lindex $info 0]
}
close $fileChannelId
}

Conclusion

After developing these macros, the knowledge of some functionalities seen at the beginning of the course such as manipulating external text files was refreshed. We also have added more tools to our toolbox.

Your portfolio, next

Ship work like this
in your own course.

Talk to a career counsellor

Free 20-minute call. We'll map the right course to where you want to work.

By submitting you agree to our Terms and Privacy Policy.

Talk to a career counsellor

Free 20-minute call. We'll map the right course to where you want to work.

By submitting you agree to our Terms and Privacy Policy.