All Courses
All Courses
Courses by Software
Courses by Semester
Courses by Domain
Tool-focused Courses
Machine learning
POPULAR COURSES
Success Stories
Aim: To create a master TCL/TK macro that performs several operations such as finding and correcting normals, final checks, creating components, reflecting geometry, creating connections and identify identical components. Objective: It should contain buttons that will call all utilities created as assignments during…
Akash M
updated on 10 Dec 2021
Aim:
To create a master TCL/TK macro that performs several operations such as finding and correcting normals, final checks, creating components, reflecting geometry, creating connections and identify identical components.
Objective:
Code:
set a .window
catch {destroy $a}
toplevel $a -class TopLevel
wm title $a "Master"
wm geometry $a 260x600+100+50; update
wm resizable $a 0 0
wm deiconify $a
button $a.01 -text "Normals" -command {normals} -bg white -font {times 10 bold}; place $a.01 -x 30 -y 30 -width 200 -height 50
button $a.02 -text "Final Check" -command {final_check} -bg white -font {times 10 bold}; place $a.02 -x 30 -y 90 -width 200 -height 50
button $a.03 -text "Check Edges" -command {check_edges} -bg white -font {times 10 bold}; place $a.03 -x 30 -y 160 -width 200 -height 50
button $a.04 -text "Create Component" -command {create_comp_prop} -bg white -font {times 10 bold}; place $a.04 -x 30 -y 220 -width 200 -height 50
button $a.05 -text "Reflect" -command {reflect_geom} -bg white -font {times 10 bold}; place $a.05 -x 30 -y 280 -width 200 -height 50
button $a.06 -text "Creating Midline" -command {create_midline_weld} -bg white -font {times 10 bold}; place $a.06 -x 30 -y 340 -width 200 -height 50
button $a.07 -text "Element Quality" -command {element_quality} -bg white -font {times 10 bold}; place $a.07 -x 30 -y 400 -width 200 -height 50
button $a.08 -text "Connections" -command {connector} -bg white -font {times 10 bold}; place $a.08 -x 30 -y 470 -width 200 -height 50
button $a.09 -text "Identical components" -command {identify} -bg white -font {times 10 bold}; place $a.09 -x 30 -y 530 -width 200 -height 50
# Normals
proc normals {} {
set a .window
catch {destroy $a}
toplevel $a -class TopLevel
wm title $a "Normals"
wm geometry $a 270x170+100+50; update
wm resizable $a 1 0
wm deiconify $a
button $a.01 -text "normals on" -command {normals_on} -bg white -font {times 10}; place $a.01 -x 10 -y 10 -width 250 -height 30
button $a.02 -text "normals off" -command {normals_off} -bg white -font {times 10}; place $a.02 -x 10 -y 50 -width 250 -height 30
button $a.03 -text "reverse normals" -command {reverse} -bg white -font {times 10}; place $a.03 -x 10 -y 90 -width 250 -height 30
button $a.04 -text "Adjust" -command {adjust} -bg white -font {times 10}; place $a.04 -x 10 -y 130 -width 250 -height 30
proc normals_on {} {
*clearmarkall 1
*setnormalsdisplaytype 1
*createmark elements 1 "displayed"
*normalsdisplay elements 1
}
proc normals_off {} {
*createmark elements 1 "displayed"
*normalsoff
}
proc reverse {} {
*createmarkpanel elements 1 "select the elements for reverse the normal"
set i [hm_marklength elements 1]
if {$i !=0} {
*normalsreverse elements 1
*createmark elements 1 "displayed"
*normalsdisplay elements 1
}
}
proc adjust {} {
*normalsadjust2 elements 1 0 0 0 0 0 50
}
}
# Final Check
proc final_check {} {
set a .window
catch {destroy $a}
toplevel $a -class TopLevel
wm title $a "Final Check"
wm geometry $a 500x650+100+50; update
wm resizable $a 0 0
wm deiconify $a
label $a.01 -text "Delete Geometric entities" -bg grey -font {times 10 bold}; place $a.01 -x 20 -y 20 -width 450 -height 50
button $a.02 -text "Delete Solids" -command "delete solids" -bg white -font {times 10 bold}; place $a.02 -x 20 -y 80 -width 200 -height 30
button $a.03 -text "Delete Surfaces" -command "delete surfaces" -bg white -font {times 10 bold}; place $a.03 -x 250 -y 80 -width 200 -height 30
button $a.04 -text "Delete Points" -command "delete points" -bg white -font {times 10 bold}; place $a.04 -x 20 -y 120 -width 200 -height 30
button $a.05 -text "Delete Lines" -command "delete lines" -bg white -font {times 10 bold}; place $a.05 -x 250 -y 120 -width 200 -height 30
proc delete {a} {
*createmark $a 1 "displayed"
if {[hm_marklength $a 1] !=0} {*deletemark $a 1}
}
label $a.06 -text "Delete Empty and unused entities" -bg grey -font {times 10 bold}; place $a.06 -x 20 -y 160 -width 450 -height 50
button $a.07 -text "Delete Assemblies" -command "empty assemblies" -bg white -font {times 10 bold}; place $a.07 -x 20 -y 220 -width 200 -height 30
button $a.08 -text "Delete Components" -command "empty components" -bg white -font {times 10 bold}; place $a.08 -x 250 -y 220 -width 200 -height 30
button $a.09 -text "Delete Materials" -command "unused materials" -bg white -font {times 10 bold}; place $a.09 -x 20 -y 260 -width 200 -height 30
button $a.10 -text "Delete Properties" -command "unused properties" -bg white -font {times 10 bold}; place $a.10 -x 250 -y 260 -width 200 -height 30
proc empty {b} {
*EntityPreviewEmpty $b 1
if {[hm_marklength $b 1] !=0} {*deletemark $b 1}
}
proc unused {c} {
*EntityPreviewUnused $c 1
if {[hm_marklength $c 1] !=0} {*deletemark $c 1}
}
label $a.11 -text "Re-order and Re-number entities" -bg grey -font {times 10 bold}; place $a.11 -x 20 -y 300 -width 450 -height 50
button $a.12 -text "Reorder Assemblies" -command "reorder assemblies" -bg white -font {times 10 bold}; place $a.12 -x 20 -y 360 -width 200 -height 30
button $a.13 -text "Reorder Components" -command "reorder components" -bg white -font {times 10 bold}; place $a.13 -x 250 -y 360 -width 200 -height 30
button $a.14 -text "Reorder Materials" -command "reorder materials" -bg white -font {times 10 bold}; place $a.14 -x 20 -y 400 -width 200 -height 30
button $a.15 -text "Reorder Properties" -command "reorder properties" -bg white -font {times 10 bold}; place $a.15 -x 250 -y 400 -width 200 -height 30
proc reorder {d} {
*createmark $d 1 "all"
if {[hm_marklength $d 1] !=0} {*collectormarkmove $d 1 1 1}
}
button $a.16 -text "Renumber Assemblies" -command "renumber assemblies" -bg white -font {times 10 bold}; place $a.16 -x 20 -y 440 -width 200 -height 30
button $a.17 -text "Renumber Components" -command "renumber components" -bg white -font {times 10 bold}; place $a.17 -x 250 -y 440 -width 200 -height 30
button $a.18 -text "Renumber Materials" -command "renumber materials" -bg white -font {times 10 bold}; place $a.18 -x 20 -y 480 -width 200 -height 30
button $a.19 -text "Renumber Properties" -command "renumber properties" -bg white -font {times 10 bold}; place $a.19 -x 250 -y 480 -width 200 -height 30
proc renumber {e} {
*createmark $e 1 "all"
if {[hm_marklength $e 1] !=0} {*renumbersolverid components 1 1 1 0 0 0 0 0}
}
button $a.20 -text "MASTER" -command "master" -bg red -font {times 15 bold}; place $a.20 -x 150 -y 520 -width 150 -height 50
proc master {} {
delete solids
delete surfaces
delete points
delete lines
empty assemblies
empty components
unused materials
unused properties
reorder assemblies
reorder components
reorder materials
reorder properties
renumber assemblies
renumber components
renumber materials
renumber properties
}
}
# Check Edges
proc check_edges {} {
set a .window
catch {destroy $a}
toplevel $a -class TopLevel
wm title $a "Check Edges"
wm geometry $a 300x200+100+50; update
wm resizable $a 0 0
wm deiconify $a
button $a.01 -text "Free Edges" -command {free_edges} -bg red -font {times 10 bold}; place $a.01 -x 20 -y 20 -width 100 -height 30
button $a.02 -text "T edges" -command {T_edges} -bg cyan -font {times 10 bold}; place $a.02 -x 140 -y 20 -width 100 -height 30
button $a.03 -text "both" -command {both} -bg white -font {times 10 bold}; place $a.03 -x 70 -y 70 -width 100 -height 30
button $a.04 -text "off" -command {off} -bg grey -font {times 10 bold}; place $a.04 -x 70 -y 120 -width 100 -height 30
proc free_edges {} {
*setdisplayattributes 4 1
*createmark components 1 "free_edges"
set a [hm_getmark components 1]
if {$a !=0} {
*createmark elements 1 "displayed"
*findedges1 elements 1 0 0 0 30
*setvalue components name={^edges} name={free_edges}
*createmark components 1 "free_edges"
*setvalue components mark=1 color=3
*createmark elements 1 "displayed"
*equivalence elements 1 0.01 0 0 30
*createmark elements 1 "displayed"
*equivalence elements 1 0.01 3 0 30
*createmark nodes 1 "retrieve"
*nodemarkaddtempmark 1
*setcomponentdisplayattributes "free_edges" 2 1
} else {
tk_messageBox -message "The Component already exists" -icon warning -type ok -title Message
}
}
proc T_edges {} {
*setdisplayattributes 4 1
*createmark components 1 "T_edges"
set b [hm_getmark components 1]
if {$b !=0} {
*createmark elements 1 "displayed"
*findedges1 elements 1 1 0 0 30
*setvalue components name={^edges} name={T_edges}
*createmark components 1 "T_edges"
*setvalue components mark=1 color=30
*createmark elements 1 "displayed"
*equivalence elements 1 0.01 0 0 30
*createmark elements 1 "displayed"
*equivalence elements 1 0.01 3 0 30
*createmark nodes 1 "retrieve"
*nodemarkaddtempmark 1
*setcomponentdisplayattributes "T_edges" 2 1
} else {
tk_messageBox -message "The Component already exists" -icon warning -type ok -title Message
}
}
proc both {} {
free_edges
T_edges
}
proc off {} {
*createmark components 1 "free_edges"
*hideentitybymark 1 1 2
*createmark components 1 "T_edges"
*hideentitybymark 1 1 2
*createstringarray 2 "elements_on" "geometry_off"
*setdisplayattributes 2 1
}
}
# Create Components and properties
proc create_comp_prop {} {
set a .window
catch {destroy $a}
toplevel $a -class TopLevel
wm title $a "Create Component"
wm geometry $a 350x250+100+50; update
wm resizable $a 0 0
wm deiconify $a
label $a.01 -text "Component" -bg grey -font {times 10 bold}; place $a.01 -x 20 -y 20 -width 150 -height 50
label $a.02 -text "Thickness" -bg grey -font {times 10 bold}; place $a.02 -x 20 -y 80 -width 150 -height 50
entry $a.03 -textvariable ::comp_name -bg white -font {times 10}; place $a.03 -x 180 -y 20 -width 150 -height 50
entry $a.04 -textvariable ::T_value -bg white -font {times 10}; place $a.04 -x 180 -y 80 -width 150 -height 50
button $a.05 -text "Create" -command {create} -bg green -font {times 10 bold}; place $a.05 -x 100 -y 140 -width 150 -height 50
set ::comp_name {}
set ::T_value {}
proc optistruct {} {
set opti [hm_getsolver]
if {$opti == "optistruct"} {
*createmark comps 1 $::comp_name
if {[hm_entityinfo exist comps $::comp_name]!=0} {
puts [tk_messageBox -message "The Component already exists" -icon warning -type ok -title Message]
} else {
*createentity comps cardimage=Part includeid=0 name=$::comp_name
*createmark components 1 $::comp_name
set compid [hm_getmark comps 1]
*createentity props cardimage=PSHELL includeid=0 name=$::comp_name
*createmark props 2 $::comp_name
set propid [hm_getmark props 2]
*setvalue props id=$propid STATUS=1 95=$::T_value;
*setvalue comps id=$compid propertyid={props $propid}
*createmark components 1 "all"
*autocolorwithmark components 1
*createmark properties 1 "all"
*autocolorwithmark properties 1
}
}
}
proc radioss {} {
set radi [hm_getsolver]
if {$radi == "radioss"} {
*createmark comps 1 $::comp_name
if {[hm_entityinfo exist comps $::comp_name]!=0} {
puts [tk_messageBox -message "The Component already exists" -icon warning -type ok -title Message]
} else {
*createentity comps cardimage=Part includeid=0 name=$::comp_name
*createmark components 1 $::comp_name
set compid [hm_getmark comps 1]
*createentity props cardimage=P1_SHELL includeid=0 name=$::comp_name
*createmark props 2 $::comp_name
set propid [hm_getmark props 2]
*setvalue props id=$propid STATUS=1 431=$::T_value;
*setvalue comps id=$compid propertyid={props $propid}
*createmark components 1 "all"
*autocolorwithmark components 1
*createmark properties 1 "all"
*autocolorwithmark properties 1
}
}
}
proc create {} {
optistruct
radioss
}
}
# Reflecting the geometry
proc reflect_geom {} {
proc optistruct {c t} {
set opti [hm_getsolver]
if {$opti == "optistruct"} {
set n $c
set m $t
*createmark comps 1 $n
if {[hm_entityinfo exist comps $n] !=0} {
puts [tk_messageBox -message "The Component already exists" -icon warning -type ok -title Message]
} else {
*createentity comps cardimage=Part includeid=0 name=$n;
*createmark comps 1 $n
set compid [hm_getmark comps 1]
*createentity props cardimage=PSHELL includeid=0 name=$n;
*createmark props 2 $n
set propid [hm_getmark props 2]
*setvalue props id=$propid STATUS=1 95=$t;
*setvalue comps id=$compid propertyid={props $propid};
}
}
}
proc radioss {c t} {
set radi [hm_getsolver]
if {$radi == "radioss"} {
set n $c
set m $t
*createmark comps 1 $n
if {[hm_entityinfo exist comps $n] !=0} {
puts [tk_messageBox -message "The Component already exists" -icon warning -type ok -title Message]
} else {
*createentity comps cardimage=Part includeid=0 name=$n;
*createmark comps 1 $n
set compid [hm_getmark comps 1]
*createentity props cardimage=P1_SHELL includeid=0 name=$n;
*createmark props 2 $n
set propid [hm_getmark props 2]
*setvalue props id=$propid STATUS=1 431=$t;
*setvalue comps id=$compid propertyid={props $propid};
}
}
}
proc reflect {} {
*clearmarkall 1; *clearmarkall 2;
set name [hm_getstring Component_Name "Enter name of reflect component followed by _"]
*createmarkpanel comps 1 "Select the component containing original geometry to be reflected"
set o_geom [hm_getmark comp 1]
*createmarkpanel comps 1 "Select the component containing target geometry"
set t_geom [hm_getmark comp 1]
*createmarkpanel comps 1 "Select the FE components you want to reflect"
set o_fea [hm_getmark comps 1]
set profile [hm_info templatetype]
foreach i $o_fea {
set t [hm_getthickness comps $i]
set old_n [hm_entityinfo name comps $i]
set n $name$t
$profile $n $t
*createmark elements 1 $old_n
*copymark elements 1 $n
*displaycollectorwithfilter components "off" "$old_n" 1 0
}
*createmark comps 2 "displayed"
*autocolorwithmark components 2
*clearmarkall 1; *clearmarkall 2;
*createmark surfaces 1 "by collector" $o_geom
set o_cog [hm_getcentroid surfaces 1]
*createnode [lindex $o_cog 0] [lindex $o_cog 1] [lindex $o_cog 2] 0
*createmark node 2 -1
set o_node [hm_getmark node 2]
*createmark surfaces 1 "by collector" $t_geom
set t_cog [hm_getcentroid surfaces 1]
*createnode [lindex $t_cog 0] [lindex $t_cog 1] [lindex $t_cog 2] 0
*createmark node 2 -1
set t_node [hm_getmark node 2]
set intercepts [hm_getdistance nodes $o_node $t_node 0];
*clearmarkall 1;
*createnodesbetweennodes $o_node $t_node 1;
*createmark nodes 1 -1
set m_node [hm_getmark nodes 1];
set m_node_info [hm_nodevalue $m_node];
*clearmarkall 1;
*createmark elements 1 "displayed"
*createplane 1 [lindex $intercepts 1] [lindex $intercepts 2] [lindex $intercepts 3] [lindex $m_node_info 0 0] [lindex $m_node_info 0 1] [lindex $m_node_info 0 2]
*reflectmarkwithoption elements 1 1 0;
*clearmarkall 1; *clearmarkall 2;
*createmark component 1 "displayed"
*equivalence components 1 0.01 1 0 0
}
reflect;
}
# Creating the midline and spot weld
proc create_midline_weld {} {
set a .window
catch {destroy $a}
toplevel $a -class TopLevel
wm title $a "Create Midline and Spot wels"
wm geometry $a 320x100+100+50; update
wm resizable $a 1 0
wm deiconify $a
button $a.01 -text "Create Midline" -command {mid_line} -bg white -font {times 10}; place $a.01 -x 10 -y 10 -width 300 -height 30
button $a.02 -text "Create Spotweld" -command {spot_weld} -bg white -font {times 10}; place $a.02 -x 10 -y 50 -width 300 -height 30
# Creating Midline
proc mid_line {} {
*createlistbypathpanel lines 1 "Select the source lines by path"
set source [hm_getlist lines 1]
*createlistbypathpanel lines 2 "Select the target lines by path"
set target [hm_getlist lines 2]
foreach i $source j $target {
*linescreatemidline 1 1 2 2
*linecombine $i $j 1
}
}
# Creating Spot weld
proc spot_weld {} {
*clearmarkall 1
*createlistbypathpanel nodes 1 "Select the source nodes by path"
set source [hm_getlist nodes 1]
*createlistbypathpanel nodes 2 "Select the target nodes by path"
set target [hm_getlist nodes 2]
foreach i $source j $target {
*elementtype 5 1
*rigid $i $j 123456
}
}
}
# Element Quality Check
proc element_quality {} {
set a .window
catch {destroy $a}
toplevel $a -class TopLevel
wm title $a "Quality Check"
wm geometry $a 330x885+100+50; update
wm resizable $a 0 0
wm deiconify $a
label $a.01 -text "2D Elements Quality Check" -bg grey -font {times 10 bold}; place $a.01 -x 0 -y 0 -width 315 -height 50
button $a.02 -text "Min length" -command {min_length $min_l} -bg white -font {times 10}; place $a.02 -x 05 -y 55 -width 150 -height 50
button $a.03 -text "Max length" -command {max_length $max_l} -bg white -font {times 10}; place $a.03 -x 05 -y 110 -width 150 -height 50
button $a.04 -text "Warpage" -command {warpage $w} -bg white -font {times 10}; place $a.04 -x 05 -y 165 -width 150 -height 50
button $a.05 -text "Skew" -command {skew $s} -bg white -font {times 10}; place $a.05 -x 05 -y 220 -width 150 -height 50
button $a.06 -text "Aspect" -command {aspect $as} -bg white -font {times 10}; place $a.06 -x 05 -y 275 -width 150 -height 50
button $a.07 -text "Jacobian" -command {jacobian $j} -bg white -font {times 10}; place $a.07 -x 05 -y 330 -width 150 -height 50
button $a.08 -text "Min quad angle" -command {min_quad_angle $min_qa} -bg white -font {times 10}; place $a.08 -x 05 -y 385 -width 150 -height 50
button $a.09 -text "Max quad angle" -command {max_quad_angle $max_qa} -bg white -font {times 10}; place $a.09 -x 05 -y 440 -width 150 -height 50
button $a.10 -text "Min tria angle" -command {min_tria_angle $min_ta} -bg white -font {times 10}; place $a.10 -x 05 -y 495 -width 150 -height 50
button $a.11 -text "Max tria angle" -command {max_tria_angle $max_ta} -bg white -font {times 10}; place $a.11 -x 05 -y 550 -width 150 -height 50
entry $a.12 -textvariable min_l -bg white -font {times 10}; place $a.12 -x 165 -y 55 -width 150 -height 50
entry $a.13 -textvariable max_l -bg white -font {times 10}; place $a.13 -x 165 -y 110 -width 150 -height 50
entry $a.14 -textvariable w -bg white -font {times 10}; place $a.14 -x 165 -y 165 -width 150 -height 50
entry $a.15 -textvariable s -bg white -font {times 10}; place $a.15 -x 165 -y 220 -width 150 -height 50
entry $a.16 -textvariable as -bg white -font {times 10}; place $a.16 -x 165 -y 275 -width 150 -height 50
entry $a.17 -textvariable j -bg white -font {times 10}; place $a.17 -x 165 -y 330 -width 150 -height 50
entry $a.18 -textvariable min_qa -bg white -font {times 10}; place $a.18 -x 165 -y 385 -width 150 -height 50
entry $a.19 -textvariable max_qa -bg white -font {times 10}; place $a.19 -x 165 -y 440 -width 150 -height 50
entry $a.20 -textvariable min_ta -bg white -font {times 10}; place $a.20 -x 165 -y 495 -width 150 -height 50
entry $a.21 -textvariable max_ta -bg white -font {times 10}; place $a.21 -x 165 -y 550 -width 150 -height 50
label $a.22 -text "3D Elements Quality Check" -bg grey -font {times 10 bold}; place $a.22 -x 0 -y 605 -width 315 -height 50
button $a.23 -text "Warpage" -command {warpage_3d $war} -bg white -font {times 10}; place $a.23 -x 05 -y 660 -width 150 -height 50
button $a.24 -text "Tetra collapse" -command {tetcollapse $tet} -bg white -font {times 10}; place $a.24 -x 05 -y 715 -width 150 -height 50
button $a.25 -text "Volume skew " -command {volumeskew $vs} -bg white -font {times 10}; place $a.25 -x 05 -y 770 -width 150 -height 50
entry $a.26 -textvariable war -bg white -font {times 10}; place $a.26 -x 165 -y 660 -width 150 -height 50
entry $a.27 -textvariable tet -bg white -font {times 10}; place $a.27 -x 165 -y 715 -width 150 -height 50
entry $a.28 -textvariable vs -bg white -font {times 10}; place $a.28 -x 165 -y 770 -width 150 -height 50
button $a.29 -text "Clear nodes" -command {clear} -bg yellow -font {times 10}; place $a.29 -x 80 -y 825 -width 150 -height 50
proc min_length {min_l} {
*nodecleartempmark
*createmark elements 1 "displayed"
*elementtestlength elements 1 $min_l 2 1 2 0 " 2D Min Length "
*maskentitymark elements 2 0
*maskreverse elements
*createmark nodes 1 "displayed"
*nodemarkaddtempmark 1
*unmaskall2
}
proc max_length {max_l} {
*nodecleartempmark
*createmark elements 1 "displayed"
*elementtestlength elements 1 $max_l 2 0 2 0 " 2D Max Length "
*maskentitymark elements 2 0
*maskreverse elements
*createmark nodes 1 "displayed"
*nodemarkaddtempmark 1
*unmaskall2
}
proc warpage {w} {
*nodecleartempmark
*nodecleartempmark
*createmark elements 1 "displayed"
*elementtestwarpage elements 1 $w 2 2 0 " 2D Warpage "
*maskentitymark elements 2 0
*maskreverse elements
*createmark nodes 1 "displayed"
*nodemarkaddtempmark 1
*unmaskall2
}
proc skew {s} {
*nodecleartempmark
*nodecleartempmark
*nodecleartempmark
*createmark elements 1 "displayed"
*elementtestskew elements 1 $s 2 2 0 " 2D Skew "
*maskentitymark elements 2 0
*maskreverse elements
*createmark nodes 1 "displayed"
*nodemarkaddtempmark 1
*unmaskall2
}
proc aspect {as} {
*nodecleartempmark
*createmark elements 1 "displayed"
*elementtestaspect elements 1 $as 2 2 0 " 2D Aspect Ratio "
*maskentitymark elements 2 0
*maskreverse elements
*createmark nodes 1 "displayed"
*nodemarkaddtempmark 1
*unmaskall2
}
proc jacobian {j} {
*nodecleartempmark
*createmark elements 1 "displayed"
*elementtestjacobian elements 1 $j 2 2 0 " 2D Jacobian "
*maskentitymark elements 2 0
*maskreverse elements
*createmark nodes 1 "displayed"
*nodemarkaddtempmark 1
*unmaskall2
}
proc min_quad_angle {min_qa} {
*nodecleartempmark
*createmark elements 1 "displayed"
*elementtestinterangle elements 1 $min_qa 0 2 1 2 0 " 2D Quad Min Angle "
*maskentitymark elements 2 0
*maskreverse elements
*createmark nodes 1 "displayed"
*nodemarkaddtempmark 1
*unmaskall2
}
proc max_quad_angle {max_qa} {
*nodecleartempmark
*createmark elements 1 "displayed"
*elementtestinterangle elements 1 $max_qa 0 2 0 2 0 " 2D Quad Max Angle "
*maskentitymark elements 2 0
*maskreverse elements
*createmark nodes 1 "displayed"
*nodemarkaddtempmark 1
*unmaskall2
}
proc min_tria_angle {min_ta} {
*nodecleartempmark
*createmark elements 1 "displayed"
*elementtestinterangle elements 1 $min_ta 1 2 1 2 0 " 2D Tria Min Angle "
*maskentitymark elements 2 0
*maskreverse elements
*createmark nodes 1 "displayed"
*nodemarkaddtempmark 1
*unmaskall2
}
proc max_tria_angle {max_ta} {
*nodecleartempmark
*createmark elements 1 "displayed"
*elementtestinterangle elements 1 $max_ta 1 2 0 2 0 " 2D Tria Max Angle "
*maskentitymark elements 2 0
*maskreverse elements
*createmark nodes 1 "displayed"
*nodemarkaddtempmark 1
*unmaskall2
}
proc warpage_3d {war} {
*nodecleartempmark
*createmark elements 1 "displayed"
*elementtestwarpage elements 1 $war 2 4 0 " 3D Warpage "
*maskentitymark elements 2 0
*maskreverse elements
*createmark nodes 1 "displayed"
*nodemarkaddtempmark 1
*unmaskall2
}
proc tetcollapse {tet} {
*nodecleartempmark
*createmark elements 1 "displayed"
*elementtesttetracollapse elements 1 $tet 2 0 " 3D Tetra Collapse "
*maskentitymark elements 2 0
*maskreverse elements
*createmark nodes 1 "displayed"
*nodemarkaddtempmark 1
*unmaskall2
}
proc volumeskew {vs} {
*nodecleartempmark
*createmark elements 1 "displayed"
*elementtestvolumetricskew elements 1 $vs 2 0 " 3D Volumetric Skew "
*maskreverse elements
*createmark nodes 1 "displayed"
*nodemarkaddtempmark 1
*unmaskall2
}
proc clear {} {
*nodecleartempmark
}
}
# Connections
proc connector {} {
set a .connectors
catch {destroy $a}
toplevel $a -class TopLevel
wm title $a "Connectors"
wm geometry $a 200x250+100+50; update
wm resizable $a 0 0
wm deiconify $a
button $a.01 -text "Create collectors" -command {create} -bg white -font {times 10 bold}; place $a.01 -x 20 -y 20 -width 150 -height 30
button $a.02 -text "Welds" -command {weld} -bg white -font {times 10 bold}; place $a.02 -x 20 -y 70 -width 150 -height 30
button $a.03 -text "X Locator" -command {X_loc} -bg white -font {times 10 bold}; place $a.03 -x 20 -y 110 -width 150 -height 30
button $a.04 -text "Y Locator" -command {Y_loc} -bg white -font {times 10 bold}; place $a.04 -x 20 -y 150 -width 150 -height 30
button $a.05 -text "Z Locator" -command {Z_loc} -bg white -font {times 10 bold}; place $a.05 -x 20 -y 190 -width 150 -height 30
proc create {} {
*clearmarkall 1
*clearmarkall 2
*createmark comps 1 welds; if {[hm_marklength comps 1] == 0} {*createentity components name=welds color=3}
*createmark comps 1 X_loc; if {[hm_marklength comps 1] == 0} {*createentity components name=X_loc color=5}
*createmark comps 1 Y_loc; if {[hm_marklength comps 1] == 0} {*createentity components name=Y_loc color=6}
*createmark comps 1 Z_loc; if {[hm_marklength comps 1] == 0} {*createentity components name=Z_loc color=56}
}
proc weld {} {
*clearmarkall 1
*clearmarkall 2
*currentcollector components "welds"
*createmarkpanel nodes 1 "Select the nodes for spider weld"
*rigidlinkinodecalandcreate 1 0 0 123456
}
proc X_loc {} {
*clearmarkall 1
*clearmarkall 2
*currentcollector components "X_loc"
*createmarkpanel nodes 1 "Select source nodes for spot weld"
set source_node [hm_getmark nodes 1]
*createmarkpanel nodes 2 "Select target nodes for spot weld"
set target_node [hm_getmark nodes 2]
*rigid $source_node $target_node 156
}
proc Y_loc {} {
*clearmarkall 1
*clearmarkall 2
*currentcollector components "Y_loc"
*createmarkpanel nodes 1 "Select source nodes for spot weld"
set source_node [hm_getmark nodes 1]
*createmarkpanel nodes 2 "Select target nodes for spot weld"
set target_node [hm_getmark nodes 2]
*rigid $source_node $target_node 246
}
proc Z_loc {} {
*clearmarkall 1
*clearmarkall 2
*currentcollector components "Z_loc"
*createmarkpanel nodes 1 "Select source nodes for spot weld"
set source_node [hm_getmark nodes 1]
*createmarkpanel nodes 2 "Select target nodes for spot weld"
set target_node [hm_getmark nodes 2]
*rigid $source_node $target_node 345
}
}
# Identify Identical components
proc identify {} {
*clearmarkall 1; *clearmarkall 2;
# List of all components
*createmark comps 1 "all"
set all_comp [hm_getmark comps 1];
*clearmarkall 1; *clearmarkall 2;
# List of all surfaces
foreach i $all_comp {
*createmark surfaces 1 "by collector" $i
lappend all_comp_surf [hm_marklength surfaces 1]
}
*clearmarkall 1; *clearmarkall 2;
# Input components
*createmarkpanel comps 2 "Select the geometric components of interest"
set target_comp [hm_getmark comp 2]
*isolateentitybymark 2
puts "Target comp id $target_comp"
*clearmarkall 1; *clearmarkall 2;
*createmark surfaces 2 "by collector" $target_comp
puts [set target_comp_surf [hm_marklength surfaces 2]]
*clearmarkall 1; *clearmarkall 2;
set match_list_surf [lsearch -all $all_comp_surf $target_comp_surf]
puts "Match list surfaces $match_list_surf"
foreach j $match_list_surf {
*clearmarkall 1
set compid [lindex $all_comp $j]
set comp_name [hm_entityinfo name components $compid]
*displaycollectorwithfilter components "on" "$comp_name" 0 1
}
}
Procedure and code explanation:
Open notepad++ and create a master.tcl file
The following commands are the basic commands that should be followed inorder to create GUI.
set a .window is the command. .window is the window name or path by which it will be referred saved in.
catch {destroy $a} is the command where catch is used to hide errors and destroy is used to close any previously existing window by same name.
toplevel $a -class TopLevel is the command that builds the window.
wm title $a "Part A" is the command that is used to create title of the window.
wm geometry $a 200x300+100+50 is the command that is used to create dimension of the window. 200x300 is width and height of the window. +100+50 is the origin of the hypermesh window where the windoe shoud be placed.
wm resizable $a 0 0 is the command that is used to fix the window means we can not resize the window by dragging. If you put 1 0, you can drag or resize the window on x axix, if you put 0 1, you can drag or resize it on y axix and if you put 1 1, you can drag and resize on both axis.
wm deiconify $a is the command that is used to make the window as active window.
We have to create buttons for all the oprerations. The syntax for creating button is button $windowpath -text "text" -command {something}; place $windowpath -x value -y value -width value - height value.
We have to create labels that indicate an idea of segregation. The syntax for create label is label $windowpath -text "Label" -bg color -font {times 10 bold} ; place $windowpath -x value -y value -width value -height value.
We have to create entry box to give inputs. The syntax for create entry box is entry $windoepath -textvariable "::var" place $windowpath -x value -y value -width value -height value. Textvariable should be the variable assigned to a command.
1. Normals:
*setnormaldisplaytype - to display type of visualization whether the direction of normal (0) or volor(1)
*createmark elements 1 "displayed" - to select the displayed elements
Functions are created for reversing the normals and select the elements using proc and these functions are called by assigning the respective buttons.
*normalsdisplay - to display the normals
*createmarkpanel elements 1 "select the elements for reverse the normal" is the command that is used to select the elements to reverse normals. set i [hm_marklength elements 1] is the command that stores the selected into a variable 'i'.
$i !=0 is null case if the selected elements is 0, it will not execute. If we select the some elements it will be execute. It will not show you an error. If the null case is not used, it will show you an error.
*normalreverse - to reverse the normals of the selected elements
*normalsoff - to hide the normals of displayed elements.
2. Final Check:
And then we have to create label called "Delete Geometric entities". The syntax for create label is label $windowpath -text "Label" -bg grey -font {times 20 bold} ; place $windowpath -x value -y value -width value -height value. Using this syntax the label is created.
We have to create four buttons called 'Delete Solids', 'Delete Surfaces', 'Delete points', 'Delete Lines'. The syntax for create button is button $windowpath -text "text" -command {something}; place $windowpath -x value -y value -width value - height value. Using these syntax buttons are created. To execute commands we have to create procedure.
Create procedure for delete displayed entities and also use null case for not getting any error if the user not selected any entities.
*deletemark - to delete the entities
*EntityPreviewEmpty - to preview the empty components and assemblies
*EntityPreviewUnused - to preview the umsed properties and materials
*renumbersolverid - ro renumber the entity ids
Using the above procedure create labels and buttons for delete empty and unused entities and re-order and re-number entities. Here, the entities could be assemblies, components, materials, properties. Use procedure for all these buttons.
Also create a master button in red and create one procedure and assign all the commands into these procedure. So, that all the above operations can be performed at one click.
3. Check Edges:
Create a procedure called 'free_edges'
*setdisplayattributes is a command that transparent all the components.
We need to give a null case condition if there is no exixt component.
*createmark elements 1 "displayed" is a command that used to store all the displayed elements into a mark id 1.
*findedges1 elements 1 0 0 0 30 is the command that is used to find the edges. 1 represent the mark id and 0 indicated free edges and 30 is the break andle of the free edges.
*setvalue components name={^edges} name={free_edges} is used to change the name of the component.
*setvalue components mark=1 color=3 is used to change the color to red.
*equivalence elements 1 0.01 0 0 30 is checking where nodes to be equivalence for the tolerance value of 0.01 for the free edges
*equivalence elements 1 0.01 3 0 30 is saves the nodes which needs to be equivalence.
*createmark nodes 1 "retrieve" is used to retrive the saved nodes.
*nodemarkaddtempmark 1 is adding the nodes.
*setcomponentdisplayattributes "free_edges" 2 1 is the command that used to display thr free edges and T edges into the solid mesh representation.
Use the same procedure to check the T edges. Replae the procedure name into T_edges and use edge type as 1.
Also create a procedure that performs both operations and create a procedure to turn off free edge display and restore the window to the way it was. *createmark components 1 "free_edges"; *hideentitybymark 1 1 2 is the command that is used to turn off the free edges. Using this same method to turn off the T_edges.
*setdisplayattributes 2 1 is the command that used to resore the shaded element and mesh line
4. Create Components and properties:
Set the global variable for component name and its thickness
Create a procedure called optistruct and set opti [hm_getsolver] command is used to find the solver deck
if {$opti == "optistruct"} command is used if the deck is optstruct then you can proceed with further commands
*createmark comps 1 $::comp_name is the command that is used to store the components into a mark id 1
if {[hm_entityinfo exist comps $::comp_name]!=0} is used to find the exists component with the same name. If there are any tk_messageBox -message "The Component already exists" -icon warning -type ok -title Message command is used to dispay the message box with warning of "The Component already exists"
*createentity comps cardimage=Part includeid=0 name=$::comp_name is the command that is used to create a component with the specified name.
set p $::comp_name is the command used to store the component names in the variable p
*createentity props cardimage=PSHELL includeid=0 name=$p is the command that is used to create a property with the specified name.
*setvalue props name=$p STATUS=1 95=$::T_value is the command used to assign thickness with the specified value.
*autocolorwithmark is used to autocolor the components and properties
Using this procedure, create another procedure called radioss
Also create a procedure called 'create' and call both operation into these procedue.
Create a tk widget that performs these operations.
5. Reflecting the geometry:
In order to create components and property create a procedure called optistruct
set opti [hm_getsolver] command is used to find the solver deck
if {$opti == "optistruct"} command is used if the deck is optstruct then you can proceed with further commands
*createmark comps 1 $n is the command that is used to store the components into a mark id 1
if {[hm_entityinfo exist comps $n] !=0} is used to find the exists component with the same name. If there are any tk_messageBox -message "The Component already exists" -icon warning -type ok -title Message command is used to dispay the message box with warning of "The Component already exists"
*createentity comps cardimage=Part includeid=0 name=$n is the command that is used to create a component with the specified name.
*createentity props cardimage=PSHELL includeid=0 name=$n is the command that is used to create a property with the specified name.
*setvalue props name=$n STATUS=1 95=$t is the command used to assign thickness with the specified value.
Using this procedure, create another procedure called radioss or you can create any solver deck.
To select the parent component and target component *createmarkpanel is used. It will open the particular entity panel to choose. using this command parent component, target component and the FE component is selected.
foreach loop is used for every component 'i' present in the list 'o_fea'. The thickness of the compoent 'i' is stored in variable 't' and name of the component 'i' stored in 'old_n'.
A new variable 'n' has the concatenation of 'name' and 't'. This creates the respective component and property to which the reflected elements will be added.
A mark is created for all the elements in component 'old_n'and these are copied to the component 'n'.
Then the components 'old_n' are turned off and the foreach loop is ended.
Then a mark is created with all surfaces in 'o_geom'. The centroid for target and original geometries is created and stored in 'o_cog' and 't_cog' respectively. A node is created at each centroid named 'o_node' and 't_node' respectively.
A mark is created with all displayed elements and a intercept is created at intercept value and centre point between the centroids.
Then the elements are reflected with the created plane as refenrence. Then the equivalence is checked and corrected for the torelence value of 0.01 by using the command *equivalence components 1 0.01 1 0 0.
6. Creating the midline and spot weld :
Midline:
*Createlistbypathpanel command is used to select the entities by using entity panel. This creates a list of selected entities in a way we select the order. Line list will be selected.
The first set of lines are saved as a source and the second set of lines are saved as a target.
foreach loop is used to create midline for a each source lines and target lines and then the lists are assigned to variables.
*linescreatemidline is used to create misline. Midline is created for between source lines and target lines.
Spot weld:
*Createlistbypathpanel command is used to select the entities by using entity panel. This creates a list of selected entities in a way we select the order. Node list for weld location will be selected.
The first set of nodes are saved as a source and the second set of nodes are saved as a target.
And then foreach loop is used to create weld for each source nodes and target nodes
To create rigid *rigid node 1 node 2 dof command is used. Inputs are node 1 i.e.source node, node 2 i.e.target node and dof 123456
7. Element Quality Check:
*nodecleartempmark - clear all the existing temp nodes mark_id $value output_mark_id dimension contour title
*createmark elements 1 "displayed" - store all the displayed elements to mark id 1.
*elementtestlength elements 1 $max_l 2 0 2 0 " 2D Max Length " - to check minimum and maximum length for 2D elements by giving respective value. $max_l is the user input value.
*elementtestwarpage elements 1 $w 2 2 0 " 2D Warpage " - to check warpage for 2D elements by giving respective value. $w is the user input value.
*elementtestskew elements 1 $s 2 2 0 " 2D Skew " - to check skewness for 2D elements by giving respective value. $s is the user input.
*elementtestaspect elements 1 $as 2 2 0 " 2D Aspect Ratio " - to check aspect ratio for 2D elements by giving respective value. $as is the user input.
*elementtestjacobian elements 1 $j 2 2 0 " 2D Jacobian " - to check jacobian for 2D elements by giving respective value. $j is the user input.
*elementtestinterangle elements 1 $min_qa 0 2 1 2 0 " 2D Quad Min Angle " - to check minimum quad angle for 2D elements by giving respective value. $min_qa is the user input.
*elementtestinterangle elements 1 $max_qa 0 2 0 2 0 " 2D Quad Max Angle " - to check maximum quad angle for 2D elements by giving respective value. $max_qa is the user input.
*elementtestinterangle elements 1 $min_ta 1 2 1 2 0 " 2D Tria Min Angle " - to check minimum tria angle for 2D elements by giving respective value. $min_ta is the user input.
*elementtestinterangle elements 1 $max_ta 1 2 0 2 0 " 2D Tria Max Angle " - to check maximum tria angle for 2D elements by giving respective value. $max_ta is the user input.
*elementtestwarpage elements 1 $war 2 4 0 " 3D Warpage " - to check warpage for 3D elements by giving respective value. $war is the user input value.
*elementtesttetracollapse elements 1 $tet 2 0 " 3D Tetra Collapse " - to check tetra collapse for 3D elements by giving respective value. $tet is the user input value.
*elementtestvolumetricskew elements 1 $vs 2 0 " 3D Volumetric Skew " - to check volumetric skew for 3D elements by giving respective value. $vs is the user input value.
*maskentitymark elements 2 0 - mask the failed elemnts stored in a mark id 2
*createmark nodes 1 "displayed" - store the failed elements( displayed elemnts since we mask those elemnts) nodes to mark id 2
*nodemarkaddtempmark 1 - add temp nodes to those failed elements
*unmaskall2 - unmask all the elements
8. Connections:
Procedures are created for weld and x, y, z locators.
*clearmarkall command is used to clear the entities stored in a particular mark.
Create components for weld and x,y, z locators. *createentity command is used to create components
Weld, x_loc, y_loc, z_loc components are created.
We have to create spider weld and spot weld. In oreder to create welds, create different procedures for weld, x, y, z locators.
To create welds on a current components *currentcollector command is used.
*createmarkpanel nodes 1 is used to select the nodes by nodes panel for weld.
*rigidlinkinodecalandcreate 1 0 0 123456 command is used to create rbe2 elements for the selected nodes ans 123456 are degrees of freedom.
Using this same method create procedures for x, y, z locators and change the digrees of freedom as per the locators.
9. Identify Identical components:
This will show identical or same surface count components.
Create a selection of all components in a model and get surface count for each components by using the command "hm_marklength".
*craetemarkpanel command is used to select the component by the user.
The surafce count for the target component was calculated by command
lsearch -all $all_comp_surf $target_comp_surf is the command used to identify the same surface component.
Matchecd components lisi was saved in a seperated variable and the variavle contains a position of the matched variable
For each varible, a component was identified and isolated.
Output:
1. Normals:
2. Final Check:
3. Check Edges:
4. Create Components and properties:
5. Element Quality Check:
Conclusion:
Sucessfully created a master TCL/TK macro that performs several operations such as finding and correcting normals, final checks, creating components, reflecting geometry, creating connections and identify identical components.
Leave a comment
Thanks for choosing to leave a comment. Please keep in mind that all the comments are moderated as per our comment policy, and your email will not be published for privacy reasons. Please leave a personal & meaningful conversation.
Other comments...
Project - 2 - Generating the report for hypermesh file
Aim: To generate the report for hypermesh file Objective: To create an ergonomic and visually appealing excel (.xlsm) report that contains following information about your model: User name, date, time Profile/deck; count of component, prop, material, elements Count of empty comp/prop/mats Elements…
20 Dec 2021 07:48 AM IST
Project 1- Building a Master TCL/TK Macro
Aim: To create a master TCL/TK macro that performs several operations such as finding and correcting normals, final checks, creating components, reflecting geometry, creating connections and identify identical components. Objective: It should contain buttons that will call all utilities created as assignments during…
10 Dec 2021 05:13 AM IST
Week - 9 - Reflecting the geometry
Aim: To create a code that performs reflecting the geometry Objective: Create a macro that will reflect given multicomponent FE part with ease It should be independent of deck The inputs should be original CAD comp, reflected CAD comp and original FE comps …
07 Dec 2021 03:01 PM IST
Week - 12 - Creating the locator, writing and reading the node data
Aim: To create a code that performs connections, identify the identical components and reading nodes from a file. Objective: Create a macro that builds a GUI containing 4 buttons. Component creator, weld, xloc, yloc, zloc. Upon pressing the buttons corresponding 1D element must be created…
07 Dec 2021 12:35 PM IST
Related Courses
0 Hours of Content
Skill-Lync offers industry relevant advanced engineering courses for engineering students by partnering with industry experts.
© 2025 Skill-Lync Inc. All Rights Reserved.