scanalyze_util.tcl
上传用户:kellyonhid
上传日期:2013-10-12
资源大小:932k
文件大小:24k
源码类别:

3D图形编程

开发平台:

Visual C++

  1. proc redraw {{force 0}} {
  2.     
  3.     if {[globalset noui]} return
  4.     if {![globalexists toglPane]} return
  5.     if {$force == "block"} {
  6. globalset noRedraw [expr [globalset noRedraw] + 1]
  7. return
  8.     } elseif {$force == "allow"} {
  9. set nr [expr [globalset noRedraw] - 1]
  10. if {$nr < 0} {
  11.     puts "Warning: noRedraw got set to $nr!"
  12.     set nr 0
  13. }
  14. globalset noRedraw $nr
  15. return
  16.     } elseif {$force == "flush"} {
  17. update idletasks
  18. redraw allow
  19. redraw 1
  20. return
  21.     } elseif {$force == "safeflush"} {
  22. if {[expr [globalset noRedraw] > 0]} {
  23.     redraw flush
  24. } else {
  25.     redraw 1
  26. }
  27. return
  28.     }
  29.     if {$force} {
  30. plv_invalidateToglCache
  31.     }
  32.     [globalset toglPane] render
  33. }
  34. proc setMenuTitle {caption menu window} {
  35.     wm title $window $caption
  36.     window_Register $window
  37. }
  38. proc setRotationCenter {{x none} {y ""}} {
  39.     set success 0
  40.     if {$x != "none"} {
  41. set result [catch 
  42. [plv_set_this_as_center_of_rotation $x $y] msg ]
  43. if { $result == 0 } {
  44.     globalset theCoR custom
  45.     set success 1
  46. } else {
  47.     tk_dialog .errMsg Error $msg "" 0 Ok
  48. }
  49. redraw 1
  50.     } else {
  51. set success 1
  52.     }
  53.     global theMover
  54.     if { $success == 1 & $theMover == "rotCenter"} {
  55. globalset theMover [globalset prevMover]
  56.     }
  57. }
  58. proc resetRotationCenter {{force 0}} {
  59.     # entry from choice of new rotation mode will use "force", and should
  60.     # always succeed.  Otherwise, this is being called from trackball
  61.     # bindings and should only continue if we're rotating (b1 and not b2).
  62.     if {![expr ($force) || 
  63.  ([globalset mouse_state_1] && ![globalset mouse_state_2])]} {
  64. return
  65.     }
  66.     switch -exact -- [globalset theCoR] {
  67. auto    {plv_reset_rotation_center object}
  68. screen  {if {[globalset theMover] == "mesh"} {
  69.     plv_reset_rotation_center object
  70. } else {
  71.     plv_reset_rotation_center screen
  72. }
  73. }
  74. # custom gets left alone unless explicitly changed
  75.     }
  76. }
  77. proc hiliteRotationMode {} {
  78.     if {[globalset noui]} return
  79.     set custom .tools.chooseCenter
  80.     set auto   .tools.autoCenter
  81.     set screen .tools.screenCenter
  82.     if {![winfo exist $custom]} return
  83.     global theCoR
  84.     globalset theCoR_save([getActiveMesh]) $theCoR
  85.     switch -exact -- $theCoR {
  86. custom {set active $custom }
  87. auto   {set active $auto }
  88. screen {set active $screen }
  89.     }
  90.     foreach control "$custom $auto $screen" {
  91. $control config -foreground Black
  92.     }
  93.     $active config -foreground ForestGreen
  94. }
  95. proc resetRotationMode {} {
  96.     global theCoR
  97.     if {[catch {set theCoR [globalset theCoR_save([getActiveMesh])]}]} {
  98. set theCoR auto
  99.     }
  100. }
  101. proc setHome {} {
  102.     global theMesh
  103.     global theMover
  104.     if {$theMover == "mesh"} {
  105. SetHome $theMesh
  106.     } else {
  107. SetHome ""
  108.     }
  109. }
  110. proc setHomeAll {} {
  111.     foreach mesh [plv_listscans] {
  112. SetHome $mesh
  113.     }
  114.     SetHome ""
  115.     redraw
  116. }
  117. proc goHome {{mesh " _"}} {
  118.     global theMesh
  119.     global theMover
  120.     # use mesh if given ("" for viewer), otherwise selected mesh (theMesh)
  121.     if {0 != [string compare $mesh " _"]} {
  122. GoHome $mesh
  123.     } else {
  124. if {$theMover == "mesh"} {
  125.     GoHome $theMesh
  126. } else {
  127.     GoHome ""
  128. }
  129.     }
  130.     redraw
  131. }
  132. proc goHomeAll {} {
  133.     foreach mesh [plv_listscans] {
  134. GoHome $mesh
  135.     }
  136.     GoHome ""
  137.     redraw
  138. }
  139. proc setWindowTitle {{extra ""}} {
  140.     global theMesh
  141.     global theMover
  142.     set title "scanalyze"
  143.     if {$extra == ""} {
  144. # if no info specified, use current mesh name
  145. if {$theMesh != ""} {
  146.     set extra $theMesh
  147.     if {$theMover == "mesh"} {
  148. set extra "$extra*"
  149.     }
  150. }
  151.     }
  152.     wm title . "$title -- $extra"
  153. }
  154. proc detectCursorCapabilities {} {
  155.     # handle tcl's cursor discrepancies -- basically, lots of cursor options
  156.     # available on unix aren't implemented at all on Windows.
  157.     global cursor
  158.     global env
  159.     set cursor(FlatHand) "@$env(SCANALYZE_DIR)/flat_hand.xbm"
  160.     if [catch {. config -cursor "$cursor(FlatHand) red"} result] {
  161. puts $result
  162. # error... assume only basic (built-in, no color) cursor support
  163. set cursor(FlatHand) boat
  164. set cursor(CurvedHand) boat
  165. set cursor(PointingHand) boat
  166. set cursor(Fore) ""
  167. set cursor(AltFore) ""
  168. set cursor(Back) ""
  169.     } else {
  170. # OK ... go ahead with other cursors and colors too
  171. set cursor(CurvedHand) "@$env(SCANALYZE_DIR)/curved_hand.xbm"
  172. set cursor(PointingHand) "@$env(SCANALYZE_DIR)/pointing_hand.xbm"
  173. set cursor(Fore) " red"
  174. set cursor(AltFore) " green"
  175. set cursor(Back) " white"
  176.     }
  177.     . config -cursor {}
  178. }
  179. proc showAllMeshes {mode} {
  180.     vg_CreateView PREVIOUS
  181.   
  182.     if {$mode != "invert"} {
  183. # hiding/showing all, might spuriously change active mesh when
  184. # we hide it when something else is still visible, or show something
  185. # else when it's not visible.  This isn't appropriate because
  186. # on hide/show all, there's no use in trying to follow visibility.
  187. # so, remember which it was
  188. set active [globalset theMesh]
  189.     }
  190.     redraw block
  191.     foreach mesh [plv_listscans root] {
  192. if {$mode == "invert"} {
  193.     set vis [expr ! [plv_getvisible $mesh]]
  194. } else {
  195.     set vis $mode
  196. }
  197. changeVis $mesh $vis
  198.     }
  199.     if {[info exists active]} {
  200. globalset theMesh $active
  201.     }
  202.     redraw flush
  203. }
  204. proc showMesh {args} {
  205.     eval showHideAllMeshes 1 - $args
  206. }
  207. proc hideMesh {args} {
  208.     eval showHideAllMeshes 0 - $args
  209. }
  210. proc showOnlyMesh {args} {
  211.     global theMesh
  212.     if {$theMesh == ""} { return }
  213.     eval showHideAllMeshes 1 0 $args
  214. }
  215. proc hideOnlyMesh {args} {
  216.     eval showHideAllMeshes 0 1 $args
  217. }
  218. proc showHideAllMeshes {ifmatch ifnot args} {
  219.     redraw block
  220.     set old [globalset theMesh]
  221.     vg_CreateView PREVIOUS
  222.   
  223.     # build lists of all meshes, and those to show, in same order
  224.     # then walk along "all" list, and if current entry is same as head
  225.     # of "yes" list, show it, else hide it; then advance all list,
  226.     # and yes list only if used
  227.     set all [lsort -dictionary [getMeshList]]
  228.     set yes [lsort -dictionary $args]
  229.     set iYes 0
  230.     foreach mesh $all {
  231. if {$mesh == [lindex $yes $iYes]} {
  232.     changeVis $mesh $ifmatch
  233.     incr iYes
  234. } else {
  235.     if {$ifnot != "-"} {
  236. changeVis $mesh $ifnot
  237.     }
  238. }
  239.     }
  240.     # preserve selection if possible
  241.     if {[plv_getvisible $old]} {
  242. globalset theMesh $old
  243.     }
  244.     redraw flush
  245. }
  246. # getVisibleMeshes 1 - to get visible meshes
  247. # getVisibleMeshes 0 - to get invisible meshes
  248. proc getVisibleMeshes {{mode 1}} {
  249.     set meshlist ""
  250.     foreach mesh [plv_listscans] {
  251. if {[plv_getvisible $mesh] == $mode} {
  252.     lappend meshlist $mesh
  253. }
  254.     }
  255.     return $meshlist
  256. }
  257. # options - root (defaults), leaves, groups.
  258. proc getMeshList {args} {
  259.     return [eval plv_listscans $args]
  260. }
  261. proc writeXform {} {
  262.     foreach mesh [plv_listscans] {
  263. mms_savexform $mesh
  264.     }
  265. }
  266. proc idlecallback {proc} {
  267.     global _idlecallbacks
  268.     if {[array get _idlecallbacks $proc] != ""} {
  269. after cancel $_idlecallbacks($proc)
  270.     }
  271.     set _idlecallbacks($proc) [after 100 _${proc}_idlecallback]
  272. }
  273. proc updatePolyCount {} {
  274.     # batch multiple requests together
  275.     idlecallback updatePolyCount
  276. }
  277. proc _updatePolyCount_idlecallback {} {
  278.     set pc 0
  279.     set vpc 0
  280.     foreach mesh [plv_listscans] {
  281. set poly [getPolyCount_maxres $mesh]
  282. set pc [expr $poly + $pc]
  283. if {[plv_getvisible $mesh]} {
  284.     set poly [plv_getcurrentres $mesh]
  285.     set vpc [expr $poly + $vpc]
  286. }
  287.     }
  288.     globalset polyCount $pc
  289.     globalset visPolyCount $vpc
  290. }
  291. proc selectScan {name} {
  292.     global theMesh
  293.     global theMover
  294.     global enabledWhenMeshSelected
  295.     set theMesh $name
  296.     if {![globalset noui]} {
  297. if {$theMesh == ""} {
  298.     set state disabled
  299. } else {
  300.     set state normal
  301. }
  302. foreach control $enabledWhenMeshSelected {
  303.     $control config -state $state
  304. }
  305. .menubar entryconfig Mesh -state $state
  306.     }
  307.     # if in manipulate-mesh mode, update selection
  308.     if {[string compare $theMover "mesh"] == 0} {
  309. manipulateScan $name
  310.     }
  311. }
  312. proc confirmQuit {} {
  313.     if {![globalset noui]} {
  314. switch -exact -- [globalset exitConfirmation] {
  315.     always
  316.     {
  317. if {[confirmSaveMeshes 1] != "succeed"} return
  318.     }
  319.     
  320.     dirty
  321.     {
  322. if {[confirmSaveMeshes 0] != "succeed"} return
  323.     }
  324.     
  325.     never
  326.     {
  327.     }
  328. }
  329. if {[globalset exitSaveXforms]} {
  330.     if {![fileWriteAllScanXforms]} {
  331. tk_messageBox 
  332.     -title "Scanalyze: quitting will lose alignment." 
  333.     -message "Some or all xforms could not be saved.  If
  334.                               you want to quit anyway, disable 'save
  335.                               xforms on exit', or use Ctrl+C."
  336. return
  337.     }
  338. }
  339.     
  340. # save settings
  341. buildUI_shutdown
  342. write_preferences
  343.     }
  344.     
  345.     # data structure cleanup on C++ side
  346.     plv_shutdown
  347.     
  348.     # and we're out
  349.     puts ""
  350.     exit
  351. }
  352. proc confirmFlattenMeshes {} {
  353.     set meshes [getMeshList]
  354.     set i 0
  355.     set unsaved $meshes
  356.     global confirmSaveMesh
  357.     if {[info exists confirmSaveMesh]} {
  358. unset confirmSaveMesh
  359.     }
  360.     set confirmSaveMesh() ""
  361.     set d [toplevel .confirmSaveMesh]
  362.     wm title $d "Scanalyze flatten confirmation"
  363.     label $d.l -text "Writes files incorporating mesh xform and current res.n  Writes to <meshname>.ply, potentially overwriting exiting.n Flatten them now?n"
  364.     set f [frame $d.caption]
  365.     label $f.lm -text "Scan named:"
  366.     label $f.lc -text "Flatten"
  367.     pack $f.lm -side left
  368.     pack $f.lc -side right
  369.     foreach mesh $unsaved {
  370. incr i
  371. set f [frame $d.f$i]
  372. label $f.l -text $mesh
  373. checkbutton $f.s -variable confirmSaveMesh($mesh)
  374. set confirmSaveMesh($mesh) 1
  375. pack $f.l -side left
  376. pack $f.s -side right
  377.     }
  378.     set c [frame $d.control]
  379.     button $c.ok -text OK 
  380. -command "set confirmSaveMesh() sure; destroy $d"
  381.     button $c.cancel -text Cancel 
  382. -command "destroy $d"
  383.     button $c.selall -text "Select all" 
  384. -command {
  385.     foreach mesh [array names confirmSaveMesh] {
  386. set confirmSaveMesh($mesh) 1
  387.     }
  388.     unset mesh
  389. }
  390.     button $c.selnone -text "Deselect all" 
  391. -command {
  392.     foreach mesh [array names confirmSaveMesh] {
  393. set confirmSaveMesh($mesh) 0
  394.     }
  395.     unset mesh
  396. }
  397.     packchildren $c -side left
  398.     packchildren $d -side top -fill x -expand 1
  399.     grab set $d
  400.     tkwait window $d
  401.     if {$confirmSaveMesh() != "sure"} {
  402. # means user clicked Cancel
  403. return fail
  404.     }
  405.     unset confirmSaveMesh()
  406.     foreach mesh [array names confirmSaveMesh] {
  407. if {$confirmSaveMesh($mesh)} {
  408.     set res [plv_getcurrentres $mesh]
  409.     plv_write_resolutionmesh $mesh $res $mesh.ply flatten
  410.     
  411. }
  412.     }
  413.     return succeed
  414. }
  415. proc confirmSaveMeshes {{confirmOnClean 0}} {
  416.     set meshes [concat [getMeshList leaves] [getMeshList groups]]
  417.     set i 0
  418.     puts $meshes 
  419.     set unsaved ""
  420.     foreach mesh $meshes {
  421. # is it modified?  if so, add to dialog
  422. if {[plv_is_scan_modified $mesh]} {
  423.     lappend unsaved $mesh
  424. }
  425.     }
  426.     if {[llength $unsaved] == 0} {
  427. if {$confirmOnClean} {
  428.     return [confirmCleanQuit]
  429. } else {
  430.     return succeed
  431. }
  432.     }
  433.     global confirmSaveMesh
  434.     if {[info exists confirmSaveMesh]} {
  435. unset confirmSaveMesh
  436.     }
  437.     set confirmSaveMesh() ""
  438.     set d [toplevel .confirmSaveMesh]
  439.     wm title $d "Scanalyze save confirmation"
  440.     wm transient $d .
  441.     label $d.l -text "You have unsaved scans/groups.  Save them now? n (Nested groups will be saved automatically if you save the parent)"
  442.     set f [frame $d.caption]
  443.     label $f.lm -text "Scan named:"
  444.     label $f.lc -text "Save"
  445.     pack $f.lm -side left
  446.     pack $f.lc -side right
  447.     foreach mesh $unsaved {
  448. incr i
  449. set f [frame $d.f$i]
  450. label $f.l -text $mesh
  451. checkbutton $f.s -variable confirmSaveMesh($mesh)
  452. set confirmSaveMesh($mesh) 1
  453. pack $f.l -side left
  454. pack $f.s -side right
  455.     }
  456.     set c [frame $d.control]
  457.     button $c.ok -text OK 
  458. -command "set confirmSaveMesh() sure; destroy $d"
  459.     button $c.cancel -text Cancel 
  460. -command "destroy $d"
  461.     button $c.selall -text "Select all" 
  462. -command {
  463.     foreach mesh [array names confirmSaveMesh] {
  464. set confirmSaveMesh($mesh) 1
  465.     }
  466.     unset mesh
  467. }
  468.     button $c.selnone -text "Deselect all" 
  469. -command {
  470.     foreach mesh [array names confirmSaveMesh] {
  471. set confirmSaveMesh($mesh) 0
  472.     }
  473.     unset mesh
  474. }
  475.     packchildren $c -side left
  476.     packchildren $d -side top -fill x -expand 1
  477.     grab set $d
  478.  
  479.     tkwait window $d
  480.     if {$confirmSaveMesh() != "sure"} {
  481. # means user clicked Cancel
  482. return fail
  483.     }
  484.     unset confirmSaveMesh()
  485.   
  486.     foreach mesh [array names confirmSaveMesh] {
  487. if {$confirmSaveMesh($mesh)} {
  488.     if { ![plv_groupscans isgroup $mesh] } {
  489. if {![saveScanFile $mesh]} {
  490.     return fail
  491. }
  492.     } else {
  493. group_recursiveSave $mesh [plv_groupscans list $mesh] [pwd]
  494.     }
  495. }
  496.     }
  497.     return succeed
  498. }
  499. proc confirmCleanQuit {} {
  500.     if (![tk_dialog .confirmQuit "Confirm quit" 
  501. "Do you really want to quit scanalyze?" 
  502.      question 0 Yes No]) {
  503. return succeed
  504.     }
  505.     return fail
  506. }
  507. proc extractRes {r} {
  508.     set col [string first ":" $r]
  509.     return [string range $r [expr 1 + $col] end]
  510. }
  511. proc selectNthResolution {iRes} {
  512.     if {[globalset noui]} {
  513. set meshes [plv_listscans]
  514.     } else {
  515. if {[globalset selectResIncludesInvisible]} {
  516.     set meshes [getMeshList]
  517. } else {
  518.     set meshes [getVisibleMeshes]
  519. }
  520.     }
  521.     redraw block
  522.     progress start [llength $meshes] "Switch to res $iRes"
  523.     set num 0
  524.     foreach mesh $meshes {
  525. if {[baildetect {selectNthResolutionForMesh $iRes $mesh} bailmsg]} {
  526.     puts "Res-change bailed: $bailmsg"
  527.     break
  528. }
  529. progress update [incr num]
  530.     }
  531.     
  532.     progress done
  533.     redraw flush
  534. }
  535. proc selectNthResolutionForMesh {iRes mesh} {
  536.     set avail [plv_getreslist $mesh]
  537.     set i $iRes
  538.     if {$i >= [llength $avail]} {
  539. set i [expr [llength $avail] - 1]
  540.     }
  541.     
  542.     set chosen [lindex $avail $i]
  543.     set chosen [extractRes $chosen]
  544.     
  545.     setMeshResolution $mesh $chosen
  546. }
  547. proc selectNthResolutionForCurrentMesh {iRes} {
  548.     selectNthResolutionForMesh $iRes [globalset theMesh]
  549. }
  550. # cd is a dangerous command, because things that were loaded from a
  551. # relative path won't be able to save themselves
  552. proc overrideCdCommand {} {
  553.     rename cd _chdir
  554.     proc cd {arg} {
  555. # we'll allow cd from scripts, assuming they know what they're
  556. # doing, but NOT from the command line.
  557. if {[info level] > 1} {
  558.     return [_chdir $arg]
  559. } else {
  560.     puts "cd is dangerous and unadvisable,
  561.                   because scans and transforms "
  562.     puts "already loaded may not be able to save
  563.                   themselves afterwards."
  564.     puts "If you understand the implications of
  565.                   this and want to do it"
  566.     puts "anyway, use chdir."
  567. }
  568.     }
  569.     proc chdir {arg} {
  570. _chdir $arg
  571. puts "Warning: working directory set to [pwd]"
  572. puts "If this causes problems, return to [globalset _initial_dir]"
  573.     }
  574.     globalset _initial_dir [pwd]
  575. }
  576. proc getMemUsage {} {
  577.     # get memory info from ps
  578.     # catch any return other than return statement (TCL_RETURN)
  579.     if {1 == [catch {
  580.  
  581. global unix
  582. if {![info exists unix]} {
  583. if {[catch  {set unix [exec uname]}]} {
  584. set unix IRIX32
  585. }
  586. }
  587. global _pageSize
  588. # need pageSize for IRIX
  589. if {![info exists _pageSize]} {
  590.     if {$unix == "IRIX64"} {
  591. set _pageSize 16
  592.     } else {
  593. set _pageSize 4
  594.     }
  595. }
  596. if {$unix == "Linux"} {
  597.     set virt [expr [exec ps -o vsz= -p [pid]] / 1024]
  598.     set res [expr [exec ps -o rss= -p [pid]] / 1024]
  599. }
  600. if {$unix == "IRIX" || $unix == "IRIX32" || $unix == "IRIX64"} {
  601.     # i.e. IRIX
  602.     set mem [exec ps -o vsz=,rss= -p [pid]]     
  603.     set virt [expr [lindex $mem 0] / 1024]
  604.     set res [expr [lindex $mem 1] * $_pageSize / 1024]
  605.    
  606.     # ps (irix 6.5) appears to have a bug, such that ps -o vsz=
  607.     # will return negative numbers for virtual sizes over 2gb even
  608.     # though the number it returns, because it's in K, is nowhere near
  609.     # 32 bits.  We can fix this between 2 and 4 gb though; processes
  610.     # bigger than 4gb will wrap over.
  611.     if {$virt < 0} {
  612. incr virt 4096
  613.     }
  614. } else {
  615. }
  616. set result "Res: ${res}M / Virt: ${virt}M"
  617.     }
  618.     ]} {
  619. set result "Mem: unavailable"
  620.     }
  621.     return $result
  622. }
  623. proc autoSetText {widget command} {
  624.     $widget config -text [$command]
  625.     after 5000 "autoSetText $widget $command"
  626. }
  627. proc releaseAllMeshes {} {
  628.     if {[globalset selectResIncludesInvisible]} {
  629. set meshes [getMeshList]
  630.     } else {
  631. set meshes [getVisibleMeshes]
  632.     }
  633.     redraw block
  634.     set ok 1
  635.    
  636.     foreach mesh $meshes {
  637. set reses [plv_getreslist $mesh]
  638. # don't want to toss top one
  639. set reses [lrange $reses 1 end]
  640. foreach res $reses {
  641.     set res [extractRes $res]
  642.     if {[catch {plv_mesh_res_unload $mesh $res}]} {
  643. set ok 0
  644.     }
  645.     
  646. }
  647.     }
  648.     redraw flush
  649.     if {!$ok} {
  650. tk_messageBox -title "scanalyze" -icon error -type ok 
  651.     -message "Some scan(s) failed to release resolution(s)."
  652.     }
  653. }
  654. proc chooseColor {usage} {
  655.     if {$usage == "background"} {
  656. set command plv_drawstyle
  657.     } else {
  658. set command plv_material
  659.     }
  660.     set old [$command -$usage]
  661.     set color [tk_chooseColor -title "Select $usage color" -initialcolor $old]
  662.     if {$color != ""} {
  663. set r [expr 0x[string range $color 1 2] / 255.0]
  664. set g [expr 0x[string range $color 3 4] / 255.0]
  665. set b [expr 0x[string range $color 5 6] / 255.0]
  666. $command -$usage $r $g $b
  667. update
  668.     }
  669. }
  670. proc getUniqueInt {} {
  671.     global uniqueInt
  672.     return [incr uniqueInt]
  673. }
  674. proc selectMesh {which} {
  675.     set list [lsort -dictionary [getVisibleMeshes]]
  676.     set ind [lsearch -exact $list [globalset theMesh]]
  677.     if {$ind != -1} {
  678. if {$which == "prev"} {
  679.     incr ind -1
  680. } else {
  681.     incr ind 1
  682. }
  683. set newMesh [lindex $list $ind]
  684. if {$newMesh != ""} {
  685.     globalset theMesh $newMesh
  686. }
  687.     }
  688. }
  689. proc getSortedMeshControlsList {} {
  690.     global meshFrame
  691.     set inlist [getSortedMeshList]
  692.     set outlist {}
  693.     foreach el $inlist {
  694. if {[lsearch -exact [array names meshFrame] "$el"] >= 0} {
  695.     lappend outlist $el
  696. }
  697.     }
  698.     return $outlist
  699. }
  700. proc selectMeshFromAll {which} {
  701.     set list [getSortedMeshControlsList]
  702.     set ind [lsearch -exact $list [globalset theMesh]]
  703.     if {$ind != -1} {
  704. if {$which == "prev"} {
  705.     incr ind -1
  706. } else {
  707.     incr ind 1
  708. }
  709. set newMesh [lindex $list $ind]
  710. if {$newMesh != ""} {
  711.     globalset theMesh $newMesh
  712. }
  713.     }
  714. }
  715. proc checkOSversion {} {
  716.     set word [plv_getwordsize]
  717.     if {![catch {set os [exec uname]}]} {
  718. if {$os == "IRIX64" && $word != 8} {
  719.     set msg 
  720. "You are running the 32-bit version of scanalyze, even
  721.                  though you're lucky enough to be using a machine that can
  722.                  handle the 64-bit version.nnIt is recommended that
  723.                  instead of continuing, you use said 64-bit version, or
  724.                  scanalyze will crash if you load too many meshes."
  725.     if [globalset noui] {
  726. puts "$msgnnPress Ctrl+C now to quit, or return to continue."
  727. gets stdin
  728.     } else {
  729. tk_messageBox -message 
  730.     "$msgnnPress Ctrl+C now to quit, or OK to continue." 
  731.     -title "Scanalyze version warning"
  732.     }
  733. }
  734.     }
  735. }
  736. proc askQuestion {q} {
  737.     toplevel .ask
  738.     wm title .ask "Scanalyze has a question for you"
  739.     label .ask.l -text $q -anchor w
  740.     entry .ask.e -width 32
  741.     frame .ask.b
  742.     button .ask.b.o -text OK 
  743. -command {set askQuestionAnswer [.ask.e get]; destroy .ask}
  744.     button .ask.b.c -text Cancel 
  745. -command {set askQuestionAnswer ""; destroy .ask}
  746.     packchildren .ask.b -side left
  747.     packchildren .ask -side top -anchor w -fill x -padx 4 -pady 3
  748.     grab set .ask
  749.     tkwait window .ask
  750.     global askQuestionAnswer
  751.     set a [set askQuestionAnswer]
  752.     unset askQuestionAnswer
  753.     return $a
  754. }
  755. proc saveCameraPosition {menu} {
  756.     set name [askQuestion "Enter name for camera position:"]
  757.     if {$name != ""} {
  758. savecam $name
  759. $menu add command -label $name 
  760.     -command "restorecam [list $name]"
  761.     }
  762. }
  763. proc savecam {name} {
  764.     global cameraPositions
  765.     set cameraPositions($name) [plv_positioncamera]
  766. }
  767. proc restorecam {{name ""}} {
  768.     global cameraPositions
  769.     if {$name == ""} {
  770. puts "Saved camera positions:"
  771. foreach pos [lsort -dictionary [array names cameraPositions]] {
  772.     puts "t$pos"
  773. }
  774.     } else {
  775. eval plv_positioncamera $cameraPositions($name)
  776.     }
  777. }
  778. proc selectResAbove {above} {
  779.     # BUGBUG this is identical to selectNthRes except for the
  780.     # proc call in the middle
  781.     if {[globalset noui]} {
  782. set meshes [plv_listscans]
  783.     } else {
  784. if {[globalset selectResIncludesInvisible]} {
  785.     set meshes [getMeshList]
  786. } else {
  787.     set meshes [getVisibleMeshes]
  788. }
  789.     }
  790.     redraw block
  791.     progress start [llength $meshes] "Switch to res above $above"
  792.     set num 0
  793.     foreach mesh $meshes {
  794. if {[baildetect {selectResAboveForMesh $above $mesh} bailmsg]} {
  795.     puts "Res-change bailed: $bailmsg"
  796.     break
  797. }
  798. progress update [incr num]
  799.     }
  800.     
  801.     progress done
  802.     redraw flush
  803. }
  804. proc selectResAboveForMesh {above mesh} {
  805.     set list [plv_getreslist $mesh]
  806.     for {set i 0} {$i < [llength $list]} {incr i} {
  807. set res [extractPolyCount [lindex $list $i]]
  808. if {$res < $above} {
  809.     if {$i > 0} {
  810. # use previous res, which was above (or 0 if they're
  811. # all under)
  812. incr i -1
  813.     }
  814.     setMeshResolution $mesh [extractPolyCount [lindex $list $i]]
  815.     return
  816. }
  817.     }
  818.     puts "Warning: selectResForMesh ($above,$mesh) failed"
  819. }
  820. proc selectResAboveUI {} {
  821.     set above [askQuestion "Select resolution of at least how many polys?"]
  822.     if {$above != ""} {
  823. selectResAbove $above
  824.     }
  825. }
  826. proc ls {args} {
  827.     eval shellcommand ls $args
  828. }
  829. proc mv {args} {
  830.     eval shellcommand mv $args
  831. }
  832. proc cp {args} {
  833.     eval shellcommand cp $args
  834. }
  835. proc shellcommand {cmd args} {
  836.     set files ""
  837.     foreach filespec $args {
  838. set glob [glob -nocomplain -- $filespec]
  839. if {$glob == ""} {
  840.     # treat as option, use verbatim
  841.     lappend files $filespec
  842. } else {
  843.     eval lappend files [lsort $glob]
  844. }
  845.     }
  846.     eval exec $cmd $files
  847. }
  848. proc deleteInvisibleMeshes {} {
  849.     redraw block
  850.     foreach mesh [getVisibleMeshes 0] {confirmDeleteMesh $mesh}
  851.     redraw flush
  852. }
  853. proc chooseMeshFalseColor {mesh} {
  854.     set oldcolor [GetMeshFalseColor $mesh]
  855.     set color [tk_chooseColor -title "Select color for $mesh" 
  856.   -initialcolor $oldcolor]
  857.     if {$color != ""} {
  858. SetMeshFalseColor $mesh $color
  859. redraw 1
  860.     }    
  861. }
  862. proc without_redraw {script {maskerrors 0}} {
  863.     redraw block
  864.     set err [catch {uplevel "$script"} errmsg]
  865.     redraw flush
  866.     if {$err} {
  867. if {$maskerrors == "maskerrors"} {
  868.     puts "[globalset errorInfo]"
  869. } else {
  870.     error $errmsg [globalset errorInfo]
  871. }
  872.     }
  873. }
  874. proc setSoftShadowLength {} {
  875.     set len [askQuestion "Soft shadow length (range .01 to .2 works
  876.                           well, default is .05)"]
  877.     if {$len != ""} {
  878. plv_drawstyle -softshadowlength $len
  879.     }
  880. }
  881. # kberg
  882. # Code from running an external program on a mesh.
  883. # Most code taken from the doICP widget
  884. #
  885. proc ExtProg {} {
  886.     set names [getMeshList]
  887.     if {[expr [llength $names] < 1]} {
  888. puts "You need at least one mesh to run an external program on"
  889. return
  890.     }
  891.     
  892.     if {[window_Activate .extProg]} { return }
  893.     toplevel .extProg
  894.     
  895.     message .extProg.instruct -aspect 750  
  896.     -text "Choose a mesh, the name of the external program to run and the name of the resulting mesh"
  897.     -justify left
  898.     
  899.     pack .extProg.instruct -side top -anchor w
  900.     
  901.     # list of all meshes
  902.     set which [frame .extProg.which]
  903.     set meshFrom [eval tk_optionMenu $which.mFrom extFrom bogus]
  904.     $meshFrom config -postcommand "refreshICPRegMeshes $meshFrom"
  905.   
  906.     listRegMeshes "$meshFrom" 0
  907.     set ind [menuInvokeByName $meshFrom [globalset theMesh]]
  908.     label $which.lFrom -text "Input Mesh:" -padx 3
  909.     
  910.     pack $which.lFrom $which.mFrom 
  911.     pack $which -side top -anchor w
  912.     # entry box
  913.     frame .extProg.eb
  914.     message .extProg.eb.instruct -aspect 1000  
  915.     -text "Resulting mesh name:"
  916.     entry .extProg.eb.resName -relief sunken -textvariable resMeshName
  917.     message .extProg.eb.cmdInstruct -aspect 1000 
  918.     -text "Command:"
  919.     entry .extProg.eb.command -relief sunken -textvariable commandName
  920.     
  921.     pack .extProg.eb.instruct .extProg.eb.resName .extProg.eb.cmdInstruct .extProg.eb.command -padx 5 -fill x
  922.     pack .extProg.eb -side top -anchor w -fill x
  923.     #checkbox
  924.     frame .extProg.cbutton
  925.     checkbutton .extProg.cbutton.cb -text "Include selection information" 
  926.     -variable incSelInfo -onvalue 1 -offvalue 0
  927.     pack .extProg.cbutton.cb
  928.     pack .extProg.cbutton -side top -anchor w
  929.     # buttons
  930.     frame .extProg.do
  931.     button .extProg.do.doIt -text "Filter" 
  932. -command { plv_extProg $commandName $extFrom $resMeshName $incSelInfo}
  933.     
  934.     packchildren .extProg.do -side top
  935.     pack .extProg.do -side top -anchor w
  936.     
  937.     wm title .extProg "External Program"
  938.     bind .extProg <KeyPress-Return> {.extProg.do.doIt invoke}
  939.     window_Register .extProg
  940. }