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 "OSGIntersectAction.h"
00052 #include "OSGRenderAction.h"
00053 #include "OSGSimpleMaterial.h"
00054 #include "OSGFatBorderChunk.h"
00055
00056 #include "OSGGeometry.h"
00057 #include "OSGTypedGeoIntegralProperty.h"
00058 #include "OSGTypedGeoVectorProperty.h"
00059
00060 #include "OSGGeoFunctions.h"
00061
00062 #include "OSGGL.h"
00063 #include "OSGGLU.h"
00064 #include "OSGGLEXT.h"
00065
00066 #include "OSGSurface.h"
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076 #include <boost/bind.hpp>
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
00087
00088
00089
00090
00091
00092
00093
00094 const OSG::BitVector Surface::CurveFieldMask =
00095 (Surface::NumCurvesFieldMask |
00096 Surface::KnotLengthsFieldMask |
00097 Surface::DimensionsFieldMask |
00098 Surface::CurveControlPointsFieldMask |
00099 Surface::KnotsFieldMask |
00100 Surface::CurvesPerLoopFieldMask);
00101
00102 const OSG::BitVector Surface::SurfaceFieldMask =
00103 (Surface::DimUFieldMask |
00104 Surface::DimVFieldMask |
00105 Surface::KnotsUFieldMask |
00106 Surface::KnotsVFieldMask |
00107 Surface::ControlPointsFieldMask |
00108 Surface::ErrorFieldMask |
00109 Surface::IsDelaunayFieldMask |
00110 Surface::TextureControlPointsFieldMask);
00111
00112
00113
00114
00116
00117 Surface::Surface(void) :
00118 Inherited()
00119 {
00120
00121 _trimmedSurface = NULL;
00122 _surfacePatch = NULL;
00123 }
00124
00126
00127 Surface::Surface(const Surface &source) :
00128 Inherited(source)
00129 {
00130
00131
00132 _trimmedSurface = new BSplineTrimmedSurface;
00133 _surfacePatch = new CNurbsPatchSurface;
00134 }
00135
00137
00138 Surface::~Surface(void)
00139 {
00140 delete _trimmedSurface;
00141 delete _surfacePatch;
00142 }
00143
00144
00145
00146
00148
00149 void Surface::initMethod(InitPhase ePhase)
00150 {
00151 Inherited::initMethod(ePhase);
00152
00153 if(ePhase == TypeObject::SystemPost)
00154 {
00155 RenderAction::registerEnterDefault(
00156 getClassType(),
00157 reinterpret_cast<Action::Callback>(&Geometry::renderActionEnterHandler));
00158
00159 RenderAction::registerLeaveDefault(
00160 getClassType(),
00161 reinterpret_cast<Action::Callback>(&Geometry::renderActionLeaveHandler));
00162
00163 IntersectAction::registerEnterDefault(
00164 getClassType(),
00165 reinterpret_cast<Action::Callback>(&Geometry::intersect));
00166
00167
00168 ::exactinit();
00169
00170
00171 CErrorQuadTree::m_sbNormalApproximation = true;
00172 }
00173 }
00174
00176
00177 void Surface::changed(ConstFieldMaskArg whichField,
00178 UInt32 origin,
00179 BitVector detail)
00180 {
00181 if( (whichField & DimUFieldMask) ||
00182 (whichField & DimVFieldMask) ||
00183 (whichField & KnotsUFieldMask) ||
00184 (whichField & KnotsVFieldMask) ||
00185 (whichField & ControlPointsFieldMask) ||
00186 (whichField & NumCurvesFieldMask) ||
00187 (whichField & KnotLengthsFieldMask) ||
00188 (whichField & DimensionsFieldMask) ||
00189 (whichField & CurveControlPointsFieldMask) ||
00190 (whichField & KnotsFieldMask) ||
00191 (whichField & CurvesPerLoopFieldMask) ||
00192 (whichField & TextureControlPointsFieldMask) )
00193 {
00194 editDirtyMask() |= TESSELLATE;
00195
00196 Window::refreshGLObject(getSurfaceGLId());
00197 }
00198 else if( (whichField & ErrorFieldMask) ||
00199 (whichField & IsDelaunayFieldMask) )
00200 {
00201 editDirtyMask() |= RETESSELLATE;
00202
00203 Window::refreshGLObject(getSurfaceGLId());
00204 }
00205
00206
00207
00208 Inherited::changed(whichField, origin, detail);
00209
00210
00211
00212 }
00213
00214
00216
00217
00218
00219
00220
00221 Real64 Surface::getDesiredError(Pnt3f viewPos, Real64 halfPixelSize)
00222 {
00223 Vec3f dist;
00224 Real64 distance;
00225
00226 findClosestPoint(dist, viewPos);
00227 distance = dist.squareLength();
00228
00229
00230
00231
00232
00233
00234
00235 distance = osgSqrt(distance);
00236
00237
00238
00239
00240 Real64 desired_error = halfPixelSize * distance;
00241
00242
00243
00244 if(desired_error < _max.dist(_min) * 0.001)
00245 {
00246
00247 desired_error = _max.dist(_min) * 0.001;
00248 }
00249
00250 return desired_error;
00251 }
00252
00254
00255
00256
00257
00258
00259 bool Surface::updateError(Pnt3f viewPos, Real64 halfPixelSize)
00260 {
00261 Real64 d_max_error = getDesiredError(viewPos, halfPixelSize);
00262
00263
00264
00265
00266 Real32 current_error = getError();
00267 if(d_max_error < current_error)
00268 {
00269 std::cerr << "retessellating due to too high error: " << d_max_error
00270 << " " << current_error << std::endl;
00271
00272
00273 setError(d_max_error / 2.0);
00274 }
00275 else if(d_max_error > current_error * 4.0)
00276 {
00277 std::cerr << "retessellating due to too low error: " << d_max_error
00278 << " " << current_error << std::endl;
00279
00280 setError(d_max_error / 2.0);
00281 }
00282 return true;
00283 }
00284
00285
00286
00287
00288
00289
00290
00291
00292 void Surface::findClosestPoint(Vec3f& rDist, const Pnt3f viewPos) const
00293 {
00294 const UInt32 parent_cnt = getParents().size();
00295 UInt32 parent_idx;
00296 Real64 min_dist = 1e300;
00297 Vec3f temp_dist;
00298 Real64 curr_dist;
00299
00300 for(parent_idx = 0; parent_idx < parent_cnt; ++parent_idx)
00301 {
00302 Node *parent = dynamic_cast<Node *>(getParents()[0]);
00303 const BoxVolume &bVol = parent->getVolume();
00304
00305 Pnt3f bb_min;
00306 Pnt3f bb_max;
00307
00308 bVol.getBounds(bb_min, bb_max);
00309
00310 if(viewPos[0] < bb_min[0])
00311 {
00312 temp_dist[0] = viewPos[0] - bb_min[0];
00313 }
00314 else if(viewPos[0] > bb_max[0])
00315 {
00316 temp_dist[0] = viewPos[0] - bb_max[0];
00317 }
00318 else
00319 {
00320 temp_dist[0] = 0.0;
00321 }
00322
00323 if(viewPos[1] < bb_min[1])
00324 {
00325 temp_dist[1] = viewPos[1] - bb_min[1];
00326 }
00327 else if(viewPos[1] > bb_max[1])
00328 {
00329 temp_dist[1] = viewPos[1] - bb_max[1];
00330 }
00331 else
00332 {
00333 temp_dist[1] = 0.0;
00334 }
00335
00336 if(viewPos[2] < bb_min[2])
00337 {
00338 temp_dist[2] = viewPos[2] - bb_min[2];
00339 }
00340 else if(viewPos[2] > bb_max[2])
00341 {
00342 temp_dist[2] = viewPos[2] - bb_max[2];
00343 }
00344 else
00345 {
00346 temp_dist[2] = 0.0;
00347 }
00348
00349 curr_dist = temp_dist.squareLength();
00350
00351 if(curr_dist < min_dist)
00352 {
00353 min_dist = curr_dist;
00354 rDist = temp_dist;
00355 }
00356 }
00357 }
00358
00359
00360 void Surface::findClosestPointExact(Vec3f& rDist, const Pnt3f viewPos) const
00361 {
00362
00363 const GeoPnt3fProperty *cpcl_points =
00364 dynamic_cast<const GeoPnt3fProperty *>(getPositions());
00365 const unsigned int cui_idx_cnt = cpcl_points->getSize();
00366 Pnt3f cl_pos;
00367 unsigned int ui_idx;
00368 Vec3f cl_temp;
00369 double d_min = DBL_MAX;
00370 double d_temp;
00371
00372 for(ui_idx = 0; ui_idx < cui_idx_cnt; ++ui_idx)
00373 {
00374 cl_pos = cpcl_points->getValue(ui_idx);
00375 cl_temp = cl_pos - viewPos;
00376 d_temp = cl_temp.squareLength();
00377 if(d_temp <= d_min)
00378 {
00379 d_min = d_temp;
00380 rDist = cl_temp;
00381 }
00382 }
00383 }
00384
00385
00387 void Surface::tessellate(void)
00388 {
00389
00390
00391
00392
00393 std::vector<SimplePolygon> tris;
00394 std::vector<Pnt3f> gverts;
00395 std::vector<Vec3f> norms;
00396 std::vector<Pnt2f> texturecoords;
00397
00398 Int32 err = convertSurface();
00399 if(err)
00400 {
00401
00402 return;
00403 }
00404 if(_sfTextureControlPoints.getValue() == NULL)
00405 {
00406 err = tessellateSurface(tris, gverts, norms);
00407 #ifdef OSG_NURBS_DEBUG
00408 std::cerr << "Surface::tessellate err1: " << err << " #tris: " << tris.size() << std::endl;
00409 #endif
00410 if(err)
00411 return;
00412 buildSurface(tris, gverts, norms, texturecoords);
00413 }
00414 else
00415 {
00416
00417
00418
00419
00420
00421
00422
00423 err = tessellateSurface(tris, gverts, norms, texturecoords);
00424 #ifdef OSG_NURBS_DEBUG
00425 std::cerr << "Surface::tessellate err2: " << err << " #tris: " << tris.size() << std::endl;
00426 #endif
00427 if(err)
00428 return;
00429 buildSurface(tris, gverts, norms, texturecoords);
00430 }
00431
00432
00433
00434 _volumeCache.setEmpty();
00435
00436
00437
00438
00439
00440
00441 }
00442
00444 void Surface::reTessellate(void)
00445 {
00446 std::vector<SimplePolygon> tris;
00447 std::vector<Pnt3f> gverts;
00448 std::vector<Vec3f> norms;
00449 std::vector<Pnt2f> texturecoords;
00450
00451
00452
00453
00454 if(getError() < DCTP_EPS)
00455 {
00456
00457
00458 setError(0.2f);
00459 }
00460
00461 _surfacePatch->setError(getError() );
00462
00463
00464 if(_sfTextureControlPoints.getValue() == NULL)
00465 {
00466 _surfacePatch->getTessellation(gverts, norms, tris, getIsDelaunay());
00467 buildSurface(tris, gverts, norms, texturecoords);
00468 }
00469 else
00470 {
00471
00472
00473
00474
00475
00476
00477
00478 _surfacePatch->getTessellation(gverts, norms, texturecoords,
00479 tris, getIsDelaunay());
00480 buildSurface(tris, gverts, norms, texturecoords);
00481
00482 }
00483
00484
00485
00486 _volumeCache.setEmpty();
00487
00488
00489
00490
00491 }
00492
00493
00494 Int32 Surface::convertSurface(void)
00495 {
00496
00497
00498 bool israt;
00499 const GeoPnt3fProperty *pPos =
00500 dynamic_cast<const GeoPnt3fProperty *>(getControlPoints());
00501 const GeoPnt4fProperty *pRatPos =
00502 dynamic_cast<const GeoPnt4fProperty *>(getControlPoints());
00503
00504
00505 if(getControlPoints() == NULL)
00506 {
00507 SLOG << "Surface::tessellate: null surfacecontrol prop " << endLog;
00508 return -1;
00509 }
00510
00511 if(pPos != NULL)
00512 {
00513 israt = false;
00514 }
00515 else if(pRatPos != NULL)
00516 {
00517 israt = true;
00518 }
00519 else
00520 {
00521 SLOG << "Surface::tessellate: null surfacecontrol prop " << endLog;
00522 return -1;
00523 }
00524
00525 const MFPnt3f *polyControlPoints = NULL;
00526 const MFPnt4f *ratControlPoints = NULL;
00527 UInt32 cpsize;
00528
00529 if(!israt)
00530 {
00531 polyControlPoints = &(pPos->getField());
00532 cpsize = polyControlPoints->size();
00533 }
00534 else
00535 {
00536 ratControlPoints = &(pRatPos->getField());
00537 cpsize = ratControlPoints->size();
00538 }
00539
00540
00541
00542 if(cpsize == 0)
00543 {
00544 SLOG << "Surface::tessellate: null surfacecontrol points " << endLog;
00545 return -1;
00546 }
00547
00548
00549
00550
00551
00552 UInt32 dimu = _sfDimU.getValue();
00553 UInt32 dimv = _sfDimV.getValue();
00554 if(dimu == 0 || dimv == 0)
00555 {
00556 SLOG << "Surface::tessellate: 0 dimensions " << endLog;
00557 return -1;
00558 }
00559
00560 UInt32 knotusize = _mfKnotsU.size();
00561 UInt32 knotvsize = _mfKnotsV.size();
00562 if(knotusize == 0 || knotvsize == 0)
00563 {
00564 SLOG << "Surface::tessellate: empty knotvectors " << endLog;
00565 return -1;
00566 }
00567
00568 UInt32 cpusize = knotusize - dimu - 1;
00569 UInt32 cpvsize = knotvsize - dimv - 1;
00570 if(cpusize < 1 || cpvsize < 1 || cpusize * cpvsize != cpsize)
00571 {
00572 SLOG << cpusize << "x" << cpvsize << ":" << cpsize << endLog;
00573 SLOG << "Surface::tessellate: inconsistent attributes " << endLog;
00574 return -1;
00575 }
00576
00577 if(_sfNumCurves.getValue() == 0)
00578 {
00579 Real64 umin = _mfKnotsU[0];
00580 Real64 vmin = _mfKnotsV[0];
00581 Real64 umax = _mfKnotsU[knotusize - 1];
00582 Real64 vmax = _mfKnotsV[knotvsize - 1];
00583
00584 std::vector<Real64> tmpknotvec(4);
00585 std::vector<Pnt2f> tmpcps(2);
00586 UInt32 dim = 1;
00587 tmpknotvec[0] = 0.0;
00588 tmpknotvec[1] = 0.0;
00589 tmpknotvec[2] = 1.0;
00590 tmpknotvec[3] = 1.0;
00591
00592
00593 tmpcps[0][0] = umin; tmpcps[0][1] = vmin;
00594 tmpcps[1][0] = umax; tmpcps[1][1] = vmin;
00595 addCurve(dim, tmpknotvec, tmpcps);
00596
00597
00598 tmpcps[0][0] = umax; tmpcps[0][1] = vmin;
00599 tmpcps[1][0] = umax; tmpcps[1][1] = vmax;
00600 addCurve(dim, tmpknotvec, tmpcps);
00601
00602
00603 tmpcps[0][0] = umax; tmpcps[0][1] = vmax;
00604 tmpcps[1][0] = umin; tmpcps[1][1] = vmax;
00605 addCurve(dim, tmpknotvec, tmpcps);
00606
00607
00608 tmpcps[0][0] = umin; tmpcps[0][1] = vmax;
00609 tmpcps[1][0] = umin; tmpcps[1][1] = vmin;
00610 addCurve(dim, tmpknotvec, tmpcps);
00611 }
00612
00613
00614
00615
00616
00617 BSplineTensorSurface tensor_surface;
00618 UInt32 i, j, k;
00619 DCTPVec4dmatrix qnet;
00620 Vec4d vec4;
00621 qnet.resize(cpusize);
00622
00623 for(i = 0; i < cpusize; ++i)
00624 {
00625 qnet[i].resize(cpvsize);
00626
00627 for(j = 0; j < cpvsize; ++j)
00628 {
00629 k = i * cpvsize + j;
00630 if(!israt)
00631 {
00632 vec4[0] = (*polyControlPoints)[k][0];
00633 vec4[1] = (*polyControlPoints)[k][1];
00634 vec4[2] = (*polyControlPoints)[k][2];
00635 vec4[3] = 1.0f;
00636
00637
00638 }
00639 else
00640 {
00641 vec4[0] = (*ratControlPoints)[k][0];
00642 vec4[1] = (*ratControlPoints)[k][1];
00643 vec4[2] = (*ratControlPoints)[k][2];
00644 vec4[3] = (*ratControlPoints)[k][3];
00645
00646
00647 }
00648 qnet[i][j] = vec4;
00649 }
00650 }
00651
00652 tensor_surface.setControlPointMatrix(qnet);
00653
00654 DCTPdvector knotuvec(knotusize);
00655 DCTPdvector knotvvec(knotvsize);
00656
00657 for(i = 0; i < knotusize; ++i)
00658 {
00659 knotuvec[i] = _mfKnotsU[i];
00660 }
00661
00662 for(i = 0; i < knotvsize; ++i)
00663 {
00664 knotvvec[i] = _mfKnotsV[i];
00665 }
00666
00667 tensor_surface.setKnotsAndDimension(knotuvec, dimu, knotvvec, dimv);
00668
00669
00670 _trimmedSurface->setSurface(tensor_surface);
00671
00672
00673
00674 trimmingloop trimloops;
00675 UInt32 cplsize = _mfCurvesPerLoop.size();
00676 trimloops.resize(cplsize);
00677
00678 for(i = 0; i < cplsize; ++i)
00679 {
00680 trimloops[i].resize(_mfCurvesPerLoop[i]);
00681 }
00682
00683 UInt32 actknotoffset = 0;
00684 UInt32 actcpoffset = 0;
00685
00686 UInt32 actcurveno = 0;
00687 UInt32 acttrimcpsize = 0;
00688 DCTPdvector actknots;
00689 DCTPVec3dvector acttrimcps;
00690 BSplineCurve2D actcurve;
00691
00692 for(i = 0; i < trimloops.size(); ++i)
00693 {
00694 for(j = 0; j < trimloops[i].size(); ++j)
00695 {
00696 actknots.resize(_mfKnotLengths[actcurveno]);
00697
00698
00699
00700 acttrimcpsize = actknots.size() - _mfDimensions[actcurveno] - 1;
00701 if(acttrimcpsize < 1)
00702 {
00703 SLOG << "Surface::tessellate: wrong trimming curve attributes "
00704 << endLog;
00705 return -1;
00706 }
00707 acttrimcps.resize(acttrimcpsize);
00708
00709 for(k = 0; k < actknots.size(); ++k)
00710 {
00711 actknots[k] = _mfKnots[actknotoffset + k];
00712 }
00713
00714 actknotoffset += actknots.size();
00715 actcurve.setKnotsAndDimension(actknots,
00716 _mfDimensions[actcurveno]);
00717
00718
00719
00720
00721
00722
00723
00724 for(k = 0; k < acttrimcpsize; ++k)
00725 {
00726
00727 acttrimcps[k][0] = _mfCurveControlPoints[actcpoffset + k][0];
00728 acttrimcps[k][1] = _mfCurveControlPoints[actcpoffset + k][1];
00729 acttrimcps[k][2] = _mfCurveControlPoints[actcpoffset + k][2];
00730 }
00731
00732 actcpoffset += acttrimcpsize;
00733 actcurve.setControlPointVector(acttrimcps);
00734
00735 trimloops[i][j] = actcurve;
00736 actcurveno++;
00737 }
00738
00739 }
00740
00741 _trimmedSurface->setTrimmingLoops(trimloops);
00742 _trimmedSurface->normalize();
00743
00744
00745 return 0;
00746 }
00747
00748
00749
00750
00751 Int32 Surface::tessellateSurface(std::vector<SimplePolygon> &triangles,
00752 std::vector<Pnt3f> & gverts,
00753 std::vector<Vec3f> & norms)
00754 {
00755
00756
00757
00758 std::vector<Pnt2f> dummy;
00759 _surfacePatch->setSurface(_trimmedSurface, dummy, false);
00760
00761 if(_sfError.getValue() < DCTP_EPS)
00762 {
00763
00764
00765 _sfError.setValue(0.2f);
00766 }
00767
00768 _surfacePatch->setError(_sfError.getValue() );
00769 _surfacePatch->getTessellation(gverts, norms, triangles, getIsDelaunay() );
00770 SSurface *surfaceData = _surfacePatch->getSurfaceData();
00771 _min = Pnt3d(surfaceData->clMin[0], surfaceData->clMin[1],
00772 surfaceData->clMin[2]);
00773 _max = Pnt3d(surfaceData->clMax[0], surfaceData->clMax[1],
00774 surfaceData->clMax[2]);
00775 #ifdef OSG_ARBITRARY_SPLIT
00776 _minParam = Pnt2d(surfaceData->clMinParam[0], surfaceData->clMinParam[1]);
00777 _maxParam = Pnt2d(surfaceData->clMaxParam[0], surfaceData->clMaxParam[1]);
00778 #endif
00779
00780
00781
00782
00783
00784 return 0;
00785 }
00786
00787
00788
00789 Int32 Surface::tessellateSurface(std::vector<SimplePolygon> &triangles,
00790 std::vector<Pnt3f> & gverts,
00791 std::vector<Vec3f> & norms,
00792 std::vector<Pnt2f> & texcoords)
00793 {
00794
00795
00796
00797 const GeoVec2fProperty *pTexPos = dynamic_cast<const GeoVec2fProperty *>(
00798 getTextureControlPoints());
00799 std::vector<Pnt2f> tmptexcoords;
00800 UInt32 i;
00801 UInt32 s = pTexPos->getField().size();
00802
00803 for(i = 0; i < s; ++i)
00804 {
00805 tmptexcoords.push_back(Pnt2f(pTexPos->getField()[i][0],
00806 pTexPos->getField()[i][1]));
00807 }
00808
00809 _surfacePatch->setSurface(_trimmedSurface, tmptexcoords, true);
00810 if(_sfError.getValue() < DCTP_EPS)
00811 {
00812
00813
00814 _sfError.setValue(0.2f);
00815 }
00816
00817 _surfacePatch->setError(_sfError.getValue() );
00818 _surfacePatch->getTessellation(gverts, norms, texcoords, triangles, getIsDelaunay() );
00819
00820
00821
00822 SSurface *surfaceData = _surfacePatch->getSurfaceData();
00823 _min = Pnt3d(surfaceData->clMin[0], surfaceData->clMin[1],
00824 surfaceData->clMin[2]);
00825 _max = Pnt3d(surfaceData->clMax[0], surfaceData->clMax[1],
00826 surfaceData->clMax[2]);
00827 #ifdef OSG_ARBITRARY_SPLIT
00828 _minParam = Pnt2d(surfaceData->clMinParam[0], surfaceData->clMinParam[1]);
00829 _maxParam = Pnt2d(surfaceData->clMaxParam[0], surfaceData->clMaxParam[1]);
00830 #endif
00831
00832
00833
00834
00835
00836 return 0;
00837 }
00838
00839
00840
00841 Int32 Surface::tessellateSurface(std::vector<SimplePolygon> &triangles,
00842 std::vector<Pnt3f> & gverts,
00843 std::vector<Pnt2f> & texcoords)
00844 {
00845
00846
00847
00848 const GeoVec2fProperty *pTexPos = dynamic_cast<const GeoVec2fProperty *>(
00849 getTextureControlPoints());
00850 std::vector<Pnt2f> tmptexcoords;
00851 UInt32 i;
00852 UInt32 s = pTexPos->getField().size();
00853
00854 for(i = 0; i < s; ++i)
00855 {
00856 tmptexcoords.push_back(Pnt2f(pTexPos->getField()[i][0],
00857 pTexPos->getField()[i][1]));
00858 }
00859
00860 _surfacePatch->setSurface(_trimmedSurface,
00861 tmptexcoords,
00862 true);
00863 if(_sfError.getValue() < DCTP_EPS)
00864 {
00865
00866
00867 _sfError.setValue(0.2f);
00868 }
00869
00870 _surfacePatch->setError(_sfError.getValue());
00871 std::vector<Vec3f> norms;
00872 _surfacePatch->getTessellation(gverts, norms, triangles, false);
00873 _surfacePatch->getTessellation(gverts, texcoords, triangles, getIsDelaunay() );
00874
00875 SSurface *surfaceData = _surfacePatch->getSurfaceData();
00876 _min = Pnt3d(surfaceData->clMin[0], surfaceData->clMin[1],
00877 surfaceData->clMin[2]);
00878 _max = Pnt3d(surfaceData->clMax[0], surfaceData->clMax[1],
00879 surfaceData->clMax[2]);
00880
00881 #ifdef OSG_ARBITRARY_SPLIT
00882 _minParam = Pnt2d(surfaceData->clMinParam[0], surfaceData->clMinParam[1]);
00883 _maxParam = Pnt2d(surfaceData->clMaxParam[0], surfaceData->clMaxParam[1]);
00884 #endif
00885
00886
00887
00888
00889
00890 return 0;
00891 }
00892
00893
00894
00895 Int32 Surface::buildSurface(std::vector<SimplePolygon> &triangles,
00896 std::vector<Pnt3f> & gverts,
00897 std::vector<Vec3f> & norms,
00898 std::vector<Pnt2f> & texcoords)
00899
00900 {
00901
00902
00903
00904
00905
00906
00907
00908
00909
00910
00911
00912
00913
00914
00915
00916
00917
00918
00919 GeoIntegralPropertyUnrecPtr pcl_type = getTypes();
00920 GeoIntegralPropertyUnrecPtr pcl_size = getLengths();
00921 GeoVectorPropertyUnrecPtr pcl_points = getPositions();
00922 GeoVectorPropertyUnrecPtr pcl_norms = getNormals();
00923 GeoIntegralPropertyUnrecPtr pcl_indices = getIndices();
00924 GeoVectorPropertyUnrecPtr pcl_texcoords = getTexCoords1();
00925
00926 GeoVec3fPropertyUnrecPtr pcl_tangents =
00927 dynamic_cast<GeoVec3fProperty *>(getTexCoords());
00928 SimpleMaterialUnrecPtr pcl_mat =
00929 dynamic_cast<SimpleMaterial *>(getMaterial());
00930
00931 SimplePolygon *pcl_face;
00932 const UInt32 cui_faces = triangles.size();
00933 UInt32 ui_face;
00934 BSplineTensorSurface cl_surf = _trimmedSurface->getSurface();
00935
00936 Vec3d cl_norm;
00937 const UInt32 cui_verts = gverts.size();
00938 UInt32 ui_vert;
00939 SSurface *pt_surfdata = _surfacePatch->getSurfaceData();
00940 const UInt32 cui_loop_cnt = pt_surfdata->vvclEdgeLoops.size();
00941 UInt32 ui_loop;
00942 UInt32 ui_vertex_cnt;
00943 UInt32 ui_idx;
00944 UInt32 ui_used;
00945
00946 Vec3d *pcl_actv;
00947 Vec3d *pcl_nextv;
00948 Vec3d *pcl_prevv;
00949 Vec3f cl_v1, cl_v2, cl_tangent;
00950 std::vector<Int32> vi_new_idx(cui_verts);
00951 bool b_show_trimming = false;
00952
00953
00954 if(pcl_mat != NULL)
00955 {
00956 if(pcl_mat->find(FatBorderChunk::getClassType()) != NULL)
00957 b_show_trimming = true;
00958 }
00959
00960
00961 if(pcl_type == NULL)
00962 {
00963 pcl_type = GeoUInt8Property::create();
00964 }
00965 if(pcl_size == NULL)
00966 {
00967 pcl_size = GeoUInt32Property::create();
00968 }
00969 if(pcl_points == NULL)
00970 {
00971 pcl_points = GeoPnt3fProperty::create();
00972 }
00973 if( (norms.size() > 0) && (pcl_norms == NULL) )
00974 {
00975 pcl_norms = GeoVec3fProperty::create();
00976 }
00977 if(pcl_indices == NULL)
00978 {
00979 pcl_indices = GeoUInt32Property::create();
00980 }
00981 if( (texcoords.size() > 0) && (pcl_texcoords == NULL) )
00982 {
00983 pcl_texcoords = GeoVec2fProperty::create();
00984 }
00985 if(b_show_trimming)
00986 {
00987 if(pcl_tangents == NULL)
00988 {
00989 pcl_tangents = GeoVec3fProperty::create();
00990 }
00991 }
00992 else
00993 {
00994 if(pcl_tangents != NULL)
00995 {
00996 setTexCoords(NULL);
00997 }
00998 }
00999
01000
01001 for(ui_vert = 0; ui_vert < cui_verts; ++ui_vert)
01002 {
01003 vi_new_idx[ui_vert] = -1;
01004 }
01005
01006 for(ui_face = 0; ui_face < cui_faces; ++ui_face)
01007 {
01008 pcl_face = &triangles[ui_face];
01009 vi_new_idx[pcl_face->vertices[0]] = 0;
01010 vi_new_idx[pcl_face->vertices[1]] = 0;
01011 vi_new_idx[pcl_face->vertices[2]] = 0;
01012 }
01013
01014
01015 ui_used = 0;
01016
01017 for(ui_vert = 0; ui_vert < cui_verts; ++ui_vert)
01018 {
01019 if(vi_new_idx[ui_vert] >= 0)
01020 {
01021 vi_new_idx[ui_vert] = ui_used;
01022 ++ui_used;
01023 }
01024 }
01025
01026
01027
01028
01029
01030 pcl_type->clear();
01031
01032 pcl_type->push_back(GL_TRIANGLES);
01033
01034 if(b_show_trimming)
01035 {
01036 for(ui_loop = 0; ui_loop < cui_loop_cnt; ++ui_loop)
01037 {
01038 pcl_type->push_back(GL_TRIANGLE_STRIP);
01039 }
01040 }
01041
01042
01043 pcl_size->clear();
01044 pcl_size->push_back(3 * cui_faces);
01045 ui_idx = 3 * cui_faces;
01046 if(b_show_trimming)
01047 {
01048 for(ui_loop = 0; ui_loop < cui_loop_cnt; ++ui_loop)
01049 {
01050 pcl_size->push_back(2 + 2 * pt_surfdata->vvclEdgeLoops[ui_loop].size() );
01051 ui_idx += 2 + 2 * pt_surfdata->vvclEdgeLoops[ui_loop].size();
01052 }
01053 }
01054
01055
01056
01057 pcl_points->clear();
01058
01059 for(ui_vert = 0; ui_vert < cui_verts; ++ui_vert)
01060 {
01061 if(vi_new_idx[ui_vert] >= 0)
01062 {
01063 pcl_points->push_back(gverts[ui_vert]);
01064 }
01065 }
01066
01067 if(b_show_trimming)
01068 {
01069 for(ui_loop = 0; ui_loop < cui_loop_cnt; ++ui_loop)
01070 {
01071 ui_vertex_cnt = pt_surfdata->vvclEdgeLoops[ui_loop].size();
01072
01073 for(ui_vert = 0; ui_vert < ui_vertex_cnt; ++ui_vert)
01074 {
01075 pcl_points->push_back(
01076 Pnt3f(pt_surfdata->vvclEdgeLoops3D[ui_loop][ui_vert][0],
01077 pt_surfdata->vvclEdgeLoops3D[ui_loop][ui_vert][1],
01078 pt_surfdata->vvclEdgeLoops3D[ui_loop][ui_vert][2] ));
01079 pcl_points->push_back(
01080 Pnt3f(pt_surfdata->vvclEdgeLoops3D[ui_loop][ui_vert][0],
01081 pt_surfdata->vvclEdgeLoops3D[ui_loop][ui_vert][1],
01082 pt_surfdata->vvclEdgeLoops3D[ui_loop][ui_vert][2] ));
01083 }
01084 }
01085 }
01086
01087
01088 if(norms.size() > 0)
01089 {
01090 pcl_norms->clear();
01091
01092 for(ui_vert = 0; ui_vert < cui_verts; ++ui_vert)
01093 {
01094 if(vi_new_idx[ui_vert] >= 0)
01095 pcl_norms->push_back(norms[ui_vert]);
01096 }
01097
01098 if(b_show_trimming)
01099 {
01100 for(ui_loop = 0; ui_loop < cui_loop_cnt; ++ui_loop)
01101 {
01102 ui_vertex_cnt = pt_surfdata->vvclEdgeLoops[ui_loop].size();
01103
01104 for(ui_vert = 0; ui_vert < ui_vertex_cnt; ++ui_vert)
01105 {
01106 pcl_norms->push_back(
01107 Vec3f(pt_surfdata->vvclEdgeLoopsNorm[ui_loop][ui_vert][0],
01108 pt_surfdata->vvclEdgeLoopsNorm[ui_loop][ui_vert][1],
01109 pt_surfdata->vvclEdgeLoopsNorm[ui_loop][ui_vert][2] ));
01110 pcl_norms->push_back(
01111 Vec3f(pt_surfdata->vvclEdgeLoopsNorm[ui_loop][ui_vert][0],
01112 pt_surfdata->vvclEdgeLoopsNorm[ui_loop][ui_vert][1],
01113 pt_surfdata->vvclEdgeLoopsNorm[ui_loop][ui_vert][2] ));
01114 }
01115 }
01116 }
01117
01118 }
01119
01120 if(texcoords.size() > 0)
01121 {
01122 pcl_texcoords->clear();
01123
01124 for(ui_vert = 0; ui_vert < cui_verts; ++ui_vert)
01125 {
01126 if(vi_new_idx[ui_vert] >= 0)
01127 {
01128 pcl_texcoords->push_back(Vec2f(texcoords[ui_vert][0],
01129 texcoords[ui_vert][1]) );
01130
01131
01132 }
01133 }
01134
01135 if(b_show_trimming)
01136 {
01137 for(ui_loop = 0; ui_loop < cui_loop_cnt; ++ui_loop)
01138 {
01139 ui_vertex_cnt = pt_surfdata->vvclEdgeLoops[ui_loop].size();
01140
01141 for(ui_vert = 0; ui_vert < ui_vertex_cnt; ++ui_vert)
01142 {
01143 pcl_texcoords->push_back(
01144 Vec2f(pt_surfdata->vvclEdgeLoopsTex[ui_loop][ui_vert][0],
01145 pt_surfdata->vvclEdgeLoopsTex[ui_loop][ui_vert][1]) );
01146 pcl_texcoords->push_back(
01147 Vec2f(pt_surfdata->vvclEdgeLoopsTex[ui_loop][ui_vert][0],
01148 pt_surfdata->vvclEdgeLoopsTex[ui_loop][ui_vert][1]) );
01149 }
01150 }
01151 }
01152 }
01153
01154 if(b_show_trimming)
01155 {
01156 pcl_tangents->clear();
01157
01158 for(ui_vert = 0; ui_vert < cui_verts; ++ui_vert)
01159 {
01160 if(vi_new_idx[ui_vert] >= 0)
01161 {
01162 pcl_tangents->editFieldPtr()->push_back(Vec3f(0.0, 0.0, 0.0) );
01163 }
01164 }
01165
01166 for(ui_loop = 0; ui_loop < cui_loop_cnt; ++ui_loop)
01167 {
01168 ui_vertex_cnt = pt_surfdata->vvclEdgeLoops[ui_loop].size();
01169
01170 for(ui_vert = 0; ui_vert < ui_vertex_cnt; ++ui_vert)
01171 {
01172 if(ui_vert == 0)
01173 {
01174 pcl_prevv = &pt_surfdata->vvclEdgeLoops3D[ui_loop][ui_vertex_cnt - 1];
01175 pcl_nextv = &pt_surfdata->vvclEdgeLoops3D[ui_loop][1];
01176 }
01177 else if(ui_vert == ui_vertex_cnt - 1)
01178 {
01179 pcl_prevv = &pt_surfdata->vvclEdgeLoops3D[ui_loop][ui_vert - 1];
01180 pcl_nextv = &pt_surfdata->vvclEdgeLoops3D[ui_loop][0];
01181 }
01182 else
01183 {
01184 pcl_prevv = &pt_surfdata->vvclEdgeLoops3D[ui_loop][ui_vert - 1];
01185 pcl_nextv = &pt_surfdata->vvclEdgeLoops3D[ui_loop][ui_vert + 1];
01186 }
01187 pcl_actv = &pt_surfdata->vvclEdgeLoops3D[ui_loop][ui_vert];
01188
01189
01190
01191 cl_v1[0] = (*pcl_nextv)[0] - (*pcl_actv)[0];
01192 cl_v1[1] = (*pcl_nextv)[1] - (*pcl_actv)[1];
01193 cl_v1[2] = (*pcl_nextv)[2] - (*pcl_actv)[2];
01194 cl_v1.normalize();
01195 cl_v2[0] = (*pcl_actv)[0] - (*pcl_prevv)[0];
01196 cl_v2[1] = (*pcl_actv)[1] - (*pcl_prevv)[1];
01197 cl_v2[2] = (*pcl_actv)[2] - (*pcl_prevv)[2];
01198 cl_v2.normalize();
01199 cl_tangent = cl_v1 + cl_v2;
01200 cl_tangent.normalize();
01201
01202 cl_tangent *= sqrt(getError() );
01203
01204 pcl_tangents->editFieldPtr()->push_back(-cl_tangent);
01205 pcl_tangents->editFieldPtr()->push_back( cl_tangent);
01206 }
01207 }
01208
01209
01210 }
01211
01212 pcl_indices->clear();
01213
01214 for(ui_face = 0; ui_face < cui_faces; ++ui_face)
01215 {
01216 pcl_face = &triangles[ui_face];
01217 if( (norms.size() == 0) ||
01218 (checkOrient(pcl_face->vertices[0],
01219 pcl_face->vertices[1],
01220 pcl_face->vertices[2], gverts, norms) ) )
01221 {
01222 pcl_indices->push_back(vi_new_idx[pcl_face->vertices[0]]);
01223 pcl_indices->push_back(vi_new_idx[pcl_face->vertices[1]]);
01224 pcl_indices->push_back(vi_new_idx[pcl_face->vertices[2]]);
01225 }
01226 else
01227 {
01228 pcl_indices->push_back(vi_new_idx[pcl_face->vertices[0]]);
01229 pcl_indices->push_back(vi_new_idx[pcl_face->vertices[2]]);
01230 pcl_indices->push_back(vi_new_idx[pcl_face->vertices[1]]);
01231 }
01232 }
01233
01234 ui_idx = ui_used;
01235 if(b_show_trimming)
01236 {
01237 for(ui_loop = 0; ui_loop < cui_loop_cnt; ++ui_loop)
01238 {
01239 ui_vertex_cnt = pt_surfdata->vvclEdgeLoops[ui_loop].size();
01240
01241 for(ui_vert = 0; ui_vert < ui_vertex_cnt; ++ui_vert)
01242 {
01243 pcl_indices->push_back(ui_idx++);
01244 pcl_indices->push_back(ui_idx++);
01245 }
01246
01247 pcl_indices->push_back(ui_idx - 2 * ui_vertex_cnt);
01248 pcl_indices->push_back(ui_idx - 2 * ui_vertex_cnt + 1);
01249 }
01250
01251
01252 }
01253
01254
01255 if(b_show_trimming)
01256 {
01257 if(norms.size() > 0)
01258 {
01259 if(texcoords.size() > 0)
01260 {
01261 setTypes (pcl_type );
01262 setLengths (pcl_size );
01263 setIndices (pcl_indices );
01264
01265 setPositions (pcl_points );
01266 setNormals (pcl_norms );
01267 setTexCoords (pcl_tangents );
01268 setTexCoords1(pcl_texcoords);
01269
01270 }
01271 else
01272 {
01273 setTypes (pcl_type );
01274 setLengths (pcl_size );
01275 setIndices (pcl_indices );
01276
01277 setPositions(pcl_points );
01278 setNormals (pcl_norms );
01279 setTexCoords(pcl_tangents);
01280
01281
01282 }
01283 }
01284 else
01285 {
01286 if(texcoords.size() > 0)
01287 {
01288 setTypes (pcl_type );
01289 setLengths (pcl_size );
01290 setIndices (pcl_indices );
01291
01292 setPositions (pcl_points );
01293 setTexCoords (pcl_tangents );
01294 setTexCoords1(pcl_texcoords);
01295 }
01296 else
01297
01298 {
01299 setTypes (pcl_type );
01300 setLengths (pcl_size );
01301 setIndices (pcl_indices );
01302
01303 setPositions(pcl_points );
01304 setTexCoords(pcl_tangents);
01305
01306 }
01307 }
01308 }
01309 else
01310 {
01311 if(norms.size() > 0)
01312 {
01313 if(texcoords.size() > 0)
01314 {
01315 setTypes (pcl_type );
01316 setLengths (pcl_size );
01317 setIndices (pcl_indices );
01318
01319 setPositions(pcl_points );
01320 setNormals (pcl_norms );
01321 setTexCoords(pcl_texcoords);
01322
01323 }
01324 else
01325 {
01326 setTypes (pcl_type );
01327 setLengths (pcl_size );
01328 setIndices (pcl_indices);
01329
01330 setPositions(pcl_points );
01331 setNormals (pcl_norms );
01332 }
01333 }
01334 else
01335 {
01336 if(texcoords.size() > 0)
01337 {
01338 setTypes (pcl_type );
01339 setLengths (pcl_size );
01340 setIndices (pcl_indices );
01341
01342 setPositions(pcl_points );
01343 setTexCoords(pcl_texcoords);
01344 }
01345 else
01346 {
01347 setTypes (pcl_type );
01348 setLengths (pcl_size );
01349 setIndices (pcl_indices);
01350
01351 setPositions(pcl_points );
01352 }
01353 }
01354 }
01355
01356
01357
01358
01359
01360
01361
01362
01363 return 0;
01364 }
01365
01366
01367
01368 bool Surface::checkOrient(UInt32 ui_v1, UInt32 ui_v2, UInt32 ui_v3,
01369 std::vector<Pnt3f> &m_vclGlobalVertices,
01370 std::vector<Vec3f> &m_vclNormal)
01371 {
01372 const Vec3f ccl_norm_p = m_vclNormal[ui_v1] + m_vclNormal[ui_v2] + m_vclNormal[ui_v3];
01373 const Vec3f ccl_vec1 = m_vclGlobalVertices[ui_v2] - m_vclGlobalVertices[ui_v1];
01374 const Vec3f ccl_vec2 = m_vclGlobalVertices[ui_v3] - m_vclGlobalVertices[ui_v1];
01375 const Vec3f ccl_norm_t = ccl_vec1.cross(ccl_vec2);
01376
01377
01378 return(ccl_norm_p.dot(ccl_norm_t) > 0.0);
01379 }
01380
01381
01383
01404 void Surface::addCurve(
01405 UInt32 dim,
01406 const std::vector<Real64> &knots,
01407 const std::vector<Pnt2f> & controlpoints,
01408 bool newloop)
01409 {
01410 UInt32 cpsize = controlpoints.size();
01411 std::vector<Pnt3f> ratcontrolpoints;
01412
01413 ratcontrolpoints.reserve(cpsize);
01414
01415 for(UInt32 i = 0; i < cpsize; ++i)
01416 {
01417 ratcontrolpoints.push_back(Pnt3f(controlpoints[i][0],
01418 controlpoints[i][1],
01419 1.0f) );
01420 }
01421
01422 addCurve(dim, knots, ratcontrolpoints, newloop);
01423 }
01424
01426
01447 void Surface::addCurve(
01448 UInt32 dim,
01449 const std::vector<Real64> &knots,
01450 const std::vector<Pnt3f> & controlpoints,
01451 bool newloop)
01452 {
01453 UInt32 cpsize = controlpoints.size();
01454 UInt32 knotsize = knots.size();
01455
01456 if(dim + cpsize + 1 != knotsize)
01457 {
01458
01459 return;
01460 }
01461
01462
01463 if(_sfNumCurves.getValue() == 0)
01464 {
01465
01466
01467 newloop = true;
01468 }
01469 _mfDimensions.push_back(dim);
01470 if(newloop)
01471 {
01472 _mfCurvesPerLoop.push_back(1);
01473
01474 }
01475 else
01476 {
01477
01478 UInt32 cplsize = _mfCurvesPerLoop.size();
01479
01480
01481 _mfCurvesPerLoop[cplsize - 1] = _mfCurvesPerLoop[cplsize - 1] + 1;
01482 }
01483 _mfKnotLengths.push_back(knotsize);
01484 UInt32 i;
01485
01486 for(i = 0; i < knotsize; ++i)
01487 {
01488 _mfKnots.push_back(Real32(knots[i]) );
01489 }
01490
01491 for(i = 0; i < cpsize; ++i)
01492 {
01493 _mfCurveControlPoints.push_back(controlpoints[i]);
01494 }
01495
01496 _sfNumCurves.setValue(_sfNumCurves.getValue() + 1);
01497 }
01498
01500
01508 void Surface::removeCurves(void)
01509 {
01510 if(_sfNumCurves.getValue() == 0)
01511 {
01512 return;
01513 }
01514
01515 _sfNumCurves.setValue(0);
01516 _mfKnotLengths.clear();
01517 _mfDimensions.clear();
01518 _mfCurveControlPoints.clear();
01519 _mfKnots.clear();
01520 _mfCurvesPerLoop.clear();
01521 }
01522
01523
01525 SurfaceTransitPtr Surface::clone(void)
01526 {
01527 SurfaceTransitPtr surf = Surface::create();
01528
01529 SWARNING << "Surface::clone not completely implemented!" << endLog;
01530
01531 if(getMFKnotsU() != NULL)
01532 surf->editMFKnotsU()->setValues(*getMFKnotsU());
01533
01534 if(getMFKnotsV() != NULL)
01535 surf->editMFKnotsV()->setValues(*getMFKnotsV());
01536
01537 if(getMFKnotLengths() != NULL)
01538 surf->editMFKnotLengths()->setValues(*getMFKnotLengths());
01539
01540 if(getMFDimensions() != NULL)
01541 surf->editMFDimensions()->setValues(*getMFDimensions());
01542
01543 if(getMFCurveControlPoints() != NULL)
01544 surf->editMFCurveControlPoints()->setValues(*getMFCurveControlPoints());
01545
01546 if(getMFKnots() != NULL)
01547 surf->editMFKnots()->setValues(*getMFKnots());
01548
01549 if(getMFCurvesPerLoop() != NULL)
01550 surf->editMFCurvesPerLoop()->setValues(*getMFCurvesPerLoop());
01551
01552 surf->setMaterial(getMaterial());
01553 surf->setDimU(getDimU());
01554 surf->setDimV(getDimV());
01555 surf->setNumCurves(getNumCurves());
01556 surf->setError(getError());
01557 surf->setIsDelaunay(getIsDelaunay());
01558 surf->setControlPoints(getControlPoints());
01559 surf->setTextureControlPoints(getTextureControlPoints());
01560
01561 return surf;
01562 }
01563
01564
01566
01583
01584 void Surface::readFromTSO(std::istream &infile, bool useTextures)
01585 {
01586 Int32 err = 0;
01587 BSplineTrimmedSurface *cl_trimmed_surface = new BSplineTrimmedSurface;
01588 BSplineTensorSurface tensor_surface;
01589 trimmingloop trimloop;
01590
01591
01592
01593
01594
01595
01596
01597
01598
01599 err = cl_trimmed_surface->read(infile);
01600 if(err)
01601 {
01602 SWARNING << "Couldn't read surface, exiting... " << err << endLog;
01603 delete cl_trimmed_surface;
01604 return;
01605 }
01606
01607 tensor_surface = cl_trimmed_surface->getSurface();
01608 trimloop = cl_trimmed_surface->getTrimmingLoops();
01609
01610
01611 DCTPVec4dmatrix v4cps = tensor_surface.getControlPointMatrix();
01612
01613 UInt32 cpusize = v4cps.size();
01614 UInt32 cpvsize = v4cps[0].size();
01615 UInt32 u,v;
01616 Vec4d vec4;
01617
01618 GeoPnt4fPropertyUnrecPtr pPos;
01619
01620 if(_sfControlPoints.getValue() == NULL)
01621 {
01622 pPos = GeoPnt4fProperty::create();
01623
01624 setControlPoints(pPos);
01625 }
01626 else
01627 {
01628 pPos = dynamic_cast<GeoPnt4fProperty *>(_sfControlPoints.getValue());
01629 }
01630
01631 MFPnt4f *mfControlPoints = pPos->editFieldPtr();
01632
01633
01634
01635 mfControlPoints->clear();
01636
01637 for(u = 0; u < cpusize; ++u)
01638 {
01639 for(v = 0; v < cpvsize; ++v)
01640 {
01641
01642 vec4 = v4cps[u][v];
01643 mfControlPoints->push_back(Pnt4f(vec4[0], vec4[1], vec4[2], vec4[3]));
01644
01645 }
01646 }
01647
01648 _sfDimU.setValue(tensor_surface.getDimension_U() );
01649 _sfDimV.setValue(tensor_surface.getDimension_V() );
01650
01651 DCTPdvector knots;
01652
01653 knots = tensor_surface.getKnotVector_U();
01654 _mfKnotsU.clear();
01655
01656 for(u = 0; u < knots.size(); ++u)
01657 {
01658 _mfKnotsU.push_back(Real32(knots[u]) );
01659 }
01660
01661 knots = tensor_surface.getKnotVector_V();
01662 _mfKnotsV.clear();
01663
01664 for(v = 0; v < knots.size(); ++v)
01665 {
01666 _mfKnotsV.push_back(Real32(knots[v]) );
01667 }
01668
01669
01670 removeCurves();
01671
01672 bool isnewloop;
01673 UInt32 actdim;
01674 std::vector<Real64> actknots;
01675 std::vector<Pnt3f> actcontrolpoints;
01676 DCTPVec3dvector v3actcps;
01677
01678 for(UInt32 i = 0; i < trimloop.size(); ++i)
01679 {
01680 isnewloop = true;
01681
01682 for(UInt32 j = 0; j < trimloop[i].size(); ++j)
01683 {
01684 actknots = trimloop[i][j].getKnotVector();
01685 actdim = trimloop[i][j].getDimension();
01686 v3actcps = trimloop[i][j].getControlPointVector();
01687 actcontrolpoints.clear();
01688
01689 for(UInt32 kk = 0; kk < v3actcps.size(); ++kk)
01690 {
01691 actcontrolpoints.push_back(Pnt3f(v3actcps[kk][0],
01692 v3actcps[kk][1],
01693 v3actcps[kk][2]));
01694 }
01695
01696 addCurve(actdim, actknots, actcontrolpoints, isnewloop);
01697 isnewloop = false;
01698 }
01699 }
01700
01701
01702 delete cl_trimmed_surface;
01703
01704 if(useTextures)
01705 {
01706
01707 char buffer[1024];
01708 infile >> buffer >> std::ws;
01709
01710 UInt32 numoftexcps = cpusize * cpvsize;
01711
01712
01713 GeoVec2fPropertyUnrecPtr pTexPos;
01714
01715 if(_sfTextureControlPoints.getValue() == NULL)
01716 {
01717 pTexPos = GeoVec2fProperty::create();
01718
01719 setTextureControlPoints(pTexPos);
01720 }
01721 else
01722 {
01723 pTexPos = dynamic_cast<GeoVec2fProperty *>(
01724 _sfTextureControlPoints.getValue());
01725 }
01726
01727 MFVec2f *mfTextureControlPoints = pTexPos->editFieldPtr();
01728 mfTextureControlPoints->clear();
01729
01730 Vec2f temp;
01731
01732 for(UInt32 ti = 0; ti < numoftexcps; ++ti)
01733 {
01734 infile >> std::ws >> temp[0] >> std::ws >> temp[1] >> std::ws;
01735 mfTextureControlPoints->push_back(temp);
01736 }
01737
01738
01739 }
01740 }
01741
01742
01743
01744 void Surface::writeToTSO(std::ostream &outfile)
01745 {
01746 _trimmedSurface->write(outfile);
01747 }
01748
01749
01751
01755 UInt32 Surface::writeToOBJ(std::ostream &outfile, UInt32 offset)
01756 {
01757 unsigned int uicnt;
01758
01759 outfile << "g obj " << std::endl;
01760 GeoVectorProperty *pcl_points = getPositions();
01761 GeoVectorProperty *pcl_norms = getNormals();
01762 GeoIntegralProperty *pcl_indices = getIndices();
01763 GeoVectorProperty *pcl_texcoords = getTexCoords();
01764 std::cerr << " indices size: " << pcl_indices->size() << std::endl;
01765 std::cerr << " points size: " << pcl_points->size() << std::endl;
01766 UInt32 ui_faces = pcl_indices->size() / 3;
01767 UInt32 uivertsize = pcl_points->size();
01768 outfile << "# vertices " << uivertsize << std::endl;
01769
01770
01771 for(uicnt = 0; uicnt < uivertsize; uicnt++)
01772 {
01773 Pnt3f ppp = pcl_points->getValue<Pnt3f>(uicnt);
01774
01775 outfile << "v " << ppp.x() << " " <<
01776 ppp.y() << " " <<
01777 ppp.z() << std::endl;
01778
01779 }
01780
01781
01782 for(uicnt = 0; uicnt < uivertsize; uicnt++)
01783 {
01784 Vec3f ppp = pcl_norms->getValue<Vec3f>(uicnt);
01785
01786 outfile << "vn " << ppp.x() << " " <<
01787 ppp.y() << " " <<
01788 ppp.z() << std::endl;
01789
01790 }
01791
01792
01793 for(uicnt = 0; uicnt < uivertsize; uicnt++)
01794 {
01795 Vec2f ppp = pcl_texcoords->getValue<Vec2f>(uicnt);
01796
01797 outfile << "vt " << ppp.x() << " " <<
01798 ppp.y() << " " << std::endl;
01799 }
01800
01801 outfile << "# faces " << ui_faces << std::endl;
01802
01803
01804 for(unsigned int uitricnt = 0; uitricnt < ui_faces; uitricnt++)
01805 {
01806 UInt32 ind1 = pcl_indices->getValue(uitricnt * 3);
01807 UInt32 ind2 = pcl_indices->getValue(uitricnt * 3 + 1);
01808 UInt32 ind3 = pcl_indices->getValue(uitricnt * 3 + 2);
01809 UInt32 i1 = ind1 + offset + 1;
01810 UInt32 i2 = ind2 + offset + 1;
01811 UInt32 i3 = ind3 + offset + 1;
01812
01813 outfile << "f ";
01814 outfile << i1 << "/" << i1 << "/" << i1 << " " <<
01815 i2 << "/" << i2 << "/" << i2 << " " <<
01816 i3 << "/" << i3 << "/" << i3 << std::endl;
01817 }
01818
01819 return offset + uivertsize;
01820 }
01821
01823
01824 void Surface::dump( UInt32,
01825 const BitVector) const
01826 {
01827 SLOG << "Dump Surface NI" << endLog;
01828 }
01829
01830 void Surface::onCreate(const Surface *source)
01831 {
01832
01833 if(GlobalSystemState == Startup)
01834 return;
01835
01836 setSurfaceGLId(
01837 Window::registerGLObject(
01838 boost::bind(&Surface::handleGL,
01839 SurfaceMTUncountedPtr(this), _1, _2, _3, _4),
01840 &Surface::handleDestroyGL));
01841
01842 Inherited::onCreate(source);
01843 }
01844
01845 void Surface::onDestroy(UInt32 id)
01846 {
01847 if(getSurfaceGLId() > 0)
01848 Window::destroyGLObject(getSurfaceGLId(), 1);
01849
01850 Inherited::onDestroy(id);
01851 }
01852
01853 UInt32 Surface::handleGL(DrawEnv *pEnv,
01854 UInt32 id,
01855 Window::GLObjectStatusE mode,
01856 UInt32 uiOptions)
01857 {
01858 if(mode == Window::initialize ||
01859 mode == Window::needrefresh ||
01860 mode == Window::reinitialize)
01861 {
01862 if((getDirtyMask() & DONTTESSELLATE) == 0x0000)
01863 {
01864 if((getDirtyMask() & TESSELLATE) != 0x0000)
01865 {
01866 tessellate();
01867 }
01868 else if((getDirtyMask() & RETESSELLATE) != 0x0000)
01869 {
01870 reTessellate();
01871 }
01872
01873 editDirtyMask() &= ~(TESSELLATE | RETESSELLATE);
01874 }
01875 }
01876
01877 return 0;
01878 }
01879
01880 void Surface::handleDestroyGL(DrawEnv *pEnv,
01881 UInt32 id,
01882 Window::GLObjectStatusE mode)
01883 {
01884 UInt32 glid;
01885 Window *pWin = pEnv->getWindow();
01886
01887 if(mode == Window::destroy)
01888 {
01889 glid = pWin->getGLObjectId(id);
01890
01891 glDeleteLists(glid, 1);
01892 }
01893 else if(mode == Window::finaldestroy)
01894 {
01895
01896 }
01897 else
01898 {
01899 SWARNING << "Surface::handleDestroyGL: Illegal mode: "
01900 << mode << " for id " << id << std::endl;
01901 }
01902 }
01903
01904
01905
01906
01907
01908
01909
01910
01911 void Surface::adjustVolume(Volume & volume)
01912 {
01913 if(!_volumeCache.isEmpty())
01914 {
01915
01916 volume.setValid();
01917 volume.extendBy(_volumeCache);
01918
01919 return;
01920 }
01921
01922 GeoVectorProperty *pos = getControlPoints();
01923 bool has_zeroweights = false;
01924
01925 _volumeCache.setValid();
01926
01927 GeoPnt3fProperty *pPos = dynamic_cast<GeoPnt3fProperty *>(pos);
01928 GeoPnt4fProperty *pRatPos = dynamic_cast<GeoPnt4fProperty *>(pos);
01929
01930 if(pos == NULL)
01931 return;
01932
01933 if(pPos != NULL)
01934 {
01935 for(UInt32 i = 0; i < pPos->size(); ++i)
01936 {
01937 _volumeCache.extendBy(pPos->getValue(i));
01938 }
01939 }
01940 else if(pRatPos != NULL)
01941 {
01942 for(UInt32 i = 0; i < pRatPos->size(); ++i)
01943 {
01944 Pnt3f pnt;
01945
01946 if(osgAbs(pRatPos->getField()[i][3]) > DCTP_EPS)
01947 {
01948 pnt[0] = pRatPos->getField()[i][0] / pRatPos->getField()[i][3];
01949 pnt[1] = pRatPos->getField()[i][1] / pRatPos->getField()[i][3];
01950 pnt[2] = pRatPos->getField()[i][2] / pRatPos->getField()[i][3];
01951 _volumeCache.extendBy(pnt);
01952 }
01953 else
01954 {
01955 has_zeroweights = true;
01956 }
01957 }
01958 }
01959
01960 if(has_zeroweights)
01961 {
01962 GeoVectorProperty *points = getPositions();
01963 if(points != NULL)
01964 {
01965 for(UInt32 i = 0; i < points->size(); ++i)
01966 {
01967 _volumeCache.extendBy(points->getValue<Pnt3r>(i));
01968 }
01969 }
01970
01971
01972
01973
01974
01975
01976
01977 }
01978
01979 volume.extendBy(_volumeCache);
01980 }
01981
01982 void Surface::forceTessellate(void)
01983 {
01984 editDirtyMask() |= DONTTESSELLATE;
01985
01986 if((getDirtyMask() & TESSELLATE) != 0x0000)
01987 {
01988 tessellate();
01989 }
01990 else if((getDirtyMask() & RETESSELLATE) != 0x0000)
01991 {
01992 reTessellate();
01993 }
01994
01995 editDirtyMask() &= ~(TESSELLATE | RETESSELLATE);
01996 }
01997
01998 void Surface::flip(void)
01999 {
02000 if(_trimmedSurface != NULL)
02001 _trimmedSurface->flip();
02002 }
02003
02004 Action::ResultE Surface::drawPrimitives(DrawEnv *pEnv)
02005 {
02006 pEnv->getWindow()->validateGLObject(getSurfaceGLId(), pEnv);
02007
02008 return Inherited::drawPrimitives(pEnv);
02009 }