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;
89 MB_SET_ERR( MB_FAILURE,
"Encountered a non-manifold mesh or a mesh with volume elements" );
121 MB_SET_ERR( MB_FAILURE,
"Unknow space dimension" );
147 double *coeffs, *coords;
149 int ncoeffs = ( degree + 2 ) * ( degree + 1 ) / 2;
194 MB_SET_ERR( MB_FAILURE,
"Input number of degrees doesn't match number of vertices" );
207 double *coeffs, *coords;
213 assert( -1 !=
index );
219 int ncoeffs = ( degrees[i] + 2 ) * ( degrees[i] + 1 ) / 2;
242 double *coords = 0, *coeffs;
244 int ncoeffs = 3 * ( degree + 1 );
248 assert(
index != -1 );
272 MB_SET_ERR( MB_FAILURE,
"Input number of degrees doesn't match the number of vertices" );
284 double *coords = 0, *coeffs;
294 int ncoeffs = 3 * ( degrees[i] + 1 );
308 const bool safeguard,
330 size_t nverts = ngbvs.
size();
332 double* ngbcoords =
new double[nverts * 3];
336 double* ngbnrms =
new double[nverts * 3];
341 assert(
index != -1 );
342 std::swap( ngbcoords[0], ngbcoords[3 *
index] );
343 std::swap( ngbcoords[1], ngbcoords[3 *
index + 1] );
344 std::swap( ngbcoords[2], ngbcoords[3 *
index + 2] );
345 std::swap( ngbnrms[0], ngbnrms[3 *
index] );
346 std::swap( ngbnrms[1], ngbnrms[3 *
index + 1] );
347 std::swap( ngbnrms[2], ngbnrms[3 *
index + 2] );
349 int degree_pnt, degree_qr;
350 polyfit3d_surf_get_coeff( nverts, ngbcoords, ngbnrms, degree, interp, safeguard, ncoords, coords, ncoeffs, coeffs,
351 degree_out, °ree_pnt, °ree_qr );
361 const bool safeguard,
375 size_t nverts = ngbvs.
size();
377 double* ngbcoords =
new double[nverts * 3];
381 double* ngbtangs =
new double[nverts * 3];
386 assert(
index != -1 );
387 std::swap( ngbcoords[0], ngbcoords[3 *
index] );
388 std::swap( ngbcoords[1], ngbcoords[3 *
index + 1] );
389 std::swap( ngbcoords[2], ngbcoords[3 *
index + 2] );
390 std::swap( ngbtangs[0], ngbtangs[3 *
index] );
391 std::swap( ngbtangs[1], ngbtangs[3 *
index + 1] );
392 std::swap( ngbtangs[2], ngbtangs[3 *
index + 2] );
394 polyfit3d_curve_get_coeff( nverts, ngbcoords, ngbtangs, degree, interp, safeguard, ncoords, coords, ncoeffs, coeffs,
408 const double* naturalcoords2fit,
414 std::vector< EntityHandle > elemconn;
417 if( nvpe != (
int)elemconn.size() )
419 MB_SET_ERR( MB_FAILURE,
"element connectivity table size doesn't match input size" );
424 MB_SET_ERR( MB_FAILURE,
"There is no existing fitting results" );
428 std::ostringstream convert;
430 std::string ID = convert.str();
431 for(
int i = 0; i < nvpe; ++i )
435 MB_SET_ERR( MB_FAILURE,
"There is no existing fitting results for element " + ID );
440 for(
int i = 0; i < npts2fit; ++i )
444 MB_SET_ERR( MB_FAILURE,
"Wrong barycentric coordinates" );
448 double* elemcoords =
new double[nvpe * 3];
452 double* coords2fit =
new double[3 * npts2fit]();
453 for(
int i = 0; i < npts2fit; ++i )
455 for(
int j = 0; j < nvpe; ++j )
457 coords2fit[3 * i] += naturalcoords2fit[i * nvpe + j] * elemcoords[3 * j];
458 coords2fit[3 * i + 1] += naturalcoords2fit[i * nvpe + j] * elemcoords[3 * j + 1];
459 coords2fit[3 * i + 2] += naturalcoords2fit[i * nvpe + j] * elemcoords[3 * j + 2];
463 double* hiproj_new =
new double[3 * npts2fit];
465 for(
int i = 0; i < npts2fit; ++i )
467 newcoords[3 * i] = newcoords[3 * i + 1] = newcoords[3 * i + 2] = 0;
470 for(
int j = 0; j < nvpe; ++j )
474 for(
int i = 0; i < npts2fit; ++i )
476 newcoords[3 * i] += naturalcoords2fit[i * nvpe + j] * hiproj_new[3 * i];
477 newcoords[3 * i + 1] += naturalcoords2fit[i * nvpe + j] * hiproj_new[3 * i + 1];
478 newcoords[3 * i + 2] += naturalcoords2fit[i * nvpe + j] * hiproj_new[3 * i + 2];
489 const double* coords2fit,
494 MB_SET_ERR( MB_FAILURE,
"There is no existing fitting results" );
498 std::ostringstream convert;
500 std::string VID = convert.str();
501 MB_SET_ERR( MB_FAILURE,
"There is no existing fitting results for vertex " + VID );
505 double local_origin[3];
512 double *uvw_coords, *local_coeffs;
534 const double* local_coords,
536 const double* local_coeffs,
539 const double* coords2fit,
542 double xaxis[3], yaxis[3], zaxis[3];
543 for(
int i = 0; i < 3; ++i )
545 xaxis[i] = local_coords[i];
546 yaxis[i] = local_coords[3 + i];
547 zaxis[i] = local_coords[6 + i];
550 std::vector< double > basis( ( local_deg + 2 ) * ( local_deg + 1 ) / 2 - 1 );
551 for(
int i = 0; i < npts2fit; ++i )
554 for(
int j = 0; j < 3; ++j )
556 local_pos[j] = coords2fit[3 * i + j] - local_origin[j];
558 double u, v, height = 0;
564 for(
int k = 2; k <= local_deg; ++k )
567 basis[l] = u * basis[l - k];
568 for(
int id = 0;
id < k; ++id )
571 basis[l] = basis[l - k - 1] * v;
576 height = local_coeffs[0];
578 for(
int p = 0; p <= l; ++p )
580 height += local_coeffs[p + 1] * basis[p];
582 hiproj_new[3 * i] = local_origin[0] + u * xaxis[0] + v * yaxis[0] + height * zaxis[0];
583 hiproj_new[3 * i + 1] = local_origin[1] + u * xaxis[1] + v * yaxis[1] + height * zaxis[1];
584 hiproj_new[3 * i + 2] = local_origin[2] + u * xaxis[2] + v * yaxis[2] + height * zaxis[2];
590 const double* local_coords,
592 const double* local_coeffs,
595 const double* coords2fit,
598 assert( local_origin && local_coords && local_coeffs );
599 int ncoeffspvpd = local_deg + 1;
600 for(
int i = 0; i < npts2fit; ++i )
603 double vec[3], ans[3] = { 0, 0, 0 };
609 ans[0] = local_coeffs[0];
610 ans[1] = local_coeffs[ncoeffspvpd];
611 ans[2] = local_coeffs[2 * ncoeffspvpd];
614 for(
int j = 1; j < ncoeffspvpd; ++j )
617 ans[0] += uk * local_coeffs[j];
618 ans[1] += uk * local_coeffs[j + ncoeffspvpd];
619 ans[2] += uk * local_coeffs[j + 2 * ncoeffspvpd];
621 hiproj_new[3 * i] = ans[0] + local_origin[0];
622 hiproj_new[3 * i + 1] = ans[1] + local_origin[1];
623 hiproj_new[3 * i + 2] = ans[2] + local_origin[2];
629 std::vector< double >& coords,
631 std::vector< double >& coeffs,
643 std::cout <<
"Input vertex is not locally hosted vertex in this mesh set" << std::endl;
652 int ncoeffs = ( degree_out + 2 ) * ( degree_out + 1 ) >> 1;
661 int ncoeffs = 3 * ( degree_out + 1 );
675 return interp ? ( ( degree + 1 ) >> 1 ) + ( ( degree + 1 ) & 1 ) : ( ( degree + 2 ) >> 1 ) + ( ( degree + 2 ) & 1 );
680 std::vector< EntityHandle >& adjents )
683 assert( elemdim ==
_dim );
697 std::deque< EntityHandle > todo;
698 todo.push_back( vid );
701 for(
int i = 1; i <= ring; ++i )
703 int count = todo.size();
709 std::vector< EntityHandle > adjents;
712 for(
size_t j = 0; j < adjents.size(); ++j )
714 std::vector< EntityHandle > elemconn;
717 int nvpe = elemconn.size();
718 for(
int k = 0; k < nvpe; ++k )
720 if( elemconn[k] ==
center )
722 pre = k == 0 ? elemconn[nvpe - 1] : elemconn[k - 1];
723 nxt = elemconn[( k + 1 ) % nvpe];
724 if( ngbvs.
find( pre ) == ngbvs.
end() )
727 todo.push_back( pre );
729 if( ngbvs.
find( nxt ) == ngbvs.
end() )
732 todo.push_back( nxt );
749 if( ( i == ring ) && ( minpnts > (int)ngbvs.
size() ) )
767 int ncoeffspv = ( degree + 2 ) * ( degree + 1 ) / 2;
772 for(
size_t i = 0; i <
_nv2rec; ++i )
794 for(
size_t i = 0; i <
_nv2rec; ++i )
797 index += ( degrees[i] + 2 ) * ( degrees[i] + 1 ) / 2;
813 int ncoeffspvpd = degree + 1;
818 for(
size_t i = 0; i <
_nv2rec; ++i )
840 for(
size_t i = 0; i <
_nv2rec; ++i )
843 index += 3 * ( degrees[i] + 1 );
868 std::vector< EntityHandle > adjfaces;
871 int npolys = adjfaces.size();
874 MB_SET_ERR( MB_FAILURE,
"Vertex has no incident 2D entities" );
878 double v1[3], v2[3], v3[3], a[3], b[3], c[3];
879 nrm[0] = nrm[1] = nrm[2] = 0;
880 for(
int i = 0; i < npolys; ++i )
883 std::vector< EntityHandle > elemconn;
887 int nvpe = elemconn.size();
888 for(
int j = 0; j < nvpe; ++j )
890 if( vid == elemconn[j] )
892 pre = j == 0 ? elemconn[nvpe - 1] : elemconn[j - 1];
893 nxt = elemconn[( j + 1 ) % nvpe];
956 assert( -1 !=
index );
978 std::vector< EntityHandle > adjedges;
981 int nedges = adjedges.size();
984 MB_SET_ERR( MB_FAILURE,
"Vertex has no incident edges" );
988 assert( nedges <= 2 );
989 tang[0] = tang[1] = tang[2] = 0;
990 for(
int i = 0; i < nedges; ++i )
992 std::vector< EntityHandle > edgeconn;
994 double istr[3], iend[3], t[3];
1033 #ifdef MOAB_HAVE_MPI
1046 assert( -1 !=
index );
1070 const double* ngbcoords,
1071 const double* ngbnrms,
1074 const bool safeguard,
1093 double nrm[3] = { ngbnrms[0], ngbnrms[1], ngbnrms[2] }, tang1[3] = { 0, 0, 0 }, tang2[3] = { 0, 0, 0 };
1094 if( fabs( nrm[0] ) > fabs( nrm[1] ) && fabs( nrm[0] ) > fabs( nrm[2] ) )
1108 if( 9 <= ncoords && coords )
1110 coords[0] = tang1[0];
1111 coords[1] = tang1[1];
1112 coords[2] = tang1[2];
1113 coords[3] = tang2[0];
1114 coords[4] = tang2[1];
1115 coords[5] = tang2[2];
1120 if( !ncoeffs || !coeffs )
1126 assert( ncoeffs >= ( degree + 2 ) * ( degree + 1 ) / 2 );
1130 int npts2fit = nverts - interp;
1133 *degree_out = *degree_pnt = *degree_qr = 0;
1134 for(
int i = 0; i < ncoeffs; ++i )
1141 std::vector< double > us( npts2fit * 2 );
1142 std::vector< double > bs( npts2fit );
1143 for(
int i = interp; i < nverts; ++i )
1154 std::vector< double > ws( npts2fit );
1160 if( nzeros == npts2fit )
1162 *degree_out = *degree_pnt = *degree_qr = 0;
1163 for(
int i = 0; i < ncoeffs; ++i )
1171 for(
int i = 0; i < npts2fit; ++i )
1177 us[
index * 2] = us[i * 2];
1178 us[
index * 2 + 1] = us[i * 2 + 1];
1186 assert(
index == npts2fit );
1187 us.resize( npts2fit * 2 );
1188 bs.resize( npts2fit );
1189 ws.resize( npts2fit );
1198 eval_vander_bivar_cmf( npts2fit, &( us[0] ), 1, &( bs[0] ), degree, &( ws[0] ), interp, safeguard, degree_out,
1199 degree_pnt, degree_qr );
1202 int ncoeffs_out = ( *degree_out + 2 ) * ( *degree_out + 1 ) / 2;
1203 assert( ncoeffs_out <= ncoeffs );
1205 for(
int j = 0; j < ncoeffs_out - interp; ++j )
1207 coeffs[j + interp] = bs[j];
1219 const bool safeguard,
1225 int ncols = ( ( ( degree + 2 ) * ( degree + 1 ) ) >> 1 ) - interp;
1226 while( 1 < degree && npts2fit < ncols )
1229 ncols = ( ( ( degree + 2 ) * ( degree + 1 ) ) >> 1 ) - interp;
1231 *degree_pnt = degree;
1236 std::vector< double > V;
1241 V.erase( V.begin(), V.begin() + npts2fit );
1253 for(
int i = 0; i < npts2fit; ++i )
1255 for(
int j = 0; j < ncols; ++j )
1257 V[j * npts2fit + i] *= ws[i];
1259 for(
int k = 0; k < ndim; ++k )
1261 bs[k * npts2fit + i] *= ws[i];
1266 std::vector< double > ts( ncols );
1270 std::vector< double > D( ncols );
1275 int ncols_sub = ncols;
1276 while( rank < ncols_sub )
1282 *degree_out = *degree_qr = degree;
1283 for(
int i = 0; i < npts2fit; ++i )
1285 for(
int k = 0; k < ndim; ++k )
1287 bs[k * npts2fit + i] = 0;
1294 ncols_sub = ( ( ( degree + 2 ) * ( degree + 1 ) ) >> 1 ) - interp;
1297 *degree_qr = degree;
1329 for(
int i = 0; i < ncols_sub; ++i )
1331 V[i * npts2fit + i] = D[i];
1340 &( ts[0] ), degree_out );
1345 *degree_out = degree;
1355 const double* ngbcors,
1356 const double* ngbtangs,
1359 const bool safeguard,
1371 double tang[3] = { ngbtangs[0], ngbtangs[1], ngbtangs[2] };
1372 if( coords && ncoords > 2 )
1374 coords[0] = tang[0];
1375 coords[1] = tang[1];
1376 coords[2] = tang[2];
1378 if( !coeffs || !ncoeffs )
1384 assert( ncoeffs >= 3 * ( degree + 1 ) );
1387 int npts2fit = nverts - interp;
1391 for(
int i = 0; i < ncoeffs; ++i )
1397 std::vector< double > us( npts2fit );
1398 std::vector< double > bs( npts2fit * 3 );
1400 for(
int i = interp; i < nverts; ++i )
1406 bs[npts2fit + k] = uu[1];
1407 bs[2 * npts2fit + k] = uu[2];
1411 std::vector< double > ws( npts2fit );
1413 assert( nzeros <= npts2fit );
1418 if( nzeros == npts2fit )
1422 for(
int i = 0; i < ncoeffs; ++i )
1428 int npts_new = npts2fit - nzeros;
1429 std::vector< double > bs_temp( 3 * npts_new );
1431 for(
int i = 0; i < npts2fit; ++i )
1440 bs_temp[
index] = bs[i];
1441 bs_temp[
index + npts_new] = bs[i + npts2fit];
1442 bs_temp[
index + 2 * npts_new] = bs[i + 2 * npts2fit];
1446 assert(
index == npts_new );
1447 npts2fit = npts_new;
1452 std::vector< double >().swap( bs_temp );
1456 eval_vander_univar_cmf( npts2fit, &( us[0] ), 3, &( bs[0] ), degree, &( ws[0] ), interp, safeguard, degree_out );
1458 int ncoeffs_out_pvpd = *degree_out + 1;
1459 assert( ncoeffs >= 3 * ncoeffs_out_pvpd );
1461 coeffs[0] = coeffs[ncoeffs_out_pvpd] = coeffs[2 * ncoeffs_out_pvpd] = 0;
1462 for(
int i = 0; i < ncoeffs_out_pvpd - interp; ++i )
1464 coeffs[i + interp] = bs[i];
1465 coeffs[i + interp + ncoeffs_out_pvpd] = bs[i + npts2fit];
1466 coeffs[i + interp + 2 * ncoeffs_out_pvpd] = bs[i + 2 * npts2fit];
1477 const bool safeguard,
1481 int ncols = degree + 1 - interp;
1482 while( npts2fit < ncols && degree >= 1 )
1485 ncols = degree + 1 - interp;
1491 for(
int icol = 0; icol < ndim; ++icol )
1493 bs[icol * npts2fit] = 0;
1496 for(
int irow = 1; irow < npts2fit; ++irow )
1498 for(
int icol = 0; icol < ndim; ++icol )
1500 bs[icol * npts2fit + irow] = 0;
1507 std::vector< double > V;
1512 V.erase( V.begin(), V.begin() + npts2fit );
1516 for(
int i = 0; i < npts2fit; ++i )
1518 for(
int j = 0; j < ncols; ++j )
1520 V[j * npts2fit + i] *= ws[i];
1522 for(
int k = 0; k < ndim; ++k )
1524 bs[k * npts2fit + i] *= ws[i];
1529 std::vector< double > ts( ncols );
1533 std::vector< double > D( ncols );
1538 int ncols_sub = ncols;
1539 while( rank < ncols_sub )
1547 for(
int i = 0; i < npts2fit; ++i )
1549 for(
int k = 0; k < ndim; ++k )
1551 bs[k * npts2fit + i] = 0;
1555 ncols_sub = degree + 1 - interp;
1563 for(
int i = 0; i < ncols_sub; ++i )
1565 V[i * npts2fit + i] = D[i];
1576 *degree_out = degree;
1584 const double* ngbnrms,
1590 bool interp =
false;
1591 if( nngbs != nrows )
1593 assert( nngbs == nrows + 1 );
1596 double epsilon = 1e-2;
1599 for(
int i = 0; i < nrows; ++i )
1606 for(
int i = 0; i < nrows; ++i )
1614 for(
int i = 0; i < nrows; ++i )
1617 if( costheta > toler )
1619 ws[i] = costheta * pow( ws[i] / h + epsilon, -1 * (
double)degree / 2.0 );
1632 for(
int i = 0; i < nws; ++i )
1634 if( naturalcoords[i] < -
_MINEPS )
1638 sum += naturalcoords[i];