00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044 #include <stdlib.h>
00045 #include <stdio.h>
00046
00047
00048 #include <OSGConfig.h>
00049
00050 #include <OSGAction.h>
00051 #include <OSGDrawAction.h>
00052 #include <OSGRenderAction.h>
00053 #include <OSGIntersectAction.h>
00054 #include <OSGRenderAction.h>
00055 #include <OSGSimpleMaterial.h>
00056 #include "OSGFatBorderChunk.h"
00057
00058 #include <OSGGeometry.h>
00059 #include <OSGGeoProperty.h>
00060
00061 #include <OSGGeoFunctions.h>
00062 #include <OSGGeoPumpFactory.h>
00063
00064 #include <OSGGL.h>
00065 #include <OSGGLU.h>
00066 #include <OSGGLEXT.h>
00067
00068 #include "OSGSurface.h"
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078 #include <OSGBSplineTrimmedSurface.h>
00079 #include <OSGNurbsPatchSurface.h>
00080 #include <OSGSimplePolygon.h>
00081
00082 #include <OSGpredicates.h>
00083
00084 OSG_USING_NAMESPACE
00085
00086 #ifdef __sgi
00087 #pragma set woff 1174
00088 #endif
00089
00090 namespace
00091 {
00092 static char cvsid_cpp[] = "@(#)$Id: OSGSurface.cpp,v 1.13 2006-11-17 17:59:30 edhellon Exp $";
00093 static char cvsid_hpp[] = OSGSURFACE_HEADER_CVSID;
00094 static char cvsid_inl[] = OSGSURFACE_INLINE_CVSID;
00095 }
00096
00097 #ifdef __sgi
00098 #pragma reset woff 1174
00099 #endif
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109 const OSG::BitVector Surface::CurveFieldMask =
00110 (Surface::NumCurvesFieldMask |
00111 Surface::KnotLengthsFieldMask |
00112 Surface::DimensionsFieldMask |
00113 Surface::CurveControlPointsFieldMask |
00114 Surface::KnotsFieldMask |
00115 Surface::CurvesPerLoopFieldMask );
00116
00117 const OSG::BitVector Surface::SurfaceFieldMask =
00118 (Surface::DimUFieldMask |
00119 Surface::DimVFieldMask |
00120 Surface::KnotsUFieldMask |
00121 Surface::KnotsVFieldMask |
00122 Surface::ControlPointsFieldMask |
00123 Surface::ErrorFieldMask |
00124 Surface::IsDelaunayFieldMask |
00125 Surface::TextureControlPointsFieldMask );
00126
00127
00128
00143
00144
00146
00147 Surface::Surface(void) :
00148 Inherited()
00149 {
00150
00151 _trimmedSurface = NULL;
00152 _surfacePatch = NULL;
00153 }
00154
00156
00157 Surface::Surface(const Surface &source) :
00158 Inherited(source)
00159 {
00160
00161
00162
00163 _trimmedSurface = new BSplineTrimmedSurface;
00164 _surfacePatch = new CNurbsPatchSurface;
00165 }
00166
00168
00169 Surface::~Surface(void)
00170 {
00171 if ( _trimmedSurface != NULL )
00172 delete _trimmedSurface;
00173 if ( _surfacePatch != NULL )
00174 delete _surfacePatch;
00175 }
00176
00177
00178
00179
00181
00182 void Surface::initMethod (void)
00183 {
00184 DrawAction::registerEnterDefault( getClassType(),
00185 osgTypedMethodFunctor2BaseCPtrRef<Action::ResultE,
00186 MaterialDrawablePtr,
00187 CNodePtr,
00188 Action *>
00189 (&MaterialDrawable::drawActionHandler));
00190
00191 RenderAction::registerEnterDefault( getClassType(),
00192 osgTypedMethodFunctor2BaseCPtrRef<Action::ResultE,
00193 SurfacePtr,
00194 CNodePtr,
00195 Action *>
00196 (&Geometry::renderActionHandler));
00197
00198 IntersectAction::registerEnterDefault( getClassType(),
00199 osgTypedMethodFunctor2BaseCPtrRef<Action::ResultE,
00200 SurfacePtr,
00201 CNodePtr,
00202 Action *>(&Geometry::intersect));
00203
00204
00205 ::exactinit();
00206
00207 CErrorQuadTree::m_sbNormalApproximation = true;
00208
00209 }
00210
00212
00213 void Surface::changed(BitVector whichField, UInt32 origin)
00214 {
00215 if(whichField & ControlPointsFieldMask)
00216 {
00217 if(origin & ChangedOrigin::Abstract)
00218 {
00219 if(origin & ChangedOrigin::AbstrCheckValid)
00220 {
00221 SurfacePtr thisP(*this);
00222
00223 if(_sfControlPoints.getValue() != NullFC &&
00224 _sfControlPoints.getValue()->findParent(thisP) == -1 )
00225 {
00226 GeoPositionsPtr pPos = _sfControlPoints.getValue();
00227
00228 _sfControlPoints.setValue(NullFC);
00229
00230 setControlPoints(pPos);
00231 }
00232 }
00233 else if(origin & ChangedOrigin::AbstrIncRefCount)
00234 {
00235 addRefCP(_sfControlPoints.getValue());
00236 }
00237 else
00238 {
00239 GeoPositionsPtr pPos = _sfControlPoints.getValue();
00240
00241 _sfControlPoints.setValue(NullFC);
00242
00243 setControlPoints(pPos);
00244 }
00245 }
00246 }
00247
00248 if(whichField & TextureControlPointsFieldMask)
00249 {
00250 if(origin & ChangedOrigin::Abstract)
00251 {
00252 if(origin & ChangedOrigin::AbstrCheckValid)
00253 {
00254 SurfacePtr thisP(*this);
00255
00256 if(_sfTextureControlPoints.getValue() != NullFC &&
00257 _sfTextureControlPoints.getValue()->findParent(thisP) == -1 )
00258 {
00259 GeoTexCoordsPtr pTexCoord = _sfTextureControlPoints.getValue();
00260
00261 _sfTextureControlPoints.setValue(NullFC);
00262
00263 setTextureControlPoints(pTexCoord);
00264 }
00265 }
00266 else if(origin & ChangedOrigin::AbstrIncRefCount)
00267 {
00268 addRefCP(_sfTextureControlPoints.getValue());
00269 }
00270 else
00271 {
00272 GeoTexCoordsPtr pTexCoord = _sfTextureControlPoints.getValue();
00273
00274 _sfTextureControlPoints.setValue(NullFC);
00275
00276 setTextureControlPoints(pTexCoord);
00277 }
00278 }
00279 }
00280
00281
00282
00283 {
00284 if( ( whichField & DimUFieldMask ) ||
00285 ( whichField & DimVFieldMask ) ||
00286 ( whichField & KnotsUFieldMask ) ||
00287 ( whichField & KnotsVFieldMask ) ||
00288 ( whichField & ControlPointsFieldMask ) ||
00289 ( whichField & NumCurvesFieldMask ) ||
00290 ( whichField & KnotLengthsFieldMask ) ||
00291 ( whichField & DimensionsFieldMask ) ||
00292 ( whichField & CurveControlPointsFieldMask ) ||
00293 ( whichField & KnotsFieldMask ) ||
00294 ( whichField & CurvesPerLoopFieldMask ) ||
00295 ( whichField & TextureControlPointsFieldMask ) )
00296 {
00297
00298 SurfacePtr tmpPtr(*this);
00299
00300 beginEditCP(tmpPtr, DirtyMaskFieldMask);
00301 {
00302 getDirtyMask() |= TESSELLATE;
00303 }
00304 endEditCP (tmpPtr, DirtyMaskFieldMask);
00305
00306 Window::refreshGLObject(getSurfaceGLId());
00307 }
00308 else if( ( whichField & ErrorFieldMask ) ||
00309 ( whichField & IsDelaunayFieldMask ) )
00310 {
00311
00312
00313 SurfacePtr tmpPtr(*this);
00314
00315 beginEditCP(tmpPtr, DirtyMaskFieldMask);
00316 {
00317 getDirtyMask() |= RETESSELLATE;
00318 }
00319 endEditCP (tmpPtr, DirtyMaskFieldMask);
00320
00321 Window::refreshGLObject(getSurfaceGLId());
00322 }
00323 }
00324
00325
00326
00327 Inherited::changed( whichField, origin );
00328
00329
00330
00331 }
00332
00333
00335
00336
00337
00338
00339
00340 Real64 Surface::getDesiredError( Pnt3f viewPos, Real64 halfPixelSize )
00341 {
00342 Vec3f dist;
00343 Real64 distance;
00344
00345 FindClosestPoint( dist, viewPos );
00346 distance = dist.squareLength( );
00347
00348
00349
00350
00351
00352
00353
00354 distance = sqrt( distance );
00355
00356
00357
00358
00359 Real64 desired_error = halfPixelSize * distance;
00360
00361
00362
00363 if( desired_error < _max.dist( _min ) * 0.001 )
00364 {
00365
00366 desired_error = _max.dist( _min ) * 0.001;
00367 }
00368
00369 return desired_error;
00370 }
00371
00373
00374
00375
00376
00377
00378 bool Surface::updateError( Pnt3f viewPos, Real64 halfPixelSize )
00379 {
00380 Real64 d_max_error = getDesiredError( viewPos, halfPixelSize );
00381
00382
00383
00384
00385 Real32 current_error = getError();
00386 if ( d_max_error < current_error )
00387 {
00388 std::cerr << "retessellating due to too high error: " << d_max_error
00389 << " " << current_error << std::endl;
00390 Real32 new_error = osgMin( d_max_error, current_error / 2.0 );
00391 SurfacePtr thisPtr = SurfacePtr( this );
00392 beginEditCP( thisPtr, Surface::ErrorFieldMask );
00393 {
00394 setError( d_max_error / 2.0 );
00395 }
00396 endEditCP( thisPtr, Surface::ErrorFieldMask );
00397 }
00398 else if ( d_max_error > current_error * 4.0 )
00399 {
00400 std::cerr << "retessellating due to too low error: " << d_max_error
00401 << " " << current_error << std::endl;
00402 SurfacePtr thisPtr = SurfacePtr( this );
00403 beginEditCP( thisPtr, Surface::ErrorFieldMask );
00404 {
00405 setError( d_max_error / 2.0 );
00406 }
00407 endEditCP( thisPtr, Surface::ErrorFieldMask );
00408 }
00409 return true;
00410 }
00411
00412
00413
00414
00415
00416
00417
00418
00419 void Surface::FindClosestPoint( Vec3f& rDist, const Pnt3f viewPos ) const
00420 {
00421 const UInt32 parent_cnt = getParents( ).size( );
00422 UInt32 parent_idx;
00423 Real64 min_dist = 1e300;
00424 Vec3f temp_dist;
00425 Real64 curr_dist;
00426
00427 for( parent_idx = 0; parent_idx < parent_cnt; ++parent_idx )
00428 {
00429 switch( getParents( )[ 0 ]->getVolume( ).getType( ) )
00430 {
00431 case DynamicVolume::BOX_VOLUME:
00432 {
00433 Pnt3f bb_min, bb_max;
00434
00435 getParents( )[ 0 ]->getVolume( ).getBounds( bb_min, bb_max );
00436
00437
00438
00439 if( viewPos[0] < bb_min[0] )
00440 {
00441 temp_dist[0] = viewPos[0] - bb_min[0];
00442 }
00443 else if( viewPos[0] > bb_max[0] )
00444 {
00445 temp_dist[0] = viewPos[0] - bb_max[0];
00446 }
00447 else
00448 {
00449 temp_dist[0] = 0.0;
00450 }
00451
00452 if( viewPos[1] < bb_min[1] )
00453 {
00454 temp_dist[1] = viewPos[1] - bb_min[1];
00455 }
00456 else if( viewPos[1] > bb_max[1] )
00457 {
00458 temp_dist[1] = viewPos[1] - bb_max[1];
00459 }
00460 else
00461 {
00462 temp_dist[1] = 0.0;
00463 }
00464
00465 if( viewPos[2] < bb_min[2] )
00466 {
00467 temp_dist[2] = viewPos[2] - bb_min[2];
00468 }
00469 else if( viewPos[2] > bb_max[2] )
00470 {
00471 temp_dist[2] = viewPos[2] - bb_max[2];
00472 }
00473 else
00474 {
00475 temp_dist[2] = 0.0;
00476 }
00477 }
00478 break;
00479 case DynamicVolume::SPHERE_VOLUME:
00480 {
00481 Real64 length;
00482 Pnt3f center;
00483
00484 getParents( )[ 0 ]->getVolume( ).getCenter( center );
00485 temp_dist = center - viewPos;
00486 length = temp_dist.length( ) - getParents( )[ 0 ]->getVolume( ).getScalarVolume( );
00487 if( length > 0.0 )
00488 {
00489 temp_dist.normalize( );
00490 temp_dist *= length;
00491 }
00492 else
00493 {
00494 temp_dist[0] = temp_dist[1] = temp_dist[2] = 0.0;
00495 }
00496 }
00497 break;
00498 }
00499 curr_dist = temp_dist.squareLength( );
00500 if( curr_dist < min_dist )
00501 {
00502 min_dist = curr_dist;
00503 rDist = temp_dist;
00504 }
00505 }
00506 }
00507
00508
00509 void Surface::FindClosestPointExact( Vec3f& rDist, const Pnt3f viewPos ) const
00510 {
00511
00512 const GeoPositions3fPtr cpcl_points = GeoPositions3fPtr::dcast( getPositions() );
00513 const unsigned int cui_idx_cnt = cpcl_points->getSize( );
00514 Pnt3f cl_pos;
00515 unsigned int ui_idx;
00516 Vec3f cl_temp;
00517 double d_min = DBL_MAX;
00518 double d_temp;
00519
00520 for( ui_idx = 0; ui_idx < cui_idx_cnt; ++ui_idx )
00521 {
00522 cl_pos = cpcl_points->getValue( ui_idx );
00523 cl_temp = cl_pos - viewPos;
00524 d_temp = cl_temp.squareLength( );
00525 if( d_temp <= d_min )
00526 {
00527 d_min = d_temp;
00528 rDist = cl_temp;
00529 }
00530 }
00531 }
00532
00533
00535 void Surface::tessellate( void )
00536 {
00537
00538
00539
00540
00541 std::vector< SimplePolygon > tris;
00542 std::vector< Pnt3f > gverts;
00543 std::vector< Vec3f > norms;
00544 std::vector< Pnt2f > texturecoords;
00545
00546 Int32 err = convertSurface();
00547 if ( err )
00548 {
00549
00550 return;
00551 }
00552 if ( _sfTextureControlPoints.getValue() == NullFC )
00553 {
00554 err = tessellateSurface( tris, gverts, norms);
00555 #ifdef OSG_NURBS_DEBUG
00556 std::cerr<<"Surface::tessellate err1: " << err << " #tris: " << tris.size() << std::endl;
00557 #endif
00558 if ( err ) return;
00559 (void) buildSurface( tris, gverts, norms, texturecoords );
00560 }
00561 else
00562 {
00563
00564
00565
00566
00567
00568
00569
00570 err = tessellateSurface( tris, gverts, norms, texturecoords );
00571 #ifdef OSG_NURBS_DEBUG
00572 std::cerr<<"Surface::tessellate err2: " << err << " #tris: " << tris.size() << std::endl;
00573 #endif
00574 if ( err ) return;
00575 (void) buildSurface( tris, gverts, norms, texturecoords );
00576
00577 }
00578
00579
00580
00581
00582
00583
00584
00585 }
00586
00588 void Surface::reTessellate( void )
00589 {
00590 std::vector< SimplePolygon > tris;
00591 std::vector< Pnt3f > gverts;
00592 std::vector< Vec3f > norms;
00593 std::vector< Pnt2f > texturecoords;
00594
00595
00596
00597
00598 if ( getError() < DCTP_EPS )
00599 {
00600
00601
00602 setError( 0.2 );
00603 }
00604
00605 _surfacePatch->setError ( getError() );
00606 SSurface *surfdata = _surfacePatch->getSurfaceData();
00607
00608 if ( _sfTextureControlPoints.getValue() == NullFC )
00609 {
00610 _surfacePatch->getTessellation( gverts, norms, tris, getIsDelaunay() );
00611 (void) buildSurface( tris, gverts, norms, texturecoords );
00612 }
00613 else
00614 {
00615
00616
00617
00618
00619
00620
00621
00622 _surfacePatch->getTessellation( gverts, norms, texturecoords,
00623 tris, getIsDelaunay() );
00624 (void) buildSurface( tris, gverts, norms, texturecoords );
00625
00626 }
00627
00628
00629
00630
00631 }
00632
00633
00634 Int32 Surface::convertSurface( void )
00635 {
00636
00637
00638 bool israt;
00639 GeoPositions3fPtr pPos = GeoPositions3fPtr::dcast(
00640 _sfControlPoints.getValue());
00641 GeoPositions4fPtr pRatPos = GeoPositions4fPtr::dcast(
00642 _sfControlPoints.getValue());
00643
00644
00645 if(_sfControlPoints.getValue() == NullFC)
00646 {
00647 SLOG << "Surface::tessellate: null surfacecontrol prop " << endLog;
00648 return -1;
00649 }
00650
00651 if ( pPos != NullFC )
00652 {
00653 israt = false;
00654 }
00655 else if ( pRatPos != NullFC )
00656 {
00657 israt = true;
00658 }
00659 else
00660 {
00661 SLOG << "Surface::tessellate: null surfacecontrol prop " << endLog;
00662 return -1;
00663 }
00664 MFPnt3f *polyControlPoints;
00665 MFPnt4f *ratControlPoints;
00666 UInt32 cpsize;
00667 if ( !israt )
00668 {
00669 polyControlPoints = &(pPos->getField());
00670 cpsize = polyControlPoints->size();
00671 }
00672 else
00673 {
00674 ratControlPoints = &(pRatPos->getField());
00675 cpsize = ratControlPoints->size();
00676 }
00677
00678
00679
00680 if( cpsize == 0 )
00681 {
00682 SLOG << "Surface::tessellate: null surfacecontrol points " << endLog;
00683 return -1;
00684 }
00685
00686
00687
00688
00689
00690 UInt32 dimu = _sfDimU.getValue();
00691 UInt32 dimv = _sfDimV.getValue();
00692 if ( dimu == 0 || dimv == 0 )
00693 {
00694 SLOG << "Surface::tessellate: 0 dimensions " << endLog;
00695 return -1;
00696 }
00697 UInt32 knotusize = _mfKnotsU.size();
00698 UInt32 knotvsize = _mfKnotsV.size();
00699 if ( knotusize == 0 || knotvsize == 0 )
00700 {
00701 SLOG << "Surface::tessellate: empty knotvectors " << endLog;
00702 return -1;
00703 }
00704 UInt32 cpusize = knotusize - dimu - 1;
00705 UInt32 cpvsize = knotvsize - dimv - 1;
00706 if ( cpusize < 1 || cpvsize < 1 || cpusize * cpvsize != cpsize )
00707 {
00708 SLOG << cpusize << "x" << cpvsize << ":" << cpsize << endLog;
00709 SLOG << "Surface::tessellate: inconsistent attributes " << endLog;
00710 return -1;
00711 }
00712 if ( _sfNumCurves.getValue() == 0 )
00713 {
00714 Real64 umin = _mfKnotsU[ 0 ];
00715 Real64 vmin = _mfKnotsV[ 0 ];
00716 Real64 umax = _mfKnotsU[ knotusize - 1 ];
00717 Real64 vmax = _mfKnotsV[ knotvsize - 1 ];
00718
00719 std::vector< Real64 > tmpknotvec(4);
00720 std::vector< Pnt2f > tmpcps(2);
00721 UInt32 dim = 1;
00722 tmpknotvec[ 0 ] = 0.0;
00723 tmpknotvec[ 1 ] = 0.0;
00724 tmpknotvec[ 2 ] = 1.0;
00725 tmpknotvec[ 3 ] = 1.0;
00726
00727
00728 tmpcps[0][0] = umin; tmpcps[0][1] = vmin;
00729 tmpcps[1][0] = umax; tmpcps[1][1] = vmin;
00730 addCurve( dim, tmpknotvec, tmpcps );
00731
00732
00733 tmpcps[0][0] = umax; tmpcps[0][1] = vmin;
00734 tmpcps[1][0] = umax; tmpcps[1][1] = vmax;
00735 addCurve( dim, tmpknotvec, tmpcps );
00736
00737
00738 tmpcps[0][0] = umax; tmpcps[0][1] = vmax;
00739 tmpcps[1][0] = umin; tmpcps[1][1] = vmax;
00740 addCurve( dim, tmpknotvec, tmpcps );
00741
00742
00743 tmpcps[0][0] = umin; tmpcps[0][1] = vmax;
00744 tmpcps[1][0] = umin; tmpcps[1][1] = vmin;
00745 addCurve( dim, tmpknotvec, tmpcps );
00746 }
00747
00748
00749
00750
00751
00752 BSplineTensorSurface tensor_surface;
00753 UInt32 i, j, k;
00754 DCTPVec4dmatrix qnet;
00755 Vec4d vec4;
00756 qnet.resize( cpusize );
00757
00758 for ( i = 0; i < cpusize; ++i )
00759 {
00760 qnet[ i ].resize( cpvsize );
00761 for ( j = 0; j < cpvsize; ++j )
00762 {
00763 k = i * cpvsize + j;
00764 if ( !israt )
00765 {
00766 vec4[0] = (*polyControlPoints)[k][0];
00767 vec4[1] = (*polyControlPoints)[k][1];
00768 vec4[2] = (*polyControlPoints)[k][2];
00769 vec4[3] = 1.0f;
00770
00771
00772 }
00773 else
00774 {
00775 vec4[0] = (*ratControlPoints)[k][0];
00776 vec4[1] = (*ratControlPoints)[k][1];
00777 vec4[2] = (*ratControlPoints)[k][2];
00778 vec4[3] = (*ratControlPoints)[k][3];
00779
00780
00781 }
00782 qnet[ i ][ j ] = vec4;
00783 }
00784 }
00785 tensor_surface.setControlPointMatrix( qnet );
00786
00787 DCTPdvector knotuvec(knotusize);
00788 DCTPdvector knotvvec(knotvsize);
00789 for ( i = 0; i < knotusize; ++i )
00790 {
00791 knotuvec[ i ] = _mfKnotsU[ i ];
00792 }
00793 for ( i = 0; i < knotvsize; ++i )
00794 {
00795 knotvvec[ i ] = _mfKnotsV[ i ];
00796 }
00797 tensor_surface.setKnotsAndDimension( knotuvec, dimu, knotvvec, dimv );
00798
00799
00800 _trimmedSurface->setSurface( tensor_surface );
00801
00802
00803
00804 trimmingloop trimloops;
00805 UInt32 cplsize = _mfCurvesPerLoop.size();
00806 trimloops.resize( cplsize );
00807 for ( i = 0; i < cplsize; ++i )
00808 {
00809 trimloops[ i ].resize( _mfCurvesPerLoop[ i ] );
00810 }
00811 UInt32 actknotoffset = 0;
00812 UInt32 actcpoffset = 0;
00813 UInt32 actloopoffset = 0;
00814 UInt32 actcurveno = 0;
00815 UInt32 acttrimcpsize = 0;
00816 DCTPdvector actknots;
00817 DCTPVec3dvector acttrimcps;
00818 BSplineCurve2D actcurve;
00819 for ( i = 0; i < trimloops.size(); ++i )
00820 {
00821 for ( j = 0; j < trimloops[i].size(); ++j )
00822 {
00823 actknots.resize( _mfKnotLengths[ actcurveno ] );
00824
00825
00826
00827 acttrimcpsize = actknots.size() - _mfDimensions[ actcurveno ] - 1;
00828 if ( acttrimcpsize < 1 )
00829 {
00830 SLOG << "Surface::tessellate: wrong trimming curve attributes "
00831 << endLog;
00832 return -1;
00833 }
00834 acttrimcps.resize( acttrimcpsize );
00835 for ( k = 0; k < actknots.size(); ++k )
00836 {
00837 actknots[ k ] = _mfKnots[ actknotoffset + k ];
00838 }
00839 actknotoffset += actknots.size();
00840 actcurve.setKnotsAndDimension( actknots,
00841 _mfDimensions[ actcurveno ] );
00842
00843
00844
00845
00846
00847
00848 for ( k = 0; k < acttrimcpsize; ++k )
00849 {
00850
00851 acttrimcps[ k ][0] = _mfCurveControlPoints[ actcpoffset + k ][0];
00852 acttrimcps[ k ][1] = _mfCurveControlPoints[ actcpoffset + k ][1];
00853 acttrimcps[ k ][2] = _mfCurveControlPoints[ actcpoffset + k ][2];
00854 }
00855 actcpoffset += acttrimcpsize;
00856 actcurve.setControlPointVector( acttrimcps );
00857
00858 trimloops[i][j] = actcurve;
00859 actcurveno++;
00860 }
00861
00862 }
00863 _trimmedSurface->setTrimmingLoops( trimloops );
00864 _trimmedSurface->normalize();
00865
00866
00867 return 0;
00868 }
00869
00870
00871
00872
00873 Int32 Surface::tessellateSurface( std::vector< SimplePolygon > &triangles,
00874 std::vector< Pnt3f > &gverts,
00875 std::vector< Vec3f > &norms )
00876 {
00877
00878
00879
00880 std::vector< Pnt2f > dummy;
00881 _surfacePatch->setSurface( _trimmedSurface, dummy, false );
00882 if ( _sfError.getValue() < DCTP_EPS )
00883 {
00884
00885
00886 _sfError.setValue( 0.2 );
00887 }
00888 _surfacePatch->setError ( _sfError.getValue() );
00889 _surfacePatch->getTessellation( gverts, norms, triangles, getIsDelaunay() );
00890 SSurface *surfaceData = _surfacePatch->getSurfaceData();
00891 _min = Pnt3d( surfaceData->clMin[0], surfaceData->clMin[1],
00892 surfaceData->clMin[2] );
00893 _max = Pnt3d( surfaceData->clMax[0], surfaceData->clMax[1],
00894 surfaceData->clMax[2] );
00895 #ifdef OSG_ARBITRARY_SPLIT
00896 _minParam = Pnt2d( surfaceData->clMinParam[0] , surfaceData->clMinParam[1] );
00897 _maxParam = Pnt2d( surfaceData->clMaxParam[0] , surfaceData->clMaxParam[1] );
00898 #endif
00899
00900
00901
00902
00903
00904 return 0;
00905 }
00906
00907
00908
00909 Int32 Surface::tessellateSurface( std::vector< SimplePolygon > &triangles,
00910 std::vector< Pnt3f > &gverts,
00911 std::vector< Vec3f > &norms,
00912 std::vector< Pnt2f > &texcoords )
00913 {
00914
00915
00916
00917 GeoTexCoords2fPtr pTexPos = GeoTexCoords2fPtr::dcast(_sfTextureControlPoints.getValue());
00918 std::vector<Pnt2f > tmptexcoords;
00919 UInt32 i;
00920 UInt32 s = pTexPos->getField().size();
00921 for ( i = 0; i < s; ++i )
00922 {
00923 tmptexcoords.push_back( Pnt2f( pTexPos->getField()[i][0],
00924 pTexPos->getField()[i][1]));
00925 }
00926 _surfacePatch->setSurface( _trimmedSurface,
00927 tmptexcoords,
00928 true);
00929 if ( _sfError.getValue() < DCTP_EPS )
00930 {
00931
00932
00933 _sfError.setValue( 0.2 );
00934 }
00935 _surfacePatch->setError ( _sfError.getValue() );
00936 _surfacePatch->getTessellation( gverts, norms, texcoords, triangles, getIsDelaunay() );
00937
00938
00939
00940 SSurface *surfaceData = _surfacePatch->getSurfaceData();
00941 _min = Pnt3d( surfaceData->clMin[0], surfaceData->clMin[1],
00942 surfaceData->clMin[2] );
00943 _max = Pnt3d( surfaceData->clMax[0], surfaceData->clMax[1],
00944 surfaceData->clMax[2] );
00945 #ifdef OSG_ARBITRARY_SPLIT
00946 _minParam = Pnt2d( surfaceData->clMinParam[0] , surfaceData->clMinParam[1] );
00947 _maxParam = Pnt2d( surfaceData->clMaxParam[0] , surfaceData->clMaxParam[1] );
00948 #endif
00949
00950
00951
00952
00953
00954 return 0;
00955 }
00956
00957
00958
00959 Int32 Surface::tessellateSurface( std::vector< SimplePolygon > &triangles,
00960 std::vector< Pnt3f > &gverts,
00961 std::vector< Pnt2f > &texcoords )
00962 {
00963
00964
00965
00966 GeoTexCoords2fPtr pTexPos = GeoTexCoords2fPtr::dcast(_sfTextureControlPoints.getValue());
00967 std::vector<Pnt2f > tmptexcoords;
00968 UInt32 i;
00969 UInt32 s = pTexPos->getField().size();
00970 for ( i = 0; i < s; ++i )
00971 {
00972 tmptexcoords.push_back( Pnt2f( pTexPos->getField()[i][0],
00973 pTexPos->getField()[i][1]));
00974 }
00975 _surfacePatch->setSurface( _trimmedSurface,
00976 tmptexcoords,
00977 true);
00978 if ( _sfError.getValue() < DCTP_EPS )
00979 {
00980
00981
00982 _sfError.setValue( 0.2 );
00983 }
00984 _surfacePatch->setError ( _sfError.getValue() );
00985 std::vector< Vec3f > norms;
00986 _surfacePatch->getTessellation( gverts, norms, triangles, false );
00987 _surfacePatch->getTessellation( gverts, texcoords, triangles, getIsDelaunay() );
00988
00989 SSurface *surfaceData = _surfacePatch->getSurfaceData();
00990 _min = Pnt3d( surfaceData->clMin[0], surfaceData->clMin[1],
00991 surfaceData->clMin[2] );
00992 _max = Pnt3d( surfaceData->clMax[0], surfaceData->clMax[1],
00993 surfaceData->clMax[2] );
00994 #ifdef OSG_ARBITRARY_SPLIT
00995 _minParam = Pnt2d( surfaceData->clMinParam[0] , surfaceData->clMinParam[1] );
00996 _maxParam = Pnt2d( surfaceData->clMaxParam[0] , surfaceData->clMaxParam[1] );
00997 #endif
00998
00999
01000
01001
01002
01003 return 0;
01004 }
01005
01006 void Surface::calcIndexMapping(void)
01007 {
01008 getIndexMapping().clear();
01009
01010 UInt16 im = 0;
01011 if(getPositions() != NullFC)
01012 im |= Geometry::MapPosition;
01013 if(getNormals() != NullFC)
01014 im |= Geometry::MapNormal;
01015 if(getTexCoords() != NullFC)
01016 im |= Geometry::MapTexCoords;
01017 if(getTexCoords1() != NullFC)
01018 im |= Geometry::MapTexCoords1;
01019
01020 if(im != 0)
01021 getIndexMapping( ).push_back(im);
01022 }
01023
01024
01025
01026
01027 Int32 Surface::buildSurface( std::vector< SimplePolygon > &triangles,
01028 std::vector< Pnt3f > &gverts,
01029 std::vector< Vec3f > &norms,
01030 std::vector< Pnt2f > &texcoords )
01031
01032 {
01033
01034
01035
01036
01037
01038
01039
01040
01041
01042
01043
01044
01045
01046
01047
01048
01049
01050
01051 GeoPTypesPtr pcl_type = getTypes();
01052 GeoPLengthsPtr pcl_size = getLengths();
01053 GeoPositionsPtr pcl_points = getPositions();
01054 GeoNormalsPtr pcl_norms = getNormals();
01055 GeoIndicesPtr pcl_indices = getIndices( );
01056 GeoTexCoordsPtr pcl_texcoords = getTexCoords1();
01057
01058 GeoTexCoords3fPtr pcl_tangents = GeoTexCoords3fPtr::dcast( getTexCoords( ) );
01059 SimpleMaterialPtr pcl_mat = SimpleMaterialPtr::dcast( getMaterial( ) );
01060 SurfacePtr thisPtr = SurfacePtr( this );
01061
01062 SimplePolygon *pcl_face;
01063 const UInt32 cui_faces = triangles.size();
01064 UInt32 ui_face;
01065 BSplineTensorSurface cl_surf = _trimmedSurface->getSurface();
01066 int i_err;
01067 Vec3d cl_norm;
01068 const UInt32 cui_verts = gverts.size( );
01069 UInt32 ui_vert;
01070 SSurface *pt_surfdata = _surfacePatch->getSurfaceData( );
01071 const UInt32 cui_loop_cnt = pt_surfdata->vvclEdgeLoops.size( );
01072 UInt32 ui_loop;
01073 UInt32 ui_vertex_cnt;
01074 UInt32 ui_idx;
01075 UInt32 ui_used;
01076 Vec3d *pcl_actn;
01077 Vec3d *pcl_actv;
01078 Vec3d *pcl_nextv;
01079 Vec3d *pcl_prevv;
01080 Vec3f cl_v1, cl_v2, cl_tangent;
01081 std::vector< Int32 > vi_new_idx( cui_verts );
01082 bool b_show_trimming = false;
01083
01084
01085 if( pcl_mat != NullFC )
01086 {
01087 const UInt32 cui_chunk_cnt = pcl_mat->getChunks( ).size( );
01088 UInt32 ui_chunk;
01089
01090 for( ui_chunk = 0; ui_chunk < cui_chunk_cnt; ++ui_chunk )
01091 {
01092 if( FatBorderChunkPtr::dcast( pcl_mat->getChunks( ui_chunk ) ) != NullFC )
01093
01094 {
01095 b_show_trimming = true;
01096 break;
01097 }
01098 }
01099 }
01100
01101
01102 if ( pcl_type == NullFC )
01103 {
01104 pcl_type = GeoPTypesUI8::create();
01105 }
01106 if ( pcl_size == NullFC )
01107 {
01108 pcl_size = GeoPLengthsUI32::create();
01109 }
01110 if ( pcl_points == NullFC )
01111 {
01112 pcl_points = GeoPositions3f::create();
01113 }
01114 if ( ( norms.size( ) > 0 ) && ( pcl_norms == NullFC ) )
01115 {
01116 pcl_norms = GeoNormals3f::create();
01117 }
01118 if ( pcl_indices == NullFC )
01119 {
01120 pcl_indices = GeoIndicesUI32::create();
01121 }
01122 if ( ( texcoords.size( ) > 0 ) && ( pcl_texcoords == NullFC ) )
01123 {
01124 pcl_texcoords = GeoTexCoords2f::create();
01125 }
01126 if( b_show_trimming )
01127 {
01128 if( pcl_tangents == NullFC )
01129 {
01130 pcl_tangents = GeoTexCoords3f::create( );
01131 }
01132 }
01133 else
01134 {
01135 if( pcl_tangents != NullFC )
01136 {
01137 beginEditCP( thisPtr, Geometry::TexCoordsFieldMask );
01138 {
01139 setTexCoords( NullFC );
01140 }
01141 endEditCP( thisPtr, Geometry::TexCoordsFieldMask );
01142 }
01143 }
01144
01145
01146 for( ui_vert = 0; ui_vert < cui_verts; ++ui_vert )
01147 {
01148 vi_new_idx[ ui_vert ] = -1;
01149 }
01150 for( ui_face = 0; ui_face < cui_faces; ++ui_face )
01151 {
01152 pcl_face = &triangles[ ui_face ];
01153 vi_new_idx[ pcl_face->vertices[ 0 ] ] = 0;
01154 vi_new_idx[ pcl_face->vertices[ 1 ] ] = 0;
01155 vi_new_idx[ pcl_face->vertices[ 2 ] ] = 0;
01156 }
01157
01158
01159 ui_used = 0;
01160 for( ui_vert = 0; ui_vert < cui_verts; ++ui_vert )
01161 {
01162 if( vi_new_idx[ ui_vert ] >= 0 )
01163 {
01164 vi_new_idx[ ui_vert ] = ui_used;
01165 ++ui_used;
01166 }
01167 }
01168
01169
01170
01171
01172 beginEditCP( pcl_type, GeoPTypesUI8::GeoPropDataFieldMask );
01173 {
01174
01175 pcl_type->clear();
01176
01177 pcl_type->push_back( GL_TRIANGLES );
01178
01179 if( b_show_trimming )
01180 {
01181 for( ui_loop = 0; ui_loop < cui_loop_cnt; ++ui_loop )
01182 {
01183 pcl_type->push_back( GL_TRIANGLE_STRIP );
01184 }
01185 }
01186 }
01187 endEditCP( pcl_type, GeoPTypesUI8::GeoPropDataFieldMask );
01188
01189 beginEditCP( pcl_size, GeoPLengthsUI32::GeoPropDataFieldMask );
01190 {
01191 pcl_size->clear();
01192 pcl_size->push_back( 3 * cui_faces );
01193 ui_idx = 3 * cui_faces;
01194 if ( b_show_trimming )
01195 {
01196 for( ui_loop = 0; ui_loop < cui_loop_cnt; ++ui_loop )
01197 {
01198 pcl_size->push_back( 2 + 2 * pt_surfdata->vvclEdgeLoops[ ui_loop ].size( ) );
01199 ui_idx += 2 + 2 * pt_surfdata->vvclEdgeLoops[ ui_loop ].size( );
01200 }
01201 }
01202
01203 }
01204 endEditCP( pcl_size, GeoPLengthsUI32::GeoPropDataFieldMask );
01205
01206
01207 beginEditCP( pcl_points, GeoPositions3f::GeoPropDataFieldMask );
01208 {
01209 pcl_points->clear();
01210 for( ui_vert = 0; ui_vert < cui_verts; ++ui_vert )
01211 {
01212 if( vi_new_idx[ ui_vert ] >= 0 )
01213 {
01214 pcl_points->push_back( gverts[ ui_vert ] );
01215 }
01216 }
01217 if( b_show_trimming )
01218 {
01219 for( ui_loop = 0; ui_loop < cui_loop_cnt; ++ui_loop )
01220 {
01221 ui_vertex_cnt = pt_surfdata->vvclEdgeLoops[ ui_loop ].size( );
01222 for( ui_vert = 0; ui_vert < ui_vertex_cnt; ++ui_vert )
01223 {
01224 pcl_points->push_back( Pnt3f( pt_surfdata->vvclEdgeLoops3D[ ui_loop ][ ui_vert ][0],
01225 pt_surfdata->vvclEdgeLoops3D[ ui_loop ][ ui_vert ][1],
01226 pt_surfdata->vvclEdgeLoops3D[ ui_loop ][ ui_vert ][2] ) );
01227 pcl_points->push_back( Pnt3f( pt_surfdata->vvclEdgeLoops3D[ ui_loop ][ ui_vert ][0],
01228 pt_surfdata->vvclEdgeLoops3D[ ui_loop ][ ui_vert ][1],
01229 pt_surfdata->vvclEdgeLoops3D[ ui_loop ][ ui_vert ][2] ) );
01230 }
01231 }
01232 }
01233 }
01234 endEditCP( pcl_points, GeoPositions3f::GeoPropDataFieldMask );
01235
01236
01237 if( norms.size( ) > 0 )
01238 {
01239 beginEditCP( pcl_norms, GeoNormals3f::GeoPropDataFieldMask );
01240 {
01241 pcl_norms->clear();
01242 for( ui_vert = 0; ui_vert < cui_verts; ++ui_vert )
01243 {
01244 if( vi_new_idx[ ui_vert ] >= 0 )
01245 {
01246 pcl_norms->push_back( norms[ ui_vert ] );
01247 }
01248 }
01249 if( b_show_trimming )
01250 {
01251 for( ui_loop = 0; ui_loop < cui_loop_cnt; ++ui_loop )
01252 {
01253 ui_vertex_cnt = pt_surfdata->vvclEdgeLoops[ ui_loop ].size( );
01254 for( ui_vert = 0; ui_vert < ui_vertex_cnt; ++ui_vert )
01255 {
01256 pcl_norms->push_back( Vec3f( pt_surfdata->vvclEdgeLoopsNorm[ ui_loop ][ ui_vert ][0],
01257 pt_surfdata->vvclEdgeLoopsNorm[ ui_loop ][ ui_vert ][1],
01258 pt_surfdata->vvclEdgeLoopsNorm[ ui_loop ][ ui_vert ][2] ) );
01259 pcl_norms->push_back( Vec3f( pt_surfdata->vvclEdgeLoopsNorm[ ui_loop ][ ui_vert ][0],
01260 pt_surfdata->vvclEdgeLoopsNorm[ ui_loop ][ ui_vert ][1],
01261 pt_surfdata->vvclEdgeLoopsNorm[ ui_loop ][ ui_vert ][2] ) );
01262 }
01263 }
01264 }
01265 }
01266 endEditCP( pcl_norms, GeoNormals3f::GeoPropDataFieldMask );
01267
01268 }
01269
01270 if( texcoords.size( ) > 0 )
01271 {
01272 beginEditCP( pcl_texcoords, GeoTexCoords2f::GeoPropDataFieldMask );
01273 {
01274 pcl_texcoords->clear();
01275 for( ui_vert = 0; ui_vert < cui_verts; ++ui_vert )
01276 {
01277 if( vi_new_idx[ ui_vert ] >= 0 )
01278 {
01279 pcl_texcoords->push_back( Vec2f( texcoords[ ui_vert ][ 0 ],
01280 texcoords[ ui_vert ][ 1 ] ) );
01281
01282
01283 }
01284 }
01285 if ( b_show_trimming )
01286 {
01287 for( ui_loop = 0; ui_loop < cui_loop_cnt; ++ui_loop )
01288 {
01289 ui_vertex_cnt = pt_surfdata->vvclEdgeLoops[ ui_loop ].size( );
01290 for( ui_vert = 0; ui_vert < ui_vertex_cnt; ++ui_vert )
01291 {
01292 pcl_texcoords->push_back( Vec2f( pt_surfdata->vvclEdgeLoopsTex[ ui_loop ][ ui_vert ][0],
01293 pt_surfdata->vvclEdgeLoopsTex[ ui_loop ][ ui_vert ][1] ) );
01294 pcl_texcoords->push_back( Vec2f( pt_surfdata->vvclEdgeLoopsTex[ ui_loop ][ ui_vert ][0],
01295 pt_surfdata->vvclEdgeLoopsTex[ ui_loop ][ ui_vert ][1] ) );
01296 }
01297 }
01298 }
01299 }
01300 endEditCP( pcl_texcoords, GeoTexCoords2f::GeoPropDataFieldMask );
01301 }
01302
01303 if( b_show_trimming )
01304 {
01305 beginEditCP( pcl_tangents, GeoTexCoords3f::GeoPropDataFieldMask );
01306 {
01307 pcl_tangents->clear();
01308 for( ui_vert = 0; ui_vert < cui_verts; ++ui_vert )
01309 {
01310 if( vi_new_idx[ ui_vert ] >= 0 )
01311 {
01312 pcl_tangents->getFieldPtr( )->push_back( Vec3f( 0.0, 0.0, 0.0 ) );
01313 }
01314 }
01315 for( ui_loop = 0; ui_loop < cui_loop_cnt; ++ui_loop )
01316 {
01317 ui_vertex_cnt = pt_surfdata->vvclEdgeLoops[ ui_loop ].size( );
01318 for( ui_vert = 0; ui_vert < ui_vertex_cnt; ++ui_vert )
01319 {
01320 if( ui_vert == 0 )
01321 {
01322 pcl_prevv = &pt_surfdata->vvclEdgeLoops3D[ ui_loop ][ ui_vertex_cnt - 1 ];
01323 pcl_nextv = &pt_surfdata->vvclEdgeLoops3D[ ui_loop ][ 1 ];
01324 }
01325 else if ( ui_vert == ui_vertex_cnt - 1 )
01326 {
01327 pcl_prevv = &pt_surfdata->vvclEdgeLoops3D[ ui_loop ][ ui_vert - 1 ];
01328 pcl_nextv = &pt_surfdata->vvclEdgeLoops3D[ ui_loop ][ 0 ];
01329 }
01330 else
01331 {
01332 pcl_prevv = &pt_surfdata->vvclEdgeLoops3D[ ui_loop ][ ui_vert - 1 ];
01333 pcl_nextv = &pt_surfdata->vvclEdgeLoops3D[ ui_loop ][ ui_vert + 1 ];
01334 }
01335 pcl_actv = &pt_surfdata->vvclEdgeLoops3D[ ui_loop ][ ui_vert ];
01336
01337
01338
01339 cl_v1[0] = (*pcl_nextv)[0] - (*pcl_actv)[0];
01340 cl_v1[1] = (*pcl_nextv)[1] - (*pcl_actv)[1];
01341 cl_v1[2] = (*pcl_nextv)[2] - (*pcl_actv)[2];
01342 cl_v1.normalize();
01343 cl_v2[0] = (*pcl_actv)[0] - (*pcl_prevv)[0];
01344 cl_v2[1] = (*pcl_actv)[1] - (*pcl_prevv)[1];
01345 cl_v2[2] = (*pcl_actv)[2] - (*pcl_prevv)[2];
01346 cl_v2.normalize();
01347 cl_tangent = cl_v1 + cl_v2;
01348 cl_tangent.normalize( );
01349
01350 cl_tangent *= sqrt( getError( ) );
01351
01352 pcl_tangents->getFieldPtr( )->push_back( -cl_tangent );
01353 pcl_tangents->getFieldPtr( )->push_back( cl_tangent );
01354 }
01355 }
01356 }
01357 endEditCP( pcl_tangents, GeoTexCoords3f::GeoPropDataFieldMask );
01358
01359 }
01360
01361 beginEditCP( pcl_indices, GeoIndicesUI32::GeoPropDataFieldMask );
01362 {
01363 pcl_indices->clear();
01364 for( ui_face = 0; ui_face < cui_faces; ++ui_face )
01365 {
01366 pcl_face = &triangles[ ui_face ];
01367 if( ( norms.size( ) == 0 ) ||
01368 ( checkOrient( pcl_face->vertices[ 0 ],
01369 pcl_face->vertices[ 1 ],
01370 pcl_face->vertices[ 2 ], gverts, norms ) ) )
01371 {
01372 pcl_indices->push_back( vi_new_idx[ pcl_face->vertices[ 0 ] ] );
01373 pcl_indices->push_back( vi_new_idx[ pcl_face->vertices[ 1 ] ] );
01374 pcl_indices->push_back( vi_new_idx[ pcl_face->vertices[ 2 ] ] );
01375 }
01376 else
01377 {
01378 pcl_indices->push_back( vi_new_idx[ pcl_face->vertices[ 0 ] ] );
01379 pcl_indices->push_back( vi_new_idx[ pcl_face->vertices[ 2 ] ] );
01380 pcl_indices->push_back( vi_new_idx[ pcl_face->vertices[ 1 ] ] );
01381 }
01382 }
01383 ui_idx = ui_used;
01384 if( b_show_trimming )
01385 {
01386 for( ui_loop = 0; ui_loop < cui_loop_cnt; ++ui_loop )
01387 {
01388 ui_vertex_cnt = pt_surfdata->vvclEdgeLoops[ ui_loop ].size( );
01389 for( ui_vert = 0; ui_vert < ui_vertex_cnt; ++ui_vert )
01390 {
01391 pcl_indices->push_back( ui_idx++ );
01392 pcl_indices->push_back( ui_idx++ );
01393 }
01394 pcl_indices->push_back( ui_idx - 2 * ui_vertex_cnt );
01395 pcl_indices->push_back( ui_idx - 2 * ui_vertex_cnt + 1 );
01396 }
01397
01398 }
01399 }
01400 endEditCP( pcl_indices, GeoIndicesUI32::GeoPropDataFieldMask );
01401
01402
01403 if( b_show_trimming )
01404 {
01405 if( norms.size( ) > 0 )
01406 {
01407 if( texcoords.size( ) > 0 )
01408 {
01409 beginEditCP( thisPtr, Geometry::TypesFieldMask |
01410 Geometry::LengthsFieldMask |
01411 Geometry::IndicesFieldMask |
01412 Geometry::PositionsFieldMask |
01413 Geometry::NormalsFieldMask |
01414 Geometry::TexCoordsFieldMask |
01415 Geometry::IndexMappingFieldMask |
01416 Geometry::TexCoords1FieldMask );
01417 {
01418 setTypes( pcl_type );
01419 setLengths( pcl_size );
01420 setIndices( pcl_indices );
01421
01422 setPositions( pcl_points );
01423 setNormals( pcl_norms );
01424 setTexCoords( pcl_tangents );
01425 setTexCoords1( pcl_texcoords );
01426
01427 calcIndexMapping();
01428
01429 }
01430 endEditCP( thisPtr, Geometry::TypesFieldMask |
01431 Geometry::LengthsFieldMask |
01432 Geometry::IndicesFieldMask |
01433 Geometry::PositionsFieldMask |
01434 Geometry::NormalsFieldMask |
01435 Geometry::TexCoordsFieldMask |
01436 Geometry::IndexMappingFieldMask |
01437 Geometry::TexCoords1FieldMask );
01438 }
01439 else
01440 {
01441 beginEditCP( thisPtr, Geometry::TypesFieldMask |
01442 Geometry::LengthsFieldMask |
01443 Geometry::IndicesFieldMask |
01444 Geometry::PositionsFieldMask |
01445 Geometry::NormalsFieldMask |
01446 Geometry::IndexMappingFieldMask |
01447 Geometry::TexCoordsFieldMask |
01448 Geometry::TexCoords1FieldMask );
01449 {
01450 setTypes( pcl_type );
01451 setLengths( pcl_size );
01452 setIndices( pcl_indices );
01453
01454 setPositions( pcl_points );
01455 setNormals( pcl_norms );
01456 setTexCoords( pcl_tangents );
01457
01458 calcIndexMapping();
01459
01460 }
01461 endEditCP( thisPtr, Geometry::TypesFieldMask |
01462 Geometry::LengthsFieldMask |
01463 Geometry::IndicesFieldMask |
01464 Geometry::PositionsFieldMask |
01465 Geometry::NormalsFieldMask |
01466 Geometry::IndexMappingFieldMask |
01467 Geometry::TexCoordsFieldMask |
01468 Geometry::TexCoords1FieldMask );
01469 }
01470 }
01471 else
01472 {
01473 if( texcoords.size( ) > 0 )
01474 {
01475 beginEditCP( thisPtr, Geometry::TypesFieldMask |
01476 Geometry::LengthsFieldMask |
01477 Geometry::IndicesFieldMask |
01478 Geometry::PositionsFieldMask |
01479 Geometry::TexCoordsFieldMask |
01480 Geometry::IndexMappingFieldMask |
01481 Geometry::TexCoords1FieldMask );
01482 {
01483 setTypes( pcl_type );
01484 setLengths( pcl_size );
01485 setIndices( pcl_indices );
01486
01487 setPositions( pcl_points );
01488 setTexCoords( pcl_tangents );
01489 setTexCoords1( pcl_texcoords );
01490
01491 calcIndexMapping();
01492
01493 }
01494 endEditCP( thisPtr, Geometry::TypesFieldMask |
01495 Geometry::LengthsFieldMask |
01496 Geometry::IndicesFieldMask |
01497 Geometry::PositionsFieldMask |
01498 Geometry::TexCoordsFieldMask |
01499 Geometry::IndexMappingFieldMask |
01500 Geometry::TexCoords1FieldMask );
01501 }
01502 else
01503
01504 {
01505 beginEditCP( thisPtr, Geometry::TypesFieldMask |
01506 Geometry::LengthsFieldMask |
01507 Geometry::IndicesFieldMask |
01508 Geometry::PositionsFieldMask |
01509 Geometry::IndexMappingFieldMask |
01510 Geometry::TexCoordsFieldMask |
01511 Geometry::TexCoords1FieldMask );
01512 {
01513 setTypes( pcl_type );
01514 setLengths( pcl_size );
01515 setIndices( pcl_indices );
01516
01517 setPositions( pcl_points );
01518 setTexCoords( pcl_tangents );
01519
01520 calcIndexMapping();
01521
01522
01523 }
01524 endEditCP( thisPtr, Geometry::TypesFieldMask |
01525 Geometry::LengthsFieldMask |
01526 Geometry::IndicesFieldMask |
01527 Geometry::PositionsFieldMask |
01528 Geometry::IndexMappingFieldMask |
01529 Geometry::TexCoordsFieldMask |
01530 Geometry::TexCoords1FieldMask );
01531 }
01532 }
01533 }
01534 else
01535 {
01536 if( norms.size( ) > 0 )
01537 {
01538 if( texcoords.size( ) > 0 )
01539 {
01540 beginEditCP( thisPtr, Geometry::TypesFieldMask |
01541 Geometry::LengthsFieldMask |
01542 Geometry::IndicesFieldMask |
01543 Geometry::PositionsFieldMask |
01544 Geometry::NormalsFieldMask |
01545 Geometry::TexCoordsFieldMask |
01546 Geometry::IndexMappingFieldMask );
01547 {
01548 setTypes( pcl_type );
01549 setLengths( pcl_size );
01550 setIndices( pcl_indices );
01551
01552 setPositions( pcl_points );
01553 setNormals( pcl_norms );
01554 setTexCoords( pcl_texcoords );
01555
01556 calcIndexMapping();
01557
01558
01559 }
01560 endEditCP( thisPtr, Geometry::TypesFieldMask |
01561 Geometry::LengthsFieldMask |
01562 Geometry::IndicesFieldMask |
01563 Geometry::PositionsFieldMask |
01564 Geometry::NormalsFieldMask |
01565 Geometry::TexCoordsFieldMask |
01566 Geometry::IndexMappingFieldMask );
01567 }
01568 else
01569 {
01570 beginEditCP( thisPtr, Geometry::TypesFieldMask |
01571 Geometry::LengthsFieldMask |
01572 Geometry::IndicesFieldMask |
01573 Geometry::PositionsFieldMask |
01574 Geometry::NormalsFieldMask |
01575 Geometry::IndexMappingFieldMask );
01576 {
01577 setTypes( pcl_type );
01578 setLengths( pcl_size );
01579 setIndices( pcl_indices );
01580
01581 setPositions( pcl_points );
01582 setNormals( pcl_norms );
01583
01584 calcIndexMapping();
01585 }
01586 endEditCP( thisPtr, Geometry::TypesFieldMask |
01587 Geometry::LengthsFieldMask |
01588 Geometry::IndicesFieldMask |
01589 Geometry::PositionsFieldMask |
01590 Geometry::NormalsFieldMask |
01591 Geometry::IndexMappingFieldMask );
01592 }
01593 }
01594 else
01595 {
01596 if( texcoords.size( ) > 0 )
01597 {
01598 beginEditCP( thisPtr, Geometry::TypesFieldMask |
01599 Geometry::LengthsFieldMask |
01600 Geometry::IndicesFieldMask |
01601 Geometry::PositionsFieldMask |
01602 Geometry::TexCoordsFieldMask |
01603 Geometry::IndexMappingFieldMask );
01604 {
01605 setTypes( pcl_type );
01606 setLengths( pcl_size );
01607 setIndices( pcl_indices );
01608
01609 setPositions( pcl_points );
01610 setTexCoords( pcl_texcoords );
01611
01612 calcIndexMapping();
01613 }
01614 endEditCP( thisPtr, Geometry::TypesFieldMask |
01615 Geometry::LengthsFieldMask |
01616 Geometry::IndicesFieldMask |
01617 Geometry::PositionsFieldMask |
01618 Geometry::TexCoordsFieldMask |
01619 Geometry::IndexMappingFieldMask );
01620 }
01621 else
01622 {
01623 beginEditCP( thisPtr, Geometry::TypesFieldMask |
01624 Geometry::LengthsFieldMask |
01625 Geometry::IndicesFieldMask |
01626 Geometry::PositionsFieldMask |
01627 Geometry::IndexMappingFieldMask );
01628 {
01629 setTypes( pcl_type );
01630 setLengths( pcl_size );
01631 setIndices( pcl_indices );
01632
01633 setPositions( pcl_points );
01634
01635 calcIndexMapping();
01636 }
01637 endEditCP( thisPtr, Geometry::TypesFieldMask |
01638 Geometry::LengthsFieldMask |
01639 Geometry::IndicesFieldMask |
01640 Geometry::PositionsFieldMask |
01641 Geometry::IndexMappingFieldMask );
01642 }
01643 }
01644 }
01645
01646
01647
01648
01649
01650
01651
01652
01653 return 0;
01654 }
01655
01656
01657
01658 bool Surface::checkOrient( UInt32 ui_v1, UInt32 ui_v2, UInt32 ui_v3,
01659 std::vector< Pnt3f > &m_vclGlobalVertices,
01660 std::vector< Vec3f > &m_vclNormal )
01661 {
01662 const Vec3f ccl_norm_p = m_vclNormal[ ui_v1 ] + m_vclNormal[ ui_v2 ] + m_vclNormal[ ui_v3 ];
01663 const Vec3f ccl_vec1 = m_vclGlobalVertices[ ui_v2 ] - m_vclGlobalVertices[ ui_v1 ];
01664 const Vec3f ccl_vec2 = m_vclGlobalVertices[ ui_v3 ] - m_vclGlobalVertices[ ui_v1 ];
01665 const Vec3f ccl_norm_t = ccl_vec1.cross( ccl_vec2 );
01666
01667
01668 return( ccl_norm_p.dot( ccl_norm_t ) > 0.0 );
01669 }
01670
01671
01673
01694 void Surface::addCurve( UInt32 dim,
01695 std::vector<Real64>& knots,
01696 std::vector<Pnt2f>& controlpoints,
01697 bool newloop)
01698 {
01699 UInt32 cpsize = controlpoints.size();
01700 std::vector<Pnt3f> ratcontrolpoints;
01701
01702 ratcontrolpoints.reserve( cpsize );
01703 for (UInt32 i = 0; i < cpsize; ++i )
01704 {
01705 ratcontrolpoints.push_back( Pnt3f(controlpoints[i][0],
01706 controlpoints[i][1],
01707 1.0f) );
01708 }
01709 addCurve(dim, knots, ratcontrolpoints, newloop);
01710 }
01711
01713
01734 void Surface::addCurve( UInt32 dim,
01735 std::vector<Real64>& knots,
01736 std::vector<Pnt3f>& controlpoints,
01737 bool newloop)
01738 {
01739 UInt32 cpsize = controlpoints.size();
01740 UInt32 knotsize = knots.size();
01741
01742 if ( dim + cpsize + 1 != knotsize )
01743 {
01744
01745 return;
01746 }
01747
01748
01749 if ( _sfNumCurves.getValue() == 0 )
01750 {
01751
01752
01753 newloop = true;
01754 }
01755 _mfDimensions.push_back( dim );
01756 if ( newloop )
01757 {
01758 _mfCurvesPerLoop.push_back( 1 );
01759
01760 }
01761 else
01762 {
01763
01764 UInt32 cplsize = _mfCurvesPerLoop.size();
01765
01766
01767 _mfCurvesPerLoop[ cplsize - 1 ] = _mfCurvesPerLoop[ cplsize - 1 ] + 1;
01768 }
01769 _mfKnotLengths.push_back( knotsize );
01770 UInt32 i;
01771 for ( i = 0; i < knotsize; ++i )
01772 {
01773 _mfKnots.push_back( (Real32) knots[ i ] );
01774 }
01775 for ( i = 0; i < cpsize; ++i )
01776 {
01777 _mfCurveControlPoints.push_back( controlpoints[ i ] );
01778 }
01779 _sfNumCurves.setValue( _sfNumCurves.getValue() + 1 );
01780 }
01781
01783
01791 void Surface::removeCurves( void )
01792 {
01793 if ( _sfNumCurves.getValue() == 0 )
01794 {
01795 return;
01796 }
01797
01798 _sfNumCurves.setValue(0);
01799 _mfKnotLengths.clear();
01800 _mfDimensions.clear();
01801 _mfCurveControlPoints.clear();
01802 _mfKnots.clear();
01803 _mfCurvesPerLoop.clear();
01804 }
01805
01806
01808 SurfacePtr Surface::clone( void )
01809 {
01810 SurfacePtr surf = Surface::create();
01811
01812 SWARNING << "Surface::clone not completely implemented!"<<endLog;
01813
01814 beginEditCP(surf);
01815 {
01816 if (getMFKnotsU() != NULL)
01817 {
01818 surf->getMFKnotsU()->setValues(*getMFKnotsU());
01819 }
01820 if (getMFKnotsV() != NULL)
01821 {
01822 surf->getMFKnotsV()->setValues(*getMFKnotsV());
01823 }
01824 if (getMFKnotLengths() != NULL)
01825 {
01826 surf->getMFKnotLengths()->setValues(*getMFKnotLengths());
01827 }
01828 if (getMFDimensions() != NULL)
01829 {
01830 surf->getMFDimensions()->setValues(*getMFDimensions());
01831 }
01832 if (getMFCurveControlPoints() != NULL)
01833 {
01834 surf->getMFCurveControlPoints()->setValues(*getMFCurveControlPoints());
01835 }
01836 if (getMFKnots() != NULL)
01837 {
01838 surf->getMFKnots()->setValues(*getMFKnots());
01839 }
01840 if (getMFCurvesPerLoop() != NULL)
01841 {
01842 surf->getMFCurvesPerLoop()->setValues(*getMFCurvesPerLoop());
01843 }
01844 surf->setMaterial (getMaterial ());
01845 surf->setDimU(getDimU());
01846 surf->setDimV(getDimV());
01847 surf->setNumCurves(getNumCurves());
01848 surf->setError(getError());
01849 surf->setIsDelaunay(getIsDelaunay());
01850 surf->setControlPoints(getControlPoints());
01851 surf->setTextureControlPoints(getTextureControlPoints());
01852 }
01853 endEditCP (surf);
01854
01855 return surf;
01856 }
01857
01858
01860
01877
01878 void Surface::readfromtso( std::istream &infile, bool useTextures )
01879 {
01880 Int32 err = 0;
01881 BSplineTrimmedSurface *cl_trimmed_surface = new BSplineTrimmedSurface;
01882 BSplineTensorSurface tensor_surface;
01883 trimmingloop trimloop;
01884
01885
01886
01887
01888
01889
01890
01891
01892
01893 err = cl_trimmed_surface->read( infile );
01894 if ( err )
01895 {
01896 SLOG << "Couldn't read surface, exiting... " << err << endLog;
01897 delete cl_trimmed_surface;
01898 return;
01899 }
01900
01901 tensor_surface = cl_trimmed_surface->getSurface();
01902 trimloop = cl_trimmed_surface->getTrimmingLoops();
01903
01904
01905 DCTPVec4dmatrix v4cps = tensor_surface.getControlPointMatrix();
01906
01907 UInt32 cpusize = v4cps.size();
01908 UInt32 cpvsize = v4cps[0].size();
01909 UInt32 k,u,v;
01910 Vec4d vec4;
01911
01912 GeoPositions4fPtr pPos;
01913
01914 if(_sfControlPoints.getValue() == NullFC)
01915 {
01916 pPos = GeoPositions4f::create();
01917
01918 SurfacePtr tmpPtr(*this);
01919
01920 beginEditCP(tmpPtr, ControlPointsFieldMask);
01921 setControlPoints(pPos);
01922 endEditCP (tmpPtr, ControlPointsFieldMask);
01923 }
01924 else
01925 {
01926 pPos = GeoPositions4fPtr::dcast(_sfControlPoints.getValue());
01927 }
01928
01929 beginEditCP(pPos, GeoPositions4f::GeoPropDataFieldMask);
01930
01931 MFPnt4f &_mfControlPoints = pPos->getField();
01932
01933
01934
01935 _mfControlPoints.clear( );
01936 for ( u = 0; u < cpusize; ++u )
01937 {
01938 for ( v = 0; v < cpvsize; ++v )
01939 {
01940
01941 vec4 = v4cps[ u ][ v ];
01942 _mfControlPoints.push_back(Pnt4f(vec4[0], vec4[1], vec4[2], vec4[3]));
01943
01944 }
01945 }
01946
01947 endEditCP(pPos, GeoPositions4f::GeoPropDataFieldMask);
01948
01949 _sfDimU.setValue( tensor_surface.getDimension_U() );
01950 _sfDimV.setValue( tensor_surface.getDimension_V() );
01951
01952 DCTPdvector knots;
01953
01954 knots = tensor_surface.getKnotVector_U();
01955 _mfKnotsU.clear();
01956 for ( u = 0; u < knots.size(); ++u )
01957 {
01958 _mfKnotsU.push_back( (Real32) knots[ u ] );
01959 }
01960 knots = tensor_surface.getKnotVector_V();
01961 _mfKnotsV.clear();
01962 for ( v = 0; v < knots.size(); ++v )
01963 {
01964 _mfKnotsV.push_back( (Real32) knots[ v ] );
01965 }
01966
01967
01968 removeCurves();
01969
01970 bool isnewloop;
01971 UInt32 actdim;
01972 std::vector<Real64> actknots;
01973 std::vector<Pnt3f> actcontrolpoints;
01974 DCTPVec3dvector v3actcps;
01975 for ( UInt32 i = 0; i < trimloop.size(); ++i )
01976 {
01977 isnewloop = true;
01978 for ( UInt32 j = 0; j < trimloop[i].size(); ++j )
01979 {
01980 actknots = trimloop[i][j].getKnotVector();
01981 actdim = trimloop[i][j].getDimension();
01982 v3actcps = trimloop[i][j].getControlPointVector();
01983 actcontrolpoints.clear();
01984 for ( UInt32 kk = 0; kk < v3actcps.size(); ++kk )
01985 {
01986 actcontrolpoints.push_back(Pnt3f(v3actcps[ kk ][0],
01987 v3actcps[ kk ][1],
01988 v3actcps[ kk ][2]));
01989 }
01990 addCurve( actdim, actknots, actcontrolpoints, isnewloop );
01991 isnewloop = false;
01992 }
01993 }
01994
01995
01996 delete cl_trimmed_surface;
01997
01998 if ( useTextures )
01999 {
02000
02001 char buffer[1024];
02002 infile >> buffer >> std::ws;
02003
02004 UInt32 numoftexcps = cpusize * cpvsize;
02005
02006
02007 GeoTexCoords2fPtr pTexPos;
02008
02009 if(_sfTextureControlPoints.getValue() == NullFC)
02010 {
02011 pTexPos = GeoTexCoords2f::create();
02012
02013 SurfacePtr tmpPtr(*this);
02014
02015 beginEditCP(tmpPtr, TextureControlPointsFieldMask);
02016 setTextureControlPoints(pTexPos);
02017 endEditCP (tmpPtr, TextureControlPointsFieldMask);
02018 }
02019 else
02020 {
02021 pTexPos = GeoTexCoords2fPtr::dcast(_sfTextureControlPoints.getValue());
02022 }
02023
02024 beginEditCP(pTexPos, GeoTexCoords2f::GeoPropDataFieldMask);
02025
02026 MFVec2f &_mfTextureControlPoints = pTexPos->getField();
02027 _mfTextureControlPoints.clear();
02028
02029 Vec2f temp;
02030 for ( UInt32 ti = 0; ti < numoftexcps; ++ti )
02031 {
02032 infile >> std::ws >> temp[0] >> std::ws >> temp[1] >> std::ws;
02033 _mfTextureControlPoints.push_back( temp );
02034 }
02035 endEditCP(pTexPos, GeoTexCoords2f::GeoPropDataFieldMask);
02036
02037 }
02038 }
02039
02040
02041
02042 void Surface::writetotso( std::ostream &outfile )
02043 {
02044 _trimmedSurface->write( outfile );
02045 }
02046
02047
02049
02053 UInt32 Surface::writetoobj( std::ostream &outfile, UInt32 offset )
02054 {
02055 unsigned int uicnt;
02056
02057 outfile << "g obj " << std::endl;
02058 GeoPositionsPtr pcl_points = getPositions();
02059 GeoNormalsPtr pcl_norms = getNormals();
02060 GeoIndicesPtr pcl_indices = getIndices();
02061 GeoTexCoordsPtr pcl_texcoords = getTexCoords();
02062 std::cerr << " indices size: " << pcl_indices->size() << std::endl;
02063 std::cerr << " points size: " << pcl_points->size() << std::endl;
02064 UInt32 ui_faces = pcl_indices->size() / 3;
02065 UInt32 uivertsize = pcl_points->size( );
02066 outfile << "# vertices " << uivertsize << std::endl;
02067
02068
02069 for ( uicnt = 0; uicnt < uivertsize; uicnt++)
02070 {
02071 Pnt3f ppp = pcl_points->getValue( uicnt );
02072
02073 outfile << "v " << ppp.x() << " " <<
02074 ppp.y() << " " <<
02075 ppp.z() << std::endl;
02076
02077 }
02078
02079 for ( uicnt = 0; uicnt < uivertsize; uicnt++)
02080 {
02081 Pnt3f ppp = pcl_norms->getValue( uicnt );
02082
02083 outfile << "vn " << ppp.x() << " " <<
02084 ppp.y() << " " <<
02085 ppp.z() << std::endl;
02086
02087 }
02088
02089 for ( uicnt = 0; uicnt < uivertsize; uicnt++)
02090 {
02091 Pnt2f ppp = pcl_texcoords->getValue( uicnt );
02092
02093 outfile << "vt " << ppp.x() << " " <<
02094 ppp.y() << " " << std::endl;
02095 }
02096
02097 outfile << "# faces " << ui_faces << std::endl;
02098
02099 for ( unsigned int uitricnt = 0; uitricnt < ui_faces; uitricnt++)
02100 {
02101 UInt32 ind1 = pcl_indices->getValue( uitricnt * 3 );
02102 UInt32 ind2 = pcl_indices->getValue( uitricnt * 3 + 1 );
02103 UInt32 ind3 = pcl_indices->getValue( uitricnt * 3 + 2 );
02104 UInt32 i1 = ind1 + offset + 1;
02105 UInt32 i2 = ind2 + offset + 1;
02106 UInt32 i3 = ind3 + offset + 1;
02107
02108 outfile << "f ";
02109 outfile << i1 << "/" << i1 << "/" << i1 << " " <<
02110 i2 << "/" << i2 << "/" << i2 << " " <<
02111 i3 << "/" << i3 << "/" << i3 << std::endl;
02112 }
02113
02114 return offset + uivertsize;
02115 }
02116
02118
02119 void Surface::dump( UInt32 ,
02120 const BitVector ) const
02121 {
02122 SLOG << "Dump Surface NI" << endLog;
02123 }
02124
02125 void Surface::onCreate(const Surface *source)
02126 {
02127
02128 if(GlobalSystemState == Startup)
02129 return;
02130
02131
02132
02133
02134 if(Thread::getAspect() != _sfIgnoreGLForAspect.getValue())
02135 {
02136 SurfacePtr tmpPtr(*this);
02137
02138 beginEditCP(tmpPtr, Surface::SurfaceGLIdFieldMask);
02139
02140 setSurfaceGLId(
02141 Window::registerGLObject(
02142 osgTypedMethodVoidFunctor2ObjCPtrPtr<SurfacePtr,
02143 Window ,
02144 UInt32>(tmpPtr,
02145 &Surface::handleGL),
02146 1));
02147
02148 endEditCP(tmpPtr, Surface::SurfaceGLIdFieldMask);
02149 }
02150
02151 Inherited::onCreate(source);
02152 }
02153
02154 void Surface::onDestroy(void)
02155 {
02156 Inherited::onDestroy();
02157
02158 SurfacePtr thisP(*this);
02159
02160 if(_sfControlPoints.getValue() != NullFC)
02161 {
02162 beginEditCP(_sfControlPoints.getValue(), Attachment::ParentsFieldMask);
02163 {
02164 _sfControlPoints.getValue()->subParent(thisP);
02165 }
02166 endEditCP(_sfControlPoints.getValue(), Attachment::ParentsFieldMask);
02167
02168 subRefCP(_sfControlPoints.getValue());
02169 }
02170
02171 if(_sfTextureControlPoints.getValue() != NullFC)
02172 {
02173 beginEditCP(_sfTextureControlPoints.getValue(), Attachment::ParentsFieldMask);
02174 {
02175 _sfTextureControlPoints.getValue()->subParent(thisP);
02176 }
02177 endEditCP(_sfTextureControlPoints.getValue(), Attachment::ParentsFieldMask);
02178
02179 subRefCP(_sfTextureControlPoints.getValue());
02180 }
02181
02182 if(getSurfaceGLId() > 0)
02183 {
02184 Window::destroyGLObject(getSurfaceGLId(), 1);
02185 }
02186 }
02187
02188 void Surface::handleGL(Window*, UInt32 idstatus)
02189 {
02190 Window::GLObjectStatusE mode;
02191 UInt32 id;
02192
02193 Window::unpackIdStatus(idstatus, id, mode);
02194
02195 if(mode == Window::initialize ||
02196 mode == Window::needrefresh ||
02197 mode == Window::reinitialize )
02198 {
02199 if((getDirtyMask() & DONTTESSELLATE) == 0x0000)
02200 {
02201 if((getDirtyMask() & TESSELLATE) != 0x0000)
02202 {
02203 tessellate( );
02204 }
02205 else if((getDirtyMask() & RETESSELLATE) != 0x0000)
02206 {
02207 reTessellate( );
02208 }
02209
02210 SurfacePtr tmpPtr(*this);
02211 beginEditCP(tmpPtr, DirtyMaskFieldMask);
02212 {
02213 getDirtyMask() &= ~(TESSELLATE | RETESSELLATE);
02214 }
02215 endEditCP (tmpPtr, DirtyMaskFieldMask);
02216 }
02217 }
02218 }
02219
02220
02221
02222
02223
02224
02225
02226
02227 void Surface::adjustVolume(Volume & volume)
02228 {
02229 GeoPositionsPtr pos = getControlPoints();
02230 bool has_zeroweights = false;
02231
02232 volume.setValid();
02233 volume.setEmpty();
02234
02235 GeoPositions3fPtr pPos = GeoPositions3fPtr::dcast(
02236 _sfControlPoints.getValue());
02237 GeoPositions4fPtr pRatPos = GeoPositions4fPtr::dcast(
02238 _sfControlPoints.getValue());
02239
02240 if(pos == NullFC)
02241 return;
02242
02243 if( pPos != NullFC )
02244 {
02245 for(UInt32 i = 0; i < pPos->size(); ++i)
02246 {
02247 volume.extendBy(pPos->getValue(i));
02248 }
02249 }
02250 else if( pRatPos != NullFC )
02251 {
02252 for(UInt32 i = 0; i < pRatPos->size(); ++i)
02253 {
02254 Pnt3f pnt;
02255
02256 if( osgabs( pRatPos->getFieldPtr()->getValue(i)[3] ) > DCTP_EPS )
02257 {
02258 pnt[0] = pRatPos->getFieldPtr()->getValue(i)[0] / pRatPos->getFieldPtr()->getValue(i)[3];
02259 pnt[1] = pRatPos->getFieldPtr()->getValue(i)[1] / pRatPos->getFieldPtr()->getValue(i)[3];
02260 pnt[2] = pRatPos->getFieldPtr()->getValue(i)[2] / pRatPos->getFieldPtr()->getValue(i)[3];
02261 volume.extendBy(pnt);
02262 }
02263 else
02264 {
02265 has_zeroweights = true;
02266 }
02267 }
02268 }
02269 if (has_zeroweights)
02270 {
02271 GeoPositionsPtr points = getPositions();
02272 if (points != NullFC)
02273 {
02274 for(UInt32 i = 0; i < points->size(); ++i)
02275 {
02276 volume.extendBy(points->getValue(i));
02277 }
02278 }
02279
02280
02281
02282
02283
02284
02285
02286 }
02287 }
02288
02289 void Surface::forceTessellate(void)
02290 {
02291 SurfacePtr tmpPtr(*this);
02292
02293 beginEditCP(tmpPtr, DirtyMaskFieldMask);
02294 {
02295 getDirtyMask() |= DONTTESSELLATE;
02296
02297 if((getDirtyMask() & TESSELLATE) != 0x0000)
02298 {
02299 tessellate( );
02300 }
02301 else if((getDirtyMask() & RETESSELLATE) != 0x0000)
02302 {
02303 reTessellate( );
02304 }
02305
02306 getDirtyMask() &= ~(TESSELLATE | RETESSELLATE);
02307 }
02308 endEditCP (tmpPtr, DirtyMaskFieldMask);
02309 }
02310
02311 void Surface::flip(void)
02312 {
02313 if(_trimmedSurface != NULL)
02314 _trimmedSurface->flip();
02315 }
02316
02317 Action::ResultE Surface::drawPrimitives(DrawActionBase *action)
02318 {
02319 action->getWindow()->validateGLObject(getSurfaceGLId());
02320
02321 return Inherited::drawPrimitives(action);
02322 }
02323
02324