File: Example4.html

package info (click to toggle)
geomview 1.9.4-2
  • links: PTS
  • area: main
  • in suites: squeeze
  • size: 21,772 kB
  • ctags: 11,826
  • sloc: ansic: 90,886; sh: 9,802; cpp: 1,215; makefile: 1,064; objc: 263; yacc: 149; tcl: 76; lex: 70
file content (213 lines) | stat: -rw-r--r-- 8,045 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
<html lang="en">
<head>
<title>Example4 - Geomview Manual</title>
<meta http-equiv="Content-Type" content="text/html">
<meta name="description" content="Geomview Manual">
<meta name="generator" content="makeinfo 4.8">
<link title="Top" rel="start" href="index.html#Top">
<link rel="up" href="Modules.html#Modules" title="Modules">
<link rel="prev" href="Example3.html#Example3" title="Example3">
<link rel="next" href="Module-Installation.html#Module-Installation" title="Module Installation">
<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
<meta http-equiv="Content-Style-Type" content="text/css">
<style type="text/css"><!--
  pre.display { font-family:inherit }
  pre.format  { font-family:inherit }
  pre.smalldisplay { font-family:inherit; font-size:smaller }
  pre.smallformat  { font-family:inherit; font-size:smaller }
  pre.smallexample { font-size:smaller }
  pre.smalllisp    { font-size:smaller }
  span.sc    { font-variant:small-caps }
  span.roman { font-family:serif; font-weight:normal; } 
  span.sansserif { font-family:sans-serif; font-weight:normal; } 
--></style>
</head>
<body>
<div class="node">
<p>
<a name="Example4"></a>
Next:&nbsp;<a rel="next" accesskey="n" href="Module-Installation.html#Module-Installation">Module Installation</a>,
Previous:&nbsp;<a rel="previous" accesskey="p" href="Example3.html#Example3">Example3</a>,
Up:&nbsp;<a rel="up" accesskey="u" href="Modules.html#Modules">Modules</a>
<hr>
</div>

<h3 class="section">6.6 Example 4: Simple Tcl/Tk Module Demonstrating Picking</h3>

<p>It's not necessary to write a Geomview module in C.  The only requirement
of an external module is that it send GCL commands to its standard output
and expect responses (if any) on its standard input.   An external module
can be written in C, perl, tcl/tk, or pretty much anything.

   <p>As an example, assuming you have Tcl/Tk version 4.0 or later,
here's an external module with a simple GUI which demonstrates interaction with
geomview.  This manual doesn't discuss the Tcl/Tk language; see the good book
on the subject by its originator John Ousterhout, published by Addison-Wesley,
titled <em>Tcl and the Tk Toolkit</em>.

   <p>The `<samp><span class="samp">#!</span></samp>' on the script's first line causes the system to interpret
the script using the Tcl/Tk `<samp><span class="samp">wish</span></samp>' program; you might have to change its
first line if that's in some location other than /usr/local/bin/wish4.0. 
Or, you could define it as a module using
<pre class="example">       (emodule-define  "Pick Demo"  "wish pickdemo.tcl")
</pre>
   <p>in which case `<samp><span class="samp">wish</span></samp>' could be anywhere on the UNIX search path.

<pre class="example">     #! /usr/local/bin/wish4.0
     
     # We use "fileevent" below to have "readsomething" be called whenever
     # data is available from standard input, i.e. when geomview has sent us
     # something.  It promises to include a trailing newline, so we can use
     # "gets" to read the geomview response, then parse its nested parentheses
     # into tcl-friendly {} braces.
     
     proc readsomething {} {
       if {[gets stdin line] &lt; 0} {
             puts stderr "EOF on input, exiting..."
             exit
       }
       regsub -all {\(} $line "\{" line
       regsub -all {\)} $line "\}" line
       # Strip outermost set of braces
       set stuff [lindex $line 0]
       # Invoke handler for whichever command we got.  Could add others here,
       # if we asked geomview for other kinds of data as well.
       switch [lindex $stuff 0] {
             pick     {handlepick $stuff}
             rawevent {handlekey $stuff}
       }
     }
     
     # Fields of a "pick" response, from geomview manual:
     #     (pick COORDSYS GEOMID G V E F P VI EI FI)
     #          The pick command is executed internally in response to pick
     #          events (right mouse double click).
     #
     #          COORDSYS = coordinate system in which coordinates of the following
     #              arguments are specified.   This can be:
     #               world: world coord sys
     #               self:  coord sys of the picked geom (GEOMID)
     #               primitive: coord sys of the actual primitive within
     #                   the picked geom where the pick occurred.
     #          GEOMID = id of picked geom
     #          G = picked point (actual intersection of pick ray with object)
     #          V = picked vertex, if any
     #          E = picked edge, if any
     #          F = picked face
     #          P = path to picked primitive [0 or more]
     #          VI = index of picked vertex in primitive
     #          EI = list of indices of endpoints of picked edge, if any
     #          FI = index of picked face
     
     # Report when user picked something.
     #
     proc handlepick {pick} {
       global nameof selvert seledge order
       set obj [lindex $pick 2]
       set xyzw [lindex $pick 3]
       set fv [lindex $pick 6]
       set vi [lindex $pick 8]
       set ei [lindex $pick 9]
       set fi [lindex $pick 10]
     
       # Report result, converting 4-component homogeneous point into 3-space point.
       set w [lindex $xyzw 3]
       set x [expr [lindex $xyzw 0]/$w]
       set y [expr [lindex $xyzw 1]/$w]
       set z [expr [lindex $xyzw 2]/$w]
       set s "$x $y $z "
       if {$vi &gt;= 0} {
             set s "$s  vertex #$vi"
       }
       if {$ei != {}} {
             set s "$s  edge [lindex $ei 0]-[lindex $ei 1]"
       }
       if {$fi != -1} {
             set s "$s  face #$fi ([expr [llength $fv]/3]-gon)"
       }
       msg $s
     }
     
     
     # Having asked for notification of these raw events, we report when
     # the user pressed these keys in the geomview graphics windows.
     
     proc handlekey {event} {
       global lastincr
       switch [lindex $event 1] {
         32 {msg "Pressed space bar"}
          8 {msg "Pressed backspace key"}
       }
     }
     
     
     #
     # Display a message on the control panel, and on the terminal where geomview
     # was started.  We use ``puts stderr ...'' rather than simply ``puts ...'',
     # since Geomview interprets anything we send to standard output
     # as a GCL command!
     #
     proc msg {str} {
       global msgtext
       puts stderr $str
       set msgtext $str
       update
     }
     
     # Load object from file
     proc loadobject {fname} {
       if {$fname != ""} {
             puts "(geometry thing &lt; $fname)"
             # Be sure to flush output to ensure geomview receives this now!
             flush stdout
       }
     }
     
     
     # Build simple "user interface"
     
     # The message area could be a simple label rather than an entry box,
     # but we want to be able to use X selection to copy text from it.
     # The default mouse bindings do that automatically.
     
     entry .msg -textvariable msgtext -width 45
     pack .msg
     
     frame .f
     
       label .f.l -text "File to load:"
       pack .f.l -side left
     
       entry .f.ent -textvariable fname
       pack .f.ent -side left -expand true -fill x
       bind .f.ent &lt;Return&gt; { loadobject $fname }
     
     pack .f
     
     
     # End UI definition.
     
     
     # Call "readsomething" when data arrives from geomview.
     
     fileevent stdin readable {readsomething}
     
     # Geomview initialization
     
     puts {
             (interest (pick primitive))
             (interest (rawevent 32))	# Be notified when user presses space
             (interest (rawevent 8))		# or backspace keys.
             (geometry thing &lt; hdodec.off)
             (normalization world none)
     }
     # Flush to ensure geomview receives this.
     flush stdout
     
     wm title . {Sample external module}
     
     msg "Click right mouse in graphics window"
</pre>
   <!-- **************************************************************** -->
</body></html>