Sie sind auf Seite 1von 8

namespace eval viewBySystem {

variable thisScript [info script]


variable ns [namespace current]::
variable pArr
array set pArr [list \
tabname ViewBySystem \
gui .vBS \
debug 0 \
]
variable dirArr
array set dirArr [list \
bottom,x [list 1.0 0.0 0.0 ]\
bottom,y [list 0.0 -1.0 0.0 ]\
bottom,z [list 0.0 0.0 -1.0 ]\
front,x [list 0.0 -1.0 0.0 ]\
front,y [list 0.0 -0.0 1.0 ]\
front,z [list -1.0 0.0 0.0 ]\
iso1,x [list 0.707107 -0.707107 0.0 ]\
iso1,y [list 0.353553 0.353553 0.866025 ]\
iso1,z [list -0.612372 -0.612372 0.5 ]\
iso2,x [list -0.866025 -0.5 0.0 ]\
iso2,y [list 0.250000 -0.433013 0.866025 ]\
iso2,z [list -0.433013 0.75 0.5 ]\
leftside,x [list 1.0 0.0 0.0 ]\
leftside,y [list 0.0 -0.0 1.0 ]\
leftside,z [list 0.0 -1.0 0.0 ]\
rear,x [list 0.0 1.0 0.0 ]\
rear,y [list 0.0 0.0 1.0 ]\
rear,z [list 1.0 0.0 0.0 ]\
rightside,x [list -1.0 0.0 0.0 ]\
rightside,y [list 0.0 0.0 1.0 ]\
rightside,z [list 0.0 1.0 0.0 ]\
top,x [list 1.0 0.0 0.0 ]\
top,y [list 0.0 1.0 0.0 ]\
top,z [list 0.0 0.0 1.0 ]\
]
variable axisArr
namespace eval math {
proc ADD {x y} {
foreach X $x Y $y {
lappend res [expr $X + $Y ]
}
return $res
}
proc SUB {x y} {
foreach X $x Y $y {
lappend res [expr $X - $Y ]
}
return $res
}
proc MUL {x y} {
foreach X $x {
lappend res [expr $X * $y ]
}
return $res
}
proc DIV {x y } {
foreach X $x {
lappend res [expr {1.0 * $X / $y} ]
}
return $res
}
proc DOT {x y} {
set sum 0
foreach X $x Y $y {
set sum [expr {$sum + $X * $Y}]
}
return $sum
}
proc NORM {x {unit "dummy"}} {
# 2. Param = Einheitsvekor, Return=Laenge
upvar $unit res
set n [expr {sqrt([DOT $x $x])}]
if {$n == 0} {
set res $x
} else {
set res [DIV $x $n]
}
return $n
}
proc CROSS {x y} {
foreach {ax ay az} $x {}
foreach {bx by bz} $y {}
return [list [expr {$ay * $bz - $az * $by}] \
[expr {$az * $bx - $ax * $bz}] \
[expr {$ax * $by - $ay * $bx}] ]
}
}

proc viewStandard dir {


variable dirArr
variable axisArr
variable pArr
if {$pArr(sys) == 0 || [lsearch [list "reverse" "cw" "ccw"] $dir]>-1} {
*view $dir
return
}
set x $dirArr($dir,x)
set y $dirArr($dir,y)
set O $axisArr(origin)
foreach {c1 c2 c3} $x break
set X [math::ADD [math::ADD [math::MUL $axisArr(x) $c1] [math::MUL $axisArr(
y) $c2]] [math::MUL $axisArr(z) $c3]]
foreach {c1 c2 c3} $y break
set Y [math::ADD [math::ADD [math::MUL $axisArr(x) $c1] [math::MUL $axisArr(
y) $c2]] [math::MUL $axisArr(z) $c3]]
viewSetFromCoords $X $Y $O none
}
proc selectSystem {} {
variable pArr
variable axisArr
*createentitypanel systems "Select orientation system"
set pArr(sys) [hm_info lastselectedentity systems 1]
selSysTxt
array unset axisArr
if {$pArr(sys)!= 0} {
foreach ax {x y z} {
foreach coord {x y z} {
lappend axisArr($ax) [hm_getentityvalue systems $pArr(sys) global${ax}
axis$coord 0]
}
}
set axisArr(origin) [list [hm_getentityvalue systems $pArr(sys) globalorig
inx 0] [hm_getentityvalue systems $pArr(sys) globaloriginz 0] [hm_getentityvalue
systems $pArr(sys) globaloriginz 0]]
}
hm_highlightentity systems 0 n
}
proc selSysTxt {} {
variable pArr
if {$pArr(sys) != 0} {
set pArr(sysTxt) "System: $pArr(sys)"
} else {
set pArr(sysTxt) "System: global"
}
}
proc accessView {} {
variable pArr
eval $pArr(view)
}
proc DestroyPanel {} {
variable pArr
catch {destroy .$pArr(gui)}
hm_framework removetab $pArr(tabname)
}
proc CreatePanel {} {
variable pArr
variable ns
variable thisScript
set tablist [ hm_framework getalltabs ]
if { [ lsearch $tablist $pArr(tabname) ] > -1 } {
DestroyPanel
}
if {[winfo exist $pArr(gui)]} {
destroy $pArr(gui)
}
set main [ frame $pArr(gui) ]
hm_framework addtab $pArr(tabname) $main
set colMax 4
set colHalf 2

set lFrame [hwt::LabeledFrame $main.frame " Set view by system" topPad 2


\
-side top \
-anchor nw \
-padx 1 \
-pady 1 \
-justify left \
-expand 0]
set p $lFrame
for {set col 0} {$col < $colMax} {incr col} {
grid columnconfigure $p $col -weight 1 -uniform A
}

set row 1
set sButton [button $p.sButton \
-bg yellow \
-activebackground yellow \
-command "${ns}selectSystem" \
-text "Orientation system" \
-font [hwt::AppFont]]
grid $sButton -row $row -column 0 -padx 2 -pady 4 -sticky we -columnspan
$colHalf
if {[info exist pArr(sys)]==0} {
set pArr(sys) 0
} else {
if {[hm_entityinfo exist systems $pArr(sys)]==0} {
set pArr(sys) 0
}
}
selSysTxt
set sLabel [label $p.sLabel \
-textvariable ${ns}pArr(sysTxt) \
-font [hwt::AppFont]]
grid $sLabel -row $row -column $colHalf -padx 2 -pady 4 -sticky we -colu
mnspan $colHalf
incr row
set col 0
set ctr 0
foreach item {leftside rightside bottom top rear front reverse iso1 cw
ccw} \
txt {left right bottom top rear front reverse iso clockwi
se counterclockwise} {
set ${item}Button [button $p.${item}Button \
-command "${ns}viewStandard $item" \
-text "$txt" \
-font [hwt::AppFont]]
grid [set ${item}Button] -row [expr $row + $ctr / 2] -column [expr $col
+ $colHalf * ($ctr % 2)] -padx 4 -pady 1 -sticky we -columnspan $colHalf
incr ctr
}
set row [expr $row+($ctr-1)/2]
set lSButton [button $p.lSButton \
-command "${ns}snapAxisLocal" \
-text "Snap local axis" \
-font [hwt::AppFont]]
grid $lSButton -row [incr row] -column 0 -padx 4 -pady 4 -sticky we -colu
mnspan $colHalf
set gSButton [button $p.gSButton \
-command "${ns}snapAxisGlobal" \
-text "Snap global axis" \
-font [hwt::AppFont]]
grid $gSButton -row $row -column $colHalf -padx 4 -pady 4 -sticky we -col
umnspan $colHalf
if {$pArr(debug)} {
foreach c [list "source $thisScript" \
"arrayVis ${ns}pArr" \
"arrayVis ${ns}dirArr" \
"arrayVis ${ns}axisArr" \
"${ns}getArrayFromView vArr ; arrayVis vArr" \
"${ns}accessView"] \
l {"Restart" \
"pArr" \
"dirArr" \
"axisArr" \
"viewArr" \
"accessView" \
} {
grid [button $p.r${row}c1 \
-command $c -text $l -font [hwt::AppFont]] -row [incr row] -column
$colHalf -padx 4 -pady 1 -sticky we -columnspan $colHalf
incr row
}
}
}

proc getArrayFromView arr {


upvar $arr vArr
array unset vArr
#Transformation matrix (first 16 values of *viewset)
foreach {x1 y1 z1 ZERO x2 y2 z2 ZERO x3 y3 z3 ZERO t1 t2 t3 ONE} [lindex [hm
_getcurrentview] 0] {}
set vArr(x) [list $x1 $x2 $x3]
set vArr(y) [list $y1 $y2 $y3]
set vArr(z) [list $z1 $z2 $z3]

#Transformation of screen center (used later)


set vArr(trans) [list $t1 $t2 $t3]
# screen range in axis units (last 4 values of *viewset)
foreach {vArr(xmin) vArr(ymin) vArr(xMax) vArr(yMax)} [lindex [hm_getviewpor
t] 0] {}

#average range values


set vArr(xcenter) [expr 0.5 * ($vArr(xmin) + $vArr(xMax))]
set vArr(ycenter) [expr 0.5 * ($vArr(ymin) + $vArr(yMax))]
set p [math::ADD [math::MUL $vArr(x) $vArr(xcenter)] [math::MUL $vArr(y) $vA
rr(ycenter)]]
set oTrans [math::ADD [math::MUL $vArr(x) $t1] [math::ADD [math::MUL $vArr(y
) $t2] [math::MUL $vArr(z) $t3]]]
#center of the screen
set vArr(origin) [math::SUB $p $oTrans]
set xLeft [math::MUL $vArr(x) [expr 0.5 * ($vArr(xmin) - $vArr(xMax))]]
set xRight [math::MUL $vArr(x) [expr 0.5 * ($vArr(xMax) - $vArr(xmin))]]
set yBottom [math::MUL $vArr(y) [expr 0.5 * ($vArr(ymin) - $vArr(yMax))]]
set yTop [math::MUL $vArr(y) [expr 0.5 * ($vArr(yMax) - $vArr(ymin))]]
return
}
proc viewSetFromCoords {X Y C {width "keep"}} {
variable pArr
# View set using screen orientation and center
if {$pArr(debug)} {puts "viewSetFromCoords:\n x: $X\n y: $Y\n C: $C\n wi
dth: $width"}
if {[llength $C]==1} {
set C [lindex [hm_nodevalue $C] 0]
}
if {[llength $X] ==1} {
set X [math::SUB [lindex [hm_nodevalue $X] 0] $C]
}
if {[llength $Y] ==1} {
set Y [math::SUB [lindex [hm_nodevalue $Y] 0] $C]
}
set Z [math::CROSS $X $Y]
math::NORM $X X
set Y [math::CROSS $Z $X]
math::NORM $X X
math::NORM $Y Y
math::NORM $Z Z
if {$pArr(debug)} {puts "resulting Dirs:\n $X\n $Y\n $Z"}
foreach x $X y $Y z $Z {
lappend vsP $x $y $z 0
}
lappend vsP [expr -1.0 * [math::DOT $X $C]] [expr -1.0 * [math::DOT $Y $C]]
[expr -1.0 * [math::DOT $Z $C]] 1
if {$width == "none" || $width == "fit"} {
lappend vsP 0 0 0 0
if {$pArr(debug)} {puts "eval *viewset $vsP" ; set pArr(view) "*viewset $v
sP"} else {
eval *viewset $vsP
*window 0 0 0 0
}
} elseif {$width =="keep"} {
set viewPoint [lindex [hm_getviewport] 0]
set xc [expr 0.5 * ([lindex $viewPoint 0] + [lindex $viewPoint 2])]
set yc [expr 0.5 * ([lindex $viewPoint 1] + [lindex $viewPoint 3])]
lappend vsP [expr [lindex $viewPoint 0] - $xc] [expr [lindex $viewPoint 1]
- $yc] [expr [lindex $viewPoint 2] - $xc] [expr [lindex $viewPoint 3] - $yc]
if {$pArr(debug)} {puts "eval *viewset $vsP" ; set pArr(view) "*viewset $v
sP"} else {
eval *viewset $vsP
}
} else {
set YY [expr $width /2.0]
set XX [expr 2.0 * $width / 3.0]
lappend vsP -$XX -$YY $XX $YY
if {$pArr(debug)} {puts "eval *viewset $vsP"; set pArr(view) "*viewset $vs
P"} else {
eval *viewset $vsP
}
}
}
proc snapAxisGlobal {} {
variable pArr
foreach {x1 y1 z1 ZERO x2 y2 z2 ZERO x3 y3 z3 ZERO t1 t2 t3 ONE} [lindex [hm
_getcurrentview] 0] {}
set firstAxis [list [list {1 0 0} $x1 x] [list {-1 0 0} [expr -$x1] x] [list
{0 1 0} $x2 y] [list {0 -1 0} [expr -$x2] y] [list {0 0 1} $x3 z] [list {0 0 -1
} [expr -$x3] z]]
set biggest [lindex [lsort -real -index 1 $firstAxis] end]
if {$pArr(debug)} {puts $firstAxis}
if {$pArr(debug)} {puts $biggest}
math::NORM [math::MUL [lindex $biggest 0] [lindex $biggest 1]] dirX
set taken [lindex $biggest 2]
switch $taken {
"x" {
set scndAxis [list [list {0 1 0} $y2] [list {0 -1 0} [expr -$y2]] [list
{0 0 1} $y3] [list {0 0 -1} [expr -$y3]]]
}
"y" {
set scndAxis [list [list {1 0 0} $y1] [list {-1 0 0} [expr -$y1]] [list
{0 0 1} $y3] [list {0 0 -1} [expr -$y3]]]
}
"z" {
set scndAxis [list [list {1 0 0} $y1] [list {-1 0 0} [expr -$y1]] [list
{0 1 0} $y2] [list {0 -1 0} [expr -$y2]]]
}
}
set biggest2 [lindex [lsort -real -index 1 $scndAxis] end]
if {$pArr(debug)} {puts $scndAxis}
if {$pArr(debug)} {puts $biggest2}
math::NORM [eval math::MUL $biggest2] dirY
if {$pArr(debug)} {puts $dirY}
getArrayFromView vArr
viewSetFromCoords $dirX $dirY $vArr(origin) keep
}
proc snapAxisLocal {} {
variable pArr
variable axisArr
if {$pArr(sys)==0} {
hm_usermessage "No local system defined!"
return
}
if {$pArr(debug)} {puts "snapAxisLocal"}
getArrayFromView vArr
set xDir [math::DOT $vArr(x) $axisArr(x)]
set yDir [math::DOT $vArr(x) $axisArr(y)]
set zDir [math::DOT $vArr(x) $axisArr(z)]
set firstAxis [list [list $xDir x 1] [list [expr -$xDir] x -1] [list $yDir y
1] [list [expr -$yDir] y -1] [list $zDir z 1] [list [expr -$zDir] z -1]]
set biggest [lindex [lsort -real -index 0 $firstAxis] end]
if {$pArr(debug)} {puts " first : $firstAxis"}
if {$pArr(debug)} {puts " $biggest"}
math::NORM [math::MUL $axisArr([lindex $biggest 1]) [lindex $biggest 2]] dir
X
set taken [lindex $biggest 1]
switch $taken {
"x" {
set yDir [math::DOT $vArr(y) $axisArr(y)]
set zDir [math::DOT $vArr(y) $axisArr(z)]
set scndAxis [list [list $yDir y 1] [list [expr -$yDir] y -1] [list $zDi
r z 1] [list [expr -$zDir] z -1]]
}
"y" {
set xDir [math::DOT $vArr(y) $axisArr(x)]
set zDir [math::DOT $vArr(y) $axisArr(z)]
set scndAxis [list [list $xDir x 1] [list [expr -$xDir] x -1] [list $zDi
r z 1] [list [expr -$zDir] z -1]]
}
"z" {
set xDir [math::DOT $vArr(y) $axisArr(x)]
set yDir [math::DOT $vArr(y) $axisArr(y)]
set scndAxis [list [list $xDir x 1] [list [expr -$xDir] x -1] [list $yDi
r y 1] [list [expr -$yDir] y -1]]
}
}
set biggest2 [lindex [lsort -real -index 0 $scndAxis] end]
if {$pArr(debug)} {puts " scnd : $scndAxis"}
if {$pArr(debug)} {puts " $biggest2"}
math::NORM [math::MUL $axisArr([lindex $biggest2 1]) [lindex $biggest2 2]] d
irY
if {$pArr(debug)} {puts $dirY}
getArrayFromView vArr
viewSetFromCoords $dirX $dirY $vArr(origin) keep
}
}
viewBySystem::CreatePanel

Das könnte Ihnen auch gefallen