home *** CD-ROM | disk | FTP | other *** search
/ SGI Freeware 1999 August / SGI Freeware 1999 August.iso / dist / fw_geomview.idb / usr / freeware / lib / geomview / doc / example3.c.z / example3.c
Encoding:
C/C++ Source or Header  |  1999-01-26  |  6.6 KB  |  231 lines

  1. /*
  2.  * example3.c: external module with bi-directional communication
  3.  *
  4.  * This example module is distributed with the geomview manual.
  5.  * If you are not reading this in the manual, see the "External
  6.  * Modules" chapter of the manual for an explanation.
  7.  *
  8.  * This module is the same as the "Nose" program that is distributed
  9.  * with geomview.  It illustrates how a module can find out about
  10.  * and respond to user pick events in geomview.  It draws a little box
  11.  * at the point where a pick occurrs.  The box is yellow if it is not
  12.  * at a vertex, and magenta if it is on a vertex.  If it is on an edge,
  13.  * the program also marks the edge.
  14.  *
  15.  * To compile:
  16.  *
  17.  *   cc -I/u/gcg/ngrap/include -g -o example3 example3.c \
  18.  *      -L/u/gcg/ngrap/lib/sgi -loogl -lm
  19.  *
  20.  * If you are not on the Geometry Center's system you should replace
  21.  * "/u/gcg/ngrap" above with the pathname of the geomview distribution
  22.  * directory on your system.
  23.  */
  24.  
  25. #include <stdio.h>
  26. #include "lisp.h"               /* We use the OOGL lisp library */
  27. #include "pickfunc.h"           /* for PICKFUNC below */
  28. #include "3d.h"                 /* for 3d geometry library */
  29.  
  30. /* boxstring gives the OOGL data to define the little box that
  31.  * we draw at the pick point.  NOTE:  It is very important to
  32.  * have a newline at the end of the OFF object in this string.
  33.  */
  34. char boxstring[] = "\
  35. INST\n\
  36. transform\n\
  37. .04 0 0 0\n\
  38. 0 .04 0 0\n\
  39. 0 0 .04 0\n\
  40. 0 0 0 1\n\
  41. geom\n\
  42. OFF\n\
  43. 8 6 12\n\
  44. \n\
  45. -.5 -.5 -.5     # 0   \n\
  46. .5 -.5 -.5      # 1   \n\
  47. .5  .5 -.5      # 2   \n\
  48. -.5  .5 -.5     # 3   \n\
  49. -.5 -.5  .5     # 4   \n\
  50. .5 -.5  .5      # 5   \n\
  51. .5  .5  .5      # 6   \n\
  52. -.5  .5  .5     # 7   \n\
  53. \n\
  54. 4 0 1 2 3\n\
  55. 4 4 5 6 7\n\
  56. 4 2 3 7 6\n\
  57. 4 0 1 5 4\n\
  58. 4 0 4 7 3\n\
  59. 4 1 2 6 5\n";
  60.  
  61. progn()
  62. {
  63.   printf("(progn\n");
  64. }
  65.  
  66. endprogn()
  67. {
  68.   printf(")\n");
  69.   fflush(stdout);
  70. }
  71.  
  72. Initialize()
  73. {
  74.   extern LObject *Lpick();  /* This is defined by PICKFUNC below but must */
  75.                   /* be used in the following LDefun() call */
  76.   LInit();
  77.   LDefun("pick", Lpick, NULL);
  78.  
  79.   progn(); {
  80.     /* Define handle "littlebox" for use later
  81.      */
  82.     printf("(read geometry { define littlebox { %s }})\n", boxstring);
  83.  
  84.     /* Express interest in pick events; see geomview manual for explanation.
  85.      */
  86.     printf("(interest (pick world * * * * nil nil nil nil nil))\n");
  87.  
  88.     /* Define "pick" object, initially the empty list (= null object).
  89.      * We replace this later upon receiving a pick event.
  90.      */
  91.     printf("(geometry \"pick\" { LIST } )\n");
  92.  
  93.     /* Make the "pick" object be non-pickable.
  94.      */
  95.     printf("(pickable \"pick\" no)\n");
  96.  
  97.     /* Turn off normalization, so that our pick object will appear in the
  98.      * right place.
  99.      */
  100.     printf("(normalization \"pick\" none)\n");
  101.  
  102.     /* Don't draw the pick object's bounding box.
  103.      */
  104.     printf("(bbox-draw \"pick\" off)\n");
  105.  
  106.   } endprogn();
  107. }
  108.  
  109. /* The following is a macro call that defines a procedure called
  110.  * Lpick().  The reason for doing this in a macro is that that macro
  111.  * encapsulates a lot of necessary stuff that would be the same for
  112.  * this procedure in any program.  If you write a geomview module that
  113.  * wants to know about user pick events you can just copy this macro
  114.  * call and change the body to suit your needs; the body is the last
  115.  * argument to the macro and is delimited by curly braces.
  116.  *
  117.  * The first argument to the macro is the name of the procedure to
  118.  * be defined, "Lpick".
  119.  *
  120.  * The next two arguments are numbers which specify the sizes that
  121.  * certain arrays inside the body of the procedure should have.
  122.  * These arrays are used for storing the face and path information
  123.  * of the picked object.  In this module we don't care about this
  124.  * information so we declare them to have length 1, the minimum
  125.  * allowed.
  126.  *
  127.  * The last argument is a block of code to be executed when the module
  128.  * receives a pick event.  In this body you can refer to certain local
  129.  * variables that hold information about the pick.  For details see
  130.  * Example 3 in the Extenal Modules chapter of the geomview manual.
  131.  */
  132. PICKFUNC(Lpick, 1, 1,
  133. {           
  134.   handle_pick(pn>0, &point, vn>0, &vertex, en>0, edge);
  135. })
  136.  
  137. handle_pick(picked, p, vert, v, edge, e)
  138.      int picked;                /* was something actually picked?     */
  139.      int vert;                  /* was the pick near a vertex?        */
  140.      int edge;                  /* was the pick near an edge?         */
  141.      HPoint3 *p;                /* coords of pick point               */
  142.      HPoint3 *v;                /* coords of picked vertex            */
  143.      HPoint3 e[2];              /* coords of endpoints of picked edge */
  144. {
  145.   Normalize(&e[0]);             /* Normalize makes 4th coord 1.0 */
  146.   Normalize(&e[1]);
  147.   Normalize(p);
  148.   progn(); {
  149.     if (!picked) {
  150.       printf("(geometry \"pick\" { LIST } )\n");
  151.     } else {
  152.       /*
  153.        * Put the box in place, and color it magenta if it's on a vertex,
  154.        * yellow if not.
  155.        */
  156.       printf("(xform-set pick { 1 0 0 0  0 1 0 0  0 0 1 0  %g %g %g 1 })\n",
  157.              p->x, p->y, p->z);
  158.       printf("(geometry \"pick\"\n");
  159.       if (vert) printf("{ appearance { material { diffuse 1 0 1 } }\n");
  160.       else printf("{ appearance { material { diffuse 1 1 0 } }\n");
  161.       printf("  { LIST { :littlebox }\n");
  162.       
  163.       /*
  164.        * If it's on an edge and not a vertex, mark the edge
  165.        * with cyan boxes at the endpoins and a yellow line
  166.        * along the edge.
  167.        */
  168.       if (edge && !vert) {
  169.         e[0].x -= p->x; e[0].y -= p->y; e[0].z -= p->z;
  170.         e[1].x -= p->x; e[1].y -= p->y; e[1].z -= p->z;
  171.         printf("{ appearance { material { diffuse 0 1 1 } }\n\
  172.   LIST\n\
  173.    { INST transform 1 0 0 0 0 1 0 0 0 0 1 0 %f %f %f 1 geom :littlebox }\n\
  174.    { INST transform 1 0 0 0 0 1 0 0 0 0 1 0 %f %f %f 1 geom :littlebox }\n\
  175.    { VECT\n\
  176.           1 2 1\n\
  177.           2\n\
  178.           1\n\
  179.           %f %f %f\n\
  180.           %f %f %f\n\
  181.           1 1 0 1\n\
  182.    }\n\
  183.   }\n",
  184.                e[0].x, e[0].y, e[0].z,
  185.                e[1].x, e[1].y, e[1].z,
  186.                e[0].x, e[0].y, e[0].z,
  187.                e[1].x, e[1].y, e[1].z);
  188.       }
  189.       printf("    }\n  }\n)\n");
  190.     }
  191.  
  192.   } endprogn();
  193.  
  194. }
  195.  
  196. Normalize(HPoint3 *p)
  197. {
  198.   if (p->w != 0) {
  199.     p->x /= p->w;
  200.     p->y /= p->w;
  201.     p->z /= p->w;
  202.     p->w = 1;
  203.   }
  204. }
  205.  
  206. main()
  207. {
  208.   Lake *lake;
  209.   LObject *lit, *val;
  210.   extern char *getenv();
  211.  
  212.   Initialize();
  213.  
  214.   lake = LakeDefine(stdin, stdout, NULL);
  215.   while (!feof(stdin)) {
  216.  
  217.     /* Parse next lisp expression from stdin.
  218.      */
  219.     lit = LSexpr(lake);
  220.  
  221.     /* Evaluate that expression; this is where Lpick() gets called.
  222.      */
  223.     val = LEval(lit);
  224.  
  225.     /* Free the two expressions from above.
  226.      */
  227.     LFree(lit);
  228.     LFree(val);
  229.   }
  230. }
  231.