1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
###############################################################################
# Copyright (c) 2007-2024 by Altair Engineering, Inc.
# All rights reserved.
#
# Altair Engineering, Inc. makes this software available as part of the Vision
# tool platform.  As long as you are a licensee of the Vision tool platform
# you may make copies of the software and modify it to be used within the
# Vision tool platform, but you must include all of this notice on any copy.
# Redistribution without written permission to any third party, with or
# without modification, is not permitted.
# Altair Engineering, Inc. does not warrant that this software is error free
# or fit for any purpose.  Altair Engineering, Inc. disclaims any liability for
# all claims, expenses, losses, damages and costs any user may incur as a
# result of using, copying or modifying the software.
# =============================================================================
#   @userware
#       Find Longest Path
#   @section
#       Miscellaneous Userware Examples
#   @description
#       Extract and show the longest path between two selected objects.
#
#       Features:
#
#           - Define start and endpoint by selecting each object in the Schem
#           window and press the corresponding button in the dialog window
#           created by this userware.
#
#           - Pressing the "Run Search" button will perform a path extraction
#           and display the result in a listbox. Each entry in this listbox
#           can be double clicked to show it in the Cone window.
#
#           - There is a limit to 100000 paths, feel free to increase this value
#           for fast machines.
#
#           - A progress bar appears which let you interrupt the path search
#           process.
#   @files
#       longPath.tcl
#   @example
#       demo/rtl/aquarius/aquarius.f
#   @cmdline
#       -F @example[0]
#       -userware @files[0]
#   @tag
#       gui zdb
###############################################################################


# -----------------------------------------------------------------------------
# showDialog - Create a toplevel dialog window.
# -----------------------------------------------------------------------------
#
proc showDialog {} {
    set w [toplevel .longPathUserware]
    ttk::entry $w.startOid
    ttk::entry $w.targetOid
    ttk::button $w.startBtn  -text "Selection as Start" \
        -command "setSel $w start"
    ttk::button $w.targetBtn -text "Selection as Target" \
        -command "setSel $w target"
    ttk::button $w.search -text "Run Search" -command "runSearch $w"
    ttk::frame  $w.result
    listbox $w.result.l -yscrollcommand [list $w.result.ysb set]
    ttk::scrollbar $w.result.ysb  -orient vertical \
        -command [list $w.result.l yview]
    grid $w.result.l   -row 0 -column 0 -sticky news
    grid $w.result.ysb -row 0 -column 1 -sticky ns
    grid rowconfigure    $w.result 0 -weight 1
    grid columnconfigure $w.result 0 -weight 1
    bind    $w.result.l <Double-1> [list showResult $w %x %y]
    ttk::button  $w.done -text "Done" -command "destroy $w"
    grid    $w.startOid  -row 0 -column 0 -sticky we
    grid    $w.startBtn  -row 0 -column 1 -sticky we
    grid    $w.targetOid -row 1 -column 0 -sticky we
    grid    $w.targetBtn -row 1 -column 1 -sticky we
    grid    $w.search    -row 2 -column 1 -sticky we
    grid    $w.result    -row 3 -column 0 -sticky news -columnspan 2
    grid    $w.done      -row 4 -column 0 -sticky we   -columnspan 2
    grid    rowconfigure    $w 3 -weight 1
    grid    columnconfigure $w 0 -weight 1
}


# -----------------------------------------------------------------------------
# setSel - Set either the startOid or the targetOid
# -----------------------------------------------------------------------------
#
proc setSel {w what} {
    set selOid [gui schem selection]
    if {[llength $selOid] != 1} {
        zmessage print ERR "Select only one element."
    }
    $w.${what}Oid delete 0 end
    $w.${what}Oid insert 0 $selOid
}


# -----------------------------------------------------------------------------
# runSearch - Run the path extraction from start to target.
# -----------------------------------------------------------------------------
#
proc runSearch {w} {
    global resList

    $w.result.l delete 0 end
    set limit 100000
    zprogress begin
    set db [gui database get]
    set startOid  [lindex [$w.startOid  get] 0]
    set targetOid [lindex [$w.targetOid get] 0]
    $db flatflag $startOid  clearall target
    $db flatflag $targetOid set      target
    set coneCmd [list $db cone]
    lappend coneCmd -paths -pathLimit $limit -out -targetFlatFlagged target
    lappend coneCmd $startOid
    set resList [eval $coneCmd]
    set numRes [llength $resList]
    zprogress end
    if {$numRes >= $limit} {
        zmessage print ERR "Hit limit ($limit): search is incomplete"
    }
    set cnt 0
    for {set i [expr {[llength $resList] - 1}]} {$i >= 0} {incr i -1} {
        set res [lindex $resList $i]
        $w.result.l insert end "Path $cnt: count [lindex $res 0]"
        incr cnt
    }
}


# -----------------------------------------------------------------------------
# showResult - Show the doubleclicked result in the Cone window.
# -----------------------------------------------------------------------------
#
proc showResult {w x y} {
    global resList

    set index [$w.result.l index @$x,$y]
    set path  [lindex $resList $index]
    set path  [lrange $path 1 end]
    gui window show Cone
    gui cone load $path
}


# =============================================================================
# Create the menu entry and a DatabaseChanged hook.
# =============================================================================
#
gui menu command {"Userware" "Search Long Paths"} {showDialog}