home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / exampleCode / inventor / noodle / profile.c++ < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-02  |  8.9 KB  |  341 lines

  1. /*
  2.  * Copyright (C) 1994, Silicon Graphics, Inc.
  3.  * All Rights Reserved.
  4.  *
  5.  * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  6.  * the contents of this file may not be disclosed to third parties, copied or
  7.  * duplicated in any form, in whole or in part, without the prior written
  8.  * permission of Silicon Graphics, Inc.
  9.  *
  10.  * RESTRICTED RIGHTS LEGEND:
  11.  * Use, duplication or disclosure by the Government is subject to restrictions
  12.  * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  13.  * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  14.  * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  15.  * rights reserved under the Copyright Laws of the United States.
  16.  */
  17. //
  18. // Some code for setting up and dealing with the profile window.
  19. //
  20.  
  21. #include <stdio.h>
  22. #include <getopt.h>
  23. #include <math.h>
  24. #include <malloc.h>
  25.  
  26. #include <Inventor/Xt/SoXt.h>
  27.  
  28. #include <Inventor/SoDB.h>
  29. #include <Inventor/nodes/SoSeparator.h>
  30. #include <Inventor/nodes/SoLightModel.h>
  31. #include <Inventor/nodes/SoPerspectiveCamera.h>
  32. #include <Inventor/nodes/SoCoordinate3.h>
  33. #include <Inventor/nodes/SoMaterial.h>
  34.  
  35. #include <Xm/Text.h>
  36.  
  37. #include "LineManip.h"
  38. #include "GeneralizedCylinder.h"
  39.  
  40. // This file defines: 
  41. // 
  42. // char *myGridBuffer
  43. // char *myGridXYBuffer
  44. //
  45. #include "MyGrids.h"
  46.  
  47. //
  48. // The line manipulator.
  49. //
  50. static LineManip2 *profileLineManip = NULL;
  51. static LineManip2 *crossSectionLineManip = NULL;
  52. static LineManip2 *spineLineManip = NULL;
  53. static LineManip2 *twistLineManip = NULL;
  54.  
  55. //
  56. // This is called when the mouse leaves a line manip window.  It turns
  57. // off that line manip's hilights.
  58. //
  59. static void
  60. leaveLineManipWindow(Widget, XtPointer mydata, XEvent *, Boolean *cont)
  61. {
  62.     ((LineManip2 *)mydata)->removeHilights();
  63.  
  64.     *cont = TRUE;    // Continue dispatching this event
  65. }
  66.  
  67.  
  68. SoSeparator * 
  69. createLineGraphCommon( SoPerspectiveCamera *&c, LineManip2 *&theManip, 
  70.                Widget theWidget, char *gridFileName, 
  71.                char *gridDfltBuf )
  72. {
  73.     SoSeparator *result = new SoSeparator;
  74.     result->ref();
  75.  
  76.     //!!!
  77.     // UGLY HACK! TEMPORARY BUG FIX!
  78.     // There is some kind of memory stomping bug going on here.
  79.     // If you call this twice, something weird happens with the old version.
  80.     // The old line manip, which should just disappear when the old scene
  81.     // gets unref'ed, apparently retains a reference to the old coordinate
  82.     // node. Anyhow, I'm not sure what's wrong, but referencing the
  83.     // whole scene graph an extra stops the core dump.
  84.     // But it should cause a pretty bad memory leak.
  85.     // It saves a whole scene graph it should get rid of, each time a new
  86.     // generalized cylinder is created or selected.
  87.     //XXX
  88.     //???
  89.     //!!!
  90.     result->ref();
  91.     //!!!
  92.     //???
  93.     //XXX
  94.  
  95.     c = new SoPerspectiveCamera;
  96.     result->addChild(c);
  97.  
  98.     c->nearDistance = 0.5;
  99.     c->farDistance = 10.0;
  100.     c->focalDistance = 5.0;    
  101.     c->heightAngle = 1.04;
  102.  
  103.     // Axes and labels (appear underneath the line manipulator)
  104.     SoInput in;
  105.     SoSeparator *g1;
  106.     if (gridFileName != NULL && in.openFile(gridFileName, TRUE) != FALSE)
  107.     g1 = SoDB::readAll(&in);
  108.     else
  109.     g1 = NULL;
  110.  
  111.     if (g1 == NULL && gridDfltBuf != NULL ) {
  112.     // If you couldn't find the file, use the default buffer...
  113.     g1 = new SoSeparator;
  114.     SoInput in;
  115.     in.setBuffer((void *) gridDfltBuf, (size_t)strlen(gridDfltBuf));
  116.     SoNode *n;
  117.     while ((SoDB::read(&in,n) != FALSE) && (n!=NULL))
  118.         g1->addChild(n);
  119.     }
  120.     if (g1 != NULL)
  121.     {
  122.     result->addChild(g1);
  123.     }
  124.  
  125.     SoSeparator *manipGroup = new SoSeparator;
  126.     result->addChild(manipGroup);
  127.  
  128.     SoLightModel *lm = new SoLightModel;
  129.     manipGroup->addChild(lm);
  130.     lm->model = SoLightModel::BASE_COLOR;
  131.  
  132.     SoMaterial *m = new SoMaterial;
  133.     m->diffuseColor.setValue(0.0, 0.8, 0.8);
  134.     manipGroup->addChild(m);
  135.  
  136.     // Remove event handler for old manip, if there was one.
  137.     if ( theManip != NULL )
  138.     XtRemoveEventHandler(theWidget, LeaveWindowMask,
  139.               FALSE, leaveLineManipWindow, (XtPointer)theManip);
  140.  
  141.     theManip = new LineManip2;
  142.     theManip->setHilightSize(0.1);
  143.     manipGroup->addChild(theManip);
  144.  
  145.     // Add event handler for new manip.
  146.     XtAddEventHandler(theWidget, LeaveWindowMask,
  147.               FALSE, leaveLineManipWindow, (XtPointer)theManip);
  148.  
  149.     result->unrefNoDelete();
  150.  
  151.     return result;
  152. }
  153.  
  154. //
  155. // This creates the profile's scene graph and sets up the callback so
  156. // the line manipulator turns off its hilights when the mouse leaves
  157. // the profile window.
  158. //
  159. SoNode *
  160. createProfileGraph(Widget profileWidget, GeneralizedCylinder *surface)
  161. {
  162.     SoPerspectiveCamera *c;
  163.  
  164.     SoSeparator *topNode = createLineGraphCommon( c, profileLineManip, 
  165.                      profileWidget, "Grid.iv", myGridBuffer );
  166.     c->position.setValue(0.5, 0.0, 5.0);
  167.  
  168.     // Get the coordinate node from the surface node...
  169.     SoCoordinate3 *c3 = NULL;
  170.     if (surface)
  171.     c3 = SO_GET_PART( surface, "profileCoords", SoCoordinate3 );
  172.     profileLineManip->setCoordinate3( c3 ); 
  173.  
  174.     return topNode;
  175. }
  176.  
  177. SoNode *
  178. createCrossSectionGraph(Widget crossSectionWidget, GeneralizedCylinder *surface)
  179. {
  180.     SoPerspectiveCamera *c;
  181.  
  182.     SoSeparator *topNode = createLineGraphCommon( c, crossSectionLineManip, 
  183.                  crossSectionWidget, "GridXY.iv", myGridXYBuffer );
  184.     c->position.setValue(0.0, 5.0, 0.0);
  185.     c->orientation.setValue(SbVec3f(1,0,0), -1.57079 );
  186.  
  187.     crossSectionLineManip->setPlaneNormal(SbVec3f( 0, 1, 0 ) );
  188.  
  189.     // Get the coordinate node from the surface node...
  190.     SoCoordinate3 *c3 = NULL;
  191.     if (surface)
  192.     c3 = SO_GET_PART( surface, "crossSectionCoords", SoCoordinate3 );
  193.     crossSectionLineManip->setCoordinate3( c3 ); 
  194.  
  195.     return topNode;
  196. }
  197. SoNode *
  198. createSpineGraph(Widget spineWidget, GeneralizedCylinder *surface)
  199. {
  200.     SoPerspectiveCamera *c;
  201.  
  202.     SoSeparator *topNode = createLineGraphCommon( c, spineLineManip, 
  203.                      spineWidget, "Grid.iv", myGridBuffer );
  204.     c->position.setValue(0.0, 0.0, 5.0);
  205.  
  206.     // Get the coordinate node from the surface node...
  207.     SoCoordinate3 *c3 = NULL;
  208.     if (surface)
  209.     c3 = SO_GET_PART( surface, "spineCoords", SoCoordinate3 );
  210.     spineLineManip->setCoordinate3( c3 ); 
  211.  
  212.     return topNode;
  213. }
  214. SoNode *
  215. createTwistGraph(Widget twistWidget, GeneralizedCylinder *surface)
  216. {
  217.     SoPerspectiveCamera *c;
  218.  
  219.     SoSeparator *topNode = createLineGraphCommon( c, twistLineManip, 
  220.                      twistWidget, "Grid.iv", myGridBuffer );
  221.     c->position.setValue(0.0, 0.0, 5.0);
  222.  
  223.     // Get the coordinate node from the surface node...
  224.     SoCoordinate3 *c3 = NULL;
  225.     if (surface)
  226.     c3 = SO_GET_PART( surface, "twistCoords", SoCoordinate3 );
  227.     twistLineManip->setCoordinate3( c3 ); 
  228.  
  229.     return topNode;
  230. }
  231.  
  232. //
  233. // Called to get rid of all the points added so far.
  234. //
  235. void
  236. clearProfilePoints()
  237. {
  238.     SoCoordinate3 *coord = profileLineManip->getCoordinate3();
  239.     coord->point.deleteValues(0);
  240. }
  241.  
  242. void
  243. clearCrossSectionPoints()
  244. {
  245.     SoCoordinate3 *coord = crossSectionLineManip->getCoordinate3();
  246.     coord->point.deleteValues(0);
  247. }
  248.  
  249. void
  250. clearSpinePoints()
  251. {
  252.     SoCoordinate3 *coord = spineLineManip->getCoordinate3();
  253.     coord->point.deleteValues(0);
  254. }
  255. void
  256. clearTwistPoints()
  257. {
  258.     SoCoordinate3 *coord = twistLineManip->getCoordinate3();
  259.     coord->point.deleteValues(0);
  260. }
  261. void
  262. makeReverseSection()
  263. {
  264.     SoCoordinate3 *coord = crossSectionLineManip->getCoordinate3();
  265.  
  266.     int numCoords = coord->point.getNum();
  267.  
  268.     SbVec3f temp;
  269.  
  270.     for (int first = 0, last = numCoords-1;
  271.      first < last;
  272.     first++, last-- ){
  273.  
  274.     temp = coord->point[first];
  275.     coord->point.set1Value(first, coord->point[last]);
  276.     coord->point.set1Value(last, temp);
  277.     }
  278. }
  279.  
  280. void
  281. makeCircularSection()
  282. {
  283.     SoCoordinate3 *coord = crossSectionLineManip->getCoordinate3();
  284.     coord->point.deleteValues(0);
  285.  
  286.     int numSegments = 35;
  287.     float maxAngle = 2 * 3.14159;
  288.  
  289.     coord->point.insertSpace(0,numSegments);
  290.  
  291.     SbVec3f newPoint(0,0,0);
  292.     float   theta;
  293.     for (int i = 0; i < numSegments; i++ ) {
  294.     theta = ((float)i/(float)(numSegments-1)) * maxAngle;
  295.     newPoint[0] = cos( theta );
  296.     newPoint[2] = sin( theta );
  297.     coord->point.set1Value(i,newPoint);
  298.     }
  299. }
  300.  
  301. void
  302. makeSemiCircularSpine()
  303. {
  304.     SoCoordinate3 *coord = spineLineManip->getCoordinate3();
  305.     coord->point.deleteValues(0);
  306.  
  307.     int numSegments = 50;
  308.     float maxAngle = 3.14159;
  309.  
  310.     coord->point.insertSpace(0,numSegments);
  311.  
  312.     SbVec3f newPoint(0,0,0);
  313.     float   theta;
  314.     for (int i = 0; i < numSegments; i++ ) {
  315.     theta = ((float)i / (float)(numSegments-1)) * maxAngle;
  316.     newPoint[0] = cos( theta );
  317.     newPoint[1] = sin( theta );
  318.     coord->point.set1Value(i,newPoint);
  319.     }
  320. }
  321. void
  322. makeCircularSpine()
  323. {
  324.     SoCoordinate3 *coord = spineLineManip->getCoordinate3();
  325.     coord->point.deleteValues(0);
  326.  
  327.     int numSegments = 50;
  328.     float maxAngle = 2 * 3.14159;
  329.  
  330.     coord->point.insertSpace(0,numSegments);
  331.  
  332.     SbVec3f newPoint(0,0,0);
  333.     float   theta;
  334.     for (int i = 0; i < numSegments; i++ ) {
  335.     theta = ((float)i/(float)(numSegments-1)) * maxAngle;
  336.     newPoint[0] = cos( theta );
  337.     newPoint[1] = sin( theta );
  338.     coord->point.set1Value(i,newPoint);
  339.     }
  340. }
  341.