core-extra/gui/topogen.tcl

378 lines
9.9 KiB
Tcl
Raw Normal View History

#
# Copyright 2007-2008 University of Zagreb, Croatia.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
# Boeing: refactor menus
set TOOLSMENUPATH .menubar.tools
set TOPOMENUPATH ${TOOLSMENUPATH}.t_g
menu $TOPOMENUPATH -tearoff 1
${TOOLSMENUPATH} add cascade -label "Topology generator" -underline 0 -menu ${TOPOMENUPATH}
# also throughout:
# s/.menubar.t_g/${TOPOMENUPATH}/g
# s///g
# end Boeing
set m ${TOPOMENUPATH}.random
menu $m -tearoff 0
${TOPOMENUPATH} add cascade -label "Random" -menu $m -underline 0
foreach i [list 1 5 10 15 20 30 40 50 75 100] {
set n $m.$i
menu $n -tearoff 0
$m add command -label "R($i)" -command "R \[newNodes $i\]"
}
set m ${TOPOMENUPATH}.grid
menu $m -tearoff 0
${TOPOMENUPATH} add cascade -label "Grid" -menu $m -underline 0
foreach i [list 1 5 10 15 20 25 30 35 40 50 60 70 80 90 100] {
set n $m.$i
menu $n -tearoff 0
$m add command -label "G($i)" -command "G \[newNodes $i\]"
}
set m ${TOPOMENUPATH}.gridc
menu $m -tearoff 0
${TOPOMENUPATH} add cascade -label "Connected Grid" -menu $m -underline 0
for { set i 1 } { $i <= 10 } { incr i } {
set n $m.$i
menu $n -tearoff 0
$m add cascade -label "$i x N" -menu $n -underline 0
for { set j 1 } { $j <= 10 } { incr j } {
$n add command -label "$i x $j" -command "Gchelper $i $j"
}
}
set m ${TOPOMENUPATH}.chain
menu $m -tearoff 0
${TOPOMENUPATH} add cascade -label "Chain" -menu $m -underline 0
for { set i 2 } { $i <= 24 } { incr i } {
$m add command -label "P($i)" -command "P \[newNodes $i\]"
}
# Boeing
foreach i [list 32 64 128] {
$m add command -label "P($i)" -command "P \[newNodes $i\]"
}
# end Boeing
set m ${TOPOMENUPATH}.star
menu $m -tearoff 0
${TOPOMENUPATH} add cascade -label "Star" -menu $m -underline 0
for { set i 3 } { $i <= 25 } { incr i } {
$m add command -label "S($i)" \
-command "Kb \[newNodes 1\] \[newNodes [expr {$i - 1}]\]"
}
set m ${TOPOMENUPATH}.cycle
menu $m -tearoff 0
${TOPOMENUPATH} add cascade -label "Cycle" -menu $m -underline 0
for { set i 3 } { $i <= 24 } { incr i } {
$m add command -label "C($i)" -command "C \[newNodes $i\]"
}
set m ${TOPOMENUPATH}.wheel
menu $m -tearoff 0
${TOPOMENUPATH} add cascade -label "Wheel" -menu $m -underline 0
for { set i 4 } { $i <= 25 } { incr i } {
$m add command -label "W($i)" \
-command "W \"\[newNodes 1\] \[newNodes [expr {$i - 1}]\]\""
}
set m ${TOPOMENUPATH}.cube
menu $m -tearoff 0
${TOPOMENUPATH} add cascade -label "Cube" -menu $m -underline 0
for { set i 2 } { $i <= 6 } { incr i } {
$m add command -label "Q($i)" \
-command "Q \[newNodes [expr {int(pow(2,$i))}]\]"
}
set m ${TOPOMENUPATH}.clique
menu $m -tearoff 0
${TOPOMENUPATH} add cascade -label "Clique" -menu $m -underline 0
for { set i 3 } { $i <= 24 } { incr i } {
$m add command -label "K($i)" -command "K \[newNodes $i\]"
}
set m ${TOPOMENUPATH}.bipartite
menu $m -tearoff 0
${TOPOMENUPATH} add cascade -label "Bipartite" -menu $m -underline 0
for { set i 1 } { $i <= 12 } { incr i } {
set n $m.$i
menu $n -tearoff 0
$m add cascade -label "K($i,N)" -menu $n -underline 0
for { set j $i } { $j <= [expr {24 - $i}] } { incr j } {
$n add command -label "K($i,$j)" -command "Kbhelper $i $j"
}
}
proc newNodes { n } {
global curcanvas grid sizex sizey activetool activetoolp CORE_DATA_DIR
global g_last_selected_node_type
if { [lsearch {select start link bgobjs} $activetool] >= 0 } {
set activetoolp ""
}
# some other tool is selected besides layer-2/3 nodes
if { $activetoolp != "routers" && $activetoolp != "hubs" } {
if { [info exists g_last_selected_node_type] && \
$g_last_selected_node_type != "" } {
set parent [lindex $g_last_selected_node_type 0]
set b [lindex $g_last_selected_node_type 1]
set imgf [lindex $g_last_selected_node_type 2]
popupMenuChoose $parent $b $imgf
} else {
# select router by default (this properly sets some globals)
set icon "$CORE_DATA_DIR/icons/tiny/router.gif"
popupMenuChoose "routers" "router" $icon
}
}
set v {}
set r [expr {($n - 1) * (1 + 4 / $n) * $grid / 2}]
set x0 [expr {$sizex / 2}]
set y0 [expr {$sizey / 2}]
set twopidivn [expr {acos(0) * 4 / $n}]
set dy 32
if { [lsearch {router rj45} $activetool] >= 0 } {
set dy 28
} elseif { [lsearch {hub lanswitch} $activetool] >= 0 } {
set dy 24
}
for { set i 0 } { $i < $n } { incr i } {
if { $activetoolp == "routers" } {
set new_node [newNode router]
setNodeModel $new_node $activetool
} else {
set new_node [newNode $activetool]
}
set x [expr {$x0 + $r * cos($twopidivn * $i)}]
set y [expr {$y0 - $r * sin($twopidivn * $i)}]
setNodeCoords $new_node "$x $y"
setNodeLabelCoords $new_node "$x [expr {$y + $dy}]"
setNodeCanvas $new_node $curcanvas
lappend v $new_node
}
return $v
}
proc topoGenDone { v } {
global changed activetool
set activetool select
set changed 1
updateUndoLog
redrawAll
selectNodes $v
}
#
# Chain
#
proc P { v } {
.c config -cursor watch; update
set n [llength $v]
for { set i 0 } { $i < [expr {$n - 1}] } { incr i } {
newLink [lindex $v $i] [lindex $v [expr {($i + 1) % $n}]]
}
topoGenDone $v
}
#
# Cycle
#
proc C { v } {
.c config -cursor watch; update
set n [llength $v]
for { set i 0 } { $i < $n } { incr i } {
newLink [lindex $v $i] [lindex $v [expr {($i + 1) % $n}]]
}
topoGenDone $v
}
#
# Wheel
#
proc W { v } {
.c config -cursor watch; update
set n [llength $v]
set vr [lindex $v 0]
set vt "$v [lindex $v 1]"
for { set i 1 } { $i < $n } { incr i } {
newLink $vr [lindex $v $i]
newLink [lindex $v $i] [lindex $vt [expr {$i + 1}]]
}
topoGenDone $v
}
#
# Cube
#
proc Q { v } {
set n [llength $v]
set order [expr int(log($n)/log(2))]
for { set i 0 } { $i < $order } { incr i } {
animateCursor
set d [expr {int(pow(2, $i))}]
for { set j 0 } { $j < $n } { incr j } {
if { [llength [ifcList [lindex $v $j]]] <= $i} {
newLink [lindex $v $j] [lindex $v [expr {($j + $d) % $n}]]
}
}
}
topoGenDone $v
}
#
# Clique
#
proc K { v } {
set n [llength $v]
for { set i 0 } { $i < [expr {$n - 1}] } { incr i } {
animateCursor
for { set j [expr {$i + 1}] } { $j < $n } {incr j } {
newLink [lindex $v $i] [lindex $v $j]
}
}
topoGenDone $v
}
#
# Bipartite
#
proc Kb { v1 v2 } {
set n1 [llength $v1]
set n2 [llength $v2]
for { set i 0 } { $i < $n1 } { incr i } {
animateCursor
for { set j 0 } { $j < $n2 } {incr j } {
newLink [lindex $v1 $i] [lindex $v2 $j]
}
}
topoGenDone "$v1 $v2"
}
proc Kbhelper { n m } {
set v [newNodes [expr $n + $m]]
Kb [lrange $v 0 [expr $n -1]] [lrange $v $n end]
}
#
# Random
#
proc R { v } {
global curcanvas
set c .c
set min 20
set xmax [expr {[lindex [getCanvasSize $curcanvas] 0] - 2*$min}]
set ymax [expr {[lindex [getCanvasSize $curcanvas] 1] - 2*$min}]
expr { srand([clock clicks -milliseconds]) }
.c config -cursor watch; update
foreach node $v {
set x [expr { int(rand() * $xmax) + $min} ]
set y [expr { int(rand() * $ymax) + $min} ]
setNodeCoords $node "$x $y"
set dy 28
setNodeLabelCoords $node "$x [expr {$y + $dy}]"
}
topoGenDone $v
}
#
# Grid
#
proc G { v } {
global curcanvas
set c .c
set step 100
set min 50
set xmax [expr {[lindex [getCanvasSize $curcanvas] 0] - 2*$min}]
set ymax [expr {[lindex [getCanvasSize $curcanvas] 1] - 2*$min}]
.c config -cursor watch; update
set x $min
set y $min
foreach node $v {
if { $x >= $xmax } { ;# end of the row
set x $min
incr y $step
if { $y >= $ymax } {
# xmax and ymax reached -- out of canvas space here!
set y $ymax
}
}
setNodeCoords $node "$x $y"
set dy 28
setNodeLabelCoords $node "$x [expr {$y + $dy}]"
incr x $step
}
topoGenDone $v
}
#
# Connected Grid
#
proc Gc { v n m } {
set step 100
set dy 28
set y $step
set nodenum 0
# m is number of rows
for { set i 0 } { $i < $m } { incr i } {
animateCursor
set x 0 ;# start a new row
# n is number of columns
for { set j 0 } { $j < $n } {incr j } {
incr x $step
set node [lindex $v $nodenum]
setNodeCoords $node "$x $y"
setNodeLabelCoords $node "$x [expr {$y + $dy}]"
if { $x > $step } { ;# link each node with prev in row
set lastnode [lindex $v [expr {$nodenum - 1}]]
newLink $lastnode $node
}
if { $y > $step } { ;# link each node with above in column
set lastnode [lindex $v [expr {$nodenum - $n}]]
newLink $lastnode $node
}
incr nodenum 1 ;# on to the next column
}
incr y $step ;# on to the next row
}
topoGenDone $v
}
proc Gchelper { n m } {
set v [newNodes [expr $n * $m]]
Gc $v $n $m
}