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 #include "PreCompiled.h"
00026 #include "UniGridApprox.h"
00027
00028 #include "best_fit.h"
00029
00030 #include <Mod/Mesh/App/Core/Grid.h>
00031 #include <Base/Builder3D.h>
00032
00033 #include <TColgp_Array2OfPnt.hxx>
00034 #include <TColStd_Array1OfReal.hxx>
00035 #include <TColStd_Array1OfInteger.hxx>
00036 #include <GeomAPI_ProjectPointOnSurf.hxx>
00037 #include <BRepBuilderAPI_MakeFace.hxx>
00038 #include <Geom_BSplineSurface.hxx>
00039 #include <Handle_Geom_BSplineSurface.hxx>
00040
00041
00043 #include <boost/numeric/bindings/traits/ublas_matrix.hpp>
00044 #include <boost/numeric/bindings/atlas/cblas.hpp>
00045 #include <boost/numeric/bindings/atlas/clapack.hpp>
00046
00047 using namespace boost::numeric::bindings;
00048
00049 typedef ublas::matrix<double, ublas::column_major> cm_t;
00050 typedef ublas::symmetric_adaptor<cm_t, ublas::upper> adapt;
00051
00052 UniGridApprox::UniGridApprox(const MeshCore::MeshKernel &mesh, double Tol)
00053 :m_Mesh(mesh),m_Tol(Tol),m_udeg(3),m_vdeg(3)
00054 {
00055 }
00056
00057 UniGridApprox::~UniGridApprox()
00058 {
00059 }
00060
00061 bool UniGridApprox::Perform(double TOL)
00062 {
00063
00064 double maxErr;
00065 cout << "MeshOffset" << endl;
00066 MeshOffset();
00067
00068 cout << "SurfMeshParam" << endl;
00069 SurfMeshParam();
00070
00071 while (true)
00072 {
00073 cout << "CompKnots" << endl;
00074 CompKnots(uCP, vCP);
00075
00076 cout << "MatComp" << endl;
00077 MatComp(uCP, vCP);
00078
00079 BuildSurf();
00080
00081 cout << "Compute Error";
00082 maxErr = CompMeshError();
00083
00084 if (maxErr == -1)
00085 throw Base::Exception("CompError() couldn't project one point...");
00086
00087 cout << " -> " << maxErr << endl;
00088
00089 if (maxErr <= TOL) break;
00090 else
00091 {
00092 if (uCP >= vCP)
00093 {
00094 uCP += 10;
00095 vCP += vCP*10/uCP;
00096 }
00097 else
00098 {
00099 vCP += 10;
00100 uCP += uCP*10/vCP;
00101 }
00102 }
00103
00104 if ( (uCP > (n_x + m_udeg + 1)) || (vCP > (n_y + m_vdeg + 1)) ) break;
00105
00106 m_Grid.clear();
00107 m_Grid = m_GridCopy;
00108 }
00109
00110 return true;
00111 }
00112
00113 bool UniGridApprox::MeshOffset()
00114 {
00115
00116 MeshCore::MeshPointIterator p_it(m_Mesh);
00117
00118
00119 std::vector<Base::Vector3f> normals = best_fit::Comp_Normals(m_Mesh);
00120
00121 double x_max=-(1e+10),y_max=-(1e+10),z_max=-(1e+10),x_min=1e+10,y_min=1e+10,st_x,st_y;
00122 int n = normals.size();
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134 m_Mesh.RecalcBoundBox();
00135
00136 for (p_it.Begin(); p_it.More(); p_it.Next())
00137 {
00138 if (p_it->z>z_max) z_max = p_it->z;
00139 if (p_it->x>x_max) x_max = p_it->x;
00140 if (p_it->x<x_min) x_min = p_it->x;
00141 if (p_it->y>y_max) y_max = p_it->y;
00142 if (p_it->y<y_min) y_min = p_it->y;
00143 }
00144
00145
00146 n_x = int((x_max - x_min)/(y_max - y_min)*sqrt((x_max - x_min)*(y_max - y_min)));
00147 n_y = int((y_max - y_min)/(x_max - x_min)*sqrt((x_max - x_min)*(y_max - y_min)));
00148
00149 st_x = (x_max - x_min)/n_x;
00150 st_y = (y_max - y_min)/n_y;
00151
00152 uCP = n_x/10;
00153 vCP = n_y/10;
00154
00155 m_Grid.resize(n_x+1);
00156 for (int i=0; i<n_x+1; ++i)
00157 m_Grid[i].resize(n_y+1);
00158
00159 unsigned long facetIndex;
00160 MeshCore::MeshFacetGrid aFacetGrid(m_Mesh);
00161 MeshCore::MeshAlgorithm malg(m_Mesh);
00162 MeshCore::MeshAlgorithm malg2(m_Mesh);
00163 Base::Vector3f projPoint, pnt, aNormal(0,0,1.0);
00164 Base::Builder3D log3d;
00165
00166 pnt.z = float(z_max);
00167
00168
00169
00170
00171 for (int i=0; i<n_x+1; ++i)
00172 {
00173 cout << double(i)/double(n_x) << endl;
00174 pnt.x = float(x_min + i*st_x);
00175 for (int j=0; j<n_y+1 - 10; ++j)
00176 {
00177 pnt.y = float(y_min + j*st_y);
00178 aNormal.z = 1.0;
00179 if (!malg.NearestFacetOnRay(pnt, aNormal, aFacetGrid, projPoint, facetIndex))
00180 {
00181 aNormal.Scale(1,1,-1);
00182 if (!malg.NearestFacetOnRay(pnt, aNormal, aFacetGrid, projPoint, facetIndex))
00183 {
00184 aNormal.Scale(1,1,-1);
00185 if (!malg2.NearestFacetOnRay(pnt, aNormal, projPoint, facetIndex))
00186 {
00187 aNormal.Scale(1,1,-1);
00188 if (!malg2.NearestFacetOnRay(pnt, aNormal, projPoint, facetIndex))
00189 {
00190 if (i != 0 && i !=n_x && j != 0 && j!= n_y)
00191 {
00192 pnt.x += float(st_x / 10.0);
00193 aNormal.Scale(1,1,-1);
00194 if (malg.NearestFacetOnRay(pnt, aNormal, aFacetGrid, projPoint, facetIndex))
00195 {
00196 log3d.addSinglePoint(projPoint, 3, 1,0,0);
00197 m_Grid[i][j] = projPoint;
00198
00199 }
00200 else
00201 {
00202 log3d.addSinglePoint(pnt, 3, 0,0,0);
00203 pnt.z = 1e+10;
00204 m_Grid[i][j] = pnt;
00205 pnt.z = (float) z_max;
00206 }
00207 }
00208 else
00209 {
00210 log3d.addSinglePoint(pnt, 3, 0,0,0);
00211 m_Grid[i][j] = pnt;
00212 }
00213 }
00214 else
00215 {
00216 log3d.addSinglePoint(projPoint, 3, 1,1,1);
00217 m_Grid[i][j] = projPoint;
00218 }
00219 }
00220 else
00221 {
00222 log3d.addSinglePoint(projPoint, 3, 1,1,1);
00223 m_Grid[i][j] = projPoint;
00224 }
00225 }
00226 else
00227 {
00228 log3d.addSinglePoint(projPoint, 3, 1,1,1);
00229 m_Grid[i][j] = projPoint;
00230 }
00231 }
00232 else
00233 {
00234 log3d.addSinglePoint(projPoint, 3, 1,1,1);
00235 m_Grid[i][j] = projPoint;
00236 }
00237 }
00238 }
00239
00240 int c=0;
00241 for (int i=0; i<n_x+1; ++i)
00242 {
00243 for (int j=0; j<n_y+1; ++j)
00244 {
00245 c=0;
00246 if (m_Grid[i][j].z == 1e+10)
00247 {
00248
00249 m_Grid[i][j].x = 0;
00250 m_Grid[i][j].y = 0;
00251 m_Grid[i][j].z = 0;
00252
00253 if (m_Grid[i-1][j].z != 1e+10)
00254 {
00255 m_Grid[i][j] += (m_Grid[i-1][j]);
00256 c++;
00257 }
00258
00259 if (m_Grid[i][j-1].z != 1e+10)
00260 {
00261 m_Grid[i][j] += (m_Grid[i][j-1]);
00262 c++;
00263 }
00264
00265 if (m_Grid[i][j+1].z != 1e+10)
00266 {
00267 m_Grid[i][j] += (m_Grid[i][j+1]);
00268 c++;
00269 }
00270
00271 if (m_Grid[i+1][j].z != 1e+10)
00272 {
00273 m_Grid[i][j] += (m_Grid[i+1][j]);
00274 c++;
00275 }
00276
00277 m_Grid[i][j].Scale( float(1.0 / double(c)), float(1.0 / double(c)), float(1.0 / double(c)));;
00278 log3d.addSinglePoint(m_Grid[i][j], 3, 0,0,0);
00279 }
00280 }
00281 }
00282
00283 m_GridCopy = m_Grid;
00284
00285 log3d.saveToFile("c:/projection.iv");
00286
00287 return true;
00288 }
00289
00290 bool UniGridApprox::SurfMeshParam()
00291 {
00292
00293
00294
00295 int n = m_Grid.size()-1;
00296 int m = m_Grid[0].size()-1;
00297
00298 std::vector<double> dist_x, dist_y;
00299 double sum,d;
00300 Base::Vector3f vlen;
00301
00302 m_uParam.clear();
00303 m_vParam.clear();
00304 m_uParam.resize(n+1);
00305 m_vParam.resize(m+1);
00306 m_uParam[n] = 1.0;
00307 m_vParam[m] = 1.0;
00308
00309
00310 for (int j=0; j<m+1; ++j)
00311 {
00312 sum = 0.0;
00313 dist_x.clear();
00314 for (int i=0; i<n; ++i)
00315 {
00316 vlen = (m_Grid[i+1][j] - m_Grid[i][j]);
00317 dist_x.push_back(vlen.Length());
00318 sum += dist_x[i];
00319 }
00320 d = 0.0;
00321 for (int i=0; i<n-1; ++i)
00322 {
00323 d += dist_x[i];
00324 m_uParam[i+1] = m_uParam[i+1] + d/sum;
00325 }
00326 }
00327
00328 for (int i=0; i<n; ++i)
00329 m_uParam[i] /= m+1;
00330
00331
00332 for (int i=0; i<n+1; ++i)
00333 {
00334 sum = 0.0;
00335 dist_y.clear();
00336 for (int j=0; j<m; ++j)
00337 {
00338 vlen = (m_Grid[i][j+1] - m_Grid[i][j]);
00339 dist_y.push_back(vlen.Length());
00340 sum += dist_y[j];
00341 }
00342 d = 0.0;
00343 for (int j=0; j<m-1; ++j)
00344 {
00345 d += dist_y[j];
00346 m_vParam[j+1] = m_vParam[j+1] + d/sum;
00347 }
00348 }
00349
00350 for (int j=0; j<m; ++j)
00351 m_vParam[j] /= n+1;
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363 return true;
00364 }
00365
00366 bool UniGridApprox::CompKnots(int u_CP, int v_CP)
00367 {
00368
00369
00370
00371
00372 int r = n_x;
00373 int s = n_y;
00374
00375 int n = u_CP-1;
00376 int m = v_CP-1;
00377
00378 m_um = u_CP;
00379 m_vm = v_CP;
00380
00381 int p = m_udeg;
00382 int q = m_vdeg;
00383
00384
00385 double d = ((double)r + 1.0)/((double)n - (double)p + 1.0);
00386
00387 m_uknots.clear();
00388 m_uknots.resize(n + p + 2);
00389
00390 for (int i=(p + 1) ; i<(n + p + 2); ++i)
00391 m_uknots[i] = 1.0;
00392
00393 int ind;
00394 double alp;
00395
00396 for (int i=1; i<(n - p + 1); ++i)
00397 {
00398
00399 ind = int(i*d);
00400 alp = i*d - ind;
00401 m_uknots[p+i] = ((1 - alp) * m_uParam[ind-1]) + (alp * m_uParam[ind]);
00402 }
00403
00404
00405
00406
00407
00408
00409 d = ((double)s + 1.0)/((double)m - (double)q + 1.0);
00410
00411 m_vknots.clear();
00412 m_vknots.resize(m + q + 2);
00413
00414 for (int i = (q + 1) ; i< (m + q + 2); ++i)
00415 m_vknots[i] = 1.0;
00416
00417 for (int i=1; i<(m - q + 1); ++i)
00418 {
00419
00420 ind = int(i*d);
00421 alp = i*d - ind;
00422 m_vknots[q+i] = ((1 - alp) * m_vParam[ind-1]) + (alp * m_vParam[ind]);
00423 }
00424
00425
00426
00427
00428
00429 return true;
00430 }
00431
00432 bool UniGridApprox::MatComp(int u_CP, int v_CP)
00433 {
00434
00435
00436 int r = n_x;
00437 int s = n_y;
00438
00439 int n = u_CP-1;
00440 int m = v_CP-1;
00441
00442 int p = m_udeg;
00443 int q = m_vdeg;
00444
00445 ublas::matrix<double> Nu_full(r - 1, n + 1);
00446 ublas::matrix<double> Nv_full(s - 1, m + 1);
00447 ublas::matrix<double> Nu_left(r - 1, n - 1);
00448 ublas::matrix<double> Nv_left(s - 1, m - 1);
00449 ublas::matrix<double> Nu (n - 1, n - 1);
00450 ublas::matrix<double> Nv (m - 1, m - 1);
00451
00452 ublas::matrix<double> bx (1, n - 1);
00453 ublas::matrix<double> by (1, n - 1);
00454 ublas::matrix<double> bz (1, n - 1);
00455
00456
00457 for (int i=0; i<r-1; ++i)
00458 for (int j=0; j<n+1; ++j)
00459 Nu_full(i,j) = 0.0;
00460
00461 for (int i=0; i<s-1; ++i)
00462 for (int j=0; j<m+1; ++j)
00463 Nv_full(i,j) = 0.0;
00464
00465 std::vector<double> output(p+1);
00466
00467 int ind;
00468 for (int i=1; i<r; ++i)
00469 {
00470 output.clear();
00471 output.resize(p+1);
00472 ind = Routines::FindSpan(n, p, m_uParam[i],m_uknots);
00473 Routines::Basisfun(ind,m_uParam[i],p,m_uknots,output);
00474
00475 for (unsigned int j=0; j<output.size(); ++j)
00476 {
00477 Nu_full(i-1,ind-p+j) = output[j];
00478 }
00479 }
00480
00481 for (int i=0; i<r-1; ++i)
00482 {
00483 for (int j=0; j<n-1; ++j)
00484 {
00485 Nu_left(i,j) = Nu_full(i,j+1);
00486 }
00487 }
00488
00489
00490
00491 for (int i=1; i<s; ++i)
00492 {
00493 output.clear();
00494 output.resize(q+1);
00495 ind = Routines::FindSpan(m, q, m_vParam[i],m_vknots);
00496 Routines::Basisfun(ind,m_vParam[i],q,m_vknots,output);
00497
00498 for (unsigned int j=0; j<output.size(); ++j)
00499 {
00500 Nv_full(i-1,ind-q+j) = output[j];
00501 }
00502 }
00503
00504 for (int i=0; i<s-1; ++i)
00505 {
00506 for (int j=0; j<m-1; ++j)
00507 {
00508 Nv_left(i,j) = Nv_full(i,j+1);
00509 }
00510 }
00511
00512
00513
00514
00515 atlas::gemm(CblasTrans,CblasNoTrans, 1.0, Nu_left,Nu_left, 0.0,Nu);
00516 atlas::gemm(CblasTrans,CblasNoTrans, 1.0, Nv_left,Nv_left, 0.0,Nv);
00517
00518 std::vector<int> upiv(n - 1);
00519 atlas::lu_factor(Nu,upiv);
00520 std::vector<int> vpiv(m - 1);
00521 atlas::lu_factor(Nv,vpiv);
00522
00523 ublas::matrix<double> uCP_x(n + 1, s + 1);
00524 ublas::matrix<double> uCP_y(n + 1, s + 1);
00525 ublas::matrix<double> uCP_z(n + 1, s + 1);
00526
00527 CPx.resize(n + 1, m + 1);
00528 CPy.resize(n + 1, m + 1);
00529 CPz.resize(n + 1, m + 1);
00530
00531
00532 for (int i=0; i<n+1; ++i)
00533 for (int j=0; j<s+1; ++j)
00534 {
00535 uCP_x(i,j) = 0.0;
00536 uCP_y(i,j) = 0.0;
00537 uCP_z(i,j) = 0.0;
00538 }
00539
00540 std::vector< ublas::matrix<double> > Ru_x(s+1);
00541 std::vector< ublas::matrix<double> > Ru_y(s+1);
00542 std::vector< ublas::matrix<double> > Ru_z(s+1);
00543
00544 for (int j=0; j<s+1; ++j)
00545 {
00546
00547 Ru_x[j].resize(r-1,1);
00548 Ru_y[j].resize(r-1,1);
00549 Ru_z[j].resize(r-1,1);
00550
00551 uCP_x(0,j) = m_Grid[0][j].x;
00552 uCP_y(0,j) = m_Grid[0][j].y;
00553 uCP_z(0,j) = m_Grid[0][j].z;
00554
00555 uCP_x(n,j) = m_Grid[r][j].x;
00556 uCP_y(n,j) = m_Grid[r][j].y;
00557 uCP_z(n,j) = m_Grid[r][j].z;
00558
00559 for (int k=0; k<r-1; ++k)
00560 {
00561 Ru_x[j](k,0) = m_Grid[k+1][j].x - Nu_full(k,0)*m_Grid[0][j].x - Nu_full(k,n)*m_Grid[r][j].x;
00562 Ru_y[j](k,0) = m_Grid[k+1][j].y - Nu_full(k,0)*m_Grid[0][j].y - Nu_full(k,n)*m_Grid[r][j].y;
00563 Ru_z[j](k,0) = m_Grid[k+1][j].z - Nu_full(k,0)*m_Grid[0][j].z - Nu_full(k,n)*m_Grid[r][j].z;
00564 }
00565
00566 atlas::gemm(CblasTrans,CblasNoTrans, 1.0, Ru_x[j],Nu_left, 0.0, bx);
00567 atlas::gemm(CblasTrans,CblasNoTrans, 1.0, Ru_y[j],Nu_left, 0.0, by);
00568 atlas::gemm(CblasTrans,CblasNoTrans, 1.0, Ru_z[j],Nu_left, 0.0, bz);
00569
00570 atlas::getrs(CblasTrans,Nu,upiv,bx);
00571 atlas::getrs(CblasTrans,Nu,upiv,by);
00572 atlas::getrs(CblasTrans,Nu,upiv,bz);
00573
00574 for (int i=1; i<n; ++i)
00575 {
00576 uCP_x(i,j) = bx(0,i-1);
00577 uCP_y(i,j) = by(0,i-1);
00578 uCP_z(i,j) = bz(0,i-1);
00579 }
00580 }
00581
00582 Base::Builder3D log3d;
00583 Base::Vector3f pnt,pnt1;
00584
00585 for (int j=0; j<s; ++j)
00586 {
00587 for (int i=0; i<n; ++i)
00588 {
00589
00590 pnt.x = (float) uCP_x(i,j);
00591 pnt.y = (float) uCP_y(i,j);
00592 pnt.z = (float) uCP_z(i,j);
00593
00594 pnt1.x = (float) uCP_x(i+1,j);
00595 pnt1.y = (float) uCP_y(i+1,j);
00596 pnt1.z = (float) uCP_z(i+1,j);
00597
00598 log3d.addSingleLine(pnt,pnt1, 1, 1,0,0);
00599 }
00600 }
00601
00602
00603 log3d.saveToFile("c:/ControlPoints_u.iv");
00604
00605
00606
00607
00608
00609
00610
00611 m_Grid.clear();
00612 m_Grid.resize(n+1);
00613 for (int i=0; i<n+1; ++i)
00614 m_Grid[i].resize(s+1);
00615
00616 for (int i=0; i<n+1; ++i)
00617 {
00618 for (int j=0; j<s+1; ++j)
00619 {
00620
00621 m_Grid[i][j].x = (float) uCP_x(i,j);
00622 m_Grid[i][j].y = (float) uCP_y(i,j);
00623 m_Grid[i][j].z = (float) uCP_z(i,j);
00624 }
00625 }
00626
00627
00628
00629
00630 for (int i=0; i<n + 1; ++i)
00631 {
00632 for (int j=0; j<m + 1; ++j)
00633 {
00634 CPx(i,j) = 0.0;
00635 CPy(i,j) = 0.0;
00636 CPz(i,j) = 0.0;
00637 }
00638 }
00639
00640 std::vector< ublas::matrix<double> > Rv_x(n+1);
00641 std::vector< ublas::matrix<double> > Rv_y(n+1);
00642 std::vector< ublas::matrix<double> > Rv_z(n+1);
00643
00644 Base::Builder3D log,logo;
00645
00646 for (int j=0; j<n+1; ++j)
00647 {
00648
00649 Rv_x[j].resize(s-1,1);
00650 Rv_y[j].resize(s-1,1);
00651 Rv_z[j].resize(s-1,1);
00652
00653 CPx(j,0) = uCP_x(j,0);
00654 CPy(j,0) = uCP_y(j,0);
00655 CPz(j,0) = uCP_z(j,0);
00656
00657 CPx(j,m) = uCP_x(j,s);
00658 CPy(j,m) = uCP_y(j,s);
00659 CPz(j,m) = uCP_z(j,s);
00660
00661 for (int k=0; k<s-1; ++k)
00662 {
00663
00664 Rv_x[j](k,0) = uCP_x(j,k+1) - Nv_full(k,0)*uCP_x(j,0) - Nv_full(k,m)*uCP_x(j,s);
00665 Rv_y[j](k,0) = uCP_y(j,k+1) - Nv_full(k,0)*uCP_y(j,0) - Nv_full(k,m)*uCP_y(j,s);
00666 Rv_z[j](k,0) = uCP_z(j,k+1) - Nv_full(k,0)*uCP_z(j,0) - Nv_full(k,m)*uCP_z(j,s);
00667
00668 pnt.x = (float) uCP_x(j,k+1);
00669 pnt.y = (float) uCP_y(j,k+1);
00670 pnt.z = (float) uCP_z(j,k+1);
00671
00672 pnt1.x = (float) uCP_x(j,k+2);
00673 pnt1.y = (float) uCP_y(j,k+2);
00674 pnt1.z = (float) uCP_z(j,k+2);
00675
00676 log.addSingleLine(pnt,pnt1, 1, 0,0,0);
00677
00678 }
00679
00680 bx.clear();
00681 by.clear();
00682 bz.clear();
00683 bx.resize(1, m - 1);
00684 by.resize(1, m - 1);
00685 bz.resize(1, m - 1);
00686
00687 atlas::gemm(CblasTrans,CblasNoTrans, 1.0, Rv_x[j],Nv_left, 0.0, bx);
00688 atlas::gemm(CblasTrans,CblasNoTrans, 1.0, Rv_y[j],Nv_left, 0.0, by);
00689 atlas::gemm(CblasTrans,CblasNoTrans, 1.0, Rv_z[j],Nv_left, 0.0, bz);
00690
00691 atlas::getrs(CblasTrans,Nv,vpiv,bx);
00692 atlas::getrs(CblasTrans,Nv,vpiv,by);
00693 atlas::getrs(CblasTrans,Nv,vpiv,bz);
00694
00695 for (int i=1; i<m; ++i)
00696 {
00697 CPx(j,i) = bx(0,i-1);
00698 CPy(j,i) = by(0,i-1);
00699 CPz(j,i) = bz(0,i-1);
00700
00701 pnt.x = (float) CPx(j,i);
00702 pnt.y = (float) CPy(j,i);
00703 pnt.z = (float) CPz(j,i);
00704
00705 logo.addSinglePoint(pnt,2,0,0,0);
00706 }
00707 }
00708
00709 logo.saveToFile("c:/contrPnts.iv");
00710
00711 ublas::matrix<double> Tmp = CPz;
00712
00713
00714 for (int i=1; i<n; ++i)
00715 {
00716 for (int j=1; j<m; ++j)
00717 {
00718
00719
00720
00721
00722 CPz(i,j) = (Tmp(i-1,j) + Tmp(i,j-1) + Tmp(i,j) + Tmp(i,j+1) +Tmp(i+1,j))/5;
00723 }
00724 }
00725
00726
00727
00728
00729
00730
00731
00732
00733
00734
00735
00736 return true;
00737 }
00738
00739 bool UniGridApprox::BuildSurf()
00740 {
00741
00742 gp_Pnt pnt;
00743 TColgp_Array2OfPnt Poles(1,m_um,1,m_vm);
00744
00745
00746
00747 for (int i=0; i<m_um; ++i)
00748 {
00749 for (int j=0; j<m_vm; ++j)
00750 {
00751 pnt.SetX(CPx(i,j));
00752 pnt.SetY(CPy(i,j));
00753 pnt.SetZ(CPz(i,j));
00754
00755 Poles.SetValue(i+1,j+1,pnt);
00756 }
00757 }
00758
00759 int c=1;
00760 for (unsigned int i=0; i<m_uknots.size()-1; ++i)
00761 {
00762 if (m_uknots[i+1] != m_uknots[i])
00763 {
00764 ++c;
00765 }
00766 }
00767
00768
00769 TColStd_Array1OfReal UKnots(1,c);
00770 TColStd_Array1OfInteger UMults(1,c);
00771
00772 c=1;
00773 for (unsigned int i=0; i<m_vknots.size()-1; ++i)
00774 {
00775 if (m_vknots[i+1] != m_vknots[i])
00776 {
00777 ++c;
00778 }
00779 }
00780
00781
00782 TColStd_Array1OfReal VKnots(1,c);
00783 TColStd_Array1OfInteger VMults(1,c);
00784
00785 int d=0;
00786 c=1;
00787 for (unsigned int i=0; i<m_uknots.size(); ++i)
00788 {
00789 if (m_uknots[i+1] != m_uknots[i])
00790 {
00791 UKnots.SetValue(d+1,m_uknots[i]);
00792 UMults.SetValue(d+1,c);
00793 ++d;
00794 c=1;
00795
00796 }
00797 else
00798 {
00799 ++c;
00800 }
00801
00802 if (i==(m_uknots.size()-2))
00803 {
00804 UKnots.SetValue(d+1,m_uknots[i+1]);
00805 UMults.SetValue(d+1,c);
00806 break;
00807 }
00808 }
00809
00810 d=0;
00811 c=1;
00812 for (unsigned int i=0; i<m_vknots.size(); ++i)
00813 {
00814 if (m_vknots[i+1] != m_vknots[i])
00815 {
00816 VKnots.SetValue(d+1,m_vknots[i]);
00817 VMults.SetValue(d+1,c);
00818 ++d;
00819 c=1;
00820
00821 }
00822 else
00823 {
00824 ++c;
00825 }
00826
00827 if (i==(m_vknots.size()-2))
00828 {
00829 VKnots.SetValue(d+1,m_vknots[i+1]);
00830 VMults.SetValue(d+1,c);
00831 break;
00832 }
00833 }
00834
00835
00836
00837
00838
00839
00840
00841
00842
00843
00844
00845
00846
00847
00848
00849
00850
00851
00852
00853
00854
00855
00856
00857
00858
00859 const Handle(Geom_BSplineSurface) surface = new Geom_BSplineSurface(
00860 Poles,
00861 UKnots,
00862 VKnots,
00863 UMults,
00864 VMults,
00865 3,
00866 3
00867
00868
00869 );
00870
00871 aAdaptorSurface.Load(surface);
00872
00873 return true;
00874 }
00875
00876 double UniGridApprox::CompGridError()
00877 {
00878 GeomAPI_ProjectPointOnSurf proj;
00879 MeshCore::MeshPointIterator pIt(m_Mesh);
00880 gp_Pnt pnt;
00881 double tmp = 0.0;
00882
00883 mG_err.clear();
00884 mG_err.resize(m_Grid.size());
00885 for (unsigned int i=0; i<m_Grid.size(); ++i)
00886 mG_err[i].resize(m_Grid[i].size());
00887
00888 for (unsigned int i=0; i<m_Grid.size(); ++i)
00889 {
00890 for (unsigned int j=0; j<m_Grid[i].size(); ++j)
00891 {
00892
00893 pnt.SetCoord(m_Grid[i][j].x, m_Grid[i][j].y, m_Grid[i][j].z);
00894 proj.Init(pnt,aAdaptorSurface.BSpline(),0.1);
00895 if (proj.IsDone() == false)
00896 return -1.0;
00897 mG_err[i][j] = proj.LowerDistance();
00898
00899 if (mG_err[i][j] > tmp)
00900 tmp = mG_err[i][j];
00901
00902 }
00903 }
00904
00905 return tmp;
00906 }
00907
00908 bool UniGridApprox::WriteMatrix(ublas::matrix<double> M)
00909 {
00910
00911 int row = M.size1();
00912 int col = M.size2();
00913
00914 for (int i=0; i<row; ++i)
00915 {
00916 for (int j=0; j<col; ++j)
00917 {
00918 cout << M(i,j) << ", ";
00919 }
00920 cout << endl;
00921 }
00922
00923 return true;
00924 }
00925
00926 double UniGridApprox::CompMeshError()
00927 {
00928 Base::Builder3D log3d;
00929 MeshCore::MeshKernel mesh;
00930 BRepBuilderAPI_MakeFace Face(aAdaptorSurface.BSpline());
00931 GeomAPI_ProjectPointOnSurf proj;
00932 best_fit::Tesselate_Face(Face.Face(), mesh, float(0.1));
00933 cout << mesh.CountPoints() << endl;
00934 std::vector<Base::Vector3f> normals = best_fit::Comp_Normals(mesh);
00935
00936 double tmp = 0.0, sqrdis;
00937 double errSum = 0.0;
00938 int c=0;
00939
00940 m_err.clear();
00941 m_err.resize(mesh.CountPoints(), 0.0);
00942
00943 MeshCore::MeshFacetGrid aFacetGrid(m_Mesh);
00944 MeshCore::MeshAlgorithm malg(m_Mesh);
00945 MeshCore::MeshAlgorithm malg2(m_Mesh);
00946 MeshCore::MeshPointIterator p_it(mesh);
00947
00948 Base::Vector3f projPoint, distVec, pnt;
00949 unsigned long facetIndex;
00950
00951
00952 for (p_it.Begin(); p_it.More(); p_it.Next())
00953 {
00954 if (!malg.NearestFacetOnRay(*p_it, normals[p_it.Position()], aFacetGrid, projPoint, facetIndex))
00955 {
00956 if (malg2.NearestFacetOnRay(*p_it, normals[p_it.Position()], projPoint, facetIndex))
00957 {
00958 pnt.x = p_it->x;
00959 pnt.y = p_it->y;
00960 pnt.z = p_it->z;
00961 log3d.addSingleLine(pnt,projPoint);
00962 distVec = projPoint - pnt;
00963 sqrdis = distVec*distVec;
00964 }
00965 else
00966 {
00967 cout << "oops, ";
00968 continue;
00969 }
00970 }
00971 else
00972 {
00973 pnt.x = p_it->x;
00974 pnt.y = p_it->y;
00975 pnt.z = p_it->z;
00976 log3d.addSingleLine(pnt,projPoint);
00977 distVec = projPoint - pnt;
00978 sqrdis = distVec*distVec;
00979 }
00980
00981 errSum += sqrt(sqrdis);
00982 ++c;
00983
00984 if (sqrt(sqrdis) > tmp)
00985 {
00986 m_err[p_it.Position()] = sqrt(sqrdis);
00987 tmp = m_err[p_it.Position()];
00988 }
00989 }
00990
00991 log3d.saveToFile("c:/Error.iv");
00992
00993 return errSum/c;
00994 }