DisplayMesh.cc
上传用户:kellyonhid
上传日期:2013-10-12
资源大小:932k
文件大小:32k
源码类别:

3D图形编程

开发平台:

Visual C++

  1. //############################################################
  2. // DisplayMesh.cc
  3. // Matt Ginzton / Brian Curless
  4. // Wed Jul  1 15:08:21 PDT 1998
  5. // 
  6. // Rendering code for mesh data
  7. //############################################################
  8. #include <vector.h>
  9. #include <algo.h>
  10. #include "RigidScan.h"
  11. #include "Mesh.h"
  12. #include "DisplayMesh.h"
  13. #include "plvMeshCmds.h"
  14. #include "plvScene.h"
  15. #include "plvDraw.h"
  16. #include "plvGlobals.h"
  17. #include "togl.h"
  18. #include "GlobalReg.h"
  19. #include "BailDetector.h"
  20. #include "VertexFilter.h"
  21. #include "Bbox.h"
  22. #include "MeshTransport.h"
  23. #include "plvViewerCmds.h"
  24. #include "OrganizingScan.h"
  25. // we use some rendering features (glPolygonOffset, vertex arrays) that
  26. // are only supported under OpenGL 1.1.  IRIX versions prior to 6.5 only
  27. // have OpenGL 1.0, but have EXT versions of the same functionality that
  28. // work almost as well.
  29. // g_glVersion >= 1.1 enables usage of OpenGL 1.1 features.
  30. // Core functionality: shared by both real meshes and organizing groups.
  31. // Lots of other stuff is "supported" by both (in the public interface)
  32. // but is stubbed out by one or the other and doesn't share implementation.
  33. DisplayableMesh::DisplayableMesh()
  34. {
  35.   meshData = NULL;
  36.   displayName = NULL;
  37. }
  38. DisplayableMesh::~DisplayableMesh()
  39. {
  40.   delete[] displayName;
  41. }
  42. bool
  43. DisplayableMesh::getVisible (void)
  44. {
  45.   return bVisible
  46.     && meshData->localBbox().valid();
  47. }
  48. void
  49. DisplayableMesh::setVisible (bool bVis)
  50. {
  51.   bVisible = bVis;
  52. }
  53. RigidScan*
  54. DisplayableMesh::getMeshData (void) const
  55. {
  56.   return meshData;
  57. }
  58. void
  59. DisplayableMesh::resetMeshData (RigidScan* _meshData)
  60. {
  61.   invalidateCachedData();
  62.   meshData = _meshData;
  63. }
  64. RigidScan*
  65. MeshData (DisplayableMesh* disp)
  66. {
  67.   return disp ? disp->getMeshData() : NULL;
  68. }
  69. const char*
  70. DisplayableMesh::getName (void) const
  71. {
  72.   return displayName;
  73. }
  74. void
  75. DisplayableMesh::setName (const char* name)
  76. {
  77.   displayName = new char [strlen (name) + 1];
  78.   strcpy (displayName, name);
  79. }
  80. const vec3uc&
  81. DisplayableMesh::getFalseColor (void) const
  82. {
  83.   return colorFalse;
  84. }
  85. void
  86. DisplayableMesh::setFalseColor (const vec3uc& color)
  87. {
  88.   colorFalse[0] = color[0];
  89.   colorFalse[1] = color[1];
  90.   colorFalse[2] = color[2];
  91. }
  92. //////////////////////////////////////////////////////////////////////
  93. // a real DisplayableMesh::
  94. //////////////////////////////////////////////////////////////////////
  95. DisplayableRealMesh::DisplayableRealMesh (RigidScan* _meshData, char* nameBase)
  96. {
  97.   meshData = _meshData;
  98.   setHome();
  99.   if (nameBase == NULL)
  100.     setName((char*)meshData->get_basename().c_str());
  101.   else
  102.     setName (nameBase);
  103.   theScene->meshColors.chooseNewColor(colorFalse);
  104.   myTexture = NULL;
  105.   bBlend = false;
  106.   alpha = 1.0;
  107.   bUseDisplayList = false;
  108.   iDisplayList = 0;
  109.   bVisible = true;
  110.   mBounds = NULL;
  111.   cache[0].mesh = cache[1].mesh = NULL;
  112.   invalidateCachedData();
  113. }
  114. DisplayableRealMesh::~DisplayableRealMesh (void)
  115. {
  116.   invalidateCachedData();
  117. }
  118. bool
  119. DisplayableRealMesh::useDisplayList (void) const
  120. {
  121.   return bUseDisplayList;
  122. }
  123. void
  124. DisplayableRealMesh::useDisplayList (bool bUseNow)
  125. {
  126.   if (bUseDisplayList && !bUseNow) {
  127.     invalidateDisplayList();
  128.   }
  129.   bUseDisplayList = bUseNow;
  130. }
  131. void
  132. DisplayableRealMesh::invalidateCachedData (void)
  133. {
  134.   for (int iCache = 0; iCache < 2; iCache++) {
  135.     delete cache[iCache].mesh;
  136.     cache[iCache].mesh = NULL;
  137.     cache[iCache].bPerVertex = 0;
  138.     cache[iCache].bStrips = 0;
  139.     cache[iCache].color = RigidScan::colorNone;
  140.     cache[iCache].cbColor = 0;
  141.   }
  142.   invalidateDisplayList();
  143. }
  144. void
  145. DisplayableRealMesh::invalidateDisplayList (void)
  146. {
  147.   if (iDisplayList != 0) {
  148.     cout << "Warning: nuking display list for "
  149.  << displayName << endl;
  150.     glDeleteLists(iDisplayList, 1);
  151.     iDisplayList = 0;
  152.   }
  153. }
  154. void 
  155. DisplayableRealMesh::setHome (void)
  156. {
  157.   homePos.setXform (meshData->getXform());
  158.   homePos.new_rotation_center (meshData->worldCenter());
  159. }
  160. void 
  161. DisplayableRealMesh::goHome (void)
  162. {
  163.   meshData->setXform (homePos.getXform());
  164.   meshData->new_rotation_center (homePos.worldCenter());
  165.   theScene->computeBBox();
  166. }
  167. void
  168. DisplayableRealMesh::setBlend (bool newBlend, float newAlpha)
  169. {
  170.   bBlend = newBlend;
  171.   alpha = newAlpha;
  172. }
  173. bool
  174. DisplayableRealMesh::transparent (void)
  175. {
  176.   return (theRenderParams->blend && bBlend)
  177.     || (theRenderParams->colorMode == registrationColor);
  178. }
  179. void
  180. DisplayableRealMesh::setTexture(Ref<TextureObj> newtexture)
  181. {
  182.   myTexture = newtexture;  // Ain't reference counting great!
  183. }
  184. void
  185. DisplayableRealMesh::drawSelf (bool bAllowList)
  186. {
  187.   if (!getVisible())
  188.     return;
  189.   
  190.   glMatrixMode (GL_MODELVIEW);
  191.   glPushMatrix();
  192.   meshData->gl_xform();
  193.   glMatrixMode (GL_TEXTURE);
  194.   glPushMatrix();
  195.   meshData->gl_xform();
  196.   
  197.   // get clipping filter, if we're using bbox acceleration
  198.   if (theRenderParams->accelerateWithBbox)
  199.     mBounds = new ScreenBox (NULL,
  200.      0, Togl_Width(toglCurrent) - 1,
  201.      0, Togl_Height(toglCurrent) - 1);
  202.   // but if the whole thing is onscreen, testing the fragment bboxes
  203.   // is a waste of time
  204.   if (mBounds && mBounds->acceptFully (meshData->localBbox())) {
  205.     //cout << displayName << ": whole scan onscreen; no clip test necessary" 
  206.     // << endl;
  207.     delete mBounds;
  208.     mBounds = NULL;
  209.   }
  210.   if (!mBounds || mBounds->accept (meshData->localBbox())) {
  211.     bManipulating = isManipulatingRender();
  212.     if (transparent()) {
  213.       glEnable (GL_BLEND);
  214.       glDepthMask (GL_FALSE);
  215.       glBlendFunc (GL_SRC_ALPHA, GL_DST_ALPHA);
  216.     }
  217.     
  218.     if (bAllowList)
  219.       drawList();
  220.     else
  221.       drawImmediate();
  222.     
  223.     if (theScene->wantMeshBBox (this))
  224.       drawBoundingBox();
  225.     
  226.     if (transparent()) {
  227.       glDisable(GL_BLEND);
  228.       glDepthMask (GL_TRUE);
  229.     }
  230.   } else {
  231.     cerr << displayName << ": skipping entire mesh" << endl;
  232.   }
  233.   glMatrixMode (GL_TEXTURE);
  234.   glPopMatrix();
  235.   glMatrixMode (GL_MODELVIEW);
  236.   glPopMatrix();
  237.   delete mBounds;
  238.   mBounds = NULL;
  239. }
  240. void
  241. DisplayableRealMesh::drawList (void)
  242. {
  243.   if (bUseDisplayList
  244.       && !(bManipulating && theRenderParams->bRenderManipsSkipDlist)) {
  245.     if (iDisplayList > 0) {
  246.       glCallList (iDisplayList);
  247.     } else {
  248.       cout << "Warning: building new display list for mesh "
  249.    << meshData->get_name() << endl;
  250.       iDisplayList = glGenLists (1);
  251.       glNewList(iDisplayList, GL_COMPILE);
  252.       drawImmediate();
  253.       glEndList();
  254.       glCallList (iDisplayList);
  255.     }
  256.   } else {
  257.     drawImmediate();
  258.   }
  259. }
  260. // hidden line rendering -- works by rendering black polygons shifted
  261. // just slightly back in z, to fill the z buffer with the necessary values
  262. // for depth testing, then rendering visible lines -- which only win the
  263. // depth test if they should be visible (in case of a tie, they should win 
  264. // due to the offset given the polygons).
  265. // This is carried out with glPolygonOffset, but it's a bit of a pain
  266. // because I can't get the OGL-1.1 specified call to work on SGI's --
  267. // whereas an older EXT flavor works fine.  On WIN32, at least with the
  268. // AccelGraphics card, glPolygonOffset with the same parameters works fine.
  269. // here, for nobody's benefit, but since it took me a while to figure this 
  270. // out, is a table of what works where:
  271. // glPolygonOffset: (supp'd) (works); glPolygonOffsetEXT: (supp'd) (works)
  272. // Lambert: (RE2, OGL1.0)  no,no                           yes,yes
  273. // Aegean: (O2, OGL1.0)    yes,no                          yes,yes
  274. // Radiance: (IR, OGL1.0)  yes,no                          yes,no
  275. // Maglio: (IR, OGL1.1)    yes,???                         yes,yes
  276. // Wavelet: (RE2, OGL1.1)  yes,yes                         yes,yes
  277. // Shape: (GLINT, OGL1.1)  yes,yes                         yes*,?
  278. //             * glGetString says it's there, but no way to link to it
  279. // This applies to the display, not the computational host -- so if you
  280. // run plyview on radiance using lambert's display, it works ok.
  281. // The problem appears to be that lambert, radiance, and aegean are using
  282. // pre-IRIX 6.5 OS's that implement OGL 1.0.  On IRIX 6.3 and 6.4,
  283. // glPolygonOffset is supported as a no-op; on IRIX 6.2 it fails and exits 
  284. // the program.  Hopefully once everyone is running IRIX 6.5 this can be
  285. // revisited.
  286. void
  287. DisplayableRealMesh::drawImmediate (void)
  288. {
  289.   if (theRenderParams->hiddenLine && !bManipulating) {
  290.     //valid for lines and points... don't use this for polys
  291.     GLenum realMode = theRenderParams->polyMode;
  292.     GLenum ofsMode;
  293.     if (g_glVersion >= 1.1) {
  294.       glEnable (ofsMode = GL_POLYGON_OFFSET_FILL);
  295.       glPolygonOffset (1.0, 1.0);
  296.     } else {
  297. #ifdef sgi
  298.       glEnable (ofsMode = GL_POLYGON_OFFSET_EXT);
  299.       glPolygonOffsetEXT (1.0, 1.0e-6);
  300. #endif
  301.     }
  302.     //first render polys to fill depth buffer
  303.     theRenderParams->polyMode = GL_FILL;
  304.     drawImmediateOnce();
  305.       
  306.     //then render the visible lines/points
  307.     theRenderParams->polyMode = realMode;
  308.     glDisable (ofsMode);
  309.   }
  310.   drawImmediateOnce();
  311. }
  312. void
  313. DisplayableRealMesh::drawImmediateOnce (void)
  314. {
  315.   if (meshData->num_resolutions() == 0)
  316.     return;         //nothing to do
  317.   int cbColor;
  318.   RigidScan::ColorSource color;
  319.   setMaterials (cbColor, color);
  320.   bool perVertex = theRenderParams->shadeModel != realPerFace;
  321.   bool strips = theRenderParams->useTstrips && perVertex;
  322.   getMeshTransport (perVertex, strips, color, cbColor);
  323.   renderMeshTransport();
  324.   if (!theRenderParams->shadows) {
  325.     // A bit of cleanup...
  326.     glDisable(GL_TEXTURE_2D);
  327.   }
  328. }
  329. void
  330. DisplayableRealMesh::getMeshTransport (bool perVertex, bool strips,
  331.    ColorSource color, int cbColor)
  332. {
  333.   bool bLores = bManipulating && theRenderParams->bRenderManipsLores;
  334.   DrawData& cache = bLores ? this->cache[1] : this->cache[0];
  335.   if (perVertex != cache.bPerVertex
  336.       || strips != cache.bStrips
  337.       || color != cache.color
  338.       || cbColor != cache.cbColor) {
  339.     delete cache.mesh;
  340.     cache.mesh = NULL;
  341.   }
  342.   if (!cache.mesh) {
  343.     int iOldRes = 0;
  344.     if (bLores) {
  345.       iOldRes = meshData->current_resolution().abs_resolution;
  346.       meshData->select_coarsest(); 
  347.     }
  348.     // RigidScan* meshData
  349.     cache.mesh = meshData->mesh (perVertex, strips, color, cbColor);
  350.     if (bLores)
  351.       meshData->select_by_count (iOldRes);
  352.     cache.bPerVertex = perVertex;
  353.     cache.bStrips = strips;
  354.     cache.color = color;
  355.     cache.cbColor = cbColor;
  356.     buildStripInds (cache);
  357.   }
  358. }
  359. void
  360. DisplayableRealMesh::renderMeshTransport (void)
  361. {
  362.   bool bLores = bManipulating && theRenderParams->bRenderManipsLores;
  363.   DrawData& cache = bLores ? this->cache[1] : this->cache[0];
  364.   if (!cache.mesh) {
  365.     if (!meshData->render_self (cache.color))
  366.       cerr << displayName << ": cannot render!" << endl;
  367.     return;
  368.   }
  369.   if (cache.bPerVertex) {
  370.     renderMeshArrays();
  371.   } else {
  372.     renderMeshSingle();
  373.   }
  374. }
  375. void
  376. DisplayableRealMesh::renderMeshArrays (void)
  377. {
  378.   BailDetector bail;
  379.   bool bPointsOnly = (theRenderParams->polyMode == GL_POINT);
  380.   bool bGeometryOnly = false;
  381.   bool bLores = bManipulating && theRenderParams->bRenderManipsLores;
  382.   DrawData& cache = bLores ? this->cache[1] : this->cache[0];
  383.   if (!bUseDisplayList || theRenderParams->bRenderManipsSkipDlist) {
  384.     // don't stick the points-only view in a dlist!
  385.     if (bManipulating) {
  386.       if (theRenderParams->bRenderManipsPoints) {
  387. // draw points-only view for speed
  388. bPointsOnly = true;
  389. if (theRenderParams->bRenderManipsTinyPoints) {
  390.   glPointSize (1.0);
  391. } else {
  392.   glPointSize (2.0);
  393. }
  394.       }
  395.       
  396.       if (theRenderParams->bRenderManipsUnlit) {
  397. glDisable (GL_LIGHTING);
  398. bGeometryOnly = true;
  399.       }
  400.     }
  401.   }
  402.   // hidden-line back pass doesn't need anything but geometry
  403.   if (theRenderParams->hiddenLine &&
  404.       (theRenderParams->polyMode == GL_FILL))
  405.     bGeometryOnly = true;
  406.   bool bWantNormals = theRenderParams->light && !bGeometryOnly;
  407.   bool bWantColor = (cache.mesh->color.size() == cache.mesh->vtx.size()
  408.      && !bGeometryOnly);
  409.   if (bWantColor)
  410.     glEnable (GL_COLOR_MATERIAL);
  411.   // set up client vertex-pointer state with relevant pointers
  412.   if (g_glVersion >= 1.1) {
  413.     // vertex arrays -- only supported under OpenGL 1.1 (Irix 6.5)
  414.     glEnableClientState (GL_VERTEX_ARRAY);
  415.     if (bWantNormals)
  416.       glEnableClientState (GL_NORMAL_ARRAY);
  417.     for (int imesh = 0; imesh < cache.mesh->vtx.size(); imesh++) {
  418.       if (cache.mesh->bbox[imesh].valid()) {
  419. Bbox bbox = cache.mesh->bbox[imesh].worldBox (cache.mesh->xf[imesh]);
  420. if (mBounds != NULL && !mBounds->accept (bbox)) {
  421.   //cerr << displayName << ": skipping fragment " << imesh << endl;
  422.   continue;
  423. }
  424.       }
  425.       glVertexPointer (3, GL_FLOAT, 0, cache.mesh->vtx[imesh]->begin());
  426.       glMatrixMode (GL_MODELVIEW);
  427.       glPushMatrix();
  428.       glMultMatrixf (cache.mesh->xf[imesh]);
  429.       // we should do this but it overflows the texture matrix stack...
  430.       // TODO: make our own internalPushMatrix function
  431.       //glMatrixMode (GL_TEXTURE);
  432.       //glPushMatrix();
  433.       //glMultMatrixf (cache.mesh->xf[imesh]);
  434.       
  435.       if (bWantNormals)
  436. glNormalPointer (MeshTransport::normal_type, 0,
  437.  cache.mesh->nrm[imesh]->begin());
  438.       // the second test below avoids using color arrays of size 1, even
  439.       // if there is only 1 vertex -- this tends to hang GL on maglio.
  440.       // The "color the whole fragment that color without using
  441.       // glColorPointer" case takes care of it anyway, without hanging.
  442.       bool bThisWantColor = bWantColor
  443. && (cache.mesh->color[imesh]->size() > 4)
  444. && (cache.mesh->color[imesh]->size()
  445.     == 4 * cache.mesh->vtx[imesh]->size());
  446.       if (bThisWantColor) {
  447. // only enable vertex-array color if array is expected size.
  448. glEnableClientState (GL_COLOR_ARRAY);
  449. glColorPointer (4, GL_UNSIGNED_BYTE, 0,
  450. cache.mesh->color[imesh]->begin());
  451.       } else {
  452. // don't have a full color array...
  453. glDisableClientState (GL_COLOR_ARRAY);
  454. // but we might have a per-fragment color for all these vertices.
  455. if (bWantColor && cache.mesh->color[imesh]->size() == 4) {
  456.   glColor4ubv (cache.mesh->color[imesh]->begin());
  457. }
  458.       }
  459.       
  460.       if (bPointsOnly) {
  461. glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
  462. #if 1
  463. // this is obviously slower than hell for small count.  But maglio
  464. // appears to have a bug such that the second form times out and
  465. // hangs for a huge vtx list, if lighting is enabled.  Turn off
  466. // lighting or glDisableClientState (GL_NORMAL_ARRAY) and it's ok.
  467. // And if we render the same data 1 at a time, no prob.
  468. // In fact, it works for count = 1M, but not 1.5M. ???
  469. // one more note on this: a dejanews search for "GL:Wait Rdata"
  470. // turns up exactly one pair of hits, in which someone else
  471. // complains of a similar situation on an Onyx2 IR irix 6.5.1, and
  472. // an sgi rep acknowledges it sounds like an sgi bug.
  473. // with any significant value for count, this shouldn't be any
  474. // slower anyway so I'll leave it enabled.
  475. // 1M vertices per pass works fine for non-colored renderings
  476. // but crashes for color sometimes, so
  477. // we'll use 400K.
  478. // While we're documenting the follies of the IR, when color is
  479. // enabled, maglio consistently hits the same GL:Wait Rdata timeout
  480. // for vertex arrays of size 1.
  481. int total = cache.mesh->vtx[imesh]->size();
  482. int count = 400000;
  483. if (bThisWantColor ) {
  484.   while ((total % count) == 1)  // to avoid yet another hang
  485.     --count;
  486. }
  487. glDrawArrays (GL_POINTS, 0, total % count);
  488. for (int i = total%count; i < total; i += count) {
  489.   glDrawArrays (GL_POINTS, i, count);
  490. }
  491. #else
  492. glDrawArrays (GL_POINTS, 0, cache.mesh->vtx[imesh]->size());
  493. #endif
  494.       } else if (cache.bStrips) {
  495. const int* lenEnd = cache.StripInds[imesh].end();
  496. const int* start = cache.mesh->tri_inds[imesh]->begin();
  497. for (const int* len = cache.StripInds[imesh].begin();
  498.      len < lenEnd; len++) {
  499.   glDrawElements (GL_TRIANGLE_STRIP, *len,
  500.   GL_UNSIGNED_INT, start);
  501.   start += *len + 1;
  502. }
  503.       } else {
  504. #if 1
  505. int total = cache.mesh->tri_inds[imesh]->size();
  506. int count = 600000; // must be divisible by 3
  507. glDrawElements (GL_TRIANGLES, total%count,
  508. GL_UNSIGNED_INT, cache.mesh->tri_inds[imesh]->begin());
  509. for (int i = total%count; i < total; i += count)
  510.   glDrawElements (GL_TRIANGLES, count,
  511.   GL_UNSIGNED_INT,
  512.   cache.mesh->tri_inds[imesh]->begin() + i);
  513. #else
  514. glDrawElements (GL_TRIANGLES, cache.mesh->tri_inds[imesh]->size(),
  515. GL_UNSIGNED_INT, cache.mesh->tri_inds[imesh]->begin());
  516. #endif
  517.       }
  518.       //glMatrixMode (GL_TEXTURE);
  519.       //glPopMatrix();
  520.       glMatrixMode (GL_MODELVIEW);
  521.       glPopMatrix();
  522.       if (bail())
  523. break;
  524.     }
  525.     glDisableClientState (GL_VERTEX_ARRAY);
  526.     glDisableClientState (GL_NORMAL_ARRAY);
  527.     glDisableClientState (GL_COLOR_ARRAY);
  528.   } else {
  529.     // OpenGL 1.0 -- no standard vertex arrays
  530.     // but can use gldrawarraysext, glvertexpointerext, etc. on older IRIX
  531.     // if anyone needs this, they need to rewrite it
  532.     cerr << "OpenGL 1.0 not currently supported.  "
  533.  << "Have fun doing anything but rendering." << endl;
  534.   }
  535.   glDisable (GL_COLOR_MATERIAL);
  536.   glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
  537. }
  538. void
  539. DisplayableRealMesh::renderMeshSingle (void)
  540. {
  541.   // kberg 10 July 2001 - actually draws while manipulating now
  542.   //DrawData& cache = bManipulating ? this->cache[1] : this->cache[0];
  543.   bool bLores = bManipulating && theRenderParams->bRenderManipsLores;
  544.   DrawData& cache = bLores ? this->cache[1] : this->cache[0];
  545.   bool bPointsOnly = (theRenderParams->polyMode == GL_POINT);
  546.   
  547.   if (!bUseDisplayList || theRenderParams->bRenderManipsSkipDlist) {
  548.     // don't stick the points-only view in a dlist!
  549.     if (bManipulating) {
  550.       if (theRenderParams->bRenderManipsPoints) {
  551. // draw points-only view for speed
  552. bPointsOnly = true;
  553. if (theRenderParams->bRenderManipsTinyPoints) {
  554.   glPointSize (1.0);
  555. } else {
  556.   glPointSize (2.0);
  557. }
  558.       }
  559.       
  560.       /* TODO: implement bGeometryOnly in renderMeshSingle*/
  561.       if (theRenderParams->bRenderManipsUnlit) {
  562. glDisable (GL_LIGHTING);
  563. //bGeometryOnly = true;
  564.       } 
  565.     }
  566.   }
  567.   int frags = cache.mesh->vtx.size();
  568.   const vector<Pnt3>* vtx = NULL;
  569.   const vector<int>* tri = NULL;
  570.   const vector<short>* nrm = NULL;
  571.   const vector<uchar>* color = NULL;
  572.   for (int ifrag = 0; ifrag < frags; ifrag++) {
  573.     vtx = cache.mesh->vtx[ifrag];
  574.     tri = cache.mesh->tri_inds[ifrag];
  575.     int nTris = tri->size() / 3;
  576. #ifndef SCZ_NORMAL_FORCEFLOAT
  577.     if (ifrag < cache.mesh->nrm.size())
  578.       nrm = cache.mesh->nrm[ifrag];
  579.     else
  580. #else
  581. cerr << "Flat normals not supported in hack-normals-back-to-floats mode" << endl;
  582. #endif
  583.       nrm = NULL;
  584.     if (nrm && nrm->size() != nTris * 3)
  585.       nrm = NULL;
  586.     if (ifrag < cache.mesh->color.size())
  587.       color = cache.mesh->color[ifrag];
  588.     else
  589.       color = NULL;
  590.     if (color && color->size() != nTris * 4)
  591.       color = NULL;
  592.     if (color)
  593.       glEnable (GL_COLOR_MATERIAL);
  594.     if (bPointsOnly) 
  595.       glBegin (GL_POINTS);
  596.     else 
  597.       glBegin(GL_TRIANGLES);
  598.     
  599.     for (int it = 0; it < nTris; it++) {
  600.       int it3 = 3*it;
  601.       if (color)
  602. glColor4ubv (&(*color)[4*it]);
  603.       if (nrm)
  604. glNormal3sv (&(*nrm)[it3]);
  605.       glVertex3fv (&((*vtx)[(*tri)[it3]])[0]);
  606.       glVertex3fv (&((*vtx)[(*tri)[it3+1]])[0]);
  607.       glVertex3fv (&((*vtx)[(*tri)[it3+2]])[0]);
  608.     }
  609.     glEnd();
  610.     glDisable (GL_COLOR_MATERIAL);
  611.   }
  612. }
  613. void
  614. DisplayableRealMesh::buildStripInds (DrawData& cache)
  615. {
  616.   cache.StripInds.clear();
  617.   if (cache.bStrips && cache.mesh) {
  618.     // store indices of ends of strips
  619.     for (int imesh = 0; imesh < cache.mesh->tri_inds.size(); imesh++) {
  620.       cache.StripInds.push_back (vector<int>());
  621.       vector<int>& si = cache.StripInds.back();
  622.       const int* last = cache.mesh->tri_inds[imesh]->begin() - 1;
  623.       const int* triEnd = cache.mesh->tri_inds[imesh]->end();
  624.       for (const int *i = cache.mesh->tri_inds[imesh]->begin();
  625.    i < triEnd; i++) {
  626. if (*i == -1) { // end of strip
  627.   si.push_back (i - last - 1);
  628.   last = i;
  629. }
  630.       }
  631.     }
  632.   }
  633. }
  634. #if 0
  635. #define OFFSETOF(Struct,Field) 
  636.       ((char*)((Struct).Field) - (char*)&(Struct))
  637. void
  638. DisplayableRealMesh::cache_smooth_confidence (const vector<Pnt3>& vtx,
  639.  const vector<Pnt3>& nrm,
  640.  const vector<int>& tri_inds,
  641.  const vector<uchar>& colors,
  642.  bool stripped)
  643. {
  644.   uchar conf;
  645.   uchar _alpha = alpha * 255;
  646.   const int* triEnd = tri_inds.end();
  647.   freeVtxArray();
  648.   buildStripInds (stripped, tri_inds);
  649.   // optimization for InfiniteReality: (man glVertexPointerEXT)
  650.   // need to store: GLubyte c[4]; GLshort n[3]; GLfloat v[3];
  651.   struct {
  652.     GLubyte c[4];
  653.     NORMAL  n[3];
  654.     GLfloat v[3];
  655.   } vertex;
  656.   cachedVertSize = sizeof (vertex);
  657.   cachedVertCount = vtx.size();
  658.   cache = new char [cachedVertSize * cachedVertCount];
  659.   cachedClrOfs = OFFSETOF (vertex, c);
  660.   cachedNrmOfs = OFFSETOF (vertex, n);
  661.   cachedVtxOfs = OFFSETOF (vertex, v);
  662.   for (int vert = 0; vert < cachedVertCount; vert++) {
  663.     char* basePtr = cache + (vert * cachedVertSize);
  664.     GLubyte* colorPtr = (GLubyte*)(basePtr + cachedClrOfs);
  665.     NORMAL* normPtr =   (NORMAL*) (basePtr + cachedNrmOfs);
  666.     GLfloat* vertPtr =  (GLfloat*)(basePtr + cachedVtxOfs);
  667.     conf = colors[vert] * theRenderParams->confScale;
  668.     conf = MIN(conf, 255) * 0.7;
  669.     colorPtr[0] = 178;
  670.     colorPtr[1] = conf;
  671.     colorPtr[2] = conf;
  672.     colorPtr[3] = _alpha;
  673.     normPtr[0] = nrm[vert][0] * NRM_SCALE;
  674.     normPtr[1] = nrm[vert][1] * NRM_SCALE;
  675.     normPtr[2] = nrm[vert][2] * NRM_SCALE;
  676.     memcpy (vertPtr, &vtx[vert][0], 3 * sizeof(vertPtr[0]));
  677.   }
  678.   cachedType = smooth_conf;
  679. }
  680. void
  681. DisplayableRealMesh::cache_smooth_color (const vector<Pnt3>& vtx,
  682.     const vector<Pnt3>& nrm,
  683.     const vector<int>& tri_inds,
  684.     const vector<uchar>& colors,
  685.     int colorsize,
  686.     bool stripped)
  687. {
  688.   uchar _alpha = 255 * alpha;
  689.   freeVtxArray();
  690.   buildStripInds (stripped, tri_inds);
  691.   // need to store: GLubyte c[4]; GLshort n[3]; GLfloat v[3];
  692.   struct {
  693.     GLubyte c[4];
  694.     NORMAL  n[3];
  695.     GLfloat v[3];
  696.   } vertex;
  697.   cachedVertSize = sizeof (vertex);
  698.   cachedVertCount = vtx.size();
  699.   cache = new char [cachedVertSize * cachedVertCount];
  700.   cachedClrOfs = OFFSETOF (vertex, c);
  701.   cachedNrmOfs = OFFSETOF (vertex, n);
  702.   cachedVtxOfs = OFFSETOF (vertex, v);
  703.   for (int vert = 0; vert < cachedVertCount; vert++) {
  704.     char* basePtr = cache + (vert * cachedVertSize);
  705.     GLubyte* colorPtr = (GLubyte*)(basePtr + cachedClrOfs);
  706.     NORMAL* normPtr =   (NORMAL*) (basePtr + cachedNrmOfs);
  707.     GLfloat* vertPtr =  (GLfloat*)(basePtr + cachedVtxOfs);
  708.     if (colorsize == 3) {
  709.       colorPtr[0] = colors[3*vert + 0];
  710.       colorPtr[1] = colors[3*vert + 1];
  711.       colorPtr[2] = colors[3*vert + 2];
  712.     } else {
  713.       colorPtr[0] = colorPtr[1] = colorPtr[2] = colors[vert];
  714.     }
  715.     colorPtr[3] = _alpha;
  716.     normPtr[0] = nrm[vert][0] * NRM_SCALE;
  717.     normPtr[1] = nrm[vert][1] * NRM_SCALE;
  718.     normPtr[2] = nrm[vert][2] * NRM_SCALE;
  719.     memcpy (vertPtr, &vtx[vert][0], 3 * sizeof (vertPtr[0]));
  720.   }
  721.   cachedType = smooth_color;
  722. }
  723. void
  724. DisplayableRealMesh::cache_smooth_solid (const vector<Pnt3>& vtx,
  725.     const vector<Pnt3>& nrm,
  726.     const vector<int>& tri_inds,
  727.     bool stripped)
  728. {
  729.   freeVtxArray();
  730.   buildStripInds (stripped, tri_inds);
  731.   // need to store: GLshort n[3]; GLfloat v[3];
  732.   struct {
  733.     NORMAL  n[3];
  734.     GLfloat v[3];
  735.   } vertex;
  736.   cachedVertSize = sizeof (vertex);
  737.   cachedVertCount = vtx.size();
  738.   cache = new char [cachedVertSize * cachedVertCount];
  739.   cachedNrmOfs = OFFSETOF (vertex, n);
  740.   cachedVtxOfs = OFFSETOF (vertex, v);
  741.   cachedClrOfs = -1;
  742.   for (int vert = 0; vert < cachedVertCount; vert++) {
  743.     char* basePtr = cache + (vert * cachedVertSize);
  744.     NORMAL* normPtr =   (NORMAL*) (basePtr + cachedNrmOfs);
  745.     GLfloat* vertPtr =  (GLfloat*)(basePtr + cachedVtxOfs);
  746.     normPtr[0] = nrm[vert][0] * NRM_SCALE;
  747.     normPtr[1] = nrm[vert][1] * NRM_SCALE;
  748.     normPtr[2] = nrm[vert][2] * NRM_SCALE;
  749.     memcpy (vertPtr, &vtx[vert][0], 3 * sizeof (vertPtr[0]));
  750.   }
  751.   cachedType = smooth_solid;
  752. }
  753. void
  754. DisplayableRealMesh::draw_flat_confidence (const vector<Pnt3>& vtx,
  755.        const vector<Pnt3>& nrm,
  756.        const vector<int>& tri_inds,
  757.        const vector<uchar>& colors)
  758. {
  759.   uchar conf;
  760.   uchar confColor[4];
  761.   confColor[0] = 178;
  762.   confColor[3] = alpha * 255;
  763.   glEnable (GL_COLOR_MATERIAL);
  764.   glBegin (GL_TRIANGLES);
  765.   const int* triEnd = tri_inds.end();
  766.   int iTri = 0;
  767.   for (const int* tri = &tri_inds[0];
  768.        tri < triEnd; tri += 3, iTri++) {
  769.     conf = theRenderParams->confScale*colors[*tri];
  770.     conf = MIN(conf, 255);
  771.     conf *= 0.7;
  772.     confColor[1] = conf;
  773.     confColor[2] = conf;
  774.     glColor4ubv(confColor);
  775.     
  776.     glNormal3fv(nrm[iTri]);
  777.     
  778.     glVertex3fv (vtx[tri[0]]);
  779.     glVertex3fv (vtx[tri[1]]);
  780.     glVertex3fv (vtx[tri[2]]);
  781.   }
  782.   glEnd();
  783.   glDisable (GL_COLOR_MATERIAL);
  784.   cachedType = flat_conf;
  785. }
  786. void
  787. DisplayableRealMesh::draw_flat_color (const vector<Pnt3>& vtx,
  788.   const vector<Pnt3>& nrm,
  789.   const vector<int>& tri_inds,
  790.   const vector<uchar>& colors,
  791.   int colorsize)
  792. {
  793.   glEnable (GL_COLOR_MATERIAL);
  794.   glBegin (GL_TRIANGLES);
  795.   const int* triEnd = tri_inds.end();
  796.   int iTri = 0;
  797.   for (const int* tri = &tri_inds[0];
  798.        tri < triEnd; tri += 3, iTri++) {
  799.     
  800.     if (colorsize == 3)
  801.       glColor3ubv(&colors[3*iTri]);
  802.     else
  803.       glColor3ub (colors[iTri], colors[iTri], colors[iTri]);
  804.     glNormal3fv(nrm[iTri]);
  805.     glVertex3fv(vtx[tri[0]]);
  806.     glVertex3fv(vtx[tri[1]]);
  807.     glVertex3fv(vtx[tri[2]]);
  808.   }
  809.   glEnd();
  810.   glDisable (GL_COLOR_MATERIAL);
  811.   cachedType = flat_color;
  812. }
  813. void
  814. DisplayableRealMesh::draw_flat_solid (const vector<Pnt3>& vtx,
  815.   const vector<Pnt3>& nrm,
  816.   const vector<int>& tri_inds)
  817. {
  818.   glBegin (GL_TRIANGLES);
  819.   const int* triEnd = tri_inds.end();
  820.   int iTri = 0;
  821.   for (const int* tri = &tri_inds[0];
  822.        tri < triEnd; tri += 3, iTri++) {
  823.     glNormal3fv(nrm[iTri]);
  824.     glVertex3fv(vtx[tri[0]]);
  825.     glVertex3fv(vtx[tri[1]]);
  826.     glVertex3fv(vtx[tri[2]]);
  827.   }
  828.   glEnd();
  829.   cachedType = flat_solid;
  830. }
  831. #endif
  832. void glMaterialubv (GLenum face, GLenum pname, const uchar* bp)
  833. {
  834.   // glMaterialubv doesn't exist, this wraps glMaterialfv
  835.   float fp[4] = { bp[0] / 255., bp[1] / 255., bp[2] / 255., bp[3] / 255. };
  836.   glMaterialfv (face, pname, fp);
  837. }
  838. void
  839. DisplayableRealMesh::setMaterials (int& colorSize,
  840.        RigidScan::ColorSource& colorSource)
  841. {
  842.   static float nocolor[4] =  { 0, 0, 0, 1 };
  843.   static float regThisColor[4] = { 0, 0, 1, .5 };
  844.   static float regYesColor[4] = { 0, 1, 0, .5 };
  845.   static float regNoColor[4] = { 1, 0, 0, .5 };
  846.   static float white[4] = { 1, 1, 1, 1 };
  847.   float diff[4];
  848.   bool bDontReset = false;
  849.   // Reset materials
  850.   glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, nocolor);
  851.   glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, nocolor);
  852.   glMaterialubv(GL_FRONT, GL_SPECULAR, theRenderParams->specular);
  853.   glMaterialfv(GL_BACK, GL_SPECULAR, nocolor);
  854.   glMaterialf (GL_FRONT, GL_SHININESS, 
  855.        theRenderParams->shininess);
  856.   if (!theRenderParams->shadows) {
  857.     glDisable(GL_TEXTURE_2D);
  858.     glDisable(GL_TEXTURE_GEN_S);
  859.     glDisable(GL_TEXTURE_GEN_T);
  860.     glDisable(GL_TEXTURE_GEN_R);
  861.   }
  862.   // not needed - two sided lighting takes care of back emmisive
  863.   //if (theRenderParams->backFaceEmissive)
  864.   //  glMaterialubv(GL_BACK, GL_EMISSION, theRenderParams->background);
  865.  
  866.   if (theRenderParams->twoSidedLighting) {
  867.     if (theRenderParams->backfaceMode == lit) {
  868.       glMaterialubv(GL_BACK, GL_AMBIENT_AND_DIFFUSE, theRenderParams->backDiffuse);
  869.       glMaterialubv(GL_BACK, GL_SPECULAR, theRenderParams->backSpecular);
  870.       glMaterialf(GL_BACK, GL_SHININESS, theRenderParams->backShininess);
  871.     }
  872.     else if (theRenderParams->backfaceMode == emissive)
  873.       glMaterialubv(GL_BACK, GL_EMISSION, theRenderParams->backDiffuse);
  874.   }
  875.   // default to solid color unless otherwise overridden
  876.   colorSize = 0;
  877.   colorSource = RigidScan::colorNone;
  878.   if (theRenderParams->hiddenLine
  879.       && theRenderParams->polyMode == GL_FILL)
  880.   {
  881.     // "fill the depth buffer" pass -- render black
  882.     // so reset the only materials that were not set to nocolor above
  883.     glMaterialfv(GL_FRONT, GL_SPECULAR, nocolor);
  884.     glMaterialf (GL_FRONT, GL_SHININESS, 0);
  885.     glColor4fv (nocolor);
  886.     // we need to go through the below switch statement to set the
  887.     // showColor and showConfidence vars, but we don't want to make
  888.     // any more glMaterial/glColor calls...
  889.     bDontReset = true;
  890.   }
  891.   GLenum matMode = theRenderParams->useEmissive ?
  892.     GL_EMISSION : GL_AMBIENT_AND_DIFFUSE;
  893.   if (!bDontReset)
  894.     glMaterialubv(GL_FRONT, matMode, theRenderParams->diffuse);
  895.   
  896.   switch (theRenderParams->colorMode) {
  897.   case falseColor:
  898.     if (!bDontReset) {
  899.       diff[0] = colorFalse[0]/255.0;
  900.       diff[1] = colorFalse[1]/255.0;
  901.       diff[2] = colorFalse[2]/255.0;
  902.       diff[3] = alpha;
  903.       
  904.       glMaterialfv (GL_FRONT, matMode, diff);
  905.       glColor4fv (diff);
  906.     }
  907.     break;
  908.     
  909.   case boundaryColor:
  910.   case confidenceColor:
  911.   case intensityColor:
  912.   case trueColor:
  913.     colorSize = 4;
  914.     switch (theRenderParams->colorMode) {
  915.     case confidenceColor:
  916.       colorSource = RigidScan::colorConf; break;
  917.     case intensityColor:
  918.       colorSource = RigidScan::colorIntensity; break;
  919.     case trueColor:
  920.       colorSource = RigidScan::colorTrue; break;
  921.     case boundaryColor:
  922.       colorSource = RigidScan::colorBoundary; break;
  923.     }
  924.     
  925.     if (!bDontReset) {
  926.       if (theRenderParams->useEmissive)
  927. glMaterialfv(GL_FRONT, GL_SPECULAR, nocolor);
  928.       glColorMaterial(GL_FRONT, matMode);
  929.     }
  930.     break;
  931.     
  932.   case registrationColor:
  933.     if (!bDontReset) {
  934.       if (this == theSelectedScan) {
  935. glMaterialfv (GL_FRONT, matMode, regThisColor);
  936.       } else {
  937. assert (theScene->globalReg);
  938. bool bTrans = atoi (Tcl_GetVar (g_tclInterp, "regColorTransitive",
  939. TCL_GLOBAL_ONLY));
  940. if (theScene->globalReg->pairRegistered
  941.     (this->getMeshData(), theSelectedScan->getMeshData(), bTrans)) {
  942.   glMaterialfv (GL_FRONT, matMode, regYesColor);
  943. } else {
  944.   glMaterialfv (GL_FRONT, matMode, regNoColor);
  945. }
  946.       }
  947.     }
  948.     break;
  949.     
  950.   case noColor:
  951.     glColor4ubv (theRenderParams->diffuse);
  952.     break;
  953.   case textureColor:
  954.     if (myTexture) {
  955.       myTexture->setupTexture();
  956.       glMaterialfv(GL_FRONT, matMode, white);
  957.       glColor4fv(white);
  958.       break;
  959.     }
  960.     // else fall through...
  961.     
  962.   case grayColor:
  963.   default:
  964.     // just set color in case it's not set from lighting
  965.     // material properties are already ok (they have to be, since this
  966.     // is the fallback case and may be invoked without warning if we
  967.     // fail to extract color info requested from the RigidScan)
  968.     if (!bDontReset) {
  969.       diff[0] = diff[1] = diff[2] = 0.7;
  970.       diff[3] = alpha;
  971.       glColor4fv (diff);
  972.     }
  973.     break;
  974.   }
  975.   // set polygon mode, so we can draw points/lines/polys with same
  976.   // series of calls to glBegin/glVertex/glEnd
  977.   if (theRenderParams->polyMode == GL_FILL) {
  978.     glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
  979.   }
  980.   else if (theRenderParams->polyMode == GL_POINT) {
  981.     glPolygonMode (GL_FRONT_AND_BACK, GL_POINT);
  982.     glPointSize(theRenderParams->pointSize);
  983.   }
  984.   else { // if (theRenderParams->polyMode == GL_LINE)
  985.     glLineWidth(theRenderParams->lineWidth);
  986.     glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
  987.   }
  988. }
  989. void
  990. DisplayableRealMesh::drawBoundingBox (void)
  991. {
  992.   // assumes mesh transformation is in place, and draws bounding box edges
  993.   // in local (mesh) coordinates
  994.   ::drawBoundingBox (meshData->localBbox());
  995. }
  996. void
  997. DisplayableRealMesh::setName (const char* baseName)
  998. {
  999.   char bName[1024];
  1000.   strcpy(bName, baseName);
  1001.   
  1002.   char* begin = strrchr (bName, '/');
  1003.   char tempName[500];
  1004.   
  1005.   if (begin == NULL)
  1006.     {
  1007.       begin=bName;
  1008.       strcpy(tempName, bName);
  1009.     }
  1010.   else
  1011.     {
  1012.       begin[0]='';
  1013.       // printf ("suffix:%sn",begin-3);
  1014.       // Check if this is really a sweep, if so name funkyness
  1015.       if (strcmp(begin-3,".sd")==0)
  1016. {
  1017.  
  1018.   char* begin2 = strrchr (bName, '/');
  1019.   if (begin2 == NULL)
  1020.     {
  1021.       begin2=bName;
  1022.     }
  1023.   else
  1024.     {
  1025.       begin2++;
  1026.     }
  1027.   // printf ("begin2:%sn",begin2);
  1028.   *(begin-3)='';
  1029.   strcpy(tempName,begin2);
  1030.   strcat(tempName,"__");
  1031.   strcat(tempName,begin+1);
  1032.    
  1033. }
  1034.       else
  1035. {
  1036.   //  printf("fail:%sn",begin+1);
  1037. begin++;
  1038. strcpy(tempName,begin  );
  1039. }
  1040.     }
  1041.  
  1042.  
  1043.   //printf ("tempname:%sn",tempName);
  1044.   int suffix = 0;
  1045.   while (FindMeshDisplayInfo (tempName) != NULL) {
  1046.     ++suffix;
  1047.     sprintf (tempName + strlen(tempName), "%d", suffix);
  1048.   }
  1049.   DisplayableMesh::setName (tempName);
  1050. }