opennurbs_gl.cpp
Go to the documentation of this file.
00001 /* $NoKeywords: $ */
00002 /*
00003 //
00004 // Copyright (c) 1993-2011 Robert McNeel & Associates. All rights reserved.
00005 // OpenNURBS, Rhinoceros, and Rhino3D are registered trademarks of Robert
00006 // McNeel & Assoicates.
00007 //
00008 // THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY.
00009 // ALL IMPLIED WARRANTIES OF FITNESS FOR ANY PARTICULAR PURPOSE AND OF
00010 // MERCHANTABILITY ARE HEREBY DISCLAIMED.
00011 //                              
00012 // For complete openNURBS copyright information see <http://www.opennurbs.org>.
00013 //
00015 */
00016 
00017 #include "pcl/surface/3rdparty/opennurbs/opennurbs.h"
00018 #include "pcl/surface/3rdparty/opennurbs/opennurbs_gl.h" // ON_GL() function declarations
00019 
00020 void ON_GL( const int order,     // ON_NurbsCurve order
00021               const int cv_count,  // ON_NurbsCurve cv count
00022               const double* knot,  // ON_NurbsCurve knot vector
00023               GLfloat* glknot,     // GL knot vector
00024               int bPermitScaling,  // true if knot scaling is allowed
00025               double* scale        // If not NULL and knot scaling is
00026                                    // allowed, then the scaling
00027                                    // parameters are returned here.
00028                                    // glknot = (knot - scale[0])*scale[1]
00029             )
00030 {
00031   // Because GL uses floats instead of doubles for knot vectors and
00032   // because some GLs are intolerant of closely spaced knots,
00033   // the returned glknots[] may be re-scaled when bPermitScaling
00034   // is true.  When the knots belong to a trimmed surface, any rescaling
00035   // done to the surface's knots must be applied to the trimming geometry.
00036 
00037   const int knot_count = order + cv_count - 2;
00038   const int nknots = knot_count+2;
00039   
00040   // GL knot vectors have old-fashioned extra knot at start and end
00041   const double k0 = ON_SuperfluousKnot( order, cv_count, knot,0);
00042   const double k1 = ON_SuperfluousKnot( order, cv_count, knot,1);
00043 
00044   if ( scale ) {
00045     scale[0] = 0.0;
00046     scale[1] = 1.0;
00047   }
00048   
00049   int i, j;
00050   if ( bPermitScaling ) {
00051     double d0 = knot[order-2];
00052     double dk = 1.0;
00053     if ( bPermitScaling ) {
00054       double dmin = 1.0;
00055       double dmax = 1.0;
00056       double d;
00057       for ( i = 1; i < knot_count; i++ ) {
00058         d = knot[i] - knot[i-1];
00059         if ( d <= 0.0 )
00060           continue; // multiple knot
00061         if ( d < dmin )
00062           dmin = d;
00063         else if ( d > dmax )
00064           dmax = d;
00065       }
00066       if ( dmin > 0.0 && dmax >= dmin ) {
00067         if ( dmin < 1.0e-2 )
00068           dk = 1.0e-2/dmin;
00069         else if ( dmax > 1.0e4 ) {
00070           if ( 1.0e4*dmin >= 1.0e-2*dmax )
00071             dk = 1.0e4/dmax;        
00072         }
00073       }
00074     }
00075     if ( scale ) {
00076       scale[0] = d0;
00077       scale[1] = dk;
00078     }
00079     glknot[0] = (GLfloat)((k0-d0)*dk);
00080     for( i = 1, j = 0; j < knot_count; i++, j++ )
00081       glknot[i] = (GLfloat)((knot[j]-d0)*dk);
00082     glknot[nknots-1] = (GLfloat)((k1-d0)*dk);
00083   }
00084   else {
00085     glknot[0] = (GLfloat)k0;
00086     for( i = 1, j = 0; j < knot_count; i++, j++ )
00087       glknot[i] = (GLfloat)knot[j];
00088     glknot[nknots-1] = (GLfloat)k1;
00089   }
00090 }
00091 
00092 static void GetGLCV( const int dim, const int is_rat, const double* cv,
00093                      double xform[4][4], 
00094                      GLfloat* glcv )
00095 {
00096   if ( xform ) {
00097     const double x = cv[0];
00098     const double y = cv[1];
00099     const double z = (dim == 3) ? cv[2] : 0.0;
00100     const double w = (is_rat) ? cv[dim] : 1.0;
00101     glcv[0] = (GLfloat)(xform[0][0]*x + xform[0][1]*y + xform[0][2]*z + xform[0][3]*w);
00102     glcv[1] = (GLfloat)(xform[1][0]*x + xform[1][1]*y + xform[1][2]*z + xform[1][3]*w);
00103     if ( dim == 3 )
00104       glcv[2] = (GLfloat)(xform[2][0]*x + xform[2][1]*y + xform[2][2]*z + xform[2][3]*w);
00105     if ( is_rat )
00106       glcv[dim] = (GLfloat)(xform[3][0]*x + xform[3][1]*y + xform[3][2]*z + xform[3][3]*w);
00107   }
00108   else {
00109     glcv[0] = (GLfloat)cv[0];
00110     glcv[1] = (GLfloat)cv[1];
00111     if ( dim == 3)
00112       glcv[2] = (GLfloat)cv[2];
00113     if ( is_rat )
00114       glcv[dim] = (GLfloat)cv[dim];
00115   }
00116 }
00117 
00118 void ON_GL( const ON_NurbsCurve& nurbs_curve,
00119               GLUnurbsObj* nobj, // created with gluNewNurbsRenderer )
00120               GLenum type, // = 0 (and type is automatically set)
00121               int bPermitKnotScaling,
00122               double* knot_scale,
00123               double xform[][4]
00124             )
00125 {
00126   ON_GL( nurbs_curve.Dimension(), 
00127          nurbs_curve.IsRational(),
00128          nurbs_curve.Order(),
00129          nurbs_curve.CVCount(),
00130          nurbs_curve.Knot(),
00131          nurbs_curve.m_cv_stride,
00132          nurbs_curve.m_cv,
00133          nobj,
00134          type,
00135          bPermitKnotScaling,
00136          knot_scale,
00137          xform
00138          );
00139 }
00140 
00141 void ON_GL( const ON_Curve& curve,
00142               GLUnurbsObj* nobj, // created with gluNewNurbsRenderer )
00143               GLenum type, // = 0 (and type is automatically set)
00144               double xform[][4]
00145             )
00146 {
00147   const ON_PolyCurve* poly_curve = ON_PolyCurve::Cast(&curve);
00148   if ( poly_curve ) 
00149   {
00150     ON_Curve* pSegmentCurve = 0;
00151     int segment_count = poly_curve->Count();
00152     int i;
00153     for ( i = 0; i < segment_count; i++ ) {
00154       pSegmentCurve = poly_curve->SegmentCurve(i);
00155       if ( pSegmentCurve )
00156         ON_GL( *pSegmentCurve, nobj, type, xform );
00157     }
00158     return;
00159   }
00160 
00161   const ON_CurveProxy* curve_proxy = ON_CurveProxy::Cast(&curve);
00162   if ( curve_proxy && !curve_proxy->ProxyCurveIsReversed() ) 
00163   {
00164     const ON_Curve* real_curve = curve_proxy->ProxyCurve();
00165     if ( 0 == real_curve )
00166       return;
00167     if ( curve_proxy == real_curve )
00168       return;
00169     if ( curve_proxy->ProxyCurveDomain() == real_curve->Domain() )
00170     {
00171       ON_GL( *real_curve, nobj, type, xform );
00172       return;
00173     }
00174   }
00175 
00176   {
00177     ON_NurbsCurve tmp;
00178     const ON_NurbsCurve* nurbs_curve = ON_NurbsCurve::Cast(&curve);
00179     if ( !nurbs_curve ) 
00180     {
00181       if ( curve.GetNurbForm(tmp) )
00182         nurbs_curve = &tmp;
00183     }
00184     ON_GL( *nurbs_curve, nobj, type, true, NULL, xform );
00185   }
00186 }
00187 
00188 void ON_GL( int dim, int is_rat, int nurb_order, int cv_count,
00189             const double* knot_vector, 
00190             int cv_stride, const double* cv,
00191             GLUnurbsObj* nobj,
00192             GLenum type,
00193             int bPermitKnotScaling,
00194             double* knot_scale,
00195             double xform[][4]
00196             )
00197 {
00198   ON_BOOL32 bCallgluBeginEndCurve = false;
00199   int i;
00200 
00201   GLint nknots = nurb_order + cv_count; // GL knot count = TL knot count + 2
00202   GLfloat* knot = (GLfloat*)onmalloc( nknots*sizeof(*knot) );
00203   ON_GL( nurb_order, cv_count, knot_vector, knot, bPermitKnotScaling, knot_scale );
00204 
00205   // control vertices
00206   //const int cv_size = (is_rat) ? dim+1: dim;
00207   GLint stride = cv_stride;
00208   GLfloat* ctlarray = (GLfloat*)onmalloc( stride*cv_count*sizeof(*ctlarray) );
00209   for ( i = 0; i < cv_count; i++ ) {
00210     GetGLCV( dim, is_rat, cv + i*cv_stride, xform, ctlarray + stride*i );
00211   }
00212 
00213   GLint order = nurb_order;
00214   switch(type)
00215   {
00216   case 0:
00217     {
00218       switch ( dim ) {
00219       case 2: // must be a GLU_MAP1_TRIM_2/3
00220         type = ( is_rat ) 
00221              ? GLU_MAP1_TRIM_3   // rational 2d trim uses homogeneous coords
00222              : GLU_MAP1_TRIM_2;  // non-rational 2d trim uses euclidean coords
00223         break;
00224       case 3: // must be a GLU_MAP1_VERTEX_3/4
00225         type = ( is_rat ) 
00226              ? GL_MAP1_VERTEX_4  // rational 3d curve uses homogeneous coords
00227              : GL_MAP1_VERTEX_3; // non-rational 3d curve used euclidean coords
00228         bCallgluBeginEndCurve = true;
00229         break;
00230       }
00231     }
00232     break;
00233 
00234   case GLU_MAP1_TRIM_2:
00235   case GLU_MAP1_TRIM_3:
00236     // make sure type matches rational flag
00237     type = ( is_rat ) 
00238          ? GLU_MAP1_TRIM_3   // rational 2d trim uses homogeneous coords
00239          : GLU_MAP1_TRIM_2;  // non-rational 2d trim uses euclidean coords
00240     break;
00241 
00242   case GL_MAP1_VERTEX_3:
00243   case GL_MAP1_VERTEX_4:
00244     // make sure type matches rational flag
00245     type = ( is_rat ) 
00246          ? GL_MAP1_VERTEX_4  // rational 3d curve uses homogeneous coords
00247          : GL_MAP1_VERTEX_3; // non-rational 3d curve used euclidean coords
00248     bCallgluBeginEndCurve = true;
00249     break;
00250   }
00251 
00252   if ( bCallgluBeginEndCurve )
00253     gluBeginCurve(nobj);
00254     gluNurbsCurve(
00255     nobj,
00256     nknots,
00257     knot,
00258     stride,     
00259     ctlarray,   
00260     order,      
00261     type        
00262   );    
00263   if ( bCallgluBeginEndCurve )
00264     gluEndCurve(nobj);
00265 
00266   onfree( ctlarray );
00267   onfree( knot );
00268 }
00269 
00270 
00271 
00272 // See comments in opennurbs_gl.h for calling instructions.
00273 
00274 void ON_GL( const ON_NurbsSurface& s,
00275               GLUnurbsObj* nobj, // created with gluNewNurbsRenderer )
00276               GLenum type,       // = 0 (and type is automatically set)
00277               int bPermitKnotScaling,
00278               double* knot_scale0,
00279               double* knot_scale1
00280              )
00281 {
00282   int i, j, k;
00283 
00284   // The "bPermitScaling" parameters to the ON_GL() call that
00285   // fills in the knot vectors is set to false because any
00286   // rescaling that is applied to a surface domain must also
00287   // be applied to parameter space trimming curve geometry.
00288 
00289   // GL "s" knots
00290   GLint sknot_count = s.KnotCount(0) + 2;
00291   GLfloat* sknot = (GLfloat*)onmalloc( sknot_count*sizeof(*sknot) );
00292   ON_GL( s.Order(0), s.CVCount(0), s.Knot(0), sknot, 
00293            bPermitKnotScaling, knot_scale0 );
00294 
00295   // GL "t" knots
00296   GLint tknot_count = s.KnotCount(1) + 2;
00297   GLfloat* tknot = (GLfloat*)onmalloc( tknot_count*sizeof(*tknot) );
00298   ON_GL( s.Order(1), s.CVCount(1), s.Knot(1), tknot,
00299            bPermitKnotScaling, knot_scale1 );
00300 
00301   // control vertices
00302   const int cv_size= s.CVSize();
00303   const int cv_count[2] = {s.CVCount(0), s.CVCount(1)};
00304   GLint s_stride = cv_size*cv_count[1];
00305   GLint t_stride = cv_size;
00306   GLfloat* ctlarray = (GLfloat*)onmalloc( s_stride*cv_count[0]*sizeof(*ctlarray) );
00307   for ( i = 0; i < cv_count[0]; i++ ) {
00308     for ( j = 0; j < cv_count[1]; j++ ) {
00309       const double*  cv = s.CV(i,j);
00310       GLfloat* gl_cv = ctlarray + s_stride*i + t_stride*j;
00311       for ( k = 0; k < cv_size; k++ ) {
00312         gl_cv[k] = (GLfloat)cv[k];
00313       }
00314     }
00315   }
00316   
00317   GLint sorder = s.Order(0);
00318   GLint torder = s.Order(1);
00319 
00320   if ( type == 0 ) {
00321     // set GL surface type for 3d CVs in homogeneous/euclidean form.
00322     type = ( s.IsRational() ) ? GL_MAP2_VERTEX_4 : GL_MAP2_VERTEX_3;
00323   }
00324 
00325   gluNurbsSurface (
00326     nobj,
00327     sknot_count,
00328     sknot,
00329     tknot_count,
00330     tknot,
00331     s_stride,   
00332     t_stride,   
00333     ctlarray,   
00334     sorder,     
00335     torder,     
00336     type        
00337   );    
00338 
00339   onfree( ctlarray );
00340   onfree( tknot );
00341   onfree( sknot );
00342 }
00343 
00344 void ON_GL( const ON_Brep& brep,
00345             GLUnurbsObj* nobj     // created with gluNewNurbsRenderer )
00346           )
00347 {
00348   const int face_count = brep.m_F.Count();
00349   int face_index;
00350   for ( face_index = 0; face_index < face_count; face_index++ ) {
00351     const ON_BrepFace& face = brep.m_F[face_index];
00352     ON_GL( face, nobj );
00353   }
00354 }
00355 
00356 // See comments in opennurbs_gl.h for calling instructions.
00357 
00358 void ON_GL( const ON_BrepFace& face,
00359             GLUnurbsObj* nobj     // created with gluNewNurbsRenderer )
00360           )
00361 {
00362   bool bSkipTrims = false;
00363 
00364   const ON_Mesh* mesh;
00365   mesh = face.Mesh(ON::render_mesh);
00366   if ( mesh ) 
00367   {
00368     // use saved render mesh
00369     ON_GL(*mesh);
00370   }
00371   else 
00372   {
00373     // use (slow and buggy) glu trimmed NURBS rendering
00374     double knot_scale[2][2] = {{0.0,1.0},{0.0,1.0}};
00375     const ON_Brep* brep = face.Brep();
00376     if ( !brep )
00377       return;
00378 
00379     // untrimmed surface
00380     {
00381       ON_NurbsSurface tmp_nurbssrf;
00382       const ON_Surface* srf = brep->m_S[face.m_si];
00383       const ON_NurbsSurface* nurbs_srf = ON_NurbsSurface::Cast(srf);
00384       if ( !nurbs_srf ) 
00385       {
00386         // attempt to get NURBS form of this surface
00387         if ( srf->GetNurbForm( tmp_nurbssrf ) )
00388           nurbs_srf = &tmp_nurbssrf;
00389       }
00390       if ( !nurbs_srf )
00391         return;
00392       gluBeginSurface( nobj );
00393       ON_GL( *nurbs_srf,
00394              nobj, 
00395              (nurbs_srf->IsRational()) ? GL_MAP2_VERTEX_4 : GL_MAP2_VERTEX_3,
00396              true, knot_scale[0], knot_scale[1]
00397             );
00398     }
00399 
00400     if ( bSkipTrims || brep->FaceIsSurface( face.m_face_index ) ) {
00401       gluEndSurface( nobj );
00402       return; // face is trivially trimmed
00403     }
00404 
00405     int fli, li, lti, ti;
00406 
00407     // any knot scaling applied to the surface must also be applied to
00408     // the parameter space trimming geometry
00409     double xform[4][4] 
00410       = {{knot_scale[0][1], 0.0, 0.0, -knot_scale[0][0]*knot_scale[0][1] },
00411          {0.0, knot_scale[1][1], 0.0, -knot_scale[1][0]*knot_scale[1][1] },
00412          {0.0, 0.0, 1.0, 0.0},
00413          {0.0, 0.0, 0.0, 1.0}};
00414 
00415     // Add face's 2d trimming loop(s)
00416     const int face_loop_count = face.m_li.Count();
00417     for ( fli = 0; fli < face_loop_count; fli++ ) 
00418     {
00419       gluBeginTrim( nobj );
00420 
00421       li = face.m_li[fli];
00422       const ON_BrepLoop& loop = brep->m_L[li];
00423       const int loop_trim_count = loop.m_ti.Count();
00424       for ( lti = 0; lti < loop_trim_count; lti++ )
00425       {
00426         ti = loop.m_ti[lti];
00427         const ON_BrepTrim& trim = brep->m_T[ti];
00428         ON_GL( trim,
00429                nobj, 
00430                GLU_MAP1_TRIM_2,
00431                xform
00432               );
00433       }
00434 
00435       gluEndTrim( nobj );
00436     }
00437     gluEndSurface( nobj );
00438   }
00439 }
00440 
00441 void ON_GL( const ON_Mesh& mesh )
00442 {
00443   int i0, i1, i2, j0, j1, j2;
00444   int fi;
00445   ON_3fPoint v[4];
00446   ON_3fVector n[4];
00447   ON_2fPoint t[4];
00448 
00449   const int face_count = mesh.FaceCount();
00450   const ON_BOOL32 bHasNormals = mesh.HasVertexNormals();
00451   const ON_BOOL32 bHasTCoords = mesh.HasTextureCoordinates();
00452 
00453   glBegin(GL_TRIANGLES);
00454   for ( fi = 0; fi < face_count; fi++ ) {
00455     const ON_MeshFace& f = mesh.m_F[fi];
00456 
00457     v[0] = mesh.m_V[f.vi[0]];
00458     v[1] = mesh.m_V[f.vi[1]];
00459     v[2] = mesh.m_V[f.vi[2]];
00460 
00461 
00462     if ( bHasNormals ) {
00463       n[0] = mesh.m_N[f.vi[0]];
00464       n[1] = mesh.m_N[f.vi[1]];
00465       n[2] = mesh.m_N[f.vi[2]];
00466     }
00467 
00468     if ( bHasTCoords ) {
00469       t[0] = mesh.m_T[f.vi[0]];
00470       t[1] = mesh.m_T[f.vi[1]];
00471       t[2] = mesh.m_T[f.vi[2]];
00472     }
00473 
00474     if ( f.IsQuad() ) {
00475       // quadrangle - render as two triangles
00476       v[3] = mesh.m_V[f.vi[3]];
00477       if ( bHasNormals )
00478         n[3] = mesh.m_N[f.vi[3]];
00479       if ( bHasTCoords )
00480         t[3] = mesh.m_T[f.vi[3]];
00481       if ( v[0].DistanceTo(v[2]) <= v[1].DistanceTo(v[3]) ) {
00482         i0 = 0; i1 = 1; i2 = 2;
00483         j0 = 0; j1 = 2; j2 = 3;
00484       }
00485       else {
00486         i0 = 1; i1 = 2; i2 = 3;
00487         j0 = 1; j1 = 3; j2 = 0;
00488       }
00489     }
00490     else {
00491       // single triangle
00492       i0 = 0; i1 = 1; i2 = 2;
00493       j0 = j1 = j2 = 0;
00494     }
00495 
00496     // first triangle
00497     if ( bHasNormals )
00498       glNormal3f( n[i0].x, n[i0].y, n[i0].z );
00499     if ( bHasTCoords )
00500       glTexCoord2f( t[i0].x, t[i0].y );
00501     glVertex3f( v[i0].x, v[i0].y, v[i0].z );
00502 
00503     if ( bHasNormals )
00504       glNormal3f( n[i1].x, n[i1].y, n[i1].z );
00505     if ( bHasTCoords )
00506       glTexCoord2f( t[i1].x, t[i1].y );
00507     glVertex3f( v[i1].x, v[i1].y, v[i1].z );
00508 
00509     if ( bHasNormals )
00510       glNormal3f( n[i2].x, n[i2].y, n[i2].z );
00511     if ( bHasTCoords )
00512       glTexCoord2f( t[i2].x, t[i2].y );
00513     glVertex3f( v[i2].x, v[i2].y, v[i2].z );
00514 
00515     if ( j0 != j1 ) {
00516       // if we have a quad, second triangle
00517       if ( bHasNormals )
00518         glNormal3f( n[j0].x, n[j0].y, n[j0].z );
00519       if ( bHasTCoords )
00520         glTexCoord2f( t[j0].x, t[j0].y );
00521       glVertex3f( v[j0].x, v[j0].y, v[j0].z );
00522 
00523       if ( bHasNormals )
00524         glNormal3f( n[j1].x, n[j1].y, n[j1].z );
00525       if ( bHasTCoords )
00526         glTexCoord2f( t[j1].x, t[j1].y );
00527       glVertex3f( v[j1].x, v[j1].y, v[j1].z );
00528 
00529       if ( bHasNormals )
00530         glNormal3f( n[j2].x, n[j2].y, n[j2].z );
00531       if ( bHasTCoords )
00532         glTexCoord2f( t[j2].x, t[j2].y );
00533       glVertex3f( v[j2].x, v[j2].y, v[j2].z );
00534     }
00535 
00536   }
00537   glEnd();
00538 }
00539 
00540 void ON_GL( 
00541       const ON_3dPoint& point
00542       )
00543 {
00544   glVertex3d( point.x, point.y, point.z );
00545 }
00546 
00547 void ON_GL( 
00548       const ON_Point& point
00549       )
00550 {
00551   glBegin(GL_POINTS);
00552   ON_GL(point.point);
00553   glEnd();
00554 }
00555 
00556 void ON_GL( const ON_PointCloud& cloud )
00557 {
00558   int i;
00559   ON_3dPoint P;
00560   glBegin(GL_POINTS);
00561   for ( i = 0; i < cloud.PointCount(); i++ ) {
00562     ON_GL( cloud.m_P[i] );
00563   }
00564   glEnd();
00565 }
00566 
00567 void ON_GL( const ON_Material& m )
00568 {
00569   ON_GL( &m );
00570 }
00571 
00572 void ON_GL( const ON_Color& rc, double alpha, GLfloat c[4] )
00573 {
00574   c[0] = (GLfloat)rc.FractionRed();
00575   c[1] = (GLfloat)rc.FractionGreen();
00576   c[2] = (GLfloat)rc.FractionBlue();
00577   c[3] = (GLfloat)alpha;
00578 }
00579 
00580 void ON_GL( const ON_Color& rc, GLfloat c[4] )
00581 {
00582   c[0] = (GLfloat)rc.FractionRed();
00583   c[1] = (GLfloat)rc.FractionGreen();
00584   c[2] = (GLfloat)rc.FractionBlue();
00585   c[3] = (GLfloat)1.0;
00586 }
00587 
00588 
00589 void ON_GL( const ON_Material* pMat )
00590 {
00591   // set GL material to match Rhino material
00592   if ( !pMat ) {
00593     ON_Material default_mat;
00594     ON_GL( &default_mat );
00595   }
00596   else {
00597     GLfloat ambient[4], diffuse[4], specular[4], emission[4];
00598     GLfloat alpha = (GLfloat)(1.0 - pMat->Transparency());
00599     ON_GL( pMat->Ambient(), alpha, ambient );
00600     ON_GL( pMat->Diffuse(), alpha, diffuse );
00601     ON_GL( pMat->Specular(), alpha, specular );
00602     ON_GL( pMat->Emission(), alpha, emission );
00603     GLint shine = (GLint)(128.0*(pMat->Shine() / ON_Material::MaxShine()));
00604     if ( shine == 0 ) {
00605       specular[0]=specular[1]=specular[2]=(GLfloat)0.0;
00606     }
00607     glMaterialfv( GL_FRONT_AND_BACK, GL_AMBIENT,   ambient  );
00608     glMaterialfv( GL_FRONT_AND_BACK, GL_DIFFUSE,   diffuse  );
00609     glMaterialfv( GL_FRONT_AND_BACK, GL_SPECULAR,  specular );
00610     glMaterialfv( GL_FRONT_AND_BACK, GL_EMISSION,  emission );
00611     glMateriali(  GL_FRONT_AND_BACK, GL_SHININESS, shine );
00612   }
00613 }
00614 
00615 void ON_GL( const ON_Light* light, GLenum light_index )
00616 {
00617   ON_Light default_light;
00618   if ( !light ) {
00619     default_light.Default();
00620     light = &default_light;
00621   }
00622   ON_GL( *light, light_index );
00623 }
00624 
00625 void ON_GL( const ON_Light& light, GLenum light_index )
00626 {
00627   ON_BOOL32 bPopModelViewMatrix = false;
00628   ON_BOOL32 bPopProjectionMatrix = false;
00629 
00630   switch ( light.CoordinateSystem() ) 
00631   {
00632   case ON::world_cs:
00633     break;
00634   case ON::clip_cs:
00635     bPopProjectionMatrix = true;
00636     glMatrixMode(GL_PROJECTION);
00637     glPushMatrix();
00638     glLoadIdentity();
00639     // no break here
00640   case ON::camera_cs:
00641     bPopModelViewMatrix = true;
00642     glMatrixMode(GL_MODELVIEW);
00643     glPushMatrix();
00644     glLoadIdentity();
00645     break;
00646   case ON::screen_cs:
00647     break;
00648   }
00649 
00650   GLfloat ambient[4], diffuse[4], specular[4];
00651   ON_GL( light.Ambient(), ambient );
00652   ON_GL( light.Diffuse(), diffuse );
00653   ON_GL( light.Specular(), specular );
00654   glLightfv( light_index, GL_AMBIENT, ambient );
00655   glLightfv( light_index, GL_DIFFUSE, diffuse );
00656   glLightfv( light_index, GL_SPECULAR, specular );
00657 
00658   ON_3dPoint loc = light.Location();
00659   GLfloat f[4] = {(GLfloat)loc.x,(GLfloat)loc.y,(GLfloat)loc.z,(GLfloat)1.0};
00660   glLightfv( light_index, GL_POSITION, f );
00661 
00662   ON_3dVector dir = light.Direction();
00663   f[0] = (GLfloat)dir.x; 
00664   f[1] = (GLfloat)dir.y; 
00665   f[2] = (GLfloat)dir.z;
00666   glLightfv( light_index, GL_SPOT_DIRECTION, f );
00667 
00668   glLightf( light_index, GL_SPOT_EXPONENT, (GLfloat)(light.SpotExponent()*128.0)  );
00669   glLightf( light_index, GL_SPOT_CUTOFF, (GLfloat)light.SpotAngleRadians() );
00670 
00671   ON_3dVector attenuation = light.Attenuation();
00672   glLightf( light_index, GL_CONSTANT_ATTENUATION,  (GLfloat)attenuation.x  );
00673   glLightf( light_index, GL_LINEAR_ATTENUATION,    (GLfloat)attenuation.y  );
00674   glLightf( light_index, GL_QUADRATIC_ATTENUATION, (GLfloat)attenuation.z  );
00675 
00676   if ( light.IsEnabled() )
00677     glEnable( light_index );
00678   else
00679     glDisable( light_index );
00680   if ( bPopProjectionMatrix ) {
00681     glMatrixMode(GL_PROJECTION);
00682     glPopMatrix();
00683   }
00684   if ( bPopModelViewMatrix ) {
00685     glMatrixMode(GL_MODELVIEW);
00686     glPopMatrix();
00687   }
00688 }
00689 
00690 void ON_GL( ON_Viewport& viewport,
00691             int port_left, int port_right,
00692             int port_bottom, int port_top
00693           )
00694 {
00695   // Sets viewport's port to port_* values and adjusts frustum
00696   // so it's aspect matches the port's.
00697   ON_Xform projectionMatrix; // camera to clip transformation
00698 
00699   const int port_width  = abs(port_right - port_left);
00700   const int port_height = abs(port_top - port_bottom);
00701   if ( port_width == 0 || port_height == 0 )
00702     return;
00703   const double port_aspect = ((double)port_width)/((double)port_height);
00704 
00705   viewport.SetFrustumAspect( port_aspect );
00706 
00707   viewport.SetScreenPort( port_left, port_right, port_bottom, port_top,
00708                           0, 0xff );
00709 
00710   ON_BOOL32 bHaveCameraToClip = viewport.GetXform( 
00711                                        ON::camera_cs,  
00712                                        ON::clip_cs,
00713                                        projectionMatrix 
00714                                        );
00715 
00716   if ( bHaveCameraToClip ) {
00717     projectionMatrix.Transpose();
00718     glMatrixMode(GL_PROJECTION);
00719     glLoadMatrixd( &projectionMatrix.m_xform[0][0] );
00720   }
00721 }
00722 
00723 void ON_GL( const ON_Viewport& viewport )
00724 {
00725   // sets model view matrix (world to camera transformation)
00726   ON_Xform modelviewMatrix; // world to camera transformation
00727   ON_BOOL32 bHaveWorldToCamera = viewport.GetXform( 
00728                                        ON::world_cs,  
00729                                        ON::camera_cs,
00730                                        modelviewMatrix 
00731                                        );
00732   if ( bHaveWorldToCamera ) {
00733     modelviewMatrix.Transpose();
00734     glMatrixMode(GL_MODELVIEW);
00735     glLoadMatrixd( &modelviewMatrix.m_xform[0][0] );
00736   }
00737 }
00738 
00739 void ON_GL( 
00740       const ON_Surface& surface,   // 
00741       GLUnurbsObj* nobj           // created with gluNewNurbsRenderer
00742       )
00743 {
00744   ON_NurbsSurface tmp;
00745   const ON_NurbsSurface* nurbs_surface;
00746   nurbs_surface = ON_NurbsSurface::Cast(&surface);
00747   if ( !nurbs_surface ) {
00748     if ( surface.GetNurbForm(tmp) ) {
00749       nurbs_surface = &tmp;
00750     }
00751   }
00752   if ( nurbs_surface )
00753     ON_GL( *nurbs_surface, nobj, 0, true );
00754 }


pcl
Author(s): Open Perception
autogenerated on Wed Aug 26 2015 15:27:01