Advertisement
Guest User

draw.cpp

a guest
Apr 8th, 2020
282
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 48.41 KB | None | 0 0
  1. #include <test_gr_draw.h>
  2. #include <test_manager.h>
  3. #include <test_service.h>
  4. #include <test.h>
  5. #include <mb_axis3d.h>
  6. #include <mb_class_traits.h>
  7. #include <mesh.h>
  8. #include <assembly.h>
  9. #include <instance.h>
  10. #include <attr_color.h>
  11. #include <attr_selected.h>
  12. #if defined(C3D_MacOS) // mac os X
  13.   #include <OpenGL/gl.h>
  14.   #include <OpenGL/glu.h>
  15. #else
  16.   #include <GL/gl.h>
  17.   #include <GL/glu.h>
  18. #endif // mac os X
  19. #include <time.h>
  20. #include <math_namespace.h>
  21. #include <last.h>
  22.  
  23. using namespace c3d;
  24.  
  25.  
  26. ///////////////////////////////////////////////////////////////////////////////////////////
  27. //
  28. // Инструмент рисования в конкретном окне
  29. //
  30. ///////////////////////////////////////////////////////////////////////////////////////////
  31.  
  32.  
  33. #define PIXEL_TO_INCH     96.0   // Число пикселей в дюйме (будет пересчитано).
  34.  
  35.  
  36. IGrDraw::IGrDraw( WorkWindow& _parent, const MbVector3D & lt )
  37.   : parent        ( _parent )
  38.   , backgr        ( 255 )
  39.   , xPixelPerMM   ( double( PIXEL_TO_INCH )/LOGIC_INCH )
  40.   , yPixelPerMM   ( double( PIXEL_TO_INCH )/LOGIC_INCH )
  41.   , lightLocal    ()
  42.   , lightSide     ()
  43.   , lightAmbient  ( (float)MB_AMBIENT )
  44.   , lightDiffuse  ( (float)MB_DIFFUSE )
  45.   , lightSpecular ( (float)MB_SPECULARITY )
  46.   , oglInitialized( false )
  47.   , oglModelReady ( false )
  48.   , renderMode    ( ovm_NormalRenderWithEdges )//( ovm_NormalRender )
  49. {
  50.   SetLight( lt );
  51. }
  52.  
  53.  
  54. //------------------------------------------------------------------------------
  55. // Инициализация для работы окна в полутоновом режиме
  56. // ---
  57. bool IGrDraw::InitializeGL()
  58. {
  59.   float red = (float)( GetRValue(backgr)/255.0 );
  60.   float gre = (float)( GetGValue(backgr)/255.0 );
  61.   float blu = (float)( GetBValue(backgr)/255.0 );
  62.   glClearColor (red, gre, blu, 0.0);
  63.  
  64.   // Enable depth testing and backface culling.
  65.   glEnable (GL_DEPTH_TEST);
  66. //  glEnable (GL_CULL_FACE);
  67.   glEnable( GL_FRONT_AND_BACK );
  68.   glEnable( GL_NORMALIZE ); // Влияет на хиты для селектирования при разных видеокартах
  69. //  glDisable( GL_NORMALIZE ); // Влияет на хиты для селектирования при разных видеокартах
  70.  
  71.   // Add a light to the scene.
  72.   GLfloat glfLightAmbient[]  = { lightAmbient, lightAmbient, lightAmbient, 1.0f };
  73.   GLfloat glfLightDiffuse[]  = { lightDiffuse, lightDiffuse, lightDiffuse, 1.0f };
  74.   GLfloat glfLightSpecular[] = { lightSpecular, lightSpecular, lightSpecular, 1.0f };
  75.   glLightfv (GL_LIGHT0, GL_AMBIENT,  glfLightAmbient);
  76.   glLightfv (GL_LIGHT0, GL_DIFFUSE,  glfLightDiffuse);
  77.   glLightfv (GL_LIGHT0, GL_SPECULAR, glfLightSpecular);
  78.  
  79.   GLfloat glfLightLocal[] = { (GLfloat)lightLocal.x, (GLfloat)lightLocal.y, (GLfloat)lightLocal.z, 1.0f };
  80.   GLfloat glfLightSide[]  = { (GLfloat)lightSide.x,  (GLfloat)lightSide.y,  (GLfloat)lightSide.z,  1.0f };
  81.   glLightModelfv( GL_LIGHT_MODEL_AMBIENT, glfLightAmbient );
  82.   glLightModelfv( GL_LIGHT_MODEL_LOCAL_VIEWER, glfLightLocal );
  83.   glLightModelfv( GL_LIGHT_MODEL_TWO_SIDE, glfLightSide );
  84.  
  85.   glDisable( GL_BLEND ); // Запрещаем смешивание цветов (Непрозрачность)
  86. //  glDisable(GL_DEPTH_TEST);
  87.   glEnable( GL_LIGHTING );
  88.   glEnable( GL_LIGHT0 );
  89.  
  90.   ::glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
  91.   ::glMatrixMode( GL_MODELVIEW ); // Делаем текущей видовую матрицу
  92. /*
  93.   {
  94.     // Альфа-копонент не используется до тех пор, пока не включено смешивание (глава 6).
  95.     // До этого момента его можно смело игнорировать.
  96.  
  97.     glClearColor(1.0, 1.0, 1.0, 0.0);
  98.  
  99.     GLfloat light_ambient[]        = {lightAmbient, lightAmbient, lightAmbient, 1.0}; // Cвет фонового освещения - ослепление.
  100.     GLfloat light_diffuse[]        = {lightDiffuse, lightDiffuse, lightDiffuse, 1.0}; // Cвет рассеянного освещения.
  101.     GLfloat light_specular[]       = {lightSpecular, lightSpecular, lightSpecular, 1.0}; // Cвет отраженного света - матовость.
  102.     GLfloat light_position[]       = {1.0, 1.0, 1.0, 0.0}; // Координаты источника света. Свет из бесконечности.
  103.     GLfloat light_spot_direction[] = {0.0, 0.0, -1.0};     // Направление распространения света.
  104.  
  105.     GLfloat light_model_ambient[]  = {(GLfloat)0.1, (GLfloat)0.1, (GLfloat)0.1, 1.0};
  106.  
  107.     glLightfv(GL_LIGHT0, GL_AMBIENT,        light_ambient);
  108.     glLightfv(GL_LIGHT0, GL_DIFFUSE,        light_diffuse);
  109.     glLightfv(GL_LIGHT0, GL_SPECULAR,       light_specular);
  110.     glLightfv(GL_LIGHT0, GL_POSITION,       light_position);
  111.     glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, light_spot_direction);
  112.  
  113.     glLightModelfv(GL_LIGHT_MODEL_AMBIENT, light_model_ambient); // Оставляем.
  114.  
  115.     glEnable(GL_LIGHTING);
  116.     glEnable(GL_LIGHT0);
  117.     glEnable(GL_DEPTH_TEST);
  118.   }
  119. */
  120.   return true;
  121. }
  122.  
  123.  
  124. //------------------------------------------------------------------------------
  125. // Установить сцену
  126. // ---
  127. void IGrDraw::SetSizeGL( int cx, int cy, double scale )
  128. {
  129.   ::glViewport( 0, 0, cx, cy );   // Задаем размеры окна вывода
  130.  
  131.   ::glMatrixMode( GL_PROJECTION );  // Делаем текущей проекционную матрицу
  132.   ::glLoadIdentity();               // Матрицу делаем единичной
  133.  
  134.   // Установить проекционную матрицу
  135.   double sideX = (double)cx / xPixelPerMM / scale;
  136.   double sideY = (double)cy / yPixelPerMM / scale;
  137.   double sideZ = std_max( sideX, sideY ) * DELTA_MAX;
  138.  
  139.   // Устанавливаем объем видимости для определения матрицы перспективы
  140. //  if ( vista.z>DELTA_MIN ) {
  141. //    double angleY = atan2(vista.y/factorY/scale,vista.z/factorY/scale)*360/M_PI;
  142. //    ::gluPerspective(angleY, sideX/sideY, 0.1*vista.z/factorY/scale, sideZ);
  143. //    ::glFrustum(-0.05*sideX, 0.05*sideX, -0.05*sideY, 0.05*sideY, 0.1*vista.z/factorY/scale, sideZ );
  144. //  }
  145. //  else
  146.     ::glOrtho( 0, sideX, -sideY, 0, -sideZ, sideZ );
  147. }
  148.  
  149.  
  150. //------------------------------------------------------------------------------
  151. // Очистить OpenGL
  152. // ---
  153. void IGrDraw::ClearGL() const
  154. {
  155.   ::glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
  156.   //SetGLModelViewMatrix();
  157.   {
  158.     ::glMatrixMode( GL_MODELVIEW ); // Делаем текущей видовую матрицу
  159.   }
  160. }
  161.  
  162.  
  163. //------------------------------------------------------------------------------
  164. // Загрузить OpenGL видовую матрицу преобразования
  165. // ---
  166. void IGrDraw::MatrixGL() const
  167. {
  168.   MbMatrix3D into0            = parent.GetOwnPlacement().GetMatrixInto();
  169.   const MbCartPoint3D & vista = parent.GetVista();
  170.   double scale                = parent.GetScale();
  171.  
  172.   if ( vista.z > DELTA_MIN ) {
  173.     double zPixelPerMM = ONE_HALF * ( xPixelPerMM + yPixelPerMM );
  174.     double x = -vista.x / xPixelPerMM / scale;
  175.     double y =  vista.y / yPixelPerMM / scale;
  176.     double z = -vista.z / zPixelPerMM / scale;
  177.     ::glLoadIdentity();                  // Матрицу делаем единичной
  178.     ::glTranslated( x, y, z );           // Сдвигаем матрицу
  179.     ::glMultMatrixd( (double *)&into0 ); // Умножаем на матрицу преобразования вида
  180.   }
  181.   else {
  182.     ::glLoadMatrixd( (double *)&into0 ); // Прираниваем видовую матрицу матрице into0
  183.   }
  184. }
  185.  
  186.  
  187. //------------------------------------------------------------------------------
  188. // Подготовить данные ГСК
  189. // ---
  190. static
  191. void FillWCS( MbMesh & mesh )
  192. {
  193.   mesh.Flush();
  194.  
  195.   SPtr<MbVisual> meshVisual( new MbVisual );
  196.   meshVisual->SetOpacity( 0.5 );
  197.   mesh.AddAttribute( meshVisual );
  198.  
  199.   double scale = TestVariables::viewManager->GetWindowScale();
  200.   double l = WCS_AXIS_LENGTH / scale;
  201.  
  202.   MbCartPoint3D p0( 0, 0, 0 ),
  203.                 px( l, 0, 0 ),
  204.                 py( 0, l, 0 ),
  205.                 pz( 0, 0, l ); // Точки в мировой СК
  206.  
  207.   mesh.ApexReserve( 1 );
  208.   mesh.PolygonsReserve( 3 );
  209.  
  210.   MbApex3D * apex = mesh.AddApex(); // добавить новый пустой объект
  211.   apex->Init( p0 );
  212.   {
  213.     MbCartPoint3D pnt;
  214.     SPtr<MbColor> polyColor;
  215.  
  216.     MbPolygon3D * poly = mesh.AddPolygon();
  217.     poly->Reserve( 2 );
  218.     poly->AddPoint( p0 );
  219.     poly->AddPoint( px );
  220.     polyColor = new MbColor( ::RGB2uint32( 1, 0, 0 ) );
  221.     poly->AddAttribute( polyColor );
  222.  
  223.     poly = mesh.AddPolygon();    
  224.     poly->Reserve( 2 );
  225.     poly->AddPoint( p0 );
  226.     poly->AddPoint( py );
  227.     polyColor = new MbColor( ::RGB2uint32( 0, 1, 0 ) );
  228.     poly->AddAttribute( polyColor );
  229.  
  230.     poly = mesh.AddPolygon();    
  231.     poly->Reserve( 2 );
  232.     poly->AddPoint( p0 );
  233.     poly->AddPoint( pz );
  234.     polyColor = new MbColor( ::RGB2uint32( 0, 0, 1 ) );
  235.     poly->AddAttribute( polyColor );
  236.   }
  237.  
  238.   mesh.SetMeshType( st_AssistedItem );
  239. }
  240.  
  241.  
  242. //------------------------------------------------------------------------------
  243. // Подготовить данные
  244. // ---
  245. void IGrDraw::PrepareGL( const MbModel & drawModel, COLORREF select ) const
  246. {
  247.   // Заполняем листы сеткой объектов
  248.   MbModel::ItemConstIterator drawIter( drawModel.CBegin() );
  249.   MbModel::ItemConstIterator drawEnd ( drawModel.CEnd() );
  250.  
  251.   if ( TestVariables::enableWCS ) // Отрисовка ГСК
  252.   {
  253.     MbMesh wcsMesh;
  254.     MbMatrix3D wcsMatr;
  255.     ::FillWCS( wcsMesh );
  256.     RenderItemGL( &wcsMesh, wcsMatr, select, false );
  257.   }
  258.  
  259.   for ( ; drawIter != drawEnd; ++drawIter )
  260.   {    
  261.     if ( const MbItem * obj = *drawIter )
  262.     {
  263.       MbMatrix3D matr;
  264.       RenderItemGL( obj, matr, select, obj->IsSelected() );
  265.     }
  266. #ifdef __USE_GL_LISTS
  267.     GLuint listName = (GLuint)(uint)(size_t)obj;
  268.     if ( glIsList( (GLuint)listName ) == GL_FALSE )
  269.       glCallList( listName );
  270. #endif // __USE_GL_LISTS
  271.   }
  272. }
  273.  
  274.  
  275. //------------------------------------------------------------------------------
  276. // Очистить OpenGL
  277. // ---
  278. void IGrDraw::FinishGL() const
  279. {
  280.   ::glFinish();
  281. }
  282.  
  283.  
  284. //------------------------------------------------------------------------------
  285. // Нарисовать сетку
  286. // ---
  287. static
  288. void RenderGridGL( const MbGrid * gr, const MbMatrix3D & from,
  289.                    COLORREF other, bool useOther, OGLViewMode renderMode,
  290.                    float ambient, float diffuse, float specularity,
  291.                    float shininess, float opacity, float emission )
  292. {
  293.   PRECONDITION( gr );
  294.  
  295.   bool visual_bit = false;
  296.   const MbColor * colorAttr = static_cast<const MbColor *>( gr->GetSimpleAttribute(at_Color) );
  297.   if ( colorAttr != NULL ) {
  298.     visual_bit = true;
  299.     ::glPushAttrib( GL_LIGHTING_BIT );
  300.  
  301.     uint32 color = colorAttr->Color();
  302.     if ( useOther )
  303.       color = other;
  304.  
  305.     GLfloat R = (GLfloat)( GetRValue( color ) / 255.0 );
  306.     GLfloat G = (GLfloat)( GetGValue( color ) / 255.0 );
  307.     GLfloat B = (GLfloat)( GetBValue( color ) / 255.0 );
  308.  
  309.     if (opacity < 1.0-DELTA_MIN) // Прозрачность
  310.       glEnable( GL_BLEND ); // Разрешаем смешивание цветов (прозрачность)
  311.     else
  312.       glDisable(GL_BLEND ); // Запрещаем смешивание цветов
  313.  
  314.     GLfloat colorAmbient[]  = { R * ambient,     G * ambient,     B * ambient,     opacity }; // Фоновый цвет материала - ослепление. (перемножаются)
  315.     GLfloat colorDiffuse[]  = { R * diffuse,     G * diffuse,     B * diffuse,     opacity }; // Рассеянный цвет материала - цвет. (перемножаются)
  316.     GLfloat colorSpecular[] = { R * specularity, G * specularity, B * specularity, opacity }; // Цвет отраженного света - матовость (перемножаются)
  317.     GLfloat colorEmission[] = { R * emission,    G * emission,    B * emission,    opacity }; // Излучаемый цвет материала - светимость.
  318.     GLfloat colorIndexes[]  = { ambient, diffuse, opacity }; // Индексы фонового, рассеянного и отражённого цветов.
  319.  
  320.     glMaterialfv( GL_FRONT, GL_AMBIENT,   colorAmbient  );
  321.     glMaterialfv( GL_FRONT, GL_DIFFUSE,   colorDiffuse  );
  322.     glMaterialfv( GL_FRONT, GL_SPECULAR,  colorSpecular );
  323.     glMaterialfv( GL_FRONT, GL_EMISSION,  colorEmission );
  324.     glMaterialf ( GL_FRONT, GL_SHININESS, shininess     );
  325.     glMaterialfv( GL_FRONT, GL_COLOR_INDEXES, colorIndexes );
  326.   }
  327.  
  328.   bool needColor = renderMode == ovm_PrimitiveRender  || // Цветные треугольники и квадраты (полосы разбираются)
  329.                    renderMode == ovm_StripePrimRender || // Цветные полосы треугольники и квадраты (+ одиночные примитивы)
  330.                    renderMode == ovm_StripesRender;      // Только полосы - без одиночных примитивов
  331.  
  332.   bool needPrims = renderMode == ovm_NormalRender     || // Нормальный - "Классический полутон"
  333.                    renderMode == ovm_NormalRenderWithEdges || // Нормальный - "Классический полутон" с ребрами
  334.                    renderMode == ovm_PrimitiveRender  || // Цветные треугольники и квадраты (полосы разбираются)
  335.                    renderMode == ovm_StripePrimRender;   // Цветные полосы треугольники и квадраты (+ одиночные примитивы)
  336.  
  337.   if ( needColor ) {
  338.     glDisable( GL_LIGHTING );
  339.     glDisable( GL_POLYGON_SMOOTH ); // Запрещаем смешивание цветов (Непрозрачность)
  340.  
  341.     // Козулин Ю.А. 2017-03-20 Для отладки триангуляции нужна большая стабильность раздачи цветов.
  342.     // ::srand( (uint)time( NULL ) );
  343.     ::srand( (uint)0 );
  344.   }
  345.  
  346.   MbCartPoint3D p0, p1, p2, p3, p4, p5, p6, p7, p9;
  347.   MbVector3D n0, n1, n2, n3, n4, n5, n6, n7;
  348.   size_t k, kCnt;
  349.   bool single = from.IsSingle();
  350.   bool invert = from.IsInvert();
  351.  
  352.   if ( needPrims ) {
  353.     // Треугольники
  354.     glBegin( GL_TRIANGLES );
  355.     for ( k = 0, kCnt = gr->TrianglesCount(); k < kCnt; k++ ) {
  356.       if ( needColor )
  357.         glColor3f( (float)rand()/RAND_MAX, (float)rand()/RAND_MAX, (float)rand()/RAND_MAX );
  358.  
  359.       if ( gr->GetTrianglePoints ( k, p0, p1, p2 ) &&
  360.            gr->GetTriangleNormals( k, n0, n1, n2 ) ) {
  361.         if ( !single ) {
  362.           p0.Transform( from );
  363.           p1.Transform( from );
  364.           p2.Transform( from );
  365.           n0.Transform( from );
  366.           n1.Transform( from );
  367.           n2.Transform( from );
  368.         }
  369.         if ( invert ) {
  370.           n5 = n1;
  371.           n1 = n2;
  372.           n2 = n5;
  373.           p5 = p1;
  374.           p1 = p2;
  375.           p2 = p5;
  376.         }
  377.         glNormal3f( (GLfloat)n0.x, (GLfloat)n0.y, (GLfloat)n0.z );
  378.         glVertex3f( (GLfloat)p0.x, (GLfloat)p0.y, (GLfloat)p0.z );
  379.         glNormal3f( (GLfloat)n1.x, (GLfloat)n1.y, (GLfloat)n1.z );
  380.         glVertex3f( (GLfloat)p1.x, (GLfloat)p1.y, (GLfloat)p1.z );
  381.         glNormal3f( (GLfloat)n2.x, (GLfloat)n2.y, (GLfloat)n2.z );
  382.         glVertex3f( (GLfloat)p2.x, (GLfloat)p2.y, (GLfloat)p2.z );
  383.       }
  384.     }
  385.     glEnd();
  386.  
  387.     // Четырёхугольники
  388.     glBegin( GL_QUADS );
  389.     for ( k = 0, kCnt = gr->QuadranglesCount(); k < kCnt; k++ ) {
  390.       if ( needColor )
  391.         glColor3f( (float)rand()/RAND_MAX, (float)rand()/RAND_MAX, (float)rand()/RAND_MAX );
  392.  
  393.       if ( gr->GetQuadranglePoints ( k, p0, p1, p2, p3 ) &&
  394.            gr->GetQuadrangleNormals( k, n0, n1, n2, n3 ) ) {
  395.         if ( !single ) {
  396.           p0.Transform( from );
  397.           p1.Transform( from );
  398.           p2.Transform( from );
  399.           p3.Transform( from );
  400.           n0.Transform( from );
  401.           n1.Transform( from );
  402.           n2.Transform( from );
  403.           n3.Transform( from );
  404.         }
  405.         if ( invert ) {
  406.           n5 = n1;
  407.           n1 = n3;
  408.           n3 = n5;
  409.           p5 = p1;
  410.           p1 = p3;
  411.           p3 = p5;
  412.         }
  413.         glNormal3f( (GLfloat)n0.x, (GLfloat)n0.y, (GLfloat)n0.z );
  414.         glVertex3f( (GLfloat)p0.x, (GLfloat)p0.y, (GLfloat)p0.z );
  415.         glNormal3f( (GLfloat)n1.x, (GLfloat)n1.y, (GLfloat)n1.z );
  416.         glVertex3f( (GLfloat)p1.x, (GLfloat)p1.y, (GLfloat)p1.z );
  417.         glNormal3f( (GLfloat)n2.x, (GLfloat)n2.y, (GLfloat)n2.z );
  418.         glVertex3f( (GLfloat)p2.x, (GLfloat)p2.y, (GLfloat)p2.z );
  419.         glNormal3f( (GLfloat)n3.x, (GLfloat)n3.y, (GLfloat)n3.z );
  420.         glVertex3f( (GLfloat)p3.x, (GLfloat)p3.y, (GLfloat)p3.z );
  421.       }
  422.     }
  423.     /*// Код ниже временный и будет удален, так как для элементов будем строить отрисовочный MbMesh из четырехугольных пластин для наружних стенок в методе CreateMesh() и др.
  424.     for ( k = 0, kCnt = gr->ElementsCount(); k < kCnt; k++ ) {
  425.       if ( needColor )
  426.         glColor3f( (float)rand()/RAND_MAX, (float)rand()/RAND_MAX, (float)rand()/RAND_MAX );
  427.  
  428.       if ( gr->GetElementPoints ( k, p0, p1, p2, p3, p4, p5, p6, p7 ) ) {
  429.         n6.Init( p0, p1 ); n7.Init( p0, p4 ); n0.SetVecM( n6, n7 ); n0.Normalize();
  430.         n6.Init( p1, p2 ); n7.Init( p1, p5 ); n1.SetVecM( n6, n7 ); n1.Normalize();
  431.         n6.Init( p2, p3 ); n7.Init( p2, p6 ); n2.SetVecM( n6, n7 ); n2.Normalize();
  432.         n6.Init( p3, p0 ); n7.Init( p3, p7 ); n3.SetVecM( n6, n7 ); n3.Normalize();
  433.         n6.Init( p0, p3 ); n7.Init( p0, p1 ); n4.SetVecM( n6, n7 ); n4.Normalize();
  434.         n6.Init( p4, p5 ); n7.Init( p4, p7 ); n5.SetVecM( n6, n7 ); n5.Normalize();
  435.  
  436.         if ( !single ) {
  437.           p0.Transform( from );
  438.           p1.Transform( from );
  439.           p2.Transform( from );
  440.           p3.Transform( from );
  441.           p4.Transform( from );
  442.           p5.Transform( from );
  443.           p6.Transform( from );
  444.           p7.Transform( from );
  445.           n0.Transform( from );
  446.           n1.Transform( from );
  447.           n2.Transform( from );
  448.           n3.Transform( from );
  449.           n4.Transform( from );
  450.           n5.Transform( from );
  451.         }
  452.         if ( invert ) {
  453.           p9 = p1;
  454.           p1 = p3;
  455.           p3 = p9;
  456.           p9 = p5;
  457.           p5 = p6;
  458.           p6 = p9;
  459.         }
  460.         glNormal3f( (GLfloat)n0.x, (GLfloat)n0.y, (GLfloat)n0.z );
  461.         glVertex3f( (GLfloat)p0.x, (GLfloat)p0.y, (GLfloat)p0.z );
  462.         glNormal3f( (GLfloat)n0.x, (GLfloat)n0.y, (GLfloat)n0.z );
  463.         glVertex3f( (GLfloat)p1.x, (GLfloat)p1.y, (GLfloat)p1.z );
  464.         glNormal3f( (GLfloat)n0.x, (GLfloat)n0.y, (GLfloat)n0.z );
  465.         glVertex3f( (GLfloat)p5.x, (GLfloat)p5.y, (GLfloat)p5.z );
  466.         glNormal3f( (GLfloat)n0.x, (GLfloat)n0.y, (GLfloat)n0.z );
  467.         glVertex3f( (GLfloat)p4.x, (GLfloat)p4.y, (GLfloat)p4.z );
  468.  
  469.         glNormal3f( (GLfloat)n1.x, (GLfloat)n1.y, (GLfloat)n1.z );
  470.         glVertex3f( (GLfloat)p1.x, (GLfloat)p1.y, (GLfloat)p1.z );
  471.         glNormal3f( (GLfloat)n1.x, (GLfloat)n1.y, (GLfloat)n1.z );
  472.         glVertex3f( (GLfloat)p2.x, (GLfloat)p2.y, (GLfloat)p2.z );
  473.         glNormal3f( (GLfloat)n1.x, (GLfloat)n1.y, (GLfloat)n1.z );
  474.         glVertex3f( (GLfloat)p6.x, (GLfloat)p6.y, (GLfloat)p6.z );
  475.         glNormal3f( (GLfloat)n1.x, (GLfloat)n1.y, (GLfloat)n1.z );
  476.         glVertex3f( (GLfloat)p5.x, (GLfloat)p5.y, (GLfloat)p5.z );
  477.  
  478.         glNormal3f( (GLfloat)n2.x, (GLfloat)n2.y, (GLfloat)n2.z );
  479.         glVertex3f( (GLfloat)p2.x, (GLfloat)p2.y, (GLfloat)p2.z );
  480.         glNormal3f( (GLfloat)n2.x, (GLfloat)n2.y, (GLfloat)n2.z );
  481.         glVertex3f( (GLfloat)p3.x, (GLfloat)p3.y, (GLfloat)p3.z );
  482.         glNormal3f( (GLfloat)n2.x, (GLfloat)n2.y, (GLfloat)n2.z );
  483.         glVertex3f( (GLfloat)p7.x, (GLfloat)p7.y, (GLfloat)p7.z );
  484.         glNormal3f( (GLfloat)n2.x, (GLfloat)n2.y, (GLfloat)n2.z );
  485.         glVertex3f( (GLfloat)p6.x, (GLfloat)p6.y, (GLfloat)p6.z );
  486.  
  487.         glNormal3f( (GLfloat)n3.x, (GLfloat)n3.y, (GLfloat)n3.z );
  488.         glVertex3f( (GLfloat)p3.x, (GLfloat)p3.y, (GLfloat)p3.z );
  489.         glNormal3f( (GLfloat)n3.x, (GLfloat)n3.y, (GLfloat)n3.z );
  490.         glVertex3f( (GLfloat)p0.x, (GLfloat)p0.y, (GLfloat)p0.z );
  491.         glNormal3f( (GLfloat)n3.x, (GLfloat)n3.y, (GLfloat)n3.z );
  492.         glVertex3f( (GLfloat)p4.x, (GLfloat)p4.y, (GLfloat)p4.z );
  493.         glNormal3f( (GLfloat)n3.x, (GLfloat)n3.y, (GLfloat)n3.z );
  494.         glVertex3f( (GLfloat)p7.x, (GLfloat)p7.y, (GLfloat)p7.z );
  495.  
  496.         glNormal3f( (GLfloat)n4.x, (GLfloat)n4.y, (GLfloat)n4.z );
  497.         glVertex3f( (GLfloat)p0.x, (GLfloat)p0.y, (GLfloat)p0.z );
  498.         glNormal3f( (GLfloat)n4.x, (GLfloat)n4.y, (GLfloat)n4.z );
  499.         glVertex3f( (GLfloat)p3.x, (GLfloat)p3.y, (GLfloat)p3.z );
  500.         glNormal3f( (GLfloat)n4.x, (GLfloat)n4.y, (GLfloat)n4.z );
  501.         glVertex3f( (GLfloat)p2.x, (GLfloat)p2.y, (GLfloat)p2.z );
  502.         glNormal3f( (GLfloat)n4.x, (GLfloat)n4.y, (GLfloat)n4.z );
  503.         glVertex3f( (GLfloat)p4.x, (GLfloat)p4.y, (GLfloat)p4.z );
  504.  
  505.         glNormal3f( (GLfloat)n5.x, (GLfloat)n5.y, (GLfloat)n5.z );
  506.         glVertex3f( (GLfloat)p4.x, (GLfloat)p4.y, (GLfloat)p4.z );
  507.         glNormal3f( (GLfloat)n5.x, (GLfloat)n5.y, (GLfloat)n5.z );
  508.         glVertex3f( (GLfloat)p5.x, (GLfloat)p5.y, (GLfloat)p5.z );
  509.         glNormal3f( (GLfloat)n5.x, (GLfloat)n5.y, (GLfloat)n5.z );
  510.         glVertex3f( (GLfloat)p6.x, (GLfloat)p6.y, (GLfloat)p6.z );
  511.         glNormal3f( (GLfloat)n5.x, (GLfloat)n5.y, (GLfloat)n5.z );
  512.         glVertex3f( (GLfloat)p7.x, (GLfloat)p7.y, (GLfloat)p7.z );
  513.       }
  514.     }
  515.     */// Конец временного кода, который будет удален.
  516.     glEnd();
  517.   }
  518.   if ( visual_bit == true )
  519.     glPopAttrib();
  520. }
  521.  
  522.  
  523. //------------------------------------------------------------------------------
  524. // Нарисовать каркасный объект.
  525. // ---
  526. static
  527. void RenderWireFrameGL( const MbMesh * mesh, bool ownColor, const MbMatrix3D & from, bool useMatrix,
  528.                         GLfloat R, GLfloat G, GLfloat B, bool edgesOnly )
  529. {
  530.   if ( (mesh != NULL) && (mesh->PolygonsCount() > 0) ) {
  531.     glPushAttrib( GL_ALL_ATTRIB_BITS );
  532.     glDisable( GL_LIGHTING );
  533.     glDisable( GL_BLEND ); // Запрещаем смешивание цветов
  534.  
  535.     GLfloat ownR = R;
  536.     GLfloat ownG = G;
  537.     GLfloat ownB = B;
  538.     glColor3f( ownR, ownG, ownB );
  539.  
  540.     size_t count = mesh->PolygonsCount();
  541.     MbCartPoint3D p;
  542.  
  543.     glLineWidth((GLfloat)mesh->GetWidth());
  544.  
  545.     for ( size_t k = 0; k < count; k++ ) {
  546.       const MbPolygon3D * polygon = mesh->GetPolygon(k);
  547.       if ( polygon == NULL )
  548.         continue;
  549.       if ( edgesOnly ) { // ребра
  550.         const MbTopItem * item = polygon->TopItem();
  551.         if ( (item == NULL) || (item->IsA() != tt_CurveEdge) )
  552.           continue;
  553.       }
  554.       if ( !polygon->IsVisible() && edgesOnly )
  555.         continue;
  556.  
  557.       if ( ownColor ) {
  558.         const MbColor * colorAttr= static_cast<const MbColor *>(polygon->GetSimpleAttribute(at_Color));
  559.         if ( colorAttr != NULL ) {
  560.           ownR = (GLfloat)( GetRValue( colorAttr->Color() ) / 255.0 );
  561.           ownG = (GLfloat)( GetGValue( colorAttr->Color() ) / 255.0 );
  562.           ownB = (GLfloat)( GetBValue( colorAttr->Color() ) / 255.0 );
  563.         }
  564.         glColor3f( ownR, ownG, ownB );
  565.       }
  566.      
  567.       int p_width = polygon->GetWidth();
  568.       p_width = std_max( p_width, 1 );
  569.       glLineWidth((GLfloat)p_width);
  570.      
  571.       glBegin( GL_LINE_STRIP );
  572.       size_t pointsCnt = polygon->Count();
  573.       for ( size_t n = 0; n < pointsCnt; n++ ) {
  574.         polygon->GetPoint( n, p );
  575.         if ( useMatrix )
  576.           p.Transform( from );
  577.         glVertex3f ((GLfloat)p.x, (GLfloat)p.y, (GLfloat)p.z);
  578.       }
  579.       glEnd();
  580.  
  581.       glLineWidth((GLfloat)mesh->GetWidth());
  582.  
  583.       ownR = R;
  584.       ownG = G;
  585.       ownB = B;
  586.     }
  587.  
  588.     glLineWidth(1);
  589.     glPopAttrib();
  590.   } // Кривая
  591. }
  592.  
  593.  
  594. //------------------------------------------------------------------------------
  595. // Нарисовать точечный объект.
  596. // ---
  597. static
  598. void RenderPointFrameGL( const MbMesh * mesh, bool ownColor, const MbMatrix3D & from, bool useMatrix,
  599.                          GLfloat R, GLfloat G, GLfloat B )
  600. {
  601.   if ( (mesh != NULL) && (mesh->ApexesCount() > 0) ) {
  602.     glPushAttrib( GL_ALL_ATTRIB_BITS );
  603.     glDisable( GL_LIGHTING );
  604.     glDisable( GL_BLEND ); // Запрещаем смешивание цветов
  605.  
  606.     GLfloat ownR = R;
  607.     GLfloat ownG = G;
  608.     GLfloat ownB = B;
  609.     glColor3f( ownR, ownG, ownB );
  610.     int width = mesh->GetWidth();
  611.     width = std_max( width, 1 );
  612.  
  613.     size_t count = mesh->ApexesCount();
  614.     MbCartPoint3D p;
  615.  
  616.     bool isWCS = ((mesh->GetMeshType() == st_AssistedItem) && (mesh->GetRefItem() == NULL)); // ГСК
  617.  
  618.     int pointSize = 1;
  619.     if ( !isWCS ) {
  620.       pointSize = mesh->GetWidth();
  621.       pointSize = std_max( pointSize, (int)5 );
  622.     }
  623.     glPointSize( (GLfloat)pointSize );
  624.     glEnable( GL_POINT_SMOOTH );
  625.  
  626.     for ( size_t k = 0; k < count; k++ ) {
  627.       const MbApex3D * apex = mesh->GetApex(k);
  628.       if ( apex == NULL )
  629.         continue;
  630.       if ( !apex->IsVisible() )
  631.         continue;
  632.  
  633.       int p_width = apex->GetWidth();
  634.       p_width = std_max( p_width, 1 );
  635.       if ( width != p_width )
  636.         glLineWidth((GLfloat)p_width);
  637.  
  638.       if ( ownColor ) {
  639.         const MbColor * colorAttr= static_cast<const MbColor *>(apex->GetSimpleAttribute(at_Color));
  640.         if ( colorAttr != NULL ) {
  641.           ownR = (GLfloat)( GetRValue( colorAttr->Color() ) / 255.0 );
  642.           ownG = (GLfloat)( GetGValue( colorAttr->Color() ) / 255.0 );
  643.           ownB = (GLfloat)( GetBValue( colorAttr->Color() ) / 255.0 );
  644.         }
  645.         glColor3f( ownR, ownG, ownB );
  646.       }
  647.       glBegin( GL_POINTS );
  648.       apex->GetPoint( p );
  649.       if ( useMatrix )
  650.         p.Transform( from );
  651.       glVertex3f ((GLfloat)p.x, (GLfloat)p.y, (GLfloat)p.z);
  652.       glEnd();
  653.     }
  654.  
  655.     glDisable( GL_POINT_SMOOTH );
  656.     glPointSize(1);
  657.     glPopAttrib();
  658.   } // Точка
  659. }
  660.  
  661.  
  662. //------------------------------------------------------------------------------
  663. // Нарисовать объект.
  664. // ---
  665. void IGrDraw::RenderMeshGL( const MbMesh * mesh, const MbMatrix3D & from, COLORREF select, bool useSelect ) const
  666. {
  667.   if ( mesh != NULL ) {
  668.     size_t k, count;
  669.     bool single = from.IsSingle();
  670.     //bool useSelect = mesh->IsSelected();
  671.  
  672. #ifdef __USE_GL_LISTS
  673.     GLuint listName = (GLuint)name;
  674. #endif // __USE_GL_LISTS
  675.  
  676.     const MbColor * colorAttr = static_cast<const MbColor *>(mesh->GetSimpleAttribute(at_Color));
  677.     COLORREF color = (colorAttr != NULL) ? colorAttr->Color() : mesh->GetColor(); // Цвет элемента
  678.     if ( useSelect )
  679.       color = select;
  680.  
  681.     GLfloat R = (GLfloat)( GetRValue( color ) / 255.0 );
  682.     GLfloat G = (GLfloat)( GetGValue( color ) / 255.0 );
  683.     GLfloat B = (GLfloat)( GetBValue( color ) / 255.0 );
  684.  
  685.     GLfloat RW = (GLfloat)1.;
  686.     GLfloat GW = (GLfloat)1.;
  687.     GLfloat BW = (GLfloat)1.;
  688.  
  689. #ifdef __USE_GL_LISTS
  690.     glNewList( listName, GL_COMPILE ); //_AND_EXECUTE );
  691. #endif // __USE_GL_LISTS
  692.  
  693.     switch ( renderMode )
  694.     {
  695.       case ovm_NormalRender     :      // Нормальный - "Классический полутон"
  696.       case ovm_NormalRenderWithEdges : // Нормальный - "Классический полутон" с ребрами
  697.       case ovm_PrimitiveRender  :      // Цветные треугольники и квадраты (полосы разбираются)
  698.       case ovm_StripePrimRender :      // Цветные полосы треугольники и квадраты (+ одиночные примитивы)
  699.       case ovm_StripesRender    :      // Только полосы - без одиночных примитивов
  700.       {
  701.         if ( (mesh->GridsCount() > 0) || // Есть триангуляция.
  702.              (mesh->GetMeshType() == st_Surface) || // Тело или поверхность
  703.              (mesh->GetMeshType() == st_Solid) ) {
  704.           float ambient     = lightAmbient;  // Общий фон
  705.           float diffuse     = lightDiffuse;  // Диффузия
  706.           float specularity = lightSpecular; // Зеркальность
  707.           float shininess   = MB_SHININESS;  // Блеск (0-128) Коэффициент зеркального отражения - сфокусированность зеркального блика.
  708.           float opacity     = MB_OPACITY;    // Непрозрачность
  709.           float emission    = MB_EMISSION;   // Излучение
  710.  
  711.           mesh->GetVisual( ambient, diffuse, specularity, shininess, opacity, emission );
  712.  
  713.           glEnable( GL_LIGHTING );
  714.           if ( opacity < (1.0 - DELTA_MIN) ) { // Прозрачность
  715.             glEnable ( GL_BLEND ); // Разрешаем смешивание цветов (прозрачность)
  716.             glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
  717.           }
  718.           else
  719.             glDisable( GL_BLEND ); // Запрещаем смешивание цветов
  720.  
  721.           if ( mesh->IsClosed() && (opacity > DELTA_MIN) ) // Тело
  722.             glEnable ( GL_CULL_FACE ); // Односторонняя закраска (изнанка цвета фона)
  723.           else
  724.             glDisable( GL_CULL_FACE ); // Двусторонняя закраска
  725.  
  726.           glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
  727. //          glPolygonMode( GL_BACK,  GL_LINE );
  728.           glDisable(GL_POLYGON_OFFSET_FILL);                
  729.  
  730.           GLfloat colorAmbient[]  = { R * ambient,     G * ambient,     B * ambient,     opacity };
  731.           GLfloat colorDiffuse[]  = { R * diffuse,     G * diffuse,     B * diffuse,     opacity };
  732.           GLfloat colorSpecular[] = { R * specularity, G * specularity, B * specularity, opacity };
  733.           GLfloat colorEmission[] = { R * emission,    G * emission,    B * emission,    opacity };
  734.           GLfloat colorIndexes[]  = { ambient, diffuse, opacity }; // Индексы фонового, рассеянного и отражённого цветов.
  735.  
  736.           if ( ((mesh->GetMeshType() == st_Solid) && !mesh->IsClosed()) || // Оболочка
  737.                 (mesh->GetMeshType() == st_Surface) || // Поверхность
  738.                 (opacity < DELTA_MIN) ) { // Полная прозрачность
  739.             glMaterialfv( GL_FRONT, GL_AMBIENT,   colorAmbient  );
  740.             glMaterialfv( GL_FRONT, GL_DIFFUSE,   colorDiffuse  );
  741.             glMaterialfv( GL_FRONT, GL_SPECULAR,  colorSpecular );
  742.             glMaterialfv( GL_FRONT, GL_EMISSION,  colorEmission );
  743.             glMaterialf ( GL_FRONT, GL_SHININESS, shininess     );
  744.             glMaterialfv( GL_FRONT, GL_COLOR_INDEXES, colorIndexes );
  745.             R = (GLfloat)( (R+1.0)/2.0f ); // Смесь с серым - цвет изнанки незамкнутого тела
  746.             G = (GLfloat)( (G+1.0)/2.0f ); // Смесь с серым - цвет изнанки незамкнутого тела
  747.             B = (GLfloat)( (B+1.0)/2.0f ); // Смесь с серым - цвет изнанки незамкнутого тела
  748.             float opacity0 = opacity; // Непрозрачность
  749.             if ( opacity0 < DELTA_MIN ) // Полная прозрачность
  750.               opacity0 = (float)DELTA_MOD;
  751.             GLfloat colorAmbient0[]  = { R * ambient,     G * ambient,     B * ambient,     opacity0 };
  752.             GLfloat colorDiffuse0[]  = { R * diffuse,     G * diffuse,     B * diffuse,     opacity0 };
  753.             GLfloat colorSpecular0[] = { R * specularity, G * specularity, B * specularity, opacity0 };
  754.             GLfloat colorEmission0[] = { R * emission,    G * emission,    B * emission,    opacity0 };
  755.             GLfloat colorIndexes0[]  = { ambient, diffuse, opacity0 }; // Индексы фонового, рассеянного и отражённого цветов.
  756.             glMaterialfv( GL_BACK, GL_AMBIENT,   colorAmbient0  );
  757.             glMaterialfv( GL_BACK, GL_DIFFUSE,   colorDiffuse0  );
  758.             glMaterialfv( GL_BACK, GL_SPECULAR,  colorSpecular0 );
  759.             glMaterialfv( GL_BACK, GL_EMISSION,  colorEmission0 );
  760.             glMaterialf ( GL_BACK, GL_SHININESS, shininess      );
  761.             glMaterialfv( GL_BACK, GL_COLOR_INDEXES, colorIndexes0 );
  762.           }
  763.           else {
  764.             glMaterialfv( GL_FRONT_AND_BACK, GL_AMBIENT,   colorAmbient  );
  765.             glMaterialfv( GL_FRONT_AND_BACK, GL_DIFFUSE,   colorDiffuse  );
  766.             glMaterialfv( GL_FRONT_AND_BACK, GL_SPECULAR,  colorSpecular );
  767.             glMaterialfv( GL_FRONT_AND_BACK, GL_EMISSION,  colorEmission );
  768.             glMaterialf ( GL_FRONT_AND_BACK, GL_SHININESS, shininess     );
  769.             glMaterialfv( GL_FRONT_AND_BACK, GL_COLOR_INDEXES, colorIndexes );
  770.           }
  771. /*
  772.           GLfloat ambientLight[]  = { ambient, ambient, ambient, 1.0 }; // Свет рассеяный.
  773.           GLfloat diffuseLight[]  = { diffuse, diffuse, diffuse, 1.0 }; // Свет диффузный.
  774.           GLfloat lightPosition[] = { 0.0, 0.0, 100.0, 1.0 }; // Свет диффузный.
  775.  
  776.           glLightfv( GL_LIGHT0, GL_AMBIENT, ambientLight );
  777.           glLightfv( GL_LIGHT0, GL_DIFFUSE, diffuseLight );
  778.           glEnable( GL_LIGHT0 ); // Разрешаем освещение.
  779.           glLightfv( GL_LIGHT0, GL_POSITION, lightPosition );
  780. */
  781. //          glMaterialf ( GL_FRONT_AND_BACK, GL_OPACITY, opacity );
  782.  
  783.           // Отрисовка граней
  784.  
  785.           glPushAttrib( GL_ALL_ATTRIB_BITS );
  786.  
  787.           if ( renderMode == ovm_NormalRenderWithEdges ) {
  788.             glEnable( GL_POLYGON_OFFSET_FILL );
  789.             glPolygonOffset( 0.5f, 1.0f );
  790.           }
  791.  
  792.           for ( size_t i = 0, iCount = mesh->GridsCount(); i < iCount; i++ ) {
  793.             const MbGrid * grid = mesh->GetGrid( i );
  794.             if ( grid != NULL ) {
  795.               if ( !grid->IsVisible() )
  796.                 continue;
  797.  
  798.               ::RenderGridGL( grid, from, select, useSelect, renderMode,
  799.                               ambient, diffuse, specularity,
  800.                               shininess, opacity, emission );
  801.             }
  802.           }
  803.  
  804.           if ( renderMode == ovm_NormalRenderWithEdges ) { // Отрисовка рёбер
  805.             glDisable( GL_POLYGON_OFFSET_FILL );
  806.             ::RenderWireFrameGL( mesh, !useSelect, from, !single, 0, 0, 0, true ); // Кривые
  807.           }
  808.  
  809.           glPopAttrib();
  810.         } // Тело или поверхность
  811.  
  812.         if ( (mesh->GetMeshType() == st_Undefined) ||
  813.              (mesh->GetMeshType() == st_Assembly) ||
  814.              (mesh->GetMeshType() == st_Curve3D) ||
  815.              (mesh->GetMeshType() == st_AssistedItem) ) { // Каркас, ЛСК, вспомогательные объекты
  816.           ::RenderWireFrameGL ( mesh, !useSelect, from, !single, R, G, B, false ); // Кривые
  817.         }
  818.         if ( (mesh->GetMeshType() == st_Undefined) ||
  819.              (mesh->GetMeshType() == st_Assembly) ||
  820.              (mesh->GetMeshType() == st_Point3D) ||
  821.              (mesh->GetMeshType() == st_AssistedItem) ) { // Точки, ЛСК, вспомогательные объекты
  822.           ::RenderPointFrameGL( mesh, !useSelect, from, !single, R, G, B ); // Точки
  823.         }
  824.       }
  825.       break;
  826.  
  827.       case ovm_IsoparamMesh      :    // Поверхности - изопараметрическими линиями
  828.       case ovm_TriangleMesh      :    // Поверхности - триангуляционными решетками (примитивами - квадраты+треугольники)
  829.       case ovm_IsoparTriMesh     :    // Поверхности - изопараметрическими линиями + триангуляция (примитивами)
  830.       case ovm_ParamTriangleMesh :    // Поверхность - триангуляция в параметрической области
  831.       {
  832.         if ( (mesh->GetMeshType() == st_Surface) || // Тело или поверхность
  833.              (mesh->GetMeshType() == st_Solid) ) {
  834.           // Нужны изопараметрические линии
  835.           bool needIsoparLines = renderMode == ovm_IsoparamMesh   || // Поверхности - изопараметрическими линиями
  836.                                  renderMode == ovm_IsoparTriMesh;    // Поверхности - изопараметрическими линиями + триангуляция (примитивами)
  837.  
  838.           // Нужна триангуляция
  839.           bool needTriangulation = renderMode == ovm_TriangleMesh   || // Поверхности - триангуляционными решетками (примитивами - квадраты+треугольники)
  840.                                    renderMode == ovm_IsoparTriMesh;    // Поверхности - изопараметрическими линиями + триангуляция (примитивами)
  841.  
  842.           // Нужна триангуляция в параметрической области
  843.           bool needParamTriangles = renderMode == ovm_ParamTriangleMesh;    // Поверхность - триангуляция в параметрической области
  844.  
  845.           glPolygonMode( GL_FRONT_AND_BACK, /*GL_LINE*/ GL_FILL );
  846.  
  847.           glDisable( GL_LIGHTING );
  848.           glDisable( GL_BLEND ); // Запрещаем смешивание цветов
  849.           glColor3f( R, G, B );
  850.  
  851.           if ( needIsoparLines ) {
  852.             ::RenderWireFrameGL( mesh, !useSelect, from, !single, R, G, B, false ); // Кривые
  853.           }
  854.  
  855.           if ( needTriangulation || needParamTriangles ) {
  856.             for ( int iTr = 0; iTr < 2; iTr++ ) {
  857.               if ( iTr ) {
  858.                 glEnable( GL_BLEND ); // Разрешаем смешивание цветов
  859.                 glPolygonMode( GL_FRONT_AND_BACK, GL_FILL);
  860.                 glColor3f( RW, GW, BW );
  861.                 glEnable(GL_POLYGON_OFFSET_FILL);
  862.                 glPolygonOffset( (GLfloat)1., (GLfloat)1. );
  863.               }
  864.               else {
  865.                 glDisable( GL_BLEND ); // Запрещаем смешивание цветов
  866.                 glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
  867.                 glColor3f( R, G, B );
  868.                 glDisable( GL_POLYGON_OFFSET_FILL );                
  869.               }
  870.  
  871.               MbFloatPoint3D p0, p1, p2, p3;
  872.               MbFloatVector3D n0, n1, n2, n3;
  873.  
  874.               if ( needTriangulation ) {
  875.                 for ( size_t i = 0, iCount = mesh->GridsCount(); i < iCount; i++ ) {
  876.                   const MbGrid * gr = mesh->GetGrid( i );
  877.                   if ( gr != NULL ) {
  878.                     count = gr->TrianglesCount();
  879.                     glBegin( GL_TRIANGLES );
  880.                     for ( k = 0; k < count; k++ ) {
  881.                       if ( gr->GetTrianglePoints( k, p0, p1, p2 ) ) {
  882.                         if ( !single ) {
  883.                           p0.Transform( from );
  884.                           p1.Transform( from );
  885.                           p2.Transform( from );
  886.                         }
  887.                         glVertex3f( (GLfloat)p0.x, (GLfloat)p0.y, (GLfloat)p0.z );
  888.                         glVertex3f( (GLfloat)p1.x, (GLfloat)p1.y, (GLfloat)p1.z );
  889.                         glVertex3f( (GLfloat)p2.x, (GLfloat)p2.y, (GLfloat)p2.z );
  890.                       }
  891.                     }
  892.                     glEnd();
  893.  
  894.                     count = gr->QuadranglesCount();
  895.                     glBegin( GL_QUADS );
  896.                     for ( k = 0; k < count; k++ ) {
  897.                       if ( gr->GetQuadranglePoints(k, p0, p1, p2, p3) ) {
  898.                         if ( !single ) {
  899.                           p0.Transform( from );
  900.                           p1.Transform( from );
  901.                           p2.Transform( from );
  902.                           p3.Transform( from );
  903.                         }
  904.                         glVertex3f( (GLfloat)p0.x, (GLfloat)p0.y, (GLfloat)p0.z );
  905.                         glVertex3f( (GLfloat)p1.x, (GLfloat)p1.y, (GLfloat)p1.z );
  906.                         glVertex3f( (GLfloat)p2.x, (GLfloat)p2.y, (GLfloat)p2.z );
  907.                         glVertex3f( (GLfloat)p3.x, (GLfloat)p3.y, (GLfloat)p3.z );
  908.                       }
  909.                     }
  910.                     glEnd();
  911.                   }
  912.                 }
  913.               }
  914.  
  915.               // !!! отображаем нормали
  916.               for ( size_t i = 0, iCnt = mesh->GridsCount(); i < iCnt; i++ ) {
  917.                 const MbGrid * gr = mesh->GetGrid( i );
  918.                 if ( gr != NULL ) {
  919.                   count = gr->PointsCount();
  920.                   glBegin( GL_LINES );
  921.                   for ( k = 0; k < count; k++ ) {
  922.                     gr->GetPoint ( k, p0 );
  923.                     gr->GetNormal( k, n1);
  924.                     n1.x += p0.x;
  925.                     n1.y += p0.y;
  926.                     n1.z += p0.z;
  927.                     if ( !single ) {
  928.                       p0.Transform( from );
  929.                       n1.Transform( from );
  930.                     }
  931.                     glVertex3f( (GLfloat)p0.x, (GLfloat)p0.y, (GLfloat)p0.z );
  932.                     glVertex3f( (GLfloat)n1.x, (GLfloat)n1.y, (GLfloat)n1.z );
  933.                   }
  934.                   glEnd();
  935.                 }
  936.               }
  937.             }
  938.           }
  939.         } // Тело или поверхность
  940.  
  941.         if ( (mesh->GetMeshType() == st_Undefined) ||
  942.              (mesh->GetMeshType() == st_Assembly) ||
  943.              (mesh->GetMeshType() == st_Curve3D) ||
  944.              (mesh->GetMeshType() == st_AssistedItem) ) { // Каркас, ЛСК, вспомогательные объекты
  945.           ::RenderWireFrameGL ( mesh, !useSelect, from, !single, R, G, B, false ); // Кривые
  946.         }
  947.         if ( (mesh->GetMeshType() == st_Undefined) ||
  948.              (mesh->GetMeshType() == st_Assembly) ||
  949.              (mesh->GetMeshType() == st_Point3D) ||
  950.              (mesh->GetMeshType() == st_AssistedItem) ) { // Точки, ЛСК, вспомогательные объекты
  951.           ::RenderPointFrameGL( mesh, !useSelect, from, !single, R, G, B ); // Точки
  952.         }
  953.       }
  954.       break;
  955.  
  956.       default: break;
  957.     }
  958. #ifdef __USE_GL_LISTS
  959.     glEndList();
  960. #endif // __USE_GL_LISTS
  961.   }
  962. }
  963.  
  964.  
  965. //----------------------------------------------------------------------------------------
  966. // Нарисовать объект.
  967. // ---
  968. void IGrDraw::RenderItemGL( const MbItem * obj, const MbMatrix3D & matr
  969.                           , COLORREF select, bool useSelect ) const
  970. {
  971.   if ( obj != NULL && obj->IsVisible() ) {
  972.     MbMatrix3D from( matr );
  973.     MbeSpaceType type = obj->IsA();
  974.     WorkViewSort viewSort = parent.GetViewSort();
  975.  
  976.     switch ( type ) {
  977.  
  978.       case st_Mesh : {
  979.         RenderMeshGL( static_cast<const MbMesh *>(obj), from, select, useSelect ); // Полигонный плоскогранный объект
  980.       } break;
  981.  
  982.       case st_Instance : {
  983.         const MbInstance * inst = static_cast<const MbInstance*>( obj );
  984.         if ( inst != NULL ) {
  985.           const MbMatrix3D _from( matr, inst->GetPlacement().GetMatrixFrom() );
  986.           RenderItemGL( inst->GetItem(), _from, select, useSelect || inst->IsSelected() );
  987.         }
  988.       } break;
  989.  
  990.       case st_Assembly : {
  991.         const MbAssembly * asse = static_cast<const MbAssembly*>( obj );
  992.         if ( asse != NULL ) {
  993.           if ( viewSort == wvs_All || viewSort == wvs_Geometry ) { // Drawing the geometric items.
  994.             for ( size_t i = 0, iCount = asse->ItemsCount(); i < iCount; i++ ) {
  995.               if ( const MbItem * asseItem = asse->GetItem( i ) ) {
  996.                 RenderItemGL( asseItem, matr, select, useSelect || asseItem->IsSelected() );
  997.               }
  998.             }
  999.           }
  1000.           if ( viewSort == wvs_All || viewSort == wvs_Constraints ) { // Drawing the geometric constraints.
  1001.             std::vector<const MbMesh *> meshes;
  1002.             asse->GetConstraintMesh( meshes ); // Get all polygonal objects for drawing the geometric constraints.
  1003.             for ( size_t i = 0, iCount = meshes.size(); i < iCount; i++ ) {
  1004.               RenderMeshGL( meshes[i], from, select, useSelect );
  1005.             }
  1006.           }
  1007.         }
  1008.       } break;
  1009.  
  1010.     }
  1011.  
  1012.   }
  1013. }
  1014.  
  1015.  
  1016. //------------------------------------------------------------------------------
  1017. // Перерисовать
  1018. // ---
  1019. void IGrDraw::ResetGL()
  1020. {}
  1021.  
  1022.  
  1023. //------------------------------------------------------------------------------
  1024. // Визуальные свойства
  1025. // ---
  1026. void IGrDraw::SetGLProperty( const MbModel & drawModel, double la, double ld, double ls, MbVector3D &ll )
  1027. {
  1028.   lightAmbient  = (float)la;
  1029.   lightDiffuse  = (float)ld;
  1030.   lightSpecular = (float)ls;
  1031.   lightLocal = ll;
  1032.   lightSide  = ll;
  1033.  
  1034.   {
  1035.     MbModel::ItemConstIterator drawIter( drawModel.CBegin() );
  1036.     MbModel::ItemConstIterator drawEnd ( drawModel.CEnd() );
  1037.     for ( ; drawIter != drawEnd; ++drawIter ) {
  1038.       const MbItem * obj = *drawIter;
  1039.     //for ( size_t i = 0, iCount = drawModel.ItemsCount(); i < iCount; i++ ) {
  1040.     //  const MbItem * obj = drawModel.GetModelItem( i ); // Выдать объект по индексу
  1041.       GLuint listName = (GLuint)(uint)(size_t)obj;
  1042.       if ( glIsList(listName) )
  1043.         glDeleteLists( listName, 1 );
  1044.     }
  1045.  
  1046.     GLfloat glfLightAmbient[]  = { lightAmbient, lightAmbient, lightAmbient, 1.0f };
  1047.     GLfloat glfLightDiffuse[]  = { lightDiffuse, lightDiffuse, lightDiffuse, 1.0f };
  1048.     GLfloat glfLightSpecular[] = { lightSpecular, lightSpecular, lightSpecular, 1.0f };
  1049.     glLightfv (GL_LIGHT0, GL_AMBIENT,  glfLightAmbient);
  1050.     glLightfv (GL_LIGHT0, GL_DIFFUSE,  glfLightDiffuse);
  1051.     glLightfv (GL_LIGHT0, GL_SPECULAR, glfLightSpecular);
  1052.  
  1053.     GLfloat glfLightLocal[] = { (GLfloat)lightLocal.x, (GLfloat)lightLocal.y, (GLfloat)lightLocal.z, 1.0f };
  1054.     GLfloat glfLightSide[]  = { (GLfloat)lightSide.x,  (GLfloat)lightSide.y,  (GLfloat)lightSide.z, 1.0f };
  1055.     glLightModelfv( GL_LIGHT_MODEL_AMBIENT, glfLightAmbient );
  1056.     glLightModelfv( GL_LIGHT_MODEL_LOCAL_VIEWER, glfLightLocal );
  1057.     glLightModelfv( GL_LIGHT_MODEL_TWO_SIDE, glfLightSide );
  1058.   }
  1059. }
  1060.  
  1061.  
  1062. //------------------------------------------------------------------------------
  1063. // Визуальные свойства
  1064. // ---
  1065. void IGrDraw::GetGLProperty( double &la, double &ld, double &ls, MbVector3D &ll ) {
  1066.   la = lightAmbient;
  1067.   ld = lightDiffuse;
  1068.   ls = lightSpecular;
  1069.   ll = lightSide;
  1070. }
  1071.  
  1072.  
  1073. //------------------------------------------------------------------------------
  1074. // Выдать мировую точку по экранной
  1075. // ---
  1076. /* Функция не работает, матрицы отсутствуют
  1077. MbCartPoint3D IGrDraw::GetGLCartPoint( POINT mouseCoord ) {
  1078.   GLdouble modelMatrix[16];
  1079.   GLdouble projMatrix[16];
  1080.   GLint viewPort[4];
  1081.   GLdouble wx = mouseCoord.x;
  1082.   GLdouble wy = mouseCoord.y;
  1083.   GLdouble wz = -parent.GetVista().z;
  1084.  
  1085.   glMatrixMode( GL_MODELVIEW );
  1086.   glGetDoublev( GL_MODELVIEW_MATRIX, modelMatrix ); // Модельная матрица
  1087.   glMatrixMode( GL_PROJECTION );
  1088.   glGetDoublev( GL_PROJECTION_MATRIX, projMatrix ); // Проекционная матрица
  1089.   glGetIntegerv( GL_VIEWPORT, viewPort ); // Экранная матрица
  1090.  
  1091.   MbCartPoint3D pnt;
  1092.   // Преобразование оконной точки в мировую
  1093.   gluUnProject( wx, wy, wz, modelMatrix, projMatrix, viewPort, &pnt.x, &pnt.y, &pnt.z );
  1094.   return pnt;
  1095. }
  1096. // */
  1097.  
  1098.  
  1099. //------------------------------------------------------------------------------
  1100. // Удалить данные
  1101. // ---
  1102. void IGrDraw::DeleteGL( const MbModel & drawModel )
  1103. {
  1104.   MbModel::ItemConstIterator drawIter( drawModel.CBegin() );
  1105.   MbModel::ItemConstIterator drawEnd ( drawModel.CEnd() );
  1106.   for ( ; drawIter != drawEnd; ++drawIter ) {
  1107.     const MbItem * obj = *drawIter;
  1108.   //for ( size_t i = 0, iCount = drawModel.ItemsCount(); i < iCount; i++ ) {
  1109.   //  const MbItem * obj = drawModel.GetModelItem( i ); // Выдать объект по индексу
  1110.     GLuint listName = (GLuint)(uint)LoUint32((size_t)obj);
  1111.     if ( glIsList(listName) )
  1112.       glDeleteLists( listName, 1 );
  1113.   }
  1114.   RefreshOGL();
  1115. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement