can't read "::gUseToplevel": no such variable
    while executing
"if { $::gUseToplevel } {
    set gRoot   .po
    set gRootFr .po.fr
} else {
    set gRoot   .
    set gRootFr .fr
}"
    (in namespace eval "::request" script line 31)
    invoked from within
"namespace eval ::request $script"
    ("::try" body line 12)

OUTPUT BUFFER:

# Copyright: 2005-2010 Paul Obermeier (obermeier@tcl3d.org) # # See the file "Tcl3D_License.txt" for information on # usage and redistribution of this file, and for a # DISCLAIMER OF ALL WARRANTIES. # # Module: Tcl3D # Filename: modelViewer.tcl # # Author: Paul Obermeier # # Description: Tcl program to display 3D model files in all formats supported # by the Tcl3D extension. # Set next variable to 1, if you want to source this file and use a separate # toplevel, instead of integrating into the widget hierarchy. set gUseToplevel 0 # Enable azimuth and elevation sliders. set gShowSliders 1 # Set next variable to 1, if your graphic supports multisampling. set gUseMultisampling 0 # Set next variable to 1, if you want screen rectangle mode enabled. set gUseScreenRect 0 # Enable the use of angles instead of trackball matrix. set gPo(useAngles) 1 if { $::gUseToplevel } { set gRoot .po set gRootFr .po.fr } else { set gRoot . set gRootFr .fr } proc InitPackages { args } { global gPo foreach pkg $args { set retVal [catch {package require $pkg} gPo(ext,$pkg,version)] set gPo(ext,$pkg,avail) [expr !$retVal] } } # Add current directory to search for Tcl3D package. set auto_path [linsert $auto_path 0 "."] InitPackages Img tcl3d set gTextureId [tcl3dVector GLuint 1] set gScriptName [info script] proc GetPackageInfo {} { global gPo set msgList {} foreach name [lsort [array names gPo "ext,*,avail"]] { set pkg [lindex [split $name ","] 1] lappend msgList [list $pkg $gPo(ext,$pkg,avail) $gPo(ext,$pkg,version)] } return $msgList } proc poWin:CreateScrolledWidget { wType w titleStr args } { if { [winfo exists $w.par] } { destroy $w.par } frame $w.par if { [string compare $titleStr ""] != 0 } { label $w.par.label -text "$titleStr" } eval { $wType $w.par.widget \ -xscrollcommand "$w.par.xscroll set" \ -yscrollcommand "$w.par.yscroll set" } $args scrollbar $w.par.xscroll -command "$w.par.widget xview" -orient horizontal scrollbar $w.par.yscroll -command "$w.par.widget yview" -orient vertical set rowNo 0 if { [string compare $titleStr ""] != 0 } { set rowNo 1 grid $w.par.label -sticky ew -columnspan 2 } grid $w.par.widget $w.par.yscroll -sticky news grid $w.par.xscroll -sticky ew grid rowconfigure $w.par $rowNo -weight 1 grid columnconfigure $w.par 0 -weight 1 pack $w.par -side top -fill both -expand 1 return $w.par.widget } proc poWin:CreateScrolledText { w titleStr args } { return [eval {poWin:CreateScrolledWidget text $w $titleStr} $args ] } proc poWin:CreateScrolledListbox { w titleStr args } { return [eval {poWin:CreateScrolledWidget listbox $w $titleStr} $args ] } proc poMisc:Max { a b } { if { $a > $b } { return $a } else { return $b } } proc PkgInfo {} { set tw .tcl3dModelView:PkgInfoWin catch { destroy $tw } toplevel $tw wm title $tw "Package Information" wm resizable $tw true true frame $tw.fr0 -relief sunken -borderwidth 1 grid $tw.fr0 -row 0 -column 0 -sticky nwse set textId [poWin:CreateScrolledText $tw.fr0 "" -wrap word -height 2] $textId insert end "Tcl version: [info patchlevel]\n" avail foreach pkgInfo [GetPackageInfo] { set msgStr "Package [lindex $pkgInfo 0]: [lindex $pkgInfo 2]\n" if { [lindex $pkgInfo 1] == 1} { set tag avail } else { set tag unavail } $textId insert end $msgStr $tag } $textId tag configure avail -background green $textId tag configure unavail -background red $textId configure -state disabled # Create OK button frame $tw.fr1 -relief sunken -borderwidth 1 grid $tw.fr1 -row 1 -column 0 -sticky nwse button $tw.fr1.b -text "OK" -command "destroy $tw" -default active bind $tw.fr1.b "destroy $tw" pack $tw.fr1.b -side left -fill x -padx 2 -expand 1 grid columnconfigure $tw 0 -weight 1 grid rowconfigure $tw 0 -weight 1 bind $tw "destroy $tw" bind $tw "destroy $tw" focus $tw } proc GLInfo {} { set tw .tcl3dModelView:GLInfoWin catch { destroy $tw } toplevel $tw wm title $tw "OpenGL Information" wm resizable $tw true true frame $tw.fr0 -relief sunken -borderwidth 1 grid $tw.fr0 -row 0 -column 0 -sticky nwse set textId [tcl3dCreateScrolledText $tw.fr0 "" -wrap word -height 4] foreach glInfo [tcl3dOglGetVersions] { set msgStr "[lindex $glInfo 0]: [lindex $glInfo 1]\n" $textId insert end $msgStr avail } $textId tag configure avail -background green $textId configure -state disabled # Create OK button frame $tw.fr1 -relief sunken -borderwidth 1 grid $tw.fr1 -row 1 -column 0 -sticky nwse button $tw.fr1.b -text "OK" -command "destroy $tw" -default active bind $tw.fr1.b "destroy $tw" pack $tw.fr1.b -side left -fill x -padx 2 -expand 1 grid columnconfigure $tw 0 -weight 1 grid rowconfigure $tw 0 -weight 1 bind $tw "destroy $tw" bind $tw "destroy $tw" focus $tw } proc ShortcutInfo {} { set tw .tcl3dModelView:ShortcutInfoWin catch { destroy $tw } toplevel $tw wm title $tw "Shortcut Information" wm resizable $tw true true frame $tw.fr0 -relief sunken -borderwidth 1 grid $tw.fr0 -row 0 -column 0 -sticky nwse set textId [poWin:CreateScrolledText $tw.fr0 "" -wrap none -height 9] $textId insert end "Key l: Toggle line and flat shaded drawing\n" $textId insert end "Key f: Toggle showing backfaces as faces or lines\n" if { $::gUseMultisampling } { $textId insert end "Key m: Toggle drawing with/without multisampling\n" } if { $::gUseScreenRect } { $textId insert end "Key b: Toggle drawing the enclosing screen rect\n" } $textId insert end "Key r: Reset translations and rotations\n" $textId insert end "\n" $textId insert end "LeftMouseButton : Rotate object\n" $textId insert end "RightMouseButton : Zoom in and out\n" $textId insert end "Ctrl + RightMouseButton : Move up and down\n" $textId insert end "Shift + RightMouseButton: Move left and right\n" $textId configure -state disabled # Create OK button frame $tw.fr1 -relief sunken -borderwidth 1 grid $tw.fr1 -row 1 -column 0 -sticky nwse button $tw.fr1.b -text "OK" -command "destroy $tw" -default active bind $tw.fr1.b "destroy $tw" pack $tw.fr1.b -side left -fill x -padx 2 -expand 1 grid columnconfigure $tw 0 -weight 1 grid rowconfigure $tw 0 -weight 1 bind $tw "destroy $tw" bind $tw "destroy $tw" focus $tw } proc AddMenuCmd { menu label acc cmd args } { eval {$menu add command -label $label -accelerator $acc -command $cmd} $args } proc AddMenuCheck { menu label acc var cmd args } { eval {$menu add checkbutton -label $label -accelerator $acc \ -variable $var -command $cmd} $args } proc MoveStart { win x y } { set ::mouseX $x set ::mouseY $y } proc MoveCont { win x y axis } { global gPo set diff [expr $y - $::mouseY] set gPo($axis) [expr $gPo($axis) + 0.1 * $diff] set ::mouseX $x set ::mouseY $y $win postredisplay } proc MoveEnd { win x y } { $win postredisplay } proc ShowMainWin { title } { global tcl_platform gPo gRoot gRootFr if { $::gUseToplevel } { if { [file tail $::gScriptName] == [file tail $::argv0] } { # If started directly from tclsh or wish, then destroy # default toplevel. wm withdraw . } toplevel $gRoot } # Create the windows title. wm title $gRoot $title wm minsize $gRoot 100 100 set sw [winfo screenwidth $gRoot] set sh [winfo screenheight $gRoot] wm maxsize $gRoot [expr $sw -20] [expr $sh -40] # Master frame. Needed to integrate demo into Tcl3D Starpack presentation. frame $gRootFr pack $gRootFr -fill both -expand 1 frame $gRootFr.workfr -relief sunken -borderwidth 1 pack $gRootFr.workfr -side top -fill both -expand 1 frame $gRootFr.workfr.imgfr -relief raised -borderwidth 1 frame $gRootFr.workfr.infofr -relief sunken -borderwidth 1 grid $gRootFr.workfr.imgfr -row 0 -column 0 -sticky news grid $gRootFr.workfr.infofr -row 1 -column 0 -sticky news grid rowconfigure $gRootFr.workfr 0 -weight 1 grid columnconfigure $gRootFr.workfr 0 -weight 1 label $gRootFr.workfr.infofr.label -text Ready -anchor w pack $gRootFr.workfr.infofr.label -fill x -in $gRootFr.workfr.infofr frame $gRootFr.workfr.imgfr.fr pack $gRootFr.workfr.imgfr.fr -expand 1 -fill both if { $::gUseMultisampling } { togl $gRootFr.workfr.imgfr.fr.toglwin \ -width 300 -height 300 \ -multisamplebuffers 1 -multisamplesamples 2 \ -double true -depth true \ -createproc CreateCallback \ -displayproc DisplayCallback \ -reshapeproc ReshapeCallback } else { togl $gRootFr.workfr.imgfr.fr.toglwin \ -width 300 -height 300 \ -double true -depth true \ -createproc CreateCallback \ -displayproc DisplayCallback \ -reshapeproc ReshapeCallback } #pack $gRootFr.workfr.imgfr.fr.toglwin -expand 1 -fill both grid $gRootFr.workfr.imgfr.fr.toglwin -row 0 -column 0 -stick news if { $::gShowSliders } { scale $gRootFr.workfr.imgfr.fr.azi -from -180 -to 180 \ -length 380 -resolution 1 \ -command UpdatePosition \ -showvalue true -orient horizontal \ -variable gPo(ry) scale $gRootFr.workfr.imgfr.fr.ele -from 180 -to -180 \ -length 380 -resolution 1 \ -command UpdatePosition \ -showvalue true -orient vertical \ -variable gPo(rx) grid $gRootFr.workfr.imgfr.fr.azi -row 1 -column 0 -columnspan 2 -sticky ew grid $gRootFr.workfr.imgfr.fr.ele -row 0 -column 1 -sticky ns } grid rowconfigure $gRootFr.workfr.imgfr.fr 0 -weight 1 grid columnconfigure $gRootFr.workfr.imgfr.fr 0 -weight 1 set gPo(toglWin) $gRootFr.workfr.imgfr.fr.toglwin bind $gPo(toglWin) "AskOpenMod" # Create menus File, Edit, View, Settings and Help set hMenu $gRootFr.menufr menu $hMenu -borderwidth 2 -relief sunken $hMenu add cascade -menu $hMenu.file -label File -underline 0 $hMenu add cascade -menu $hMenu.edit -label Edit -underline 0 $hMenu add cascade -menu $hMenu.view -label View -underline 0 $hMenu add cascade -menu $hMenu.help -label Help -underline 0 set fileMenu $hMenu.file menu $fileMenu -tearoff 0 AddMenuCmd $fileMenu "Open ..." "Ctrl+O" AskOpenMod AddMenuCmd $fileMenu "Save as ..." "Ctrl+S" AskSaveMod if { $::tcl_platform(os) ne "Darwin" } { $fileMenu add separator AddMenuCmd $fileMenu "Quit" "Ctrl+Q" ExitProg } bind $gRoot AskOpenMod bind $gRoot AskSaveMod bind $gRoot ExitProg if { [string compare $tcl_platform(os) "windows"] == 0 } { bind $gRoot ExitProg } wm protocol $gRoot WM_DELETE_WINDOW "ExitProg" set editMenu $hMenu.edit menu $editMenu -tearoff 0 AddMenuCmd $editMenu "Add texture ..." "Ctrl+T" AskOpenTex $editMenu add separator AddMenuCmd $editMenu "Reset transformations" "r" \ "ResetTfms; $::gPo(toglWin) postredisplay" bind $gRoot AskOpenTex set viewMenu $hMenu.view menu $viewMenu -tearoff 0 AddMenuCheck $viewMenu "Use display list" "d" \ ::optUseDisplayList "ToggleDisplayList 0" AddMenuCheck $viewMenu "View back faces as lines" "f" \ ::optMarkBackFaces "ToggleBackFaceMode 0" AddMenuCheck $viewMenu "Line mode" "l" \ ::optLines "ToggleDrawMode 0" if { $::gUseMultisampling } { AddMenuCheck $viewMenu "Multisampling mode" "m" \ ::optMultisampling "ToggleMultisampling 0" } if { $::gUseScreenRect } { AddMenuCheck $viewMenu "Show enclosing screen rect" "b" \ ::optShowBB "ToggleScreenRect 0" } AddMenuCheck $viewMenu "Lighting on/off" "" \ ::optMakeLight "ToggleLighting 0" $viewMenu add separator AddMenuCmd $viewMenu "Show Euler angles" "" \ "ShowAngleWindow" set helpMenu $hMenu.help menu $helpMenu -tearoff 0 AddMenuCmd $helpMenu "About $gPo(appName) ..." "" HelpProg AddMenuCmd $helpMenu "About shortcuts ..." "" ShortcutInfo AddMenuCmd $helpMenu "About packages ..." "" PkgInfo AddMenuCmd $helpMenu "About OpenGL version..." "" GLInfo $gRoot configure -menu $hMenu bind $gRoot "ToggleDisplayList" bind $gRoot "ToggleDrawMode" bind $gRoot "ToggleBackFaceMode" if { $::gUseMultisampling } { bind $gRoot "ToggleMultisampling" } if { $::gUseScreenRect } { bind $gRoot "ToggleScreenRect" } bind $gRoot "ResetTfms; $::gPo(toglWin) postredisplay" bind $gPo(toglWin) "AngOff ; tcl3dTbStartMotion %W %x %y" bind $gPo(toglWin) "tcl3dTbStopMotion %W" bind $gPo(toglWin) "tcl3dTbMotion %W %x %y" if { $::tcl_platform(os) eq "Darwin" } { bind $gPo(toglWin) "MoveStart %W %x %y" bind $gPo(toglWin) "MoveCont %W %x %y tz" bind $gPo(toglWin) "MoveEnd %W %x %y" bind $gPo(toglWin) "MoveStart %W %x %y" bind $gPo(toglWin) "MoveCont %W %x %y ty" bind $gPo(toglWin) "MoveEnd %W %x %y" bind $gPo(toglWin) "MoveStart %W %x %y" bind $gPo(toglWin) "MoveCont %W %x %y tx" bind $gPo(toglWin) "MoveEnd %W %x %y" } else { bind $gPo(toglWin) "MoveStart %W %x %y" bind $gPo(toglWin) "MoveCont %W %x %y tz" bind $gPo(toglWin) "MoveEnd %W %x %y" bind $gPo(toglWin) "MoveStart %W %x %y" bind $gPo(toglWin) "MoveCont %W %x %y ty" bind $gPo(toglWin) "MoveEnd %W %x %y" bind $gPo(toglWin) "MoveStart %W %x %y" bind $gPo(toglWin) "MoveCont %W %x %y tx" bind $gPo(toglWin) "MoveEnd %W %x %y" } } proc WriteInfoStr { str } { global gRootFr $gRootFr.workfr.infofr.label configure -text $str } proc HelpProg {} { global gRoot tk_messageBox -message "Simple model viewer powered by Tcl3D.\n\ Copyright 2006-2010 by Paul Obermeier.\n\n\ http://www.tcl3d.org" \ -type ok -icon info -title "$::gPo(appName)" focus $gRoot } proc Cleanup {} { foreach w [winfo children .] { if { [string match ".tcl3dModelView:*" $w] } { destroy $w } } if { [info exists ::objId] } { glmDelete $::objId unset ::objId } uplevel #0 unset gPo } proc ExitProg {} { global gPo gRoot tcl3dTbStopMotion $gPo(toglWin) Cleanup if { $::gUseToplevel } { destroy $gRoot } if { [file tail $::gScriptName] == [file tail $::argv0] } { # If started directly from tclsh or wish, then exit application. exit } } proc ReadModel { fileName } { global gPo gRoot WriteInfoStr "Reading model file $fileName ..." if { [info exists ::objId] } { glmDelete $::objId unset ::objId } ResetTfms if { [file extension $fileName] eq ".sab" } { set ::objId [glmReadSAB $fileName] set gPo(curFile,type) "sab" } elseif { [file extension $fileName] eq ".obj" } { set ::objId [glmReadOBJ $fileName] set gPo(curFile,type) "obj" } elseif { [file extension $fileName] eq ".pof" } { set ::objId [glmReadPOF $fileName] set gPo(curFile,type) "pof" } else { error "Unknown file extension $fileName" } set gPo(curFile,name) $fileName set ::scaleFactor [glmUnitize $::objId] if { ! [glmHaveVertexNormals $::objId] } { if { ! [glmHaveFacetNormals $::objId] } { # puts "Creating facet normals" glmFacetNormals $::objId } } calculateObjSizes wm title $gRoot [format "%s (%s)" \ $gPo(appName) [file tail $fileName]] $::gPo(toglWin) postredisplay } proc SaveModel { fileName } { global gPo if { [file extension $gPo(curFile,name)] eq ".sab" } { set tmpObjId [glmReadSAB $gPo(curFile,name)] } elseif { [file extension $gPo(curFile,name)] eq ".obj" } { set tmpObjId [glmReadOBJ $gPo(curFile,name)] } elseif { [file extension $gPo(curFile,name)] eq ".pof" } { set tmpObjId [glmReadPOF $gPo(curFile,name)] } else { error "Unknown file extension $gPo(curFile,name)" } if { [file extension $fileName] eq ".sab" } { glmWriteSAB $tmpObjId $fileName } elseif { [file extension $fileName] eq ".pof" } { glmWritePOF $tmpObjId $fileName } elseif { [file extension $fileName] eq ".obj" } { glmWriteOBJ $tmpObjId $fileName $::GLM_FLAT } else { error "Unknown file extension $fileName" } glmDelete $tmpObjId } proc AskOpenMod {} { global gPo set fileTypes { { "All files" "*" } { "Wavefront files" "*.obj" } { "SAB CAD files" "*.sab" } { "POF CAD files" "*.pof" } } set modName [tk_getOpenFile -filetypes $fileTypes \ -initialdir $gPo(lastDir)] if { $modName != "" } { set gPo(lastDir) [file dirname $modName] ReadModel $modName } } proc AskSaveMod {} { global gPo set fileTypes { { "All files" "*" } { "Wavefront files" "*.obj" } { "SAB CAD files" "*.sab" } { "POF CAD files" "*.pof" } } set modName [tk_getSaveFile -filetypes $fileTypes \ -initialdir $gPo(lastDir)] if { $modName != "" } { set gPo(lastDir) [file dirname $modName] SaveModel $modName } } proc AskOpenTex {} { global gPo set fileTypes { { "Image files" "*.pcx *ppm *.tga *.bmp *.jpg *.rgb *.rgba" } { "All files" "*" } } set texName [tk_getOpenFile -filetypes $fileTypes \ -initialdir $gPo(lastDir)] if { $texName != "" } { set gPo(lastDir) [file dirname $texName] ReadTex $texName set gPo(curFile,haveTex) 1 } } # The Togl callback functions, when the Togl window is created, # it's size is changed, and when the window content has to be redrawn. proc CreateCallback { toglwin } { set light0_ambient { 0.0 0.0 0.0 1.0 } set light0_diffuse { 1.0 1.0 1.0 1.0 } set light0_specular { 1.0 1.0 1.0 1.0 } set light0_position { -1.0 1.0 1.0 0.0 } set light1_ambient { 0.0 0.0 0.0 1.0 } set light1_diffuse { 1.0 1.0 1.0 1.0 } set light1_specular { 1.0 1.0 1.0 1.0 } set light1_position { 1.0 1.0 1.0 0.0 } glLightfv GL_LIGHT0 GL_AMBIENT $light0_ambient glLightfv GL_LIGHT0 GL_DIFFUSE $light0_diffuse glLightfv GL_LIGHT0 GL_SPECULAR $light0_specular glLightfv GL_LIGHT0 GL_POSITION $light0_position glLightfv GL_LIGHT1 GL_AMBIENT $light1_ambient glLightfv GL_LIGHT1 GL_DIFFUSE $light1_diffuse glLightfv GL_LIGHT1 GL_SPECULAR $light1_specular glLightfv GL_LIGHT1 GL_POSITION $light1_position glEnable GL_DEPTH_TEST glEnable GL_LIGHTING glEnable GL_LIGHT0 glEnable GL_LIGHT1 tcl3dTbInit $toglwin tcl3dTbAnimate $toglwin $::GL_TRUE } proc ReshapeCallback { toglwin { w -1 } { h -1 } } { set w [$toglwin width] set h [$toglwin height] set aspect [expr double ($w) / double ($h)] glViewport 0 0 $w $h glMatrixMode GL_PROJECTION glLoadIdentity gluPerspective $::fov $aspect 0.1 [expr 50 * $::maxSize] glMatrixMode GL_MODELVIEW glLoadIdentity gluLookAt 0.0 0.0 $::dist 0.0 0.0 0.0 0.0 1.0 0.0 tcl3dTbReshape $toglwin $w $h } # Write contents of one vertex to stdout. proc print2DVertex { size } { # puts -nonewline " " set n [$::feedbackBuffer get [expr {$size - $::count}]] incr ::count -1 for { set i 0 } { $i < $n } { incr i } { set x [$::feedbackBuffer get [expr {$size - $::count}]] incr ::count -1 set y [$::feedbackBuffer get [expr {$size - $::count}]] incr ::count -1 # puts -nonewline [format "(%4.2f, %4.2f) " $x $y] if { $x > $::bb(x2) } { set ::bb(x2) $x } if { $y > $::bb(y2) } { set ::bb(y2) $y } if { $x < $::bb(x1) } { set ::bb(x1) $x } if { $y < $::bb(y1) } { set ::bb(y1) $y } } # puts "" } # Write contents of entire buffer. (Parse tokens!) proc printBuffer { size } { set ::count $size set ::bb(x1) 10000 set ::bb(x2) -10000 set ::bb(y1) 10000 set ::bb(y2) -10000 while { $::count } { set token [$::feedbackBuffer get [expr {$size-$::count}]] incr ::count -1 if { $token == $::GL_PASS_THROUGH_TOKEN } { puts "GL_PASS_THROUGH_TOKEN" puts [format " %4.2f" [$::feedbackBuffer get [expr {$size-$::count}]]] incr ::count -1 } elseif { $token == $::GL_POLYGON_TOKEN } { # puts "GL_POLYGON_TOKEN" print2DVertex $size } } WriteInfoStr [format "BBox (x1,x2) (y1,y2): (%4.1f, %4.1f) (%4.1f, %4.1f)" \ $::bb(x1) $::bb(x2) $::bb(y1) $::bb(y2)] } proc drawScreenRect { toglwin x1 x2 y1 y2 } { glDisable GL_LIGHTING glMatrixMode GL_PROJECTION glPushMatrix glLoadIdentity gluOrtho2D 0 [$toglwin width] 0 [$toglwin height] glMatrixMode GL_MODELVIEW glPushMatrix glLoadIdentity glColor3f 0 1 1 glBegin GL_LINE_LOOP glVertex2f $x1 $y1 glVertex2f $x2 $y1 glVertex2f $x2 $y2 glVertex2f $x1 $y2 glEnd glPopMatrix glMatrixMode GL_PROJECTION glPopMatrix glMatrixMode GL_MODELVIEW glEnable GL_LIGHTING } proc drawGeometry { mode } { global gPo glPushMatrix obj2ogl $mode glPopMatrix } proc SetCamera {} { global gPo glMatrixMode GL_MODELVIEW glLoadIdentity gluLookAt 0.0 0.0 $::dist 0.0 0.0 0.0 0.0 1.0 0.0 glTranslatef $gPo(tx) $gPo(ty) $gPo(tz) } proc Abs { a } { if { $a < 0 } { return [expr -1 * $a] } else { return $a } } proc getMatrixAngles {} { set tmpMat [tcl3dVector GLfloat 16] set tmpVec [tcl3dVector GLfloat 3] glGetFloatv GL_MODELVIEW_MATRIX $tmpMat set retVal [tcl3dMatfGetAngles1 $tmpMat $tmpVec] set rx [tcl3dRadToDeg [$tmpVec get 0]] set ry [tcl3dRadToDeg [$tmpVec get 1]] set rz [tcl3dRadToDeg [$tmpVec get 2]] #puts "Angles1 ($retVal): $rx $ry $rz" set retVal [tcl3dMatfGetAngles $tmpMat $tmpVec] set rx [tcl3dRadToDeg [$tmpVec get 0]] set ry [tcl3dRadToDeg [$tmpVec get 1]] set rz [tcl3dRadToDeg [$tmpVec get 2]] #puts "Angles ($retVal): $rx $ry $rz" $tmpMat delete $tmpVec delete return [list $rx $ry $rz] } proc convertMatrixToAngles {} { global gPo set angList [getMatrixAngles] set gPo(rx) [expr int ([lindex $angList 0])] set gPo(ry) [expr -1 * int ([lindex $angList 1])] set gPo(rz) [expr int ([lindex $angList 2])] } proc DisplayCallback { toglwin } { global gPo if { $::optMultisampling } { glEnable GL_MULTISAMPLE } else { glDisable GL_MULTISAMPLE } if { [info exists ::objId] && [glmHaveTexCoords $::objId] && $gPo(curFile,haveTex) } { glEnable GL_TEXTURE_2D } else { glDisable GL_TEXTURE_2D } glClear [expr $::GL_COLOR_BUFFER_BIT | $::GL_DEPTH_BUFFER_BIT] # Viewport command is not really needed, but has been inserted for # Mac OSX. Presentation framework (Tk) does not send a reshape event, # when switching from one demo to another. glViewport 0 0 [$toglwin width] [$toglwin height] glColor3f 0.0 1.0 0.0 SetCamera if { $gPo(useAngles) } { glRotatef $gPo(rx) 1 0 0 glRotatef $gPo(ry) 0 1 0 glRotatef $gPo(rz) 0 0 1 } else { tcl3dTbMatrix $toglwin convertMatrixToAngles } glPolygonMode GL_FRONT GL_FILL if { $::optMarkBackFaces } { glPolygonMode GL_BACK GL_LINE } else { glPolygonMode GL_BACK GL_FILL } drawGeometry $::GL_RENDER if { $::optShowBB } { glFeedbackBuffer $::feedbackSize GL_2D $::feedbackBuffer glRenderMode GL_FEEDBACK drawGeometry $::GL_FEEDBACK set size [glRenderMode GL_RENDER] # TODO: Check size for being in correct range. printBuffer $size drawScreenRect $toglwin $::bb(x1) $::bb(x2) $::bb(y1) $::bb(y2) } glFlush $toglwin swapbuffers } proc calculateObjSizes {} { set objSize [tcl3dVector GLfloat 3] glmDimensions $::objId $objSize set ::maxSize 0.0 set ::maxSize [poMisc:Max $::maxSize [$objSize get 0]] set ::maxSize [poMisc:Max $::maxSize [$objSize get 1]] set ::maxSize [poMisc:Max $::maxSize [$objSize get 2]] set ::dist [expr 0.5 * $::maxSize / tan (3.1415926 / 180.0 * (0.5 * $::fov))] WriteInfoStr [format "Size (x,y,z): (%.2f, %.2f, %.2f)" \ [expr 1.0 / $::scaleFactor * [$objSize get 0]] \ [expr 1.0 / $::scaleFactor * [$objSize get 1]] \ [expr 1.0 / $::scaleFactor * [$objSize get 2]]] $objSize delete } proc CreateDisplayList { mode } { global gPo if { $::optUseDisplayList } { if { [info exists gPo(displayList)] } { glDeleteLists $gPo(displayList) 1 } set gPo(displayList) [glmList $::objId $mode] } } # Function to draw the in-memory representation of a Wavefront 3D model # with OpenGL calls. proc obj2ogl { mode } { global gPo if { ! [info exists ::objId] } { return } set mode 0 if { [glmHaveTexCoords $::objId] && $gPo(curFile,haveTex) } { #puts "Have texture coordinates and texture file" set mode [expr $mode | $::GLM_TEXTURE] } if { [glmHaveMaterials $::objId] } { #puts "Have materials" set mode [expr $mode | $::GLM_MATERIAL] } if { $::optLines } { #puts "Drawing lines" set mode [expr $mode | $::GLM_LINE] } elseif { [glmHaveVertexNormals $::objId] } { #puts "Drawing smooth shaded" glShadeModel GL_SMOOTH set mode [expr $mode | $::GLM_SMOOTH] } elseif { [glmHaveFacetNormals $::objId] } { #puts "Drawing flat shaded" glShadeModel GL_FLAT set mode [expr $mode | $::GLM_FLAT] } else { #puts "Drawing without shading" set mode [expr $mode | $::GLM_NONE] } if { $::optUseDisplayList } { if { ! [info exists gPo(displayList)] } { CreateDisplayList $mode } glCallList $gPo(displayList) } else { glmDraw $::objId $mode } } proc ToggleScreenRect { { sw 1 } } { if { $::optLines } { tk_messageBox \ -message "Screen rectangle mode only supported in face mode." \ -type ok -icon info -title "$::gPo(appName) Information" return } if { $sw } { set ::optShowBB [expr ! $::optShowBB] } $::gPo(toglWin) postredisplay } proc ToggleDisplayList { { sw 1 } } { global gPo if { $sw } { set ::optUseDisplayList [expr ! $::optUseDisplayList] } if { ! $::optUseDisplayList && [info exists gPo(displayList)] } { glDeleteLists $gPo(displayList) 1 unset gPo(displayList) } $::gPo(toglWin) postredisplay } proc ToggleMultisampling { { sw 1 } } { if { $sw } { set ::optMultisampling [expr ! $::optMultisampling] } $::gPo(toglWin) postredisplay } proc ToggleDrawMode { { sw 1 } } { if { $sw } { set ::optLines [expr ! $::optLines] } $::gPo(toglWin) postredisplay } proc ToggleBackFaceMode { { sw 1 } } { if { $sw } { set ::optMarkBackFaces [expr ! $::optMarkBackFaces] } $::gPo(toglWin) postredisplay } proc ToggleLighting { { sw 1 } } { if { $sw } { set ::optMakeLight [expr ! $::optMakeLight] } if { $::optMakeLight } { glEnable GL_LIGHTING glEnable GL_LIGHT0 } else { glDisable GL_LIGHTING glDisable GL_LIGHT0 } $::gPo(toglWin) postredisplay } proc AngOn {} { global gPo set gPo(useAngles) 1 #puts "Angle on $gPo(count)" incr gPo(count) } proc AngOff {} { global gPo set gPo(useAngles) 0 convertMatrixToAngles #puts "Angle off $gPo(count)" } proc ShowAngleWindow {} { global gPo set tw .modelViewer:angleWin if { [winfo exists $tw] } { wm deiconify $tw update raise $tw return } toplevel $tw wm title $tw "Euler angles" wm resizable $tw false false AngOn set labels { "Pitch (X):" \ "Roll (Y):" \ "Yaw (Z):" } # Generate left column with text labels. set row 0 foreach labelStr $labels { label $tw.l$row -text $labelStr grid $tw.l$row -row $row -column 0 -sticky nw incr row } # Generate right column with scale widgets. set row 0 frame $tw.fr$row grid $tw.fr$row -row $row -column 1 -sticky news scale $tw.fr$row.sx -from -180 -to 180 \ -length 380 -resolution 1 \ -command UpdatePosition \ -showvalue false -orient horizontal \ -variable gPo(rx) entry $tw.fr$row.ex -textvariable gPo(rx) -width 10 pack $tw.fr$row.sx $tw.fr$row.ex -side left -anchor w -pady 2 bind $tw.fr$row.ex "UpdatePositionGlobal" incr row frame $tw.fr$row grid $tw.fr$row -row $row -column 1 -sticky news scale $tw.fr$row.sx -from -180 -to 180 \ -length 380 -resolution 1 \ -command UpdatePosition \ -showvalue false -orient horizontal \ -variable gPo(ry) entry $tw.fr$row.ex -textvariable gPo(ry) -width 10 pack $tw.fr$row.sx $tw.fr$row.ex -side left -anchor w -pady 2 bind $tw.fr$row.ex "UpdatePositionGlobal" incr row frame $tw.fr$row grid $tw.fr$row -row $row -column 1 -sticky news scale $tw.fr$row.sx -from -180 -to 180 \ -length 380 -resolution 1 \ -command UpdatePosition \ -showvalue false -orient horizontal \ -variable gPo(rz) entry $tw.fr$row.ex -textvariable gPo(rz) -width 10 pack $tw.fr$row.sx $tw.fr$row.ex -side left -anchor w -pady 2 bind $tw.fr$row.ex "UpdatePositionGlobal" # Create Close button incr row frame $tw.fr$row grid $tw.fr$row -row $row -column 0 -columnspan 2 -sticky news bind $tw "AngOff ; destroy $tw" button $tw.fr$row.b -text "Close" -command "AngOff ; destroy $tw" wm protocol $tw WM_DELETE_WINDOW "AngOff ; destroy $tw" pack $tw.fr$row.b -side left -fill x -padx 2 -expand 1 focus $tw } proc UpdatePositionGlobal {} { global gPo $::gPo(toglWin) postredisplay } proc UpdatePosition { val } { global gPo AngOn $::gPo(toglWin) postredisplay getMatrixAngles } proc ResetTfms {} { global gPo set gPo(tx) 0.0 set gPo(ty) 0.0 set gPo(tz) 0.0 # Start values for model rotation set gPo(rx) 45 set gPo(ry) 30 set gPo(rz) 0 if { [info exists gPo(toglWin)] } { tcl3dTbInit $gPo(toglWin) } } proc ReadImg { imgName numChans } { if { $numChans != 3 && $numChans != 4 } { error "Error: Only 3 or 4 channels allowed ($numChans supplied)" } set retVal [catch {set phImg [image create photo -file $imgName]} err1] if { $retVal != 0 } { error "Error reading image $imgName ($err1)" } else { set w [image width $phImg] set h [image height $phImg] set texImg [tcl3dVectorFromPhoto $phImg $numChans] image delete $phImg } return [list $texImg $w $h] } proc ReadTex { fileName } { set imgInfo [ReadImg $fileName 3] set imgData [lindex $imgInfo 0] set imgWidth [lindex $imgInfo 1] set imgHeight [lindex $imgInfo 2] if { [tcl3dIsPow2 $imgWidth] && [tcl3dIsPow2 $imgHeight] } { # Create The Texture glGenTextures 1 $::gTextureId glTexEnvf GL_TEXTURE_ENV GL_TEXTURE_ENV_MODE $::GL_DECAL glBindTexture GL_TEXTURE_2D [$::gTextureId get 0] glTexParameteri GL_TEXTURE_2D GL_TEXTURE_MIN_FILTER $::GL_LINEAR glTexParameteri GL_TEXTURE_2D GL_TEXTURE_MAG_FILTER $::GL_LINEAR glTexImage2D GL_TEXTURE_2D 0 $::GL_RGB $imgWidth $imgHeight \ 0 GL_RGB GL_UNSIGNED_BYTE $imgData } else { tk_messageBox \ -message "Texture dimensions must be a power of two." \ -type ok -icon info -title "$::gPo(appName) Information" } # Delete the image data vector. $imgData delete } if { $gUseToplevel } { catch { destroy $gRoot } } set gPo(appName) "Tcl3D Model Viewer" set gPo(lastDir) [pwd] set gPo(lastFile) "Default" set gPo(curFile,type) "" set gPo(curFile,haveTex) 0 set gPo(count) 0 #AngOff set ::maxSize 10 set ::dist 10 set ::fov 60 set ::optShowBB 0 set ::optLines 0 set ::optMarkBackFaces 0 set ::optMultisampling 0 set ::optMakeLight 1 set ::optUseDisplayList 0 ResetTfms # TODO: # This size must be changed according to the number of polygons of the model. # Plus take into account the format specified with glFeedbackBuffer. set feedbackSize 100000 set feedbackBuffer [tcl3dVector GLfloat $feedbackSize] ShowMainWin $gPo(appName) if { $argc != 0 } { set modName [lindex $argv 0] if { $modName ne "" } { ReadModel $modName } }