1
##########################################################################
3
# Routines for creating cutting planes for stacked raster surfaces in NVIZ
5
# Original author unknown.
6
# Probably U.S. Army Construction Engineering Research Laboratory
9
# Major update of GUI Nov 2006, Michael Barton, Arizona State University
11
##########################################################################
12
# COPYRIGHT: (C) 2006 by Michael Barton and the GRASS Development Team
14
# This program is free software under the GNU General Public
15
# License (>=v2). Read the file COPYING that comes with GRASS
18
##########################################################################
19
# Default Priority for this panel
21
# priority is from 0 to 10
22
# the lower the number, the quicker it will be bumped
24
# Panels will be loaded by the greater of 5 or their current priority
25
##########################################################################
27
# Nv_(CurrCutPlane) 0-5
28
# Nv_(CutPlaneFence) { NONE, TOP, BOTTOM, BLEND, GREY }
36
##########################################################################
37
# Procedure to make cutting planes panel
38
##########################################################################
39
set Nv_(CutPlanesMade) 0
40
set Nv_(CutPlaneFence) NONE
41
set Nv_(CurrCutPlane) -1
43
proc mkcutplanePanel { BASE } {
47
# Initialize panel info
48
set panel [St_create {window name size priority} $BASE "Cutting Planes" 1 5]
49
frame $BASE -relief flat -borderwidth 0
50
Nv_mkPanelname $BASE "Cutting Planes Panel"
51
set Nv_(CutPlaneBase) $BASE
53
set update_routine xyupdate
54
append update_routine $BASE
55
set ucmd "proc $update_routine \{ x y \} \{ cutplaneXYTrans $BASE \$x \$y \}"
58
# Create the active plane pulldown
60
label $BASE.current.lbl -text "Active cutting plane: "
61
label $BASE.current.cpl -text "None" -relief raised -bd 1 \
62
-width 8 -fg black -font $nviztxtfont
63
pack $BASE.current.lbl $BASE.current.cpl -side left -fill none
65
menu $BASE.cut_plane_menu
66
set rname $BASE.cut_plane_menu
67
$rname add command -label "None" -command "cutplaneSetPlane $BASE -1"
68
$rname add command -label "Plane 0" -command "cutplaneSetPlane $BASE 0"
69
$rname add command -label "Plane 1" -command "cutplaneSetPlane $BASE 1"
70
$rname add command -label "Plane 2" -command "cutplaneSetPlane $BASE 2"
71
$rname add command -label "Plane 3" -command "cutplaneSetPlane $BASE 3"
72
$rname add command -label "Plane 4" -command "cutplaneSetPlane $BASE 4"
73
$rname add command -label "Plane 5" -command "cutplaneSetPlane $BASE 5"
75
if {$Nv_(CutPlanesMade) == 0} then {
76
for {set i 0} {$i < 6} {incr i} {
81
bind $BASE.current.cpl <1> "$rname post %X %Y"
82
set Nv_(CutPlaneFence) OFF
85
# Create radio buttons for cut plane shading
86
menubutton $BASE.current.shading -menu $BASE.current.shading.m \
87
-relief raised -indicatoron 1 -bd 1 -width 10 -text "set shading"
89
set shademenu [menu $BASE.current.shading.m -tearoff 0]
90
$shademenu add radiobutton -label "top color" \
91
-command "Nset_fence_color ABOVE" -variable Nv_(CutPlaneFence) -value "TOP"
92
$shademenu add radiobutton -label "bottom color" \
93
-command "Nset_fence_color BELOW" -variable Nv_(CutPlaneFence) -value "BELOW"
94
$shademenu add radiobutton -label "blend" \
95
-command "Nset_fence_color BLEND" -variable Nv_(CutPlaneFence) -value "BLEND"
96
$shademenu add radiobutton -label "shaded" \
97
-command "Nset_fence_color GREY" -variable Nv_(CutPlaneFence) -value "GREY"
98
$shademenu add radiobutton -label "clear" \
99
-command "Nset_fence_color OFF" -variable Nv_(CutPlaneFence) -value "OFF"
101
pack $BASE.current.shading -side right -anchor e
102
pack $BASE.current -side top -pady 5 -anchor w -expand 1 -fill both
108
set pos [Nv_mkXYScale $BASE.left.pos cross CPLANE_POS 125 125 63 63 $update_routine $update_routine]
109
pack $pos -side top -anchor e
111
# Create X,Y, and Z entry widgets along with
112
# Reset, all off and close buttons
114
label $BASE.coords.x_lbl -text "X:"
115
label $BASE.coords.y_lbl -text "Y:"
116
entry $BASE.coords.x_ent -width 7 -relief sunken -bg white
117
entry $BASE.coords.y_ent -width 7 -relief sunken -bg white
118
bind $BASE.coords.x_ent <Return> "cutplaneSetTransFromEntry $BASE x"
119
bind $BASE.coords.y_ent <Return> "cutplaneSetTransFromEntry $BASE y"
120
pack $BASE.coords.x_lbl $BASE.coords.x_ent \
121
$BASE.coords.y_lbl $BASE.coords.y_ent -side left -anchor w
122
pack $BASE.coords -side bottom -in $BASE.left -anchor e -pady 3
124
pack $BASE.left -side left -fill x -expand 1 -pady 3 -anchor w
126
# Create z coord, rotate, and tilt sliders, labels and text entry widgets
129
set update_routine zupdate
130
append update_routine $BASE
131
set ucmd "proc $update_routine \{ z \} \{ cutplaneZTrans $BASE \$z \}"
133
set range [Nget_zrange]
134
# set range [list 0 1000]
136
scale $BASE.zcoord.scl -orient vertical -to [expr int([lindex $range 0])] \
137
-from [expr int([lindex $range 1])] -showvalue false -width 13 \
138
-activebackground gray80 -background gray90 -command $update_routine
139
label $BASE.zcoord.lbl -text "Z coord"
140
entry $BASE.zcoord.val -width 5 -relief sunken -bg white
141
pack $BASE.zcoord.scl $BASE.zcoord.lbl $BASE.zcoord.val
142
bind $BASE.zcoord.val <KeyPress-Return> "cutplaneSetTransFromEntry $BASE z"
144
set update_routine rot_update
145
append update_routine $BASE
146
set ucmd "proc $update_routine \{ r \} \{ cutplaneUpdateRotation $BASE \}"
149
scale $BASE.rotate.scl -orient vertical -from 360 -to 0 -showvalue false -width 13\
150
-activebackground gray80 -background gray90 -command $update_routine
151
label $BASE.rotate.lbl -text "Rotate"
152
entry $BASE.rotate.val -width 5 -relief sunken -bg white
153
pack $BASE.rotate.scl $BASE.rotate.lbl $BASE.rotate.val
154
bind $BASE.rotate.val <KeyPress-Return> "cutplaneUpdateRotation2 $BASE"
156
set update_routine tilt_update
157
append update_routine $BASE
158
set ucmd "proc $update_routine \{ t \} \{ cutplaneUpdateTilt $BASE \}"
161
scale $BASE.tilt.scl -orient vertical -from 360 -to 0 -showvalue false -width 13\
162
-activebackground gray80 -background gray90 -command $update_routine
163
label $BASE.tilt.lbl -text "Tilt"
164
entry $BASE.tilt.val -width 5 -relief sunken -bg white
165
pack $BASE.tilt.scl $BASE.tilt.lbl $BASE.tilt.val
166
bind $BASE.tilt.val <KeyPress-Return> "cutplaneUpdateTilt2 $BASE"
168
pack $BASE.zcoord $BASE.tilt $BASE.rotate -side right -in $BASE.right -padx 1 -anchor e
169
$BASE.tilt.val insert 0 0
170
$BASE.rotate.val insert 0 0
172
# cutplaneUpdateRotation $BASE
173
# cutplaneUpdateTilt $BASE
175
pack $BASE.right -side right -fill none -expand 0 -pady 3 -anchor e
177
cutplaneSetPlane $BASE $Nv_(CurrCutPlane)
179
# panel control buttons at bottom
182
button $BASE.bottom.reset -text "Reset" -width 7 -bd 1 \
183
-command "cutplaneReset $BASE"
184
button $BASE.bottom.all_off -text "All Off" -width 7 -bd 1 \
185
-command "cutplaneAllOff; cutplaneSetPlane $BASE -1"
186
button $BASE.bottom.close -text "Close" -width 7 -bd 1 \
187
-command "Nv_closePanel $BASE"
188
pack $BASE.bottom.reset $BASE.bottom.all_off $BASE.bottom.close \
189
-side left -fill none -expand 1
191
pack $BASE.left $BASE.right -side left -in $BASE.top -expand 1 -fill both
192
pack $BASE.top $BASE.bottom -side top -fill both -pady 3 -expand 1
198
# Update routine - sets panel from gsf library
199
proc cutplaneUpdateFromGSF { BASE } {
202
set curr $Nv_(CurrCutPlane)
203
set fence [Nget_fence_color]
205
if { $curr != -1 } then {
206
set rot [Ncutplane$curr get_rot]
207
set trans [Ncutplane$curr get_trans]
210
set trans [list 0.5 0.5 0]
213
$BASE.rotate.scl set [lindex $rot 2]
214
$BASE.tilt.scl set [lindex $rot 1]
215
cutplaneXYTrans $BASE [lindex $trans 0] [lindex $trans 1]
216
cutplaneZTrans $BASE [lindex $trans 2]
217
set Nv_(CutPlaneFence) $fence
220
# Reset routine for cutplane panel
221
proc Nviz_cutplane_reset {} {
224
set Nv_(CurrCutPlane) -1
225
set Nv_(CutPlaneFence) NONE
227
for {set i 0} {$i < 6} {incr i} {
229
Ncutplane$i set_rot 0 0 0
230
Ncutplane$i set_trans 0 0 0
233
cutplaneSetPlane $Nv_(CutPlaneBase) $Nv_(CurrCutPlane)
234
cutplaneUpdateFromGSF $Nv_(CutPlaneBase)
237
# Save routine for saving state of Nviz
238
proc Nviz_cutplane_save { file_hook } {
241
puts $file_hook ">>>start cutplane"
242
# Collect and save all the attributes from the six cutplanes
243
# Plus save which one happens to be active
244
puts $file_hook "$Nv_(CurrCutPlane)"
245
puts $file_hook "$Nv_(CutPlaneFence)"
247
for {set i 0} {$i < 6} {incr i} {
248
puts $file_hook "[Ncutplane$i state]"
249
puts $file_hook "[Ncutplane$i get_rot]"
250
puts $file_hook "[Ncutplane$i get_trans]"
254
# Load routine for loading state of Nviz
255
proc Nviz_cutplane_load { file_hook } {
258
gets $file_hook "$Nv_(CurrCutPlane)"
259
gets $file_hook "$Nv_(CutPlaneFence)"
261
for {set i 0} {$i < 6} {incr i} {
262
gets $file_hook cstate
263
if {"$cstate" == "on"} then {
270
set crot [split "$crot"]
271
Ncutplane$i set_rot [lindex $crot 0] [lindex $crot 1] [lindex $crot 2]
273
gets $file_hook ctrans
274
set ctrans [split "$ctrans"]
275
Ncutplane$i set_trans [lindex $ctrans 0] [lindex $ctrans 1] [lindex $ctrans 2]
278
cutplaneSetPlane $Nv_(CutPlaneBase) $Nv_(CurrCutPlane)
282
##########################################################################
283
# Callbacks to set current cut plane
284
##########################################################################
285
proc cutplaneSetPlane { BASE plane } {
288
$BASE.cut_plane_menu unpost
289
if {$plane == -1} then {
290
$BASE.current.cpl configure -text "None"
292
$BASE.current.cpl configure -text "Plane $plane"
294
for {set i 0} {$i < [Nnum_cutplane_obj]} {incr i} {
295
if {$plane == $i} then {
302
set Nv_(CurrCutPlane) $plane
304
set curr [Nget_current_cutplane]
305
if {$curr != "None"} then {
311
##########################################################################
312
# Callbacks to update slider displays for rotate and tilt
313
##########################################################################
314
proc cutplaneUpdateRotation { BASE } {
315
set value [$BASE.rotate.scl get]
316
$BASE.rotate.val delete 0 end
317
$BASE.rotate.val insert end $value
319
# Call the rotation/tilt routine
320
cutplaneUpdateRT $BASE
323
proc cutplaneUpdateRotation2 { BASE } {
324
set value [$BASE.rotate.val get]
325
if {[catch "expr int($value)"] == 1} then {
328
set value [expr int($value)]
330
$BASE.rotate.scl set $value
332
# Call the rotation/tilt routine
333
cutplaneUpdateRT $BASE
336
proc cutplaneUpdateTilt { BASE } {
337
set value [$BASE.tilt.scl get]
338
$BASE.tilt.val delete 0 end
339
$BASE.tilt.val insert end $value
341
# Call the rotation/tilt routine
342
cutplaneUpdateRT $BASE
345
proc cutplaneUpdateTilt2 { BASE } {
346
set value [$BASE.tilt.val get]
347
if {[catch "expr int($value)"] == 1} then {
350
set value [expr int($value)]
352
$BASE.tilt.scl set $value
354
# Call the rotation/tilt routine
355
cutplaneUpdateRT $BASE
358
proc cutplaneUpdateRT { BASE } {
359
set curr [Nget_current_cutplane]
361
if {$curr != "None"} then {
362
set tilt [$BASE.tilt.val get]
363
set rot [$BASE.rotate.val get]
364
$curr set_rot 0 $tilt $rot
369
##########################################################################
370
# Routine to reset the current cutplane
371
##########################################################################
372
proc cutplaneReset { BASE } {
374
set curr [Nget_current_cutplane]
375
set Nv_(CurrCutPlane) [string range $curr 9 end]
377
if {$curr != "None"} then {
378
$curr set_trans 0 0 0
380
cutplaneSetTrans $BASE 0 0 0
382
# Now update the interface
383
$BASE.rotate.val delete 0 end
384
$BASE.rotate.val insert 0 0
385
$BASE.tilt.val delete 0 end
386
$BASE.tilt.val insert 0 0
387
$BASE.zcoord.scl set 0
388
cutplaneUpdateRotation2 $BASE
389
cutplaneUpdateTilt2 $BASE
391
Nv_itemDrag $BASE.pos $Nv_(CPLANE_POS) 63 63
395
##########################################################################
396
# Routine to turn off all cutplanes
397
##########################################################################
398
proc cutplaneAllOff {} {
399
for {set i 0} {$i < [Nnum_cutplane_obj]} {incr i} {
406
##########################################################################
407
# Routine to set position of cutplane based on XY position
408
##########################################################################
409
proc cutplaneXYTrans { w x y } {
410
set curr [Nget_current_cutplane]
412
if {"$curr" != "None"} then {
413
# Figure out translation coordinates
414
set new_x [expr ($x - 0.5) * [Nget_xyrange]]
415
set new_y [expr ($y - 0.5) * [Nget_xyrange]]
416
set new_z [lindex [$curr get_trans] 2]
418
# Call the general translation routine
419
cutplaneSetTrans $w $new_x $new_y $new_z
423
##########################################################################
424
# Routine to set position of cutplane based on Z position
425
##########################################################################
426
proc cutplaneZTrans { w z } {
427
set curr [Nget_current_cutplane]
429
if {"$curr" != "None"} then {
430
# Figure out translation coordinates
431
set old [$curr get_trans]
432
set new_x [lindex $old 0]
433
set new_y [lindex $old 1]
435
# Call the general translation routine
436
cutplaneSetTrans $w $new_x $new_y $z
440
##########################################################################
441
# Routine to set cutplane translation from an entry widget
442
##########################################################################
443
proc cutplaneSetTransFromEntry { BASE coord } {
446
set curr [Nget_current_cutplane]
448
if {"$curr" != "None"} then {
449
# Get old translation coordinates
450
set old_coords [$curr get_trans]
451
set new_x [lindex $old_coords 0]
452
set new_y [lindex $old_coords 1]
453
set new_z [lindex $old_coords 2]
455
# Get the appropriate new coordinate
457
x { set new_x [$BASE.coords.x_ent get] }
458
y { set new_y [$BASE.coords.y_ent get] }
459
z { set new_z [$BASE.zcoord.val get] }
462
# Make sure user entered a numerical value
463
# if not force a numerical value
464
if {[catch "expr $new_x + 0"] != 0} then { set new_x 0 }
465
if {[catch "expr $new_y + 0"] != 0} then { set new_y 0 }
466
if {[catch "expr $new_z + 0"] != 0} then { set new_z 0 }
468
#Update Z-scale to match entry value
469
#Reset to / from limits if required
470
if {$new_z < [lindex [$BASE.zcoord.scl configure -to] 4]} {
471
$BASE.zcoord.scl configure -to [expr int($new_z - 1)]
473
if {$new_z > [lindex [$BASE.zcoord.scl configure -from] 4]} {
474
$BASE.zcoord.scl configure -from [expr int($new_z + 1)]
476
$BASE.zcoord.scl set $new_z
478
#Update Canvas position based on entered XY
479
if { [Nget_xyrange] > 0} {
480
set dis_x [expr int( ($new_x/([Nget_xyrange]/2))*63)+63]
481
set dis_y [expr int( ($new_y/([Nget_xyrange]/2))*63)+63]
482
Nv_itemDrag $BASE.pos $Nv_(CPLANE_POS) $dis_x $dis_y
485
# Finally set the translation
486
cutplaneSetTrans $BASE $new_x $new_y $new_z
490
##########################################################################
491
# Routine to set position (general)
492
##########################################################################
493
proc cutplaneSetTrans { w x y z } {
494
set curr [Nget_current_cutplane]
496
if {"$curr" != "None"} then {
497
$w.coords.x_ent delete 0 end
498
$w.coords.y_ent delete 0 end
499
$w.zcoord.val delete 0 end
501
$w.coords.x_ent insert 0 $x
502
$w.coords.y_ent insert 0 $y
503
$w.zcoord.val insert 0 $z
505
$curr set_trans $x $y $z