00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00015
00016
00017 #include "pcl/surface/3rdparty/opennurbs/opennurbs.h"
00018 #include "pcl/surface/3rdparty/opennurbs/opennurbs_gl.h"
00019
00020 void ON_GL( const int order,
00021 const int cv_count,
00022 const double* knot,
00023 GLfloat* glknot,
00024 int bPermitScaling,
00025 double* scale
00026
00027
00028
00029 )
00030 {
00031
00032
00033
00034
00035
00036
00037 const int knot_count = order + cv_count - 2;
00038 const int nknots = knot_count+2;
00039
00040
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;
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,
00120 GLenum type,
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,
00143 GLenum type,
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;
00202 GLfloat* knot = (GLfloat*)onmalloc( nknots*sizeof(*knot) );
00203 ON_GL( nurb_order, cv_count, knot_vector, knot, bPermitKnotScaling, knot_scale );
00204
00205
00206
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:
00220 type = ( is_rat )
00221 ? GLU_MAP1_TRIM_3
00222 : GLU_MAP1_TRIM_2;
00223 break;
00224 case 3:
00225 type = ( is_rat )
00226 ? GL_MAP1_VERTEX_4
00227 : GL_MAP1_VERTEX_3;
00228 bCallgluBeginEndCurve = true;
00229 break;
00230 }
00231 }
00232 break;
00233
00234 case GLU_MAP1_TRIM_2:
00235 case GLU_MAP1_TRIM_3:
00236
00237 type = ( is_rat )
00238 ? GLU_MAP1_TRIM_3
00239 : GLU_MAP1_TRIM_2;
00240 break;
00241
00242 case GL_MAP1_VERTEX_3:
00243 case GL_MAP1_VERTEX_4:
00244
00245 type = ( is_rat )
00246 ? GL_MAP1_VERTEX_4
00247 : GL_MAP1_VERTEX_3;
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
00273
00274 void ON_GL( const ON_NurbsSurface& s,
00275 GLUnurbsObj* nobj,
00276 GLenum type,
00277 int bPermitKnotScaling,
00278 double* knot_scale0,
00279 double* knot_scale1
00280 )
00281 {
00282 int i, j, k;
00283
00284
00285
00286
00287
00288
00289
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
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
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
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
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
00357
00358 void ON_GL( const ON_BrepFace& face,
00359 GLUnurbsObj* nobj
00360 )
00361 {
00362 bool bSkipTrims = false;
00363
00364 const ON_Mesh* mesh;
00365 mesh = face.Mesh(ON::render_mesh);
00366 if ( mesh )
00367 {
00368
00369 ON_GL(*mesh);
00370 }
00371 else
00372 {
00373
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
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
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;
00403 }
00404
00405 int fli, li, lti, ti;
00406
00407
00408
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
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
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
00492 i0 = 0; i1 = 1; i2 = 2;
00493 j0 = j1 = j2 = 0;
00494 }
00495
00496
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
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
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
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
00696
00697 ON_Xform projectionMatrix;
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
00726 ON_Xform modelviewMatrix;
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
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 }