# # Copyright 2003 (c) Pointwise, Inc. # All rights reserved. # # This sample Gridgen script is not supported by Pointwise, Inc. # It is provided freely for demonstration purposes only. # SEE THE WARRANTY DISCLAIMER AT THE BOTTOM OF THIS FILE. # gg::tkLoad catch { set scriptDir [file dirname [info script]] source [file join $scriptDir pwiLogo.glf] } set Center "0,0,0" set Radius 1 set Dimensions {} proc axisAngleToQuat { axis angle } { variable u variable w variable x variable y variable z set axis [ggu::vec3Normalize $axis] # convert from degrees to radians and negate set Pi 3.14159265358979 set angle [expr {-fmod($angle, 360.0) * $Pi / 180.0}] set u [expr {sin(0.5 * $angle)}] set axis [ggu::vec3Scale $axis $u] foreach {x y z} $axis {break} set w [expr {cos(0.5 * $angle)}] return [list $x $y $z $w] } proc quatToMatrix { quat matName } { upvar $matName mat foreach {x y z w} $quat {break} set Nq [expr {$x*$x + $y*$y + $z*$z + $w*$w}] if {$Nq > 0.0} { set s [expr {2.0 / $Nq}] } else { set s 0.0 } set xs [expr {$x * $s}] set ys [expr {$y * $s}] set zs [expr {$z * $s}] set wx [expr {$w * $xs}] set wy [expr {$w * $ys}] set wz [expr {$w * $zs}] set xx [expr {$x * $xs}] set xy [expr {$x * $ys}] set xz [expr {$x * $zs}] set yy [expr {$y * $ys}] set yz [expr {$y * $zs}] set zz [expr {$z * $zs}] set mat(0,0) [expr {1.0 - ($yy + $zz)}] set mat(1,0) [expr {$xy + $wz}] set mat(2,0) [expr {$xz - $wy}] set mat(3,0) 0.0 set mat(0,1) [expr {$xy - $wz}] set mat(1,1) [expr {1.0 - ($xx + $zz)}] set mat(2,1) [expr {$yz + $wx}] set mat(3,1) 0.0 set mat(0,2) [expr {$xz + $wy}] set mat(1,2) [expr {$yz - $wx}] set mat(2,2) [expr {1.0 - ($xx + $yy)}] set mat(3,2) 0.0 set mat(0,3) 0.0 set mat(1,3) 0.0 set mat(2,3) 0.0 set mat(3,3) 1.0 } proc transformPoint { xyz matName } { upvar $matName mat foreach {x y z} $xyz {break} return [list [expr $x*$mat(0,0)+$y*$mat(0,1)+$z*$mat(0,2)] [expr $x*$mat(1,0)+$y*$mat(1,1)+$z*$mat(1,2)] [expr $x*$mat(2,0)+$y*$mat(2,1)+$z*$mat(2,2)]] } proc Coord2List { coord } { set a "?" set x "?" set y "?" set z "?" set re {^\s*([-.eE0-9]+)[, ]+([-.eE0-9]+)[, ]+([-.eE0-9]+)\s*$} catch { regexp $re $coord a x y z } if {[string is double $x] == 0 || [string is double $y] == 0 || \ [string is double $z] == 0 } { set st [list 0 0 0] } else { set st [list $x $y $z] } return $st } proc makeConnector { } { global Center Radius Dimensions if { ![isCoordinate $Center] } { bell focus .inputs.coord return 0 } if { ![string is double $Radius] } { bell focus .inputs.rad return 0 } if { $Dimensions != "" && ![string is integer $Dimensions] } { bell focus .inputs.dim return 0 } if { $Radius == 0 } { focus .inputs.rad return 0; } set point(0) "0 $Radius 0" set point(1) "[expr -1*$Radius] 0 0" set point(2) "0 [expr -1*$Radius] 0" set point(3) "$Radius 0 0" foreach {axis angle} [gg::dispViewRot] {break} quatToMatrix [axisAngleToQuat $axis $angle] mat set centerVec [Coord2List $Center] set point(0) [ggu::vec3Add [transformPoint $point(0) mat] $centerVec] set point(1) [ggu::vec3Add [transformPoint $point(1) mat] $centerVec] set point(2) [ggu::vec3Add [transformPoint $point(2) mat] $centerVec] set point(3) [ggu::vec3Add [transformPoint $point(3) mat] $centerVec] gg::conBegin gg::segBegin -type CIRCULAR_ARC gg::segAddControlPt $point(0) gg::segAddControlPt $point(1) gg::segAddControlPt -alternate CENTER $centerVec gg::segEnd gg::segBegin -type CIRCULAR_ARC gg::segAddControlPt $point(1) gg::segAddControlPt $point(2) gg::segAddControlPt -alternate CENTER $centerVec gg::segEnd if { [catch { set con1 [gg::conEnd] }] == 1 } { tk_messageBox -icon error -title "Connector already exists" \ -message "The connector that you are trying to create already exists." \ -type ok return 0 } gg::conBegin gg::segBegin -type CIRCULAR_ARC gg::segAddControlPt $point(2) gg::segAddControlPt $point(3) gg::segAddControlPt -alternate CENTER $centerVec gg::segEnd gg::segBegin -type CIRCULAR_ARC gg::segAddControlPt $point(3) gg::segAddControlPt $point(0) gg::segAddControlPt -alternate CENTER $centerVec gg::segEnd if { [catch { set con2 [gg::conEnd] }] == 1 } { tk_messageBox -icon error -title "Connector already exists" \ -message "The connector that you are trying to create already exists." \ -type ok gg::conDelete $con1 return 0 } if { $Dimensions != "" } { if { [string is integer $Dimensions] && $Dimensions >= 4 } { set dim1 [expr {1 + ($Dimensions)/2}] set dim2 [expr {$Dimensions + 2 - $dim1}] gg::conDim $con1 $dim1 gg::conDim $con2 $dim2 } else { tk_messageBox -icon error -title "Error: Dimensions too small" \ -message "The connectors could not be dimensioned because the dimensions for each connector (Dimension / 2) was less than 3." \ -type ok } } return 1 } proc isCoordinate { str } { global errorCode set a "?" set x "?" set y "?" set z "?" set re {^\s*([-.eE0-9]+)[, ]+([-.eE0-9]+)[, ]+([-.eE0-9]+)\s*$} catch { regexp $re $str a x y z } if {[string is double $x] == 0 || [string is double $y] == 0 || \ [string is double $z] == 0 } { set st 0 } else { set st 1 } return $st } proc checkCoordinateInput { w var text action } { global ConCircle # Ignore force validations if {$action == -1} { return 1 } if {![isCoordinate $text]} { set ConCircle($var) 0 $w configure -bg "#FFCCCC" } else { set ConCircle($var) 1 $w configure -bg "#FFFFFF" } checkInputStatus return 1 } proc checkRadiusInput { w var text action } { global ConCircle # Ignore force validations if {$action == -1} { return 1 } if {![string is double $text] || 0.0 >= $text} { set ConCircle($var) 0 $w configure -bg "#FFCCCC" } else { set ConCircle($var) 1 $w configure -bg "#FFFFFF" } checkInputStatus return 1 } proc checkDimInput { w var text action } { global ConCircle # Ignore force validations if {$action == -1} { return 1 } if {![string is integer $text] || 4 > $text} { set ConCircle($var) 0 $w configure -bg "#FFCCCC" } else { set ConCircle($var) 1 $w configure -bg "#FFFFFF" } checkInputStatus return 1 } proc checkInputStatus { } { global ConCircle if {0 == $ConCircle(coord) || 0 == $ConCircle(rad) || \ 0 == $ConCircle(dim)} { $ConCircle(okButton) configure -state disabled } else { $ConCircle(okButton) configure -state normal } } proc makeInputField { parent name title variable {width 7} {valid ""}} { frame $parent.$name label .lbl$name -text $title entry .ent$name -textvariable $variable -width $width if { [string compare $valid ""]!=0 } { .ent$name configure -validate all .ent$name configure -validatecommand $valid } pack ".lbl$name" -side left -padx 3 -pady 1 -in $parent.$name pack ".ent$name" -side right -padx 3 -pady 1 -in $parent.$name return $parent.$name } proc makeWindow { } { global ConCircle label .title -text "Circular Connector" set font [.title cget -font] .title configure -font [font create -family [font actual $font -family] -weight bold] pack .title -expand 1 -side top pack [frame .hr1 -relief sunken -height 2 -bd 1] -side top -padx 2 -fill x -pady 1 pack [frame .inputs] -fill x -padx 2 set ConCircle(coord) 1 set ConCircle(rad) 1 set ConCircle(dim) 0 pack [makeInputField .inputs coord "Center Coordinate:" Center 7 [list checkCoordinateInput %W coord %P %d]] -fill x -padx 20 -pady 2 pack [makeInputField .inputs rad "Radius:" Radius 7 [list checkRadiusInput %W rad %P %d]] -fill x -padx 20 -pady 2 pack [makeInputField .inputs dim "Dimensions:" Dimensions 7 [list checkDimInput %W dim %P %d]] -fill x -padx 20 -pady 2 pack [frame .hr2 -relief sunken -height 2 -bd 1] -side top -padx 2 -fill x -pady 1 pack [frame .buttons] -fill x -padx 2 -pady 1 pack [button .buttons.cancel -text "Cancel" -command { exit }] -side right -padx 2 pack [button .buttons.ok -text "OK" -command { if { [makeConnector] == 1 } { exit } }] -side right -padx 2 set ConCircle(okButton) .buttons.ok if {![catch {pwiLogoCreate .buttons.logo 1} b]} { $b configure -bd 0 -relief flat pack $b -side left -padx 5 -fill y } checkInputStatus } makeWindow ::tk::PlaceWindow . widget gg::tkLoop # # DISCLAIMER: # TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, POINTWISE DISCLAIMS # ALL WARRANTIES, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED # TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR # PURPOSE, WITH REGARD TO THIS SCRIPT. TO THE MAXIMUM EXTENT PERMITTED # BY APPLICABLE LAW, IN NO EVENT SHALL POINTWISE BE LIABLE TO ANY PARTY # FOR ANY SPECIAL, INCIDENTAL, INDIRECT, OR CONSEQUENTIAL DAMAGES # WHATSOEVER (INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF # BUSINESS INFORMATION, OR ANY OTHER PECUNIARY LOSS) ARISING OUT OF THE # USE OF OR INABILITY TO USE THIS SCRIPT EVEN IF POINTWISE HAS BEEN # ADVISED OF THE POSSIBILITY OF SUCH DAMAGES AND REGARDLESS OF THE # FAULT OR NEGLIGENCE OF POINTWISE. #