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 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232
|
<html lang="en">
<head>
<title>Example1 - 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="Interface.html#Interface" title="Interface">
<link rel="next" href="Example2.html#Example2" title="Example2">
<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="Example1"></a>
Next: <a rel="next" accesskey="n" href="Example2.html#Example2">Example2</a>,
Previous: <a rel="previous" accesskey="p" href="Interface.html#Interface">Interface</a>,
Up: <a rel="up" accesskey="u" href="Modules.html#Modules">Modules</a>
<hr>
</div>
<h3 class="section">6.2 Example 1: Simple External Module</h3>
<p>This section gives a very simple external module which displays an
oscillating mesh. To try out this example, make a copy of the file
<samp><span class="file">example1.c</span></samp> (it is distributed with Geomview in the <samp><span class="file">doc</span></samp>
subdirectory) in your directory and compile it with the command
<pre class="example"> cc -o example1 example1.c -lm
</pre>
<p>Then put the line
<pre class="example"> (emodule-define "Example 1" "./example1")
</pre>
<p class="noindent">in a file called <samp><span class="file">.geomview</span></samp> in your current directory. Then invoke
Geomview; it is important that you compile the example program, create
the <samp><span class="file">.geomview</span></samp> file, and invoke Geomview all in the same
directory. You should see "Example 1" in the <em>Modules</em> browser
of Geomview's <em>Main</em> panel; click on this entry in the browser to
start the module. A surface should appear in your camera window and should
begin oscillating. You can stop the module by clicking on the red "[1]
Example 1" line in the <em>Modules</em> browser.
<pre class="example"> <!-- #include "example1.c" -->
/*
* example1.c: oscillating mesh
*
* This example module is distributed with the Geomview manual.
* If you are not reading this in the manual, see the "External
* Modules" chapter of the manual for more details.
*
* This module creates an oscillating mesh.
*/
#include <math.h>
#include <stdio.h>
/* F is the function that we plot
*/
float F(x,y,t)
float x,y,t;
{
float r = sqrt(x*x+y*y);
return(sin(r + t)*sqrt(r));
}
main(argc, argv)
char **argv;
{
int xdim, ydim;
float xmin, xmax, ymin, ymax, dx, dy, t, dt;
xmin = ymin = -5; /* Set x and y */
xmax = ymax = 5; /* plot ranges */
xdim = ydim = 24; /* Set x and y resolution */
dt = 0.1; /* Time increment is 0.1 */
/* Geomview setup. We begin by sending the command
* (geometry example { : foo})
* to Geomview. This tells Geomview to create a geom called
* "example" which is an instance of the handle "foo".
*/
printf("(geometry example { : foo })\n");
fflush(stdout);
/* Loop until killed.
*/
for (t=0; ; t+=dt) {
UpdateMesh(xmin, xmax, ymin, ymax, xdim, ydim, t);
}
}
/* UpdateMesh sends one mesh iteration to Geomview. This consists of
* a command of the form
* (read geometry { define foo
* MESH
* ...
* })
* where ... is the actual data of the mesh. This command tells
* Geomview to make the value of the handle "foo" be the specified
* mesh.
*/
UpdateMesh(xmin, xmax, ymin, ymax, xdim, ydim, t)
float xmin, xmax, ymin, ymax, t;
int xdim, ydim;
{
int i,j;
float x,y, dx,dy;
dx = (xmax-xmin)/(xdim-1);
dy = (ymax-ymin)/(ydim-1);
printf("(read geometry { define foo \n");
printf("MESH\n");
printf("%1d %1d\n", xdim, ydim);
for (j=0, y = ymin; j<ydim; ++j, y += dy) {
for (i=0, x = xmin; i<xdim; ++i, x += dx) {
printf("%f %f %f\t", x, y, F(x,y,t));
}
printf("\n");
}
printf("})\n");
fflush(stdout);
}
<!-- #end include -->
</pre>
<p>The module begins by defining a function <code>F(x,y,t)</code> that
specifies a time-varying surface. The purpose of the module is to
animate this surface over time.
<p>The main program begins by defining some variables that specify
the parameters with which the function is to be plotted.
<p>The next bit of code in the main program prints the following
line to standard output
<pre class="example"> (geometry example { : foo })
</pre>
<p>This tells Geomview to create a geom called <code>example</code> which is an
instance of the handle <code>foo</code>. <em>Handles</em> are a part of the
OOGL file format which allow you to name a piece of geometry whose value
can be specified elsewhere (and in this case updated many times); for
more information on handles, See <a href="OOGL-File-Formats.html#OOGL-File-Formats">OOGL File Formats</a>. In this case,
<code>example</code> is the title by which the user will see the object in
Geomview's object browser, and <code>foo</code> is the internal name of the
handle that the object is a reference to.
<p>We then do <code>fflush(stdout)</code> to ensure that Geomview
receives this command immediately. In general, since pipes may be
buffered, an external module should do this whenever it wants to be
sure Geomview has actually received everything it has printed out.
<p>The last thing in the main program is an infinite loop that cycles
through calls to the procedure <code>UpdateMesh</code> with increasing
values of <code>t</code>. <code>UpdateMesh</code> sends Geomview a command
of the form
<pre class="example"> (read geometry { define foo
MESH
24 24
...
})
</pre>
<p class="noindent">where <code>...</code> is a long list of numbers. This command tells Geomview
to make the value of the handle <code>foo</code> be the specified mesh. As
soon as Geomview receives this command, the geom being displayed
changes to reflect the new geometry.
<p>The mesh is given in the format of an OOGL MESH. This begins with
the keyword <code>MESH</code>. Next come two numbers that give the x and y
dimensions of the mesh; in this case they are both 24. This line is
followed by 24 lines, each containing 24 triples of numbers. Each of
these triples is a point on the surface. Then finally there is a line
with "<code>})</code>" on it that ends the "<code>{</code>" which began the
<code>define</code> statement and the "<code>(</code>" that began the command. For
more details on the format of MESH data, see <a href="MESH.html#MESH">MESH</a>.
<p>This module could be written without the use of handles by having it
write out commands of the form
<pre class="example"> (geometry example {
MESH
24 24
...
})
</pre>
<p class="noindent">This first time Geomview receives a command of this form it would create
a geom called <code>example</code> with the given <code>MESH</code> data.
Subsequent <code>(geometry example ...)</code> commands would cause
Geomview to replace the geometry of the geom <code>example</code> with the new
<code>MESH</code> data. If done in this way there would be no need to send
the initial <code>(geometry example { : foo })</code> command as above. The
handle technique is useful, however, because it can be used in more
general situations where a handle represents only part of a complex
geom, allowing an external module to replace only that part without
having to retransmit the entire geom. For more information on handles,
see <a href="GCL.html#GCL">GCL</a>. See <a href="References.html#References">References</a>. See <a href="hdefine.html#hdefine"><code>(hdefine ...)</code></a>. See <a href="read.html#read"><code>(read ...)</code></a>.
<p>The module loops through calls to <code>UpdateMesh</code> which print out
commands of the above form one after the other as fast as possible.
The loop continues indefinitely; the module will terminate when the
user kills it by clicking on its instance line in the <em>Modules</em>
browser, or else when Geomview exits.
<p>Sometimes when you terminate this module by clicking on its instance
entry the <em>Modules</em> browser, Geomview will kill it while it is in
the middle of sending a command to Geomview. Geomview will then receive
only a piece of a command and will print out a cryptic but harmless
error message about this. When a module has a user interface panel
it can use a "Quit" button to provide a more graceful way for the user
to terminate the module. See the next example.
<p>You can run this module in a shell window without Geomview to see the
commands it prints out. You will have to kill it with
<kbd>ctrl-C</kbd> to get it to stop.
<!-- ================================================================ -->
</body></html>
|