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 #include "OSGLog.h"
00039
00040 #include "OSGQuadTreeCreator.h"
00041 #include "OSGParSpaceTrimmer.h"
00042 #include "OSGNurbsPatchSurface.h"
00043
00044 #include "OSGpredicates.h"
00045
00046 #include "OSGSurface.h"
00047
00048 #include <map>
00049
00050
00051
00052 OSG_USING_NAMESPACE
00053
00054
00055
00056
00057 #ifdef WIN32
00058 #pragma warning (disable : 985)
00059 #endif
00060
00061
00062 #define OSG_VEC_COMPUTE
00063
00064
00065
00066 #ifdef WRITE_STAT
00067 static double g_dTrimmingConversionTime = 0.0;
00068 static double g_dTrimmingApproximationTime = 0.0;
00069 static OSG::Time g_clTrimmingApproximationStart;
00070 static double g_dTotalTime = 0.0;
00071 static OSG::Time g_clTotalStart;
00072 static OSG::Time g_clActTime;
00073 #endif
00074
00075 #define OSG_3D_LOOPS
00076
00077 CNurbsPatchSurface::CNurbsPatchSurface()
00078 {
00079 m_pclGraph = NULL;
00080 m_bErrorTreeValid = false;
00081 m_pclQuadTree = NULL;
00082 }
00083
00084
00085 CNurbsPatchSurface::~CNurbsPatchSurface()
00086 {
00087
00088
00089 if(m_pclGraph)
00090 {
00091 delete m_pclGraph;
00092 }
00093
00094 for(unsigned int ui_number = 0; ui_number < m_vtSurfaces.size(); ++ui_number)
00095 {
00096 delete m_vtSurfaces[ui_number].pclErrorTree;
00097 }
00098
00099 m_vclBSplineSurfaces.clear();
00100 m_vvvclBezierSurfaces.clear();
00101 m_vvdUParams.clear();
00102 m_vvdVParams.clear();
00103 m_vtSurfaces.clear();
00104
00105 if(m_pclQuadTree != NULL)
00106 {
00107 delete m_pclQuadTree;
00108 m_pclQuadTree = NULL;
00109 }
00110 }
00111
00112
00113
00114 void CNurbsPatchSurface::AddSurface(BSplineTrimmedSurface *clSurface)
00115 {
00116 #ifdef WRITE_STAT
00117 g_clTotalStart = OSG::getSystemTime();
00118 #endif
00119
00120 unsigned int ui_number = m_vclBSplineSurfaces.size();
00121
00122
00123
00124
00125 m_vclBSplineSurfaces.resize(ui_number + 1);
00126 m_vvvclBezierSurfaces.resize(ui_number + 1);
00127 m_vvdUParams.resize(ui_number + 1);
00128 m_vvdVParams.resize(ui_number + 1);
00129
00130
00131 m_vtSurfaces.resize(ui_number + 1);
00132
00133
00134
00135
00136
00137 m_vclBSplineSurfaces[ui_number] = *clSurface;
00138 m_vtSurfaces[ui_number].dError = 10.0;
00139 m_vtSurfaces[ui_number].ucStatus = 0;
00140 m_vtSurfaces[ui_number].pclErrorTree = new CErrorQuadTree();
00141 m_bErrorTreeValid = true;
00142 m_vtSurfaces[ui_number].uiTriangleCnt = 0;
00143
00144
00145 ConvertToBezier(ui_number);
00146
00147 #ifdef WRITE_STAT
00148 g_clActTime = OSG::getSystemTime();
00149 g_dTotalTime += g_clActTime - g_clTotalStart;
00150 g_dTrimmingConversionTime += g_clActTime - g_clTotalStart;
00151 #endif
00152 }
00153
00154
00155 void CNurbsPatchSurface::setSurface(BSplineTrimmedSurface *clSurface,
00156 std::vector<Pnt2f> & texturecps,
00157 bool bUseTextures)
00158 {
00159
00160 if(m_pclGraph)
00161 {
00162 delete m_pclGraph;
00163 m_pclGraph = NULL;
00164 }
00165
00166 for(unsigned int ui_number = 0; ui_number < m_vtSurfaces.size(); ++ui_number)
00167 {
00168 delete m_vtSurfaces[ui_number].pclErrorTree;
00169 m_vtSurfaces[ui_number].pclErrorTree = NULL;
00170 }
00171
00172 m_vclBSplineSurfaces.clear();
00173 m_vvvclBezierSurfaces.clear();
00174 m_vvdUParams.clear();
00175 m_vvdVParams.clear();
00176 m_vtSurfaces.clear();
00177
00178
00179
00180
00181 AddSurface(clSurface);
00182
00183 m_bUseTextures = bUseTextures;
00184 if(m_bUseTextures)
00185 {
00186 UInt32 k = 0;
00187 UInt32 i, j;
00188 BSplineTensorSurface &tensor_surface = clSurface->getSurface();
00189 DCTPVec4dmatrix & surf_cps = tensor_surface.getControlPointMatrix();
00190 UInt32 u_size = surf_cps.size();
00191 UInt32 v_size = surf_cps[0].size();
00192 Vec2d tempv2d;
00193 if( (u_size * v_size) != texturecps.size() )
00194 {
00195 std::cerr << "setSurface: wrong number of texture control points, texturing disabled" << std::endl;
00196 m_bUseTextures = false;
00197 return;
00198 }
00199 m_vvTextureControlPoints.resize(u_size);
00200
00201 for(i = 0; i < u_size; ++i)
00202 {
00203 m_vvTextureControlPoints[i].resize(v_size);
00204 }
00205
00206 for(i = 0; i < u_size; ++i)
00207 {
00208 for(j = 0; j < v_size; ++j)
00209 {
00210 tempv2d[0] = texturecps[k][0];
00211 tempv2d[1] = texturecps[k][1];
00212 m_vvTextureControlPoints[i][j] = tempv2d;
00213 k++;
00214 }
00215 }
00216
00217 }
00218 }
00219
00220 void CNurbsPatchSurface::setupErrorTree(double dError)
00221 {
00222 double d_old_err = m_vtSurfaces[0].dError;
00223
00224 m_vtSurfaces[0].dError = dError;
00225 CalculateQuadTree(0, false);
00226 m_clMesh.reinit();
00227 m_vtSurfaces[0].dError = d_old_err;
00228 }
00229
00230 void CNurbsPatchSurface::setError(double dError)
00231 {
00232 if(m_pclGraph)
00233 {
00234 delete m_pclGraph;
00235 m_pclGraph = NULL;
00236 }
00237 m_vtSurfaces[0].vvclEdgeLoops.clear();
00238 m_vtSurfaces[0].vvclEdgeLoops3D.clear();
00239 m_vtSurfaces[0].vvclEdgeLoopsNorm.clear();
00240 m_vtSurfaces[0].vvclEdgeLoopsTex.clear();
00241 SetError(0, dError);
00242 }
00243
00244
00245
00246 void CNurbsPatchSurface::getTessellation(std::vector<Pnt3f> & gverts,
00247 std::vector<Vec3f> & norms,
00248 std::vector<SimplePolygon> &tris,
00249 bool usedelaunay)
00250 {
00251 #ifdef WRITE_STAT
00252 g_clTotalStart = OSG::getSystemTime();
00253 #endif
00254
00255 if( (m_vtSurfaces[0].ucStatus & BEZIER_SURFACES_VALID) &&
00256 ( (m_vtSurfaces[0].ucStatus & TRIM_SEGS_VALID) == 0) )
00257 {
00258 #ifdef WRITE_STAT
00259 g_clTrimmingApproximationStart = OSG::getSystemTime();
00260 #endif
00261 CalculateQuadTree(0, true);
00262 CalculateTrimmingLoops(0);
00263 #ifdef WRITE_STAT
00264 g_clActTime = OSG::getSystemTime();
00265 g_dTrimmingApproximationTime += g_clActTime - g_clTrimmingApproximationStart;
00266 #endif
00267 CalculateQuadTree(0, false);
00268
00269 CalculateActualTrimming(0);
00270 CalculateGraph(0, usedelaunay);
00271
00273 if(m_pclGraph)
00274 {
00275 delete m_pclGraph;
00276 m_pclGraph = NULL;
00277 }
00278
00280 calculatePointsAndNormals(gverts, tris, norms);
00281 ComputeNormalCone(0, norms);
00282 m_vclParameterVertices.clear();
00283 m_vclGlobalVertices.clear();
00284 m_vclTriangles.clear();
00285 }
00286 else
00287 {
00288 std::cerr << "shouldn't be here..." << std::endl;
00289 }
00290
00291 #ifdef WRITE_STAT
00292 g_clActTime = OSG::getSystemTime();
00293 g_dTotalTime += g_clActTime - g_clTotalStart;
00294
00295
00296
00297 #endif
00298 }
00299
00300
00301 void CNurbsPatchSurface::getTessellation(std::vector<Pnt3f> & gverts,
00302 std::vector<Vec3f> & norms,
00303 std::vector<Pnt2f> & texturecoords,
00304 std::vector<SimplePolygon> &tris,
00305 bool usedelaunay)
00306 {
00307
00308 if( (m_vtSurfaces[0].ucStatus & BEZIER_SURFACES_VALID) &&
00309 ( (m_vtSurfaces[0].ucStatus & TRIM_SEGS_VALID) == 0) )
00310 {
00311 CalculateQuadTree(0, true);
00312 CalculateTrimmingLoops(0);
00313 CalculateQuadTree(0, false);
00314
00315 CalculateActualTrimming(0);
00316 CalculateGraph(0, usedelaunay);
00317 if(m_pclGraph)
00318 {
00319 delete m_pclGraph;
00320 m_pclGraph = NULL;
00321 }
00322
00324 calculatePointsNormalsAndTextureCoords(gverts,
00325 tris,
00326 norms,
00327 texturecoords);
00328 ComputeNormalCone(0, norms);
00329 m_vclParameterVertices.clear();
00330 m_vclGlobalVertices.clear();
00331 m_vclTriangles.clear();
00332 }
00333 else
00334 {
00335 std::cerr << "shouldn't be here..." << std::endl;
00336 }
00337
00338
00339 }
00340
00341
00342 void CNurbsPatchSurface::getTessellation(std::vector<Pnt3f> & gverts,
00343 std::vector<Pnt2f> & texturecoords,
00344 std::vector<SimplePolygon> &tris,
00345 bool usedelaunay)
00346 {
00347
00348
00349
00350 if( (m_vtSurfaces[0].ucStatus & BEZIER_SURFACES_VALID) &&
00351 ( (m_vtSurfaces[0].ucStatus & TRIM_SEGS_VALID) == 0) )
00352 {
00353
00354 CalculateQuadTree(0, true);
00355
00356
00357
00358
00359 CalculateTrimmingLoops(0);
00360
00361
00362
00363
00364 CalculateQuadTree(0, false);
00365
00366
00367
00368
00369
00370 CalculateActualTrimming(0);
00371
00372
00373
00374
00375 CalculateGraph(0, usedelaunay);
00376
00377
00378
00379
00381 if(m_pclGraph)
00382 {
00383 delete m_pclGraph;
00384 m_pclGraph = NULL;
00385 }
00386
00388
00389
00390 calculatePointsAndTextureCoords(gverts, tris, texturecoords);
00391
00392
00393
00394
00395
00396 m_vclParameterVertices.clear();
00397 m_vclGlobalVertices.clear();
00398 m_vclTriangles.clear();
00399 }
00400 else
00401 {
00402 std::cerr << "shouldn't be here..." << std::endl;
00403 }
00404
00405
00406
00407 }
00408
00409
00410
00411 void CNurbsPatchSurface::calculatePointsAndNormals(
00412 std::vector<Pnt3f> & gverts,
00413 std::vector<SimplePolygon> &tris,
00414 std::vector<Vec3f> & norms)
00415 {
00416 BSplineTensorSurface cl_surf;
00417
00418
00419
00420 cl_surf = m_vclBSplineSurfaces[0].getSurface();
00421
00422 #ifdef OSG_VEC_COMPUTE
00423 cl_surf.computeNormal(m_vclParameterVertices,
00424 gverts,
00425 norms);
00426 #else
00427 gverts.resize(m_vclParameterVertices.size() );
00428 norms.resize(m_vclParameterVertices.size() );
00429
00430 for(unsigned int i = 0; i < m_vclParameterVertices.size(); ++i)
00431 {
00432 int i_err = 0;
00433 norms[i] = cl_surf.computeNormal(m_vclParameterVertices[i], i_err, gverts[i]);
00434 }
00435
00436 #endif
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456 tris.clear();
00457 tris = m_vclTriangles;
00458
00459
00460 unsigned int numloops = m_vtSurfaces[0].vvclEdgeLoops.size();
00461 unsigned int actlooplength;
00462 #ifdef OSG_KEEP_2D_POINTS
00463 unsigned int ui_actvertidx = 0;
00464 #endif
00465
00466 Vec3d cl_norm;
00467
00468 m_vtSurfaces[0].vvclEdgeLoopsNorm.resize(numloops);
00469 #ifndef OSG_FORCE_NO_T_VERTICES
00470 m_vtSurfaces[0].vvclEdgeLoops3D.resize(numloops);
00471 #endif
00472
00473 for(unsigned int ui_actloop = 0; ui_actloop < numloops; ++ui_actloop)
00474 {
00475 actlooplength = m_vtSurfaces[0].vvclEdgeLoops[ui_actloop].size();
00476 m_vtSurfaces[0].vvclEdgeLoopsNorm[ui_actloop].resize(actlooplength);
00477 #ifdef OSG_KEEP_2D_POINTS
00478
00479 for(unsigned int ui_act = 0; ui_act < actlooplength; ++ui_act)
00480 {
00481 m_vtSurfaces[0].vvclEdgeLoopsNorm[ui_actloop][ui_act] =
00482 Vec3d(norms[ui_actvertidx][0],
00483 norms[ui_actvertidx][1],
00484 norms[ui_actvertidx][2]);
00485
00486
00487
00488
00489
00490 ui_actvertidx++;
00491 }
00492
00493 #else
00494 #ifdef OSG_FORCE_NO_T_VERTICES
00495 cl_surf.computeNormalforTrimming(
00496 m_vtSurfaces[0].vvclEdgeLoops[ui_actloop],
00497 m_vtSurfaces[0].vvclEdgeLoopsNorm[ui_actloop]);
00498 #else
00499 cl_surf.computeNormalforTrimming(
00500 m_vtSurfaces[0].vvclEdgeLoops[ui_actloop],
00501 m_vtSurfaces[0].vvclEdgeLoopsNorm[ui_actloop],
00502 &m_vtSurfaces[0].vvclEdgeLoops3D[ui_actloop]);
00503 #endif
00504 #endif
00505 }
00506
00507
00508
00509 }
00510
00511
00512 void CNurbsPatchSurface::calculatePointsNormalsAndTextureCoords(
00513 std::vector<Pnt3f> & gverts,
00514 std::vector<SimplePolygon> &tris,
00515 std::vector<Vec3f> & norms,
00516 std::vector<Pnt2f> & texturecoords)
00517 {
00518 BSplineTensorSurface cl_surf;
00519
00520
00521 cl_surf = m_vclBSplineSurfaces[0].getSurface();
00522
00523 cl_surf.computeNormal(m_vclParameterVertices,
00524 gverts,
00525 norms);
00526
00527
00528
00529 std::vector<Pnt3f> dummyverts;
00530 cl_surf.computeTex(m_vclParameterVertices,
00531 dummyverts,
00532 texturecoords,
00533 &m_vvTextureControlPoints);
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544 tris.clear();
00545 tris = m_vclTriangles;
00546
00547
00548 unsigned int numloops = m_vtSurfaces[0].vvclEdgeLoops.size();
00549 unsigned int actlooplength;
00550 unsigned int ui_actloop;
00551 #ifdef OSG_KEEP_2D_POINTS
00552 unsigned int ui_actvertidx = 0;
00553 #endif
00554
00555 Vec3d cl_norm;
00556
00557 m_vtSurfaces[0].vvclEdgeLoopsNorm.resize(numloops);
00558 #ifndef OSG_FORCE_NO_T_VERTICES
00559 m_vtSurfaces[0].vvclEdgeLoops3D.resize(numloops);
00560 #endif
00561
00562 for(ui_actloop = 0; ui_actloop < numloops; ++ui_actloop)
00563 {
00564 actlooplength = m_vtSurfaces[0].vvclEdgeLoops[ui_actloop].size();
00565 m_vtSurfaces[0].vvclEdgeLoopsNorm[ui_actloop].resize(actlooplength);
00566 #ifdef OSG_KEEP_2D_POINTS
00567
00568 for(unsigned int ui_act = 0; ui_act < actlooplength; ++ui_act)
00569 {
00570 m_vtSurfaces[0].vvclEdgeLoopsNorm[ui_actloop][ui_act] =
00571 Vec3d(norms[ui_actvertidx][0],
00572 norms[ui_actvertidx][1],
00573 norms[ui_actvertidx][2]);
00574 ui_actvertidx++;
00575 }
00576
00577 #else
00578 #ifdef OSG_FORCE_NO_T_VERTICES
00579 cl_surf.computeNormalforTrimming(
00580 m_vtSurfaces[0].vvclEdgeLoops[ui_actloop],
00581 m_vtSurfaces[0].vvclEdgeLoopsNorm[ui_actloop]);
00582 #else
00583 cl_surf.computeNormalforTrimming(
00584 m_vtSurfaces[0].vvclEdgeLoops[ui_actloop],
00585 m_vtSurfaces[0].vvclEdgeLoopsNorm[ui_actloop],
00586 &m_vtSurfaces[0].vvclEdgeLoops3D[ui_actloop]);
00587 #endif
00588 #endif
00589 }
00590
00591
00592
00593 numloops = m_vtSurfaces[0].vvclEdgeLoops.size();
00594 #ifdef OSG_KEEP_2D_POINTS
00595 ui_actvertidx = 0;
00596 #endif
00597
00598 m_vtSurfaces[0].vvclEdgeLoopsTex.resize(numloops);
00599
00600 for(ui_actloop = 0; ui_actloop < numloops; ++ui_actloop)
00601 {
00602 actlooplength = m_vtSurfaces[0].vvclEdgeLoops[ui_actloop].size();
00603 m_vtSurfaces[0].vvclEdgeLoopsTex[ui_actloop].resize(actlooplength);
00604 #ifdef OSG_KEEP_2D_POINTS
00605
00606 for(unsigned int ui_act = 0; ui_act < actlooplength; ++ui_act)
00607 {
00608 m_vtSurfaces[0].vvclEdgeLoopsTex[ui_actloop][ui_act] =
00609 Vec3d(texturecoords[ui_actvertidx][0],
00610 texturecoords[ui_actvertidx][1],
00611 texturecoords[ui_actvertidx][2]);
00612 ui_actvertidx++;
00613 }
00614
00615 #else
00616 cl_surf.computeTexforTrimming(
00617 m_vtSurfaces[0].vvclEdgeLoops[ui_actloop],
00618 m_vtSurfaces[0].vvclEdgeLoopsTex[ui_actloop],
00619 &m_vvTextureControlPoints);
00620 #endif
00621 }
00622
00623
00624
00625
00626
00627 }
00628
00629
00630 void CNurbsPatchSurface::calculatePointsAndTextureCoords(
00631 std::vector<Pnt3f> & gverts,
00632 std::vector<SimplePolygon> &tris,
00633 std::vector<Pnt2f> & texturecoords)
00634 {
00635 BSplineTensorSurface cl_surf;
00636
00637
00638 cl_surf = m_vclBSplineSurfaces[0].getSurface();
00639 cl_surf.computeTex(m_vclParameterVertices,
00640 gverts,
00641 texturecoords,
00642 &m_vvTextureControlPoints);
00643
00644
00645
00646
00647
00648
00649
00650 tris.clear();
00651 tris = m_vclTriangles;
00652
00653
00654 unsigned int numloops = m_vtSurfaces[0].vvclEdgeLoops.size();
00655 unsigned int actlooplength;
00656 #ifdef OSG_KEEP_2D_POINTS
00657 unsigned int ui_actvertidx = 0;
00658 #endif
00659
00660 Vec3d cl_norm;
00661
00662 m_vtSurfaces[0].vvclEdgeLoopsTex.resize(numloops);
00663
00664 for(unsigned int ui_actloop = 0; ui_actloop < numloops; ++ui_actloop)
00665 {
00666 actlooplength = m_vtSurfaces[0].vvclEdgeLoops[ui_actloop].size();
00667 m_vtSurfaces[0].vvclEdgeLoopsTex[ui_actloop].resize(actlooplength);
00668 #ifdef OSG_KEEP_2D_POINTS
00669
00670 for(unsigned int ui_act = 0; ui_act < actlooplength; ++ui_act)
00671 {
00672 m_vtSurfaces[0].vvclEdgeLoopsTex[ui_actloop][ui_act] =
00673 Vec3d(texturecoords[ui_actvertidx][0],
00674 texturecoords[ui_actvertidx][1],
00675 texturecoords[ui_actvertidx][2]);
00676 ui_actvertidx++;
00677 }
00678
00679 #else
00680 cl_surf.computeTexforTrimming(
00681 m_vtSurfaces[0].vvclEdgeLoops[ui_actloop],
00682 m_vtSurfaces[0].vvclEdgeLoopsTex[ui_actloop],
00683 &m_vvTextureControlPoints);
00684 #endif
00685 }
00686
00687
00688
00689 }
00690
00691
00692
00693
00694 void CNurbsPatchSurface::SetError(const unsigned int cuiSurface, double dError)
00695 {
00696 if(cuiSurface >= m_vtSurfaces.size() )
00697 {
00698 return;
00699 }
00700
00701
00702
00703 m_vtSurfaces[cuiSurface].dError = dError;
00704
00705 m_vtSurfaces[cuiSurface].ucStatus &= BEZIER_SURFACES_VALID;
00706 }
00707
00708
00709
00710 void CNurbsPatchSurface::ConvertToBezier(unsigned int uiSurface)
00711 {
00712 BSplineTensorSurface& rcl_bspline_surface = m_vclBSplineSurfaces[uiSurface].getSurface();
00713 trimmingloop& rvvcl_trimming_loops = m_vclBSplineSurfaces[uiSurface].getTrimmingLoops();
00714 bezier2dvector vcl_beziertrimmingcurves;
00715 std::vector<unsigned int> vui_curves_per_loop(0);
00716 unsigned int ui_tloops = rvvcl_trimming_loops.size();
00717 unsigned int ui_curve;
00718
00719
00720
00721 vui_curves_per_loop.resize(ui_tloops);
00722 m_vtSurfaces[uiSurface].vvclBezierCurves.resize(ui_tloops);
00723
00724
00725 for(unsigned int ui_loop = 0; ui_loop < ui_tloops; ++ui_loop)
00726 {
00727 unsigned int ui_curves = rvvcl_trimming_loops[ui_loop].size();
00728 unsigned int ui_prev = ui_curves - 1;
00729
00730 vui_curves_per_loop[ui_loop] = 0;
00731 vcl_beziertrimmingcurves.clear();
00732
00733 for(ui_curve = 0; ui_curve < ui_curves; ++ui_curve)
00734 {
00735
00736 bezier2dvector vcl_converted_tmp;
00737 DCTPdvector vd_pars;
00738
00739 DCTPVec3dvector vcl_cp =
00740 rvvcl_trimming_loops[ui_loop][ui_prev].getControlPointVector();
00741 Vec3d cl_prev = vcl_cp[vcl_cp.size() - 1];
00742 vcl_cp = rvvcl_trimming_loops[ui_loop][ui_curve].getControlPointVector();
00743 if(DCTPVecIsNotEqual(cl_prev, vcl_cp[0]) )
00744 {
00745 BezierCurve2D cl_temp;
00746 DCTPVec3dvector vcl_temp(2);
00747
00748 vcl_temp[0] = cl_prev;
00749 vcl_temp[1] = vcl_cp[0];
00750 cl_temp.setControlPointVector(vcl_temp);
00751 cl_temp.optimizeDegree();
00752
00753
00754 vcl_beziertrimmingcurves.insert(vcl_beziertrimmingcurves.end(), cl_temp);
00755 ++vui_curves_per_loop[ui_loop];
00756 }
00757 ui_prev = ui_curve;
00758
00759 if(rvvcl_trimming_loops[ui_loop][ui_curve].makeBezier(vcl_converted_tmp, vd_pars) )
00760 {
00761
00762
00763
00764 }
00765 else
00766 {
00767 vcl_beziertrimmingcurves.insert(
00768 vcl_beziertrimmingcurves.end(), vcl_converted_tmp.begin(), vcl_converted_tmp.end() );
00769 vui_curves_per_loop[ui_loop] += vcl_converted_tmp.size();
00770 }
00771 }
00772
00773
00774 for(ui_curve = 0; ui_curve < vcl_beziertrimmingcurves.size(); ++ui_curve)
00775 {
00776 unsigned int ui_next = (ui_curve + 1) % vcl_beziertrimmingcurves.size();
00777
00778
00779 if( (vcl_beziertrimmingcurves[ui_curve].getControlPointVector().size() == 2) &&
00780 (vcl_beziertrimmingcurves[ui_next].getControlPointVector().size() == 2) &&
00781 (DCTPVecIsEqual(vcl_beziertrimmingcurves[ui_curve].getControlPointVector()[1],
00782 vcl_beziertrimmingcurves[ui_next].getControlPointVector()[0]) ) )
00783 {
00784
00785 Vec2d cl_s0, cl_e0, cl_s1, cl_e1;
00786 Vec2d cl_tmp;
00787
00788 cl_s0[0] = vcl_beziertrimmingcurves[ui_curve].getControlPointVector()[0][0]
00789 / vcl_beziertrimmingcurves[ui_curve].getControlPointVector()[0][2];
00790 cl_s0[1] = vcl_beziertrimmingcurves[ui_curve].getControlPointVector()[0][1]
00791 / vcl_beziertrimmingcurves[ui_curve].getControlPointVector()[0][2];
00792
00793 cl_e0[0] = vcl_beziertrimmingcurves[ui_curve].getControlPointVector()[1][0]
00794 / vcl_beziertrimmingcurves[ui_curve].getControlPointVector()[1][2];
00795 cl_e0[1] = vcl_beziertrimmingcurves[ui_curve].getControlPointVector()[1][1]
00796 / vcl_beziertrimmingcurves[ui_curve].getControlPointVector()[1][2];
00797
00798 cl_s1[0] = vcl_beziertrimmingcurves[ui_next].getControlPointVector()[0][0]
00799 / vcl_beziertrimmingcurves[ui_next].getControlPointVector()[0][2];
00800 cl_s1[1] = vcl_beziertrimmingcurves[ui_next].getControlPointVector()[0][1]
00801 / vcl_beziertrimmingcurves[ui_next].getControlPointVector()[0][2];
00802
00803 cl_e1[0] = vcl_beziertrimmingcurves[ui_next].getControlPointVector()[1][0]
00804 / vcl_beziertrimmingcurves[ui_next].getControlPointVector()[1][2];
00805 cl_e1[1] = vcl_beziertrimmingcurves[ui_next].getControlPointVector()[1][1]
00806 / vcl_beziertrimmingcurves[ui_next].getControlPointVector()[1][2];
00807
00808 cl_tmp = cl_e1 - cl_s0;
00809
00810 cl_tmp *= 1.0 / sqrt(cl_tmp.squareLength() );
00811 cl_tmp *= cl_tmp.dot(cl_e0 - cl_s0);
00812 cl_tmp -= cl_e0 - cl_s0;
00813
00814 if(cl_tmp.squareLength() < DCTP_EPS * DCTP_EPS)
00815 {
00816 if(ui_next == 0)
00817 {
00818 vcl_beziertrimmingcurves[ui_next].getControlPointVector()[0] =
00819 vcl_beziertrimmingcurves[ui_curve].getControlPointVector()[0];
00820 }
00821 else
00822 {
00823 vcl_beziertrimmingcurves[ui_curve].getControlPointVector()[1] =
00824 vcl_beziertrimmingcurves[ui_next].getControlPointVector()[1];
00825
00826 for( ; ui_next < vcl_beziertrimmingcurves.size() - 1; ++ui_next)
00827 {
00828 vcl_beziertrimmingcurves[ui_next] = vcl_beziertrimmingcurves[ui_next + 1];
00829 }
00830 }
00831 vcl_beziertrimmingcurves.pop_back();
00832 --ui_curve;
00833 }
00834 }
00835 }
00836
00837 vui_curves_per_loop[ui_loop] = vcl_beziertrimmingcurves.size();
00838
00839
00840 for(ui_curve = 0; ui_curve < vui_curves_per_loop[ui_loop]; ++ui_curve)
00841 {
00842
00843
00844
00845 m_vtSurfaces[uiSurface].vvclBezierCurves[ui_loop].push_back(vcl_beziertrimmingcurves[ui_curve]);
00846 }
00847 }
00848
00849 if(rcl_bspline_surface.makeBezier(m_vvvclBezierSurfaces[uiSurface],
00850 m_vvdUParams[uiSurface],
00851 m_vvdVParams[uiSurface]) )
00852 {
00853
00854 }
00855
00856 #ifdef OSG_3D_LOOPS
00857 Gen3DLoops(uiSurface);
00858 m_vvvclBezierSurfaces[uiSurface].clear();
00859 #endif
00860
00861
00862
00863 m_vtSurfaces[uiSurface].ucStatus |= BEZIER_SURFACES_VALID;
00864 }
00865
00866
00867
00868
00869
00870
00871 void CNurbsPatchSurface::CalculateQuadTree(unsigned int uiSurface, bool bForEdges)
00872 {
00873 if(!(m_vtSurfaces[uiSurface].ucStatus & BEZIER_SURFACES_VALID) )
00874 {
00875 std::cerr << "Bezier surfaces invalid for surface " << uiSurface + 1 << std::endl;
00876 return;
00877 }
00878
00879
00880
00881
00882 if(bForEdges)
00883 {
00884 if(m_vtSurfaces[uiSurface].vvcl3DCurves.size() != 0)
00885 {
00886
00887 m_vtSurfaces[uiSurface].ucStatus |= QUAD_TREE_VALID;
00888 return;
00889 }
00890
00891 m_clMesh.reinit();
00892
00893 m_pclQuadTree = new QuadTreeCreator(&m_clMesh );
00894
00895 m_pclQuadTree->setErrorTolerance(m_vtSurfaces[uiSurface].dError / 3.0);
00896 if(m_pclQuadTree->setInitialLeaves(m_vvvclBezierSurfaces[uiSurface],
00897 m_vvdUParams[uiSurface],
00898 m_vvdVParams[uiSurface]) )
00899 {
00900 std::cerr << "QuadTree setup of surface " << uiSurface + 1 << " failed." << std::endl;
00901 m_vtSurfaces[uiSurface].ucStatus |= QUAD_TREE_ERROR;
00902 delete m_pclQuadTree;
00903 return;
00904 }
00905 #ifndef OSG_ADAPTIVE_QUAD_TREE
00906 if(m_pclQuadTree->createQuadTree() )
00907 {
00908 std::cerr << "QuadTree creation of surface " << uiSurface + 1 << " failed." << std::endl;
00909 m_vtSurfaces[uiSurface].ucStatus |= QUAD_TREE_ERROR;
00910 delete m_pclQuadTree;
00911 return;
00912 }
00913 delete m_pclQuadTree;
00914 #endif
00915 }
00916 else
00917 {
00918
00919 m_clMesh.reinit();
00920
00921 #ifdef OSG_USE_NURBS_PATCH
00922 m_vtSurfaces[uiSurface].pclErrorTree->BuildMesh(&m_clMesh,
00923 &(m_vclBSplineSurfaces[uiSurface].getSurface() ),
00924 #ifdef OSG_ARBITRARY_SPLIT
00925 m_vtSurfaces[uiSurface].clMinParam,
00926 m_vtSurfaces[uiSurface].clMaxParam,
00927 #endif
00928 m_vtSurfaces[uiSurface].dError,
00929 m_vtSurfaces[uiSurface].fMinError,
00930 m_vtSurfaces[uiSurface].fMaxError);
00931 #else
00932 m_vtSurfaces[uiSurface].pclErrorTree->BuildMesh(&m_clMesh,
00933 &m_vvvclBezierSurfaces[uiSurface],
00934 &m_vvdUParams[uiSurface],
00935 &m_vvdVParams[uiSurface],
00936 m_vtSurfaces[uiSurface].dError,
00937 m_vtSurfaces[uiSurface].fMinError,
00938 m_vtSurfaces[uiSurface].fMaxError);
00939 #endif
00940
00941
00942
00943 }
00944 m_vtSurfaces[uiSurface].ucStatus |= QUAD_TREE_VALID;
00945 }
00946
00947
00948
00949
00950
00951
00952
00953 void CNurbsPatchSurface::CalculateTrimmingLoops(unsigned int uiSurface)
00954 {
00955 bezier2ddequevector vvcl_curves = m_vtSurfaces[uiSurface].vvclBezierCurves;
00956
00957 if(!(m_vtSurfaces[uiSurface].ucStatus & QUAD_TREE_VALID) )
00958 {
00959 std::cerr << "Quad tree invalid for surface " << uiSurface + 1 << std::endl;
00960 m_vtSurfaces[uiSurface].clMin = Vec3d(m_vtSurfaces[uiSurface].dError * 100, m_vtSurfaces[uiSurface].dError * 100, m_vtSurfaces[uiSurface].dError * 100);
00961 m_vtSurfaces[uiSurface].clMax = Vec3d(0, 0, 0);
00962 return;
00963 }
00964
00965
00966
00967 ParSpaceTrimmer cl_trimmer;
00968
00969 if(m_vtSurfaces[uiSurface].vvcl3DCurves.size() != 0)
00970 {
00971 #ifdef OSG_USE_SIMPLIFIER
00972 cl_trimmer.Initialize(m_clMesh, vvcl_curves,
00973 m_vtSurfaces[uiSurface].vvcl3DCurves,
00974 m_vtSurfaces[uiSurface].vvclEdgeLoops,
00975 m_vtSurfaces[uiSurface].dError,
00976 &m_vclBSplineSurfaces[uiSurface].getSurface() );
00977 #else
00978 cl_trimmer.Initialize(m_clMesh, vvcl_curves,
00979 m_vtSurfaces[uiSurface].vvcl3DCurves,
00980 m_vtSurfaces[uiSurface].vvclEdgeLoops,
00981 m_vtSurfaces[uiSurface].dError);
00982 #endif
00983 }
00984 else
00985 {
00986 #ifdef OSG_ADAPTIVE_QUAD_TREE
00987 #ifdef OSG_USE_SIMPLIFIER
00988 cl_trimmer.Initialize(m_clMesh, vvcl_curves,
00989 m_vtSurfaces[uiSurface].vvclEdgeLoops, m_pclQuadTree,
00990 &m_vclBSplineSurfaces[uiSurface].getSurface() );
00991 #else
00992 cl_trimmer.Initialize(m_clMesh, vvcl_curves, m_vtSurfaces[uiSurface].vvclEdgeLoops, m_pclQuadTree);
00993 #endif
00994 #else
00995 cl_trimmer.Initialize(m_clMesh, vvcl_curves, m_vtSurfaces[uiSurface].vvclEdgeLoops);
00996 #endif
00997 }
00998 try
00999 {
01000 if(cl_trimmer.PerformTrimming() )
01001 {
01002 std::cerr << "Par space trimmer failed (surface " << uiSurface + 1 << ")." << std::endl;
01003 m_vtSurfaces[uiSurface].clMin = Vec3d(m_vtSurfaces[uiSurface].dError * 100, m_vtSurfaces[uiSurface].dError * 100, m_vtSurfaces[uiSurface].dError * 100);
01004 m_vtSurfaces[uiSurface].clMax = Vec3d(0, 0, 0);
01005 #ifndef OSG_ADAPTIVE_QUAD_TREE
01006 if(m_pclQuadTree != NULL)
01007 {
01008 delete m_pclQuadTree;
01009 m_pclQuadTree = NULL;
01010 }
01011 #endif
01012 return;
01013 }
01014 }
01015 catch(ParSpaceTrimmerError cl_err)
01016 {
01017 std::cerr << "Par space trimmer exception caught: " << cl_err.errtype << " (surface " << uiSurface + 1 << ")" << std::endl;
01018 m_vtSurfaces[uiSurface].clMin = Vec3d(m_vtSurfaces[uiSurface].dError * 100, m_vtSurfaces[uiSurface].dError * 100, m_vtSurfaces[uiSurface].dError * 100);
01019 m_vtSurfaces[uiSurface].clMax = Vec3d(0, 0, 0);
01020 #ifndef OSG_ADAPTIVE_QUAD_TREE
01021 if(m_pclQuadTree != NULL)
01022 {
01023 delete m_pclQuadTree;
01024 m_pclQuadTree = NULL;
01025 }
01026 #endif
01027 return;
01028 }
01029
01030
01031
01032 const unsigned int cui_size =
01033 m_vtSurfaces[uiSurface].vvclEdgeLoops.size();
01034
01035 m_vtSurfaces[uiSurface].vvclEdgeLoops3D.resize(cui_size);
01036 m_vtSurfaces[uiSurface].vbReversed.resize(cui_size);
01037 m_vtSurfaces[uiSurface].vbUsed.resize(cui_size);
01038
01039
01040 unsigned int ui_vertex;
01041
01042 for(unsigned int ui_loop = 0; ui_loop < cui_size; ++ui_loop)
01043 {
01044
01045 const unsigned int cui_size2 = m_vtSurfaces[uiSurface].vvclEdgeLoops[ui_loop].size();
01046 std::vector<Pnt3f> vcl_temp3d;
01047
01048 m_vtSurfaces[uiSurface].vvclEdgeLoops3D[ui_loop].resize(cui_size2);
01049 vcl_temp3d.resize(cui_size2);
01050 m_vclBSplineSurfaces[uiSurface].getSurface().compute(
01051 m_vtSurfaces[uiSurface].vvclEdgeLoops[ui_loop],
01052 vcl_temp3d);
01053
01054 for(ui_vertex = 0; ui_vertex < cui_size2; ++ui_vertex)
01055 {
01056
01057
01058
01059
01060 Vec3d ccl_vec;
01061 ccl_vec[0] = vcl_temp3d[ui_vertex][0];
01062 ccl_vec[1] = vcl_temp3d[ui_vertex][1];
01063 ccl_vec[2] = vcl_temp3d[ui_vertex][2];
01064
01065
01066 m_vtSurfaces[uiSurface].vvclEdgeLoops3D[ui_loop][ui_vertex] = ccl_vec;
01067
01068 if( (ui_loop == 0) && (ui_vertex == 0) )
01069 {
01070 m_vtSurfaces[uiSurface].clMin =
01071 m_vtSurfaces[uiSurface].clMax = ccl_vec;
01072 #ifdef OSG_ARBITRARY_SPLIT
01073 m_vtSurfaces[uiSurface].clMinParam = m_vtSurfaces[uiSurface].clMaxParam =
01074 m_vtSurfaces[uiSurface].vvclEdgeLoops[ui_loop][ui_vertex];
01075 #endif
01076 }
01077 else
01078 {
01079 if(ccl_vec[0] < m_vtSurfaces[uiSurface].clMin[0])
01080 m_vtSurfaces[uiSurface].clMin[0] = ccl_vec[0];
01081 else if(ccl_vec[0] > m_vtSurfaces[uiSurface].clMax[0])
01082 m_vtSurfaces[uiSurface].clMax[0] = ccl_vec[0];
01083 if(ccl_vec[1] < m_vtSurfaces[uiSurface].clMin[1])
01084 m_vtSurfaces[uiSurface].clMin[1] = ccl_vec[1];
01085 else if(ccl_vec[1] > m_vtSurfaces[uiSurface].clMax[1])
01086 m_vtSurfaces[uiSurface].clMax[1] = ccl_vec[1];
01087 if(ccl_vec[2] < m_vtSurfaces[uiSurface].clMin[2])
01088 m_vtSurfaces[uiSurface].clMin[2] = ccl_vec[2];
01089 else if(ccl_vec[2] > m_vtSurfaces[uiSurface].clMax[2])
01090 m_vtSurfaces[uiSurface].clMax[2] = ccl_vec[2];
01091 #ifdef OSG_ARBITRARY_SPLIT
01092 if(m_vtSurfaces[uiSurface].vvclEdgeLoops[ui_loop][ui_vertex][0] < m_vtSurfaces[uiSurface].clMinParam[0])
01093 m_vtSurfaces[uiSurface].clMinParam[0] = m_vtSurfaces[uiSurface].vvclEdgeLoops[ui_loop][ui_vertex][0];
01094 else if(m_vtSurfaces[uiSurface].vvclEdgeLoops[ui_loop][ui_vertex][0] > m_vtSurfaces[uiSurface].clMaxParam[0])
01095 m_vtSurfaces[uiSurface].clMaxParam[0] = m_vtSurfaces[uiSurface].vvclEdgeLoops[ui_loop][ui_vertex][0];
01096 if(m_vtSurfaces[uiSurface].vvclEdgeLoops[ui_loop][ui_vertex][1] < m_vtSurfaces[uiSurface].clMinParam[1])
01097 m_vtSurfaces[uiSurface].clMinParam[1] = m_vtSurfaces[uiSurface].vvclEdgeLoops[ui_loop][ui_vertex][1];
01098 else if(m_vtSurfaces[uiSurface].vvclEdgeLoops[ui_loop][ui_vertex][1] > m_vtSurfaces[uiSurface].clMaxParam[1])
01099 m_vtSurfaces[uiSurface].clMaxParam[1] = m_vtSurfaces[uiSurface].vvclEdgeLoops[ui_loop][ui_vertex][1];
01100 #endif
01101 }
01102 }
01103
01104
01105 SimplePolygon cl_check;
01106
01107 cl_check.vertices.resize(cui_size2 - 1);
01108
01109 for(ui_vertex = 0; ui_vertex < cui_size2 - 1; ++ui_vertex)
01110 {
01111 cl_check.vertices[ui_vertex] = ui_vertex;
01112 }
01113
01114
01115
01116
01117
01118
01119
01120
01121
01122
01123 if(cl_check.isReversed(m_vtSurfaces[uiSurface].vvclEdgeLoops[ui_loop]) )
01124 {
01125
01126 m_vtSurfaces[uiSurface].vbReversed[ui_loop] = true;
01127
01128
01129 }
01130 else
01131 {
01132
01133 m_vtSurfaces[uiSurface].vbReversed[ui_loop] = false;
01134
01135 }
01136
01137 m_vtSurfaces[uiSurface].vbUsed[ui_loop] = true;
01138
01139 }
01140
01141 m_vtSurfaces[uiSurface].clMin -= Vec3d(m_vtSurfaces[uiSurface].dError, m_vtSurfaces[uiSurface].dError, m_vtSurfaces[uiSurface].dError);
01142 m_vtSurfaces[uiSurface].clMax += Vec3d(m_vtSurfaces[uiSurface].dError, m_vtSurfaces[uiSurface].dError, m_vtSurfaces[uiSurface].dError);
01143 #ifdef OSG_ADAPTIVE_QUAD_TREE
01144 if(m_pclQuadTree != NULL)
01145 {
01146 delete m_pclQuadTree;
01147 m_pclQuadTree = NULL;
01148 }
01149 #endif
01150 m_vtSurfaces[uiSurface].ucStatus |= TRIMMING_VALID;
01151 }
01152
01153
01154
01155
01156
01157
01158 void CNurbsPatchSurface::CalculateActualTrimming(unsigned int uiSurface)
01159 {
01160 ParSpaceTrimmer cl_trimmer;
01161
01162
01163
01165
01166 #ifdef OSG_FORCE_NO_T_VERTICES
01167 cl_trimmer.Initialize2(m_clMesh,
01168 m_vtSurfaces[uiSurface].vvclEdgeLoops,
01169 m_vtSurfaces[uiSurface].vvclEdgeLoops3D,
01170
01171 m_vtSurfaces[uiSurface].vbReversed,
01172 m_vtSurfaces[uiSurface].vbUsed);
01173
01174 #else
01175 cl_trimmer.Initialize2(m_clMesh, m_vtSurfaces[uiSurface].vvclEdgeLoops, m_vtSurfaces[uiSurface].vvclEdgeLoops3D, m_vtSurfaces[uiSurface].vbReversed, m_vtSurfaces[uiSurface].vbUsed);
01176 #endif
01177
01178 try
01179 {
01180 if(cl_trimmer.PerformTrimming2() )
01181 {
01182 std::cerr << "Par space trimmer2 failed (surface " << uiSurface + 1 << ")." << std::endl;
01183 return;
01184 }
01185 }
01186 catch(ParSpaceTrimmerError cl_err)
01187 {
01188 std::cerr << "Par space trimmer2 exception caught: " << cl_err.errtype << " (surface " << uiSurface + 1 << ")" << std::endl;
01189 return;
01190 }
01191
01192 #ifndef OSG_FORCE_NO_T_VERTICES
01193
01194 cl_trimmer.getTrimmingLoops(m_vtSurfaces[uiSurface].vvclEdgeLoops);
01195 #endif
01196
01197 try
01198 {
01199 if(m_pclGraph)
01200 {
01201 delete m_pclGraph;
01202 }
01203 m_pclGraph = new DirectedGraph<Vec2d, unsigned char>;
01204 #ifdef OSG_KEEP_2D_POINTS
01205 if(cl_trimmer.buildSurfaceGraph(m_pclGraph, &m_vclGlobalVertices, NULL, &m_vuiIndex) )
01206 #else
01207 if(cl_trimmer.buildSurfaceGraph(m_pclGraph, &m_vclGlobalVertices) )
01208 #endif
01209 {
01210 std::cerr << "Build surface graph failed (surface " << uiSurface + 1 << ")." << std::endl;
01211 return;
01212 }
01213 }
01214 catch(ParSpaceTrimmerError cl_err)
01215 {
01216 std::cerr << "Par space trimmer exception caught: " << cl_err.errtype << " (surface " << uiSurface + 1 << ")" << std::endl;
01217
01218 return;
01219 }
01220
01221 m_vtSurfaces[uiSurface].ucStatus |= TRIMMING_VALID;
01222 }
01223
01224
01225
01226 void CNurbsPatchSurface::CalculateGraph(unsigned int uiSurface, bool usedelaunay)
01227 {
01228 GraphTraverser cl_traverser;
01229
01230 if(!(m_vtSurfaces[uiSurface].ucStatus & TRIMMING_VALID) )
01231 {
01232 std::cerr << "Trimming invalid for surface " << uiSurface + 1 << std::endl;
01233 return;
01234 }
01235
01236
01237
01238
01239 cl_traverser.Initialize(*m_pclGraph, usedelaunay);
01240 try
01241 {
01242 if(cl_traverser.Traverse() )
01243 {
01244 std::cerr << "Graph traverser failed (surface " << uiSurface + 1 << ")." << std::endl;
01245
01246
01247 }
01248 }
01249 catch(GraphTraverserError cl_err)
01250 {
01251 std::cerr << "Graph traverser exception caught: " << cl_err.errtype << " (surface " << uiSurface + 1 << ")" << std::endl;
01252
01253
01254 }
01255
01256 m_vclTriangles = *(cl_traverser.getPolys() );
01257 m_vclParameterVertices = *(cl_traverser.getVertices() );
01258 m_vtSurfaces[uiSurface].ucStatus |= TRIANGULATION_VALID;
01259
01260 #ifdef OSG_KEEP_2D_POINTS
01261
01262 const unsigned int cui_size = m_vclTriangles.size();
01263 unsigned int ui_idx;
01264
01265 for(ui_idx = 0; ui_idx < cui_size; ++ui_idx)
01266 {
01267 std::vector<int> & rvi_verts = m_vclTriangles[ui_idx].vertices;
01268 const unsigned int cui_vert_cnt = rvi_verts.size();
01269 unsigned int ui_vert;
01270
01271 for(ui_vert = 0; ui_vert < cui_vert_cnt; ++ui_vert)
01272 {
01273
01274 if(rvi_verts[ui_vert] < ( int ) m_vuiIndex.size() )
01275 rvi_verts[ui_vert] = ( int ) m_vuiIndex[rvi_verts[ui_vert]];
01276 }
01277 }
01278
01279
01280 const unsigned int cui_loop_cnt = m_vtSurfaces[0].vvclEdgeLoops3D.size();
01281 unsigned int ui_loop;
01282
01283 ui_idx = 0;
01284
01285 for(ui_loop = 0; ui_loop < cui_loop_cnt; ++ui_loop)
01286 {
01287 if(m_vtSurfaces[0].vbUsed[ui_loop])
01288 {
01289 const unsigned int cui_vert_cnt = m_vtSurfaces[0].vvclEdgeLoops[ui_loop].size();
01290 unsigned int ui_vert;
01291
01292 for(ui_vert = 0; ui_vert < cui_vert_cnt; ++ui_vert)
01293 {
01294 m_vclParameterVertices[ui_idx] = m_vtSurfaces[0].vvclEdgeLoops[ui_loop][ui_vert];
01295 ++ui_idx;
01296 }
01297 }
01298 }
01299
01300
01301
01302
01303
01304 #endif
01305 }
01306
01307
01308
01309
01310 void CNurbsPatchSurface::ComputeNormalCone(const unsigned int cuiSurface,
01311 std::vector<Vec3f>& normals)
01312 {
01313
01314
01315
01316
01317
01318
01319
01320
01321
01322
01323
01324
01325
01326
01327
01328
01329
01330
01331
01332
01333
01334
01335
01336
01337
01338
01339
01340
01341
01342
01343
01344
01345
01346
01347
01348
01349
01350
01351
01352
01353
01354
01355
01356
01357
01358
01359
01360
01361
01362
01363 }
01364
01365 void CNurbsPatchSurface::Gen3DLoops(const unsigned int cuiSurface)
01366 {
01367 const unsigned int cui_loop_cnt = m_vtSurfaces[cuiSurface].vvclBezierCurves.size();
01368 unsigned int ui_loop;
01369 unsigned int ui_curve_cnt;
01370 unsigned int ui_curve;
01371 bezier2ddeque vcl_new_curves;
01372 std::vector<unsigned int> vui_u_seg;
01373 std::vector<unsigned int> vui_v_seg;
01374 unsigned int ui_dim;
01375 unsigned int ui_pos;
01376 Vec2d cl_param;
01377 std::vector<Vec4d> vcl_points;
01378 int i_err;
01379
01380 m_vtSurfaces[cuiSurface].vvcl3DCurves.resize(cui_loop_cnt);
01381
01382 for(ui_loop = 0; ui_loop < cui_loop_cnt; ++ui_loop)
01383 {
01384
01385 vcl_new_curves.clear();
01386 vui_u_seg.clear();
01387 vui_v_seg.clear();
01388 ui_curve_cnt = m_vtSurfaces[cuiSurface].vvclBezierCurves[ui_loop].size();
01389
01390 for(ui_curve = 0; ui_curve < ui_curve_cnt; ++ui_curve)
01391 {
01392 CutCurve(cuiSurface, m_vtSurfaces[cuiSurface].vvclBezierCurves[ui_loop][ui_curve],
01393 vcl_new_curves, vui_u_seg, vui_v_seg);
01394 }
01395
01396 m_vtSurfaces[cuiSurface].vvclBezierCurves[ui_loop] = vcl_new_curves;
01397
01398
01399 ui_curve_cnt = m_vtSurfaces[cuiSurface].vvclBezierCurves[ui_loop].size();
01400 m_vtSurfaces[cuiSurface].vvcl3DCurves[ui_loop].resize(ui_curve_cnt);
01401
01402 for(ui_curve = 0; ui_curve < ui_curve_cnt; ++ui_curve)
01403 {
01404 const unsigned int cui_u_seg = vui_u_seg[ui_curve];
01405 const unsigned int cui_v_seg = vui_v_seg[ui_curve];
01406 BezierTensorSurface &rcl_surf = m_vvvclBezierSurfaces[cuiSurface][cui_u_seg][cui_v_seg];
01407 BezierCurve2D & rcl_curve2d = m_vtSurfaces[cuiSurface].vvclBezierCurves[ui_loop][ui_curve];
01408
01409 rcl_curve2d.optimizeDegree();
01410
01411
01412
01413
01414
01415
01416
01417
01418
01419
01420
01421
01422
01423 unsigned int approxdegree = rcl_curve2d.computeNonratApproximationDegree(1e-4);
01424 ui_dim = ( (rcl_surf.getControlPointMatrix().size() - 1)
01425 + (rcl_surf.getControlPointMatrix()[0].size() - 1) )
01426 * approxdegree;
01427 #ifdef OSG_NURBS_DEBUG
01428 if(approxdegree != rcl_curve2d.getControlPointVector().size() - 1)
01429 {
01430 std::cerr << "approxdegree: " << approxdegree << " dim: " << ui_dim << std::endl;
01431 }
01432 #endif
01433
01434 if(ui_dim > 40)
01435 ui_dim = 40;
01436
01437 vcl_points.clear();
01438
01439 for(ui_pos = 0; ui_pos <= ui_dim; ++ui_pos)
01440 {
01441 i_err = 0;
01442 cl_param = rcl_curve2d.computewdeCasteljau( (double(ui_pos) ) / ui_dim, i_err);
01443
01444 vcl_points.push_back(m_vclBSplineSurfaces[cuiSurface].getSurface().compute4D(cl_param, i_err) );
01445 }
01446
01447 if(m_vtSurfaces[cuiSurface].vvcl3DCurves[ui_loop][ui_curve].createCurve(vcl_points) == 0)
01448 {
01449 m_vtSurfaces[cuiSurface].vvcl3DCurves[ui_loop][ui_curve].optimizeDegree();
01450 }
01451 #ifdef OSG_NURBS_DEBUG
01452 if(approxdegree != rcl_curve2d.getControlPointVector().size() - 1)
01453 {
01454 std::cerr << "optimdegree: " << m_vtSurfaces[cuiSurface].vvcl3DCurves[ui_loop][ui_curve].getControlPointVector().size() - 1 << std::endl;
01455 }
01456 #endif
01457
01458
01459 }
01460 }
01461 }
01462
01463 void CNurbsPatchSurface::CutCurve(const unsigned int cuiSurface, BezierCurve2D &rclCurve, bezier2ddeque &rclCut, std::vector<unsigned int> &rvuiUSeg, std::vector<unsigned int> &rvuiVSeg)
01464 {
01465 const int ci_u_seg_cnt = m_vvdUParams[cuiSurface].size();
01466 const int ci_v_seg_cnt = m_vvdVParams[cuiSurface].size();
01467 int i_u_seg;
01468 int i_v_seg;
01469 unsigned int ui_curve;
01470 unsigned int ui_curve_cnt = 1;
01471 std::vector<BezierCurve2D> vcl_curves;
01472 std::vector<double> vd_curvestart;
01473 std::vector<double> vd_curveend;
01474 std::vector<double> vd_int;
01475 unsigned int ui_int;
01476 BezierCurve2D cl_new_curve;
01477 std::multimap<double, unsigned int> mm_curve_sort;
01478 std::multimap<double, unsigned int>::iterator
01479 itmm_curve_it;
01480 int i_err;
01481
01482 bool b_cut;
01483
01484 vcl_curves.push_back(rclCurve);
01485 vd_curvestart.push_back(0.0);
01486 vd_curveend.push_back(1.0);
01487 mm_curve_sort.insert(std::make_pair<const double, unsigned int>(0.0, 0u));
01488
01489 for(ui_curve = 0; ui_curve < ui_curve_cnt; ++ui_curve)
01490 {
01491 b_cut = false;
01492
01493
01494 for(i_u_seg = 0; i_u_seg < ci_u_seg_cnt; ++i_u_seg)
01495 {
01496 vd_int.clear();
01497 vcl_curves[ui_curve].intersection(vd_int, m_vvdUParams[cuiSurface][i_u_seg], false);
01498
01499 for(ui_int = 0; ui_int < vd_int.size(); ++ui_int)
01500 {
01501 if( (vd_int[ui_int] > 1e-7) &&
01502 (1.0 - vd_int[ui_int] > 1e-7) )
01503 {
01504 vcl_curves[ui_curve].subDivision(vd_int[ui_int], cl_new_curve);
01505 vcl_curves.push_back(cl_new_curve);
01506 vd_curvestart.push_back( (vd_curvestart[ui_curve] + vd_curveend[ui_curve]) * 0.5);
01507 vd_curveend.push_back(vd_curveend[ui_curve]);
01508 vd_curveend[ui_curve] = vd_curvestart[ui_curve_cnt];
01509 mm_curve_sort.insert(std::make_pair<const double, unsigned int>(vd_curvestart[ui_curve_cnt], ui_curve_cnt) );
01510 ++ui_curve_cnt;
01511 b_cut = true;
01512 break;
01513 }
01514 }
01515 }
01516
01517 if(!b_cut)
01518 {
01519
01520 for(i_v_seg = 0; i_v_seg < ci_v_seg_cnt; ++i_v_seg)
01521 {
01522 vd_int.clear();
01523 vcl_curves[ui_curve].intersection(vd_int, m_vvdVParams[cuiSurface][i_v_seg], true);
01524
01525 for(ui_int = 0; ui_int < vd_int.size(); ++ui_int)
01526 {
01527 if( (vd_int[ui_int] > 1e-7) &&
01528 (1.0 - vd_int[ui_int] > 1e-7) )
01529 {
01530 vcl_curves[ui_curve].subDivision(vd_int[ui_int], cl_new_curve);
01531 vcl_curves.push_back(cl_new_curve);
01532 vd_curvestart.push_back( (vd_curvestart[ui_curve] + vd_curveend[ui_curve]) * 0.5);
01533 vd_curveend.push_back(vd_curveend[ui_curve]);
01534 vd_curveend[ui_curve] = vd_curvestart[ui_curve_cnt];
01535 mm_curve_sort.insert(std::make_pair<const double, unsigned int>(vd_curvestart[ui_curve_cnt], ui_curve_cnt) );
01536 ++ui_curve_cnt;
01537 b_cut = true;
01538 break;
01539 }
01540 }
01541 }
01542 }
01543 if(b_cut)
01544 {
01545 --ui_curve;
01546 }
01547 }
01548
01549
01550 const unsigned int cui_offset = rclCut.size();
01551
01552 rclCut.resize(ui_curve_cnt + cui_offset);
01553 ui_curve = 0;
01554
01555 for(itmm_curve_it = mm_curve_sort.begin(); itmm_curve_it != mm_curve_sort.end(); ++itmm_curve_it)
01556 {
01557
01558 rclCut[ui_curve + cui_offset] = vcl_curves[itmm_curve_it->second];
01559 ++ui_curve;
01560 }
01561
01562
01563
01564
01565 for(ui_curve = 0; ui_curve < ui_curve_cnt; ++ui_curve)
01566 {
01567 const Vec2d ccl_mid = rclCut[ui_curve + cui_offset].computewdeCasteljau(0.5, i_err);
01568
01569
01570 if(ccl_mid[0] <= m_vvdUParams[cuiSurface][0])
01571 {
01572 std::vector<Vec3d> &rcl_cp = rclCut[ui_curve + cui_offset].getControlPointVector();
01573
01574 rcl_cp[1] = rcl_cp[rcl_cp.size() - 1];
01575 rcl_cp[0][0] = m_vvdUParams[cuiSurface][0] * rcl_cp[0][2];
01576 rcl_cp[1][0] = m_vvdUParams[cuiSurface][0] * rcl_cp[1][2];
01577 rcl_cp.resize(2);
01578 rvuiUSeg.push_back(0);
01579 }
01580 else if(ccl_mid[0] >= m_vvdUParams[cuiSurface][ci_u_seg_cnt - 1])
01581 {
01582 std::vector<Vec3d> &rcl_cp = rclCut[ui_curve + cui_offset].getControlPointVector();
01583
01584 rcl_cp[1] = rcl_cp[rcl_cp.size() - 1];
01585 rcl_cp[0][0] = m_vvdUParams[cuiSurface][ci_u_seg_cnt - 1] * rcl_cp[0][2];
01586 rcl_cp[1][0] = m_vvdUParams[cuiSurface][ci_u_seg_cnt - 1] * rcl_cp[1][2];
01587 rcl_cp.resize(2);
01588 rvuiUSeg.push_back(ci_u_seg_cnt - 2);
01589 }
01590 else
01591 {
01592 for(i_u_seg = 1; i_u_seg < ci_u_seg_cnt; ++i_u_seg)
01593 {
01594 if(ccl_mid[0] <= m_vvdUParams[cuiSurface][i_u_seg])
01595 {
01596 rvuiUSeg.push_back(i_u_seg - 1);
01597 break;
01598 }
01599 }
01600 }
01601
01602
01603 if(ccl_mid[1] <= m_vvdVParams[cuiSurface][0])
01604 {
01605 std::vector<Vec3d> &rcl_cp = rclCut[ui_curve + cui_offset].getControlPointVector();
01606
01607 rcl_cp[1] = rcl_cp[rcl_cp.size() - 1];
01608 rcl_cp[0][1] = m_vvdVParams[cuiSurface][0] * rcl_cp[0][2];
01609 rcl_cp[1][1] = m_vvdVParams[cuiSurface][0] * rcl_cp[1][2];
01610 rcl_cp.resize(2);
01611 rvuiVSeg.push_back(0);
01612 }
01613 else if(ccl_mid[1] >= m_vvdVParams[cuiSurface][ci_v_seg_cnt - 1])
01614 {
01615 std::vector<Vec3d> &rcl_cp = rclCut[ui_curve + cui_offset].getControlPointVector();
01616
01617 rcl_cp[1] = rcl_cp[rcl_cp.size() - 1];
01618 rcl_cp[0][1] = m_vvdVParams[cuiSurface][ci_v_seg_cnt - 1] * rcl_cp[0][2];
01619 rcl_cp[1][1] = m_vvdVParams[cuiSurface][ci_v_seg_cnt - 1] * rcl_cp[1][2];
01620 rcl_cp.resize(2);
01621 rvuiVSeg.push_back(ci_v_seg_cnt - 2);
01622 }
01623 else
01624 {
01625 for(i_v_seg = 1; i_v_seg < ci_v_seg_cnt; ++i_v_seg)
01626 {
01627 if(ccl_mid[1] <= m_vvdVParams[cuiSurface][i_v_seg])
01628 {
01629 rvuiVSeg.push_back(i_v_seg - 1);
01630 break;
01631 }
01632 }
01633 }
01634 }
01635 }