19 : mbImpl( impl ), pcomm( comm ), _mesh2rec( meshIn ), _MINPNTS( minpnts )
21 assert( NULL != impl );
37 std::cout <<
"Error initializing HiReconstruction\n" << std::endl;
56 std::cout <<
"HIREC_USE_AHF: Initializing" << std::endl;
84 MB_SET_ERR( MB_FAILURE,
"Encountered a non-manifold mesh or a mesh with volume elements" );
115 MB_SET_ERR( MB_FAILURE,
"Unknow space dimension" );
141 double *coeffs, *coords;
143 int ncoeffs = ( degree + 2 ) * ( degree + 1 ) / 2;
187 MB_SET_ERR( MB_FAILURE,
"Input number of degrees doesn't match number of vertices" );
200 double *coeffs, *coords;
206 assert( -1 != index );
212 int ncoeffs = ( degrees[i] + 2 ) * ( degrees[i] + 1 ) / 2;
234 double *coords = 0, *coeffs;
236 int ncoeffs = 3 * ( degree + 1 );
240 assert( index != -1 );
263 MB_SET_ERR( MB_FAILURE,
"Input number of degrees doesn't match the number of vertices" );
275 double *coords = 0, *coeffs;
285 int ncoeffs = 3 * ( degrees[i] + 1 );
298 const bool safeguard,
319 size_t nverts = ngbvs.
size();
321 double* ngbcoords =
new double[nverts * 3];
324 double* ngbnrms =
new double[nverts * 3];
327 int index = ngbvs.
index( vid );
328 assert( index != -1 );
329 std::swap( ngbcoords[0], ngbcoords[3 * index] );
330 std::swap( ngbcoords[1], ngbcoords[3 * index + 1] );
331 std::swap( ngbcoords[2], ngbcoords[3 * index + 2] );
332 std::swap( ngbnrms[0], ngbnrms[3 * index] );
333 std::swap( ngbnrms[1], ngbnrms[3 * index + 1] );
334 std::swap( ngbnrms[2], ngbnrms[3 * index + 2] );
336 int degree_pnt, degree_qr;
337 polyfit3d_surf_get_coeff( nverts, ngbcoords, ngbnrms, degree, interp, safeguard, ncoords, coords, ncoeffs, coeffs,
338 degree_out, °ree_pnt, °ree_qr );
348 const bool safeguard,
361 size_t nverts = ngbvs.
size();
363 double* ngbcoords =
new double[nverts * 3];
366 double* ngbtangs =
new double[nverts * 3];
369 int index = ngbvs.
index( vid );
370 assert( index != -1 );
371 std::swap( ngbcoords[0], ngbcoords[3 * index] );
372 std::swap( ngbcoords[1], ngbcoords[3 * index + 1] );
373 std::swap( ngbcoords[2], ngbcoords[3 * index + 2] );
374 std::swap( ngbtangs[0], ngbtangs[3 * index] );
375 std::swap( ngbtangs[1], ngbtangs[3 * index + 1] );
376 std::swap( ngbtangs[2], ngbtangs[3 * index + 2] );
378 polyfit3d_curve_get_coeff( nverts, ngbcoords, ngbtangs, degree, interp, safeguard, ncoords, coords, ncoeffs, coeffs,
392 const double* naturalcoords2fit,
398 std::vector< EntityHandle > elemconn;
400 if( nvpe != (
int)elemconn.size() )
402 MB_SET_ERR( MB_FAILURE,
"element connectivity table size doesn't match input size" );
407 MB_SET_ERR( MB_FAILURE,
"There is no existing fitting results" );
411 std::ostringstream convert;
413 std::string ID = convert.str();
414 for(
int i = 0; i < nvpe; ++i )
418 MB_SET_ERR( MB_FAILURE,
"There is no existing fitting results for element " + ID );
423 for(
int i = 0; i < npts2fit; ++i )
427 MB_SET_ERR( MB_FAILURE,
"Wrong barycentric coordinates" );
431 double* elemcoords =
new double[nvpe * 3];
434 double* coords2fit =
new double[3 * npts2fit]();
435 for(
int i = 0; i < npts2fit; ++i )
437 for(
int j = 0; j < nvpe; ++j )
439 coords2fit[3 * i] += naturalcoords2fit[i * nvpe + j] * elemcoords[3 * j];
440 coords2fit[3 * i + 1] += naturalcoords2fit[i * nvpe + j] * elemcoords[3 * j + 1];
441 coords2fit[3 * i + 2] += naturalcoords2fit[i * nvpe + j] * elemcoords[3 * j + 2];
445 double* hiproj_new =
new double[3 * npts2fit];
447 for(
int i = 0; i < npts2fit; ++i )
449 newcoords[3 * i] = newcoords[3 * i + 1] = newcoords[3 * i + 2] = 0;
452 for(
int j = 0; j < nvpe; ++j )
455 for(
int i = 0; i < npts2fit; ++i )
457 newcoords[3 * i] += naturalcoords2fit[i * nvpe + j] * hiproj_new[3 * i];
458 newcoords[3 * i + 1] += naturalcoords2fit[i * nvpe + j] * hiproj_new[3 * i + 1];
459 newcoords[3 * i + 2] += naturalcoords2fit[i * nvpe + j] * hiproj_new[3 * i + 2];
470 const double* coords2fit,
475 MB_SET_ERR( MB_FAILURE,
"There is no existing fitting results" );
479 std::ostringstream convert;
481 std::string VID = convert.str();
482 MB_SET_ERR( MB_FAILURE,
"There is no existing fitting results for vertex " + VID );
486 double local_origin[3];
492 double *uvw_coords, *local_coeffs;
514 const double* local_coords,
516 const double* local_coeffs,
519 const double* coords2fit,
522 double xaxis[3], yaxis[3], zaxis[3];
523 for(
int i = 0; i < 3; ++i )
525 xaxis[i] = local_coords[i];
526 yaxis[i] = local_coords[3 + i];
527 zaxis[i] = local_coords[6 + i];
530 std::vector< double > basis( ( local_deg + 2 ) * ( local_deg + 1 ) / 2 - 1 );
531 for(
int i = 0; i < npts2fit; ++i )
534 for(
int j = 0; j < 3; ++j )
536 local_pos[j] = coords2fit[3 * i + j] - local_origin[j];
538 double u, v, height = 0;
544 for(
int k = 2; k <= local_deg; ++k )
547 basis[l] = u * basis[l - k];
548 for(
int id = 0;
id < k; ++id )
551 basis[l] = basis[l - k - 1] * v;
556 height = local_coeffs[0];
558 for(
int p = 0; p <= l; ++p )
560 height += local_coeffs[p + 1] * basis[p];
562 hiproj_new[3 * i] = local_origin[0] + u * xaxis[0] + v * yaxis[0] + height * zaxis[0];
563 hiproj_new[3 * i + 1] = local_origin[1] + u * xaxis[1] + v * yaxis[1] + height * zaxis[1];
564 hiproj_new[3 * i + 2] = local_origin[2] + u * xaxis[2] + v * yaxis[2] + height * zaxis[2];
570 const double* local_coords,
572 const double* local_coeffs,
575 const double* coords2fit,
578 assert( local_origin && local_coords && local_coeffs );
579 int ncoeffspvpd = local_deg + 1;
580 for(
int i = 0; i < npts2fit; ++i )
583 double vec[3], ans[3] = { 0, 0, 0 };
589 ans[0] = local_coeffs[0];
590 ans[1] = local_coeffs[ncoeffspvpd];
591 ans[2] = local_coeffs[2 * ncoeffspvpd];
594 for(
int j = 1; j < ncoeffspvpd; ++j )
597 ans[0] += uk * local_coeffs[j];
598 ans[1] += uk * local_coeffs[j + ncoeffspvpd];
599 ans[2] += uk * local_coeffs[j + 2 * ncoeffspvpd];
601 hiproj_new[3 * i] = ans[0] + local_origin[0];
602 hiproj_new[3 * i + 1] = ans[1] + local_origin[1];
603 hiproj_new[3 * i + 2] = ans[2] + local_origin[2];
609 std::vector< double >& coords,
611 std::vector< double >& coeffs,
623 std::cout <<
"Input vertex is not locally hosted vertex in this mesh set" << std::endl;
632 int ncoeffs = ( degree_out + 2 ) * ( degree_out + 1 ) >> 1;
641 int ncoeffs = 3 * ( degree_out + 1 );
655 return interp ? ( ( degree + 1 ) >> 1 ) + ( ( degree + 1 ) & 1 ) : ( ( degree + 2 ) >> 1 ) + ( ( degree + 2 ) & 1 );
660 std::vector< EntityHandle >& adjents )
663 assert( elemdim ==
_dim );
675 std::deque< EntityHandle > todo;
676 todo.push_back( vid );
679 for(
int i = 1; i <= ring; ++i )
681 int count = todo.size();
687 std::vector< EntityHandle > adjents;
689 for(
size_t j = 0; j < adjents.size(); ++j )
691 std::vector< EntityHandle > elemconn;
693 int nvpe = elemconn.size();
694 for(
int k = 0; k < nvpe; ++k )
696 if( elemconn[k] ==
center )
698 pre = k == 0 ? elemconn[nvpe - 1] : elemconn[k - 1];
699 nxt = elemconn[( k + 1 ) % nvpe];
700 if( ngbvs.
find( pre ) == ngbvs.
end() )
703 todo.push_back( pre );
705 if( ngbvs.
find( nxt ) == ngbvs.
end() )
708 todo.push_back( nxt );
725 if( ( i == ring ) && ( minpnts > (int)ngbvs.
size() ) )
743 int ncoeffspv = ( degree + 2 ) * ( degree + 1 ) / 2;
748 for(
size_t i = 0; i <
_nv2rec; ++i )
770 for(
size_t i = 0; i <
_nv2rec; ++i )
773 index += ( degrees[i] + 2 ) * ( degrees[i] + 1 ) / 2;
789 int ncoeffspvpd = degree + 1;
794 for(
size_t i = 0; i <
_nv2rec; ++i )
816 for(
size_t i = 0; i <
_nv2rec; ++i )
819 index += 3 * ( degrees[i] + 1 );
844 std::vector< EntityHandle > adjfaces;
846 int npolys = adjfaces.size();
849 MB_SET_ERR( MB_FAILURE,
"Vertex has no incident 2D entities" );
853 double v1[3], v2[3], v3[3], a[3], b[3], c[3];
854 nrm[0] = nrm[1] = nrm[2] = 0;
855 for(
int i = 0; i < npolys; ++i )
858 std::vector< EntityHandle > elemconn;
861 int nvpe = elemconn.size();
862 for(
int j = 0; j < nvpe; ++j )
864 if( vid == elemconn[j] )
866 pre = j == 0 ? elemconn[nvpe - 1] : elemconn[j - 1];
867 nxt = elemconn[( j + 1 ) % nvpe];
925 assert( -1 != index );
946 std::vector< EntityHandle > adjedges;
948 int nedges = adjedges.size();
951 MB_SET_ERR( MB_FAILURE,
"Vertex has no incident edges" );
955 assert( nedges <= 2 );
956 tang[0] = tang[1] = tang[2] = 0;
957 for(
int i = 0; i < nedges; ++i )
959 std::vector< EntityHandle > edgeconn;
961 double istr[3], iend[3], t[3];
1011 assert( -1 != index );
1034 const double* ngbcoords,
1035 const double* ngbnrms,
1038 const bool safeguard,
1057 double nrm[3] = { ngbnrms[0], ngbnrms[1], ngbnrms[2] }, tang1[3] = { 0, 0, 0 }, tang2[3] = { 0, 0, 0 };
1058 if( fabs( nrm[0] ) > fabs( nrm[1] ) && fabs( nrm[0] ) > fabs( nrm[2] ) )
1072 if( 9 <= ncoords && coords )
1074 coords[0] = tang1[0];
1075 coords[1] = tang1[1];
1076 coords[2] = tang1[2];
1077 coords[3] = tang2[0];
1078 coords[4] = tang2[1];
1079 coords[5] = tang2[2];
1084 if( !ncoeffs || !coeffs )
1090 assert( ncoeffs >= ( degree + 2 ) * ( degree + 1 ) / 2 );
1094 int npts2fit = nverts - interp;
1097 *degree_out = *degree_pnt = *degree_qr = 0;
1098 for(
int i = 0; i < ncoeffs; ++i )
1105 std::vector< double > us( npts2fit * 2 );
1106 std::vector< double > bs( npts2fit );
1107 for(
int i = interp; i < nverts; ++i )
1118 std::vector< double > ws( npts2fit );
1124 if( nzeros == npts2fit )
1126 *degree_out = *degree_pnt = *degree_qr = 0;
1127 for(
int i = 0; i < ncoeffs; ++i )
1135 for(
int i = 0; i < npts2fit; ++i )
1141 us[index * 2] = us[i * 2];
1142 us[index * 2 + 1] = us[i * 2 + 1];
1150 assert( index == npts2fit );
1151 us.resize( npts2fit * 2 );
1152 bs.resize( npts2fit );
1153 ws.resize( npts2fit );
1162 eval_vander_bivar_cmf( npts2fit, &( us[0] ), 1, &( bs[0] ), degree, &( ws[0] ), interp, safeguard, degree_out,
1163 degree_pnt, degree_qr );
1166 int ncoeffs_out = ( *degree_out + 2 ) * ( *degree_out + 1 ) / 2;
1167 assert( ncoeffs_out <= ncoeffs );
1169 for(
int j = 0; j < ncoeffs_out - interp; ++j )
1171 coeffs[j + interp] = bs[j];
1183 const bool safeguard,
1189 int ncols = ( ( ( degree + 2 ) * ( degree + 1 ) ) >> 1 ) - interp;
1190 while( 1 < degree && npts2fit < ncols )
1193 ncols = ( ( ( degree + 2 ) * ( degree + 1 ) ) >> 1 ) - interp;
1195 *degree_pnt = degree;
1200 std::vector< double > V;
1205 V.erase( V.begin(), V.begin() + npts2fit );
1217 for(
int i = 0; i < npts2fit; ++i )
1219 for(
int j = 0; j < ncols; ++j )
1221 V[j * npts2fit + i] *= ws[i];
1223 for(
int k = 0; k < ndim; ++k )
1225 bs[k * npts2fit + i] *= ws[i];
1230 std::vector< double > ts( ncols );
1234 std::vector< double > D( ncols );
1239 int ncols_sub = ncols;
1240 while( rank < ncols_sub )
1246 *degree_out = *degree_qr = degree;
1247 for(
int i = 0; i < npts2fit; ++i )
1249 for(
int k = 0; k < ndim; ++k )
1251 bs[k * npts2fit + i] = 0;
1258 ncols_sub = ( ( ( degree + 2 ) * ( degree + 1 ) ) >> 1 ) - interp;
1261 *degree_qr = degree;
1293 for(
int i = 0; i < ncols_sub; ++i )
1295 V[i * npts2fit + i] = D[i];
1304 &( ts[0] ), degree_out );
1309 *degree_out = degree;
1319 const double* ngbcors,
1320 const double* ngbtangs,
1323 const bool safeguard,
1335 double tang[3] = { ngbtangs[0], ngbtangs[1], ngbtangs[2] };
1336 if( coords && ncoords > 2 )
1338 coords[0] = tang[0];
1339 coords[1] = tang[1];
1340 coords[2] = tang[2];
1342 if( !coeffs || !ncoeffs )
1348 assert( ncoeffs >= 3 * ( degree + 1 ) );
1351 int npts2fit = nverts - interp;
1355 for(
int i = 0; i < ncoeffs; ++i )
1361 std::vector< double > us( npts2fit );
1362 std::vector< double > bs( npts2fit * 3 );
1364 for(
int i = interp; i < nverts; ++i )
1370 bs[npts2fit + k] = uu[1];
1371 bs[2 * npts2fit + k] = uu[2];
1375 std::vector< double > ws( npts2fit );
1377 assert( nzeros <= npts2fit );
1382 if( nzeros == npts2fit )
1386 for(
int i = 0; i < ncoeffs; ++i )
1392 int npts_new = npts2fit - nzeros;
1393 std::vector< double > bs_temp( 3 * npts_new );
1395 for(
int i = 0; i < npts2fit; ++i )
1404 bs_temp[index] = bs[i];
1405 bs_temp[index + npts_new] = bs[i + npts2fit];
1406 bs_temp[index + 2 * npts_new] = bs[i + 2 * npts2fit];
1410 assert( index == npts_new );
1411 npts2fit = npts_new;
1416 std::vector< double >().swap( bs_temp );
1420 eval_vander_univar_cmf( npts2fit, &( us[0] ), 3, &( bs[0] ), degree, &( ws[0] ), interp, safeguard, degree_out );
1422 int ncoeffs_out_pvpd = *degree_out + 1;
1423 assert( ncoeffs >= 3 * ncoeffs_out_pvpd );
1425 coeffs[0] = coeffs[ncoeffs_out_pvpd] = coeffs[2 * ncoeffs_out_pvpd] = 0;
1426 for(
int i = 0; i < ncoeffs_out_pvpd - interp; ++i )
1428 coeffs[i + interp] = bs[i];
1429 coeffs[i + interp + ncoeffs_out_pvpd] = bs[i + npts2fit];
1430 coeffs[i + interp + 2 * ncoeffs_out_pvpd] = bs[i + 2 * npts2fit];
1441 const bool safeguard,
1445 int ncols = degree + 1 - interp;
1446 while( npts2fit < ncols && degree >= 1 )
1449 ncols = degree + 1 - interp;
1455 for(
int icol = 0; icol < ndim; ++icol )
1457 bs[icol * npts2fit] = 0;
1460 for(
int irow = 1; irow < npts2fit; ++irow )
1462 for(
int icol = 0; icol < ndim; ++icol )
1464 bs[icol * npts2fit + irow] = 0;
1471 std::vector< double > V;
1476 V.erase( V.begin(), V.begin() + npts2fit );
1480 for(
int i = 0; i < npts2fit; ++i )
1482 for(
int j = 0; j < ncols; ++j )
1484 V[j * npts2fit + i] *= ws[i];
1486 for(
int k = 0; k < ndim; ++k )
1488 bs[k * npts2fit + i] *= ws[i];
1493 std::vector< double > ts( ncols );
1497 std::vector< double > D( ncols );
1502 int ncols_sub = ncols;
1503 while( rank < ncols_sub )
1511 for(
int i = 0; i < npts2fit; ++i )
1513 for(
int k = 0; k < ndim; ++k )
1515 bs[k * npts2fit + i] = 0;
1519 ncols_sub = degree + 1 - interp;
1527 for(
int i = 0; i < ncols_sub; ++i )
1529 V[i * npts2fit + i] = D[i];
1540 *degree_out = degree;
1548 const double* ngbnrms,
1554 bool interp =
false;
1555 if( nngbs != nrows )
1557 assert( nngbs == nrows + 1 );
1560 double epsilon = 1e-2;
1563 for(
int i = 0; i < nrows; ++i )
1570 for(
int i = 0; i < nrows; ++i )
1578 for(
int i = 0; i < nrows; ++i )
1581 if( costheta > toler )
1583 ws[i] = costheta * pow( ws[i] / h + epsilon, -1 * (
double)degree / 2.0 );
1596 for(
int i = 0; i < nws; ++i )
1598 if( naturalcoords[i] < -
_MINEPS )
1602 sum += naturalcoords[i];