Loading [MathJax]/extensions/tex2jax.js
Mesh Oriented datABase  (version 5.5.1)
An array-based unstructured mesh library
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
moab::SmoothFace Class Reference

Implement CAMAL geometry callbacks using smooth iMesh. More...

#include <SmoothFace.hpp>

+ Collaboration diagram for moab::SmoothFace:

Public Member Functions

 SmoothFace (Interface *mb, EntityHandle surface_set, GeomTopoTool *gTool)
 
virtual ~SmoothFace ()
 
virtual double area ()
 
virtual void bounding_box (double box_min[3], double box_max[3])
 
virtual void move_to_surface (double &x, double &y, double &z)
 
virtual bool normal_at (double x, double y, double z, double &nx, double &ny, double &nz)
 
int init_gradient ()
 
ErrorCode evaluate_smooth_edge (EntityHandle eh, double &t, CartVect &outv)
 
ErrorCode eval_bezier_patch (EntityHandle tri, CartVect &areacoord, CartVect &pt)
 
void project_to_facet_plane (EntityHandle tri, CartVect &pt, CartVect &point_on_plane, double &dist_to_plane)
 
void facet_area_coordinate (EntityHandle facet, CartVect &pt_on_plane, CartVect &areacoord)
 
ErrorCode project_to_facets_main (CartVect &this_point, bool trim, bool &outside, CartVect *closest_point_ptr=NULL, CartVect *normal_ptr=NULL)
 
ErrorCode project_to_facets (std::vector< EntityHandle > &facet_list, EntityHandle &lastFacet, int interpOrder, double compareTol, CartVect &this_point, bool trim, bool &outside, CartVect *closest_point_ptr, CartVect *normal_ptr)
 
ErrorCode project_to_facet (EntityHandle facet, CartVect &pt, CartVect &areacoord, CartVect &close_point, bool &outside_facet, double compare_tol)
 
bool is_at_vertex (EntityHandle facet, CartVect &pt, CartVect &ac, double compare_tol, CartVect &eval_pt, CartVect *eval_norm_ptr)
 
ErrorCode project_to_patch (EntityHandle facet, CartVect &ac, CartVect &pt, CartVect &eval_pt, CartVect *eval_norm, bool &outside, double compare_tol, int edge_id)
 
ErrorCode eval_bezier_patch_normal (EntityHandle facet, CartVect &areacoord, CartVect &normal)
 
ErrorCode compute_tangents_for_each_edge ()
 
ErrorCode get_normals_for_vertices (const EntityHandle *conn2, CartVect N[2])
 
ErrorCode init_edge_control_points (CartVect &P0, CartVect &P3, CartVect &N0, CartVect &N3, CartVect &T0, CartVect &T3, CartVect *Pi)
 
ErrorCode compute_control_points_on_edges (double min_dot, Tag edgeCtrlTag, Tag markTag)
 
ErrorCode compute_internal_control_points_on_facets (double min_dot, Tag facetCtrlTag, Tag facetEdgeCtrlTag)
 
void DumpModelControlPoints ()
 
int eval_counter ()
 
ErrorCode ray_intersection_correct (EntityHandle facet, CartVect &pt, CartVect &ray, CartVect &eval_pt, double &distance, bool &outside)
 
void append_smooth_tags (std::vector< Tag > &smoothTags)
 

Private Member Functions

bool move_ac_inside (CartVect &ac, double tol)
 
void ac_at_edge (CartVect &fac, CartVect &eac, int edge_id)
 
ErrorCode init_bezier_edge (EntityHandle edge, double min_dot)
 
ErrorCode find_edges_orientations (EntityHandle edges[3], const EntityHandle *conn3, int orient[3])
 
ErrorCode init_facet_control_points (CartVect N[6], CartVect P[3][5], CartVect G[6])
 
void adjust_bounding_box (CartVect &vect)
 

Private Attributes

CartVect _minim
 
CartVect _maxim
 
Range _triangles
 
Range _edges
 
Range _nodes
 
Tag _markTag
 
Tag _gradientTag
 
Tag _tangentsTag
 
Tag _edgeCtrlTag
 
Tag _facetCtrlTag
 
Tag _facetEdgeCtrlTag
 
Tag _planeTag
 
Interface_mb
 
EntityHandle _set
 
GeomTopoTool_my_geomTopoTool
 
EntityHandle _obb_root
 
long _evaluationsCounter
 

Detailed Description

Implement CAMAL geometry callbacks using smooth iMesh.

Definition at line 29 of file SmoothFace.hpp.

Constructor & Destructor Documentation

◆ SmoothFace()

moab::SmoothFace::SmoothFace ( Interface mb,
EntityHandle  surface_set,
GeomTopoTool gTool 
)

Definition at line 41 of file SmoothFace.cpp.

42  : _markTag( 0 ), _gradientTag( 0 ), _tangentsTag( 0 ), _edgeCtrlTag( 0 ), _facetCtrlTag( 0 ), 43  _facetEdgeCtrlTag( 0 ), _planeTag( 0 ), _mb( mb ), _set( surface_set ), _my_geomTopoTool( gTool ), _obb_root( 0 ), 44  _evaluationsCounter( 0 ) 45 { 46  //_smooth_face = NULL; 47  //_mbOut->create_meshset(MESHSET_SET, _oSet); //will contain the 48  // get also the obb_root 49  if( _my_geomTopoTool ) 50  { 51  _my_geomTopoTool->get_root( this->_set, _obb_root ); 52  if( debug_surf_eval1 ) _my_geomTopoTool->obb_tree()->stats( _obb_root, std::cout ); 53  } 54 }

References _my_geomTopoTool, _obb_root, _set, moab::GeomTopoTool::get_root(), moab::GeomTopoTool::obb_tree(), and moab::OrientedBoxTreeTool::stats().

◆ ~SmoothFace()

moab::SmoothFace::~SmoothFace ( )
virtual

Definition at line 56 of file SmoothFace.cpp.

56 {}

Member Function Documentation

◆ ac_at_edge()

void moab::SmoothFace::ac_at_edge ( CartVect fac,
CartVect eac,
int  edge_id 
)
private

Definition at line 1504 of file SmoothFace.cpp.

1507 { 1508  double u, v, w; 1509  switch( edge_id ) 1510  { 1511  case 0: 1512  u = 0.0; 1513  v = fac[1] / ( fac[1] + fac[2] ); // v = fac.y() / (fac.y() + fac.z()); 1514  w = 1.0 - v; 1515  break; 1516  case 1: 1517  u = fac[0] / ( fac[0] + fac[2] ); // u = fac.x() / (fac.x() + fac.z()); 1518  v = 0.0; 1519  w = 1.0 - u; 1520  break; 1521  case 2: 1522  u = fac[0] / ( fac[0] + fac[1] ); // u = fac.x() / (fac.x() + fac.y()); 1523  v = 1.0 - u; 1524  w = 0.0; 1525  break; 1526  default: 1527  assert( 0 ); 1528  u = -1; // needed to eliminate warnings about used before set 1529  v = -1; // needed to eliminate warnings about used before set 1530  w = -1; // needed to eliminate warnings about used before set 1531  break; 1532  } 1533  eac[0] = u; 1534  eac[1] = v; 1535  eac[2] = w; //= CartVect(u, v, w); 1536 }

Referenced by project_to_patch().

◆ adjust_bounding_box()

void moab::SmoothFace::adjust_bounding_box ( CartVect vect)
private

Definition at line 565 of file SmoothFace.cpp.

566 { 567  // _minim, _maxim 568  for( int j = 0; j < 3; j++ ) 569  { 570  if( _minim[j] > vect[j] ) _minim[j] = vect[j]; 571  if( _maxim[j] < vect[j] ) _maxim[j] = vect[j]; 572  } 573 }

References _maxim, and _minim.

Referenced by compute_internal_control_points_on_facets().

◆ append_smooth_tags()

void moab::SmoothFace::append_smooth_tags ( std::vector< Tag > &  smoothTags)

Definition at line 87 of file SmoothFace.cpp.

88 { 89  // these are created locally, for each smooth face 90  smoothTags.push_back( _gradientTag ); 91  smoothTags.push_back( _planeTag ); 92 }

References _gradientTag, and _planeTag.

Referenced by moab::FBEngine::delete_smooth_tags().

◆ area()

double moab::SmoothFace::area ( )
virtual

Definition at line 58 of file SmoothFace.cpp.

59 { 60  // find the area of this entity 61  // assert(_smooth_face); 62  // double area1 = _smooth_face->area(); 63  double totArea = 0.; 64  for( Range::iterator it = _triangles.begin(); it != _triangles.end(); ++it ) 65  { 66  EntityHandle tria = *it; 67  const EntityHandle* conn3; 68  int nnodes; 69  _mb->get_connectivity( tria, conn3, nnodes ); 70  // 71  // double coords[9]; // store the coordinates for the nodes 72  //_mb->get_coords(conn3, 3, coords); 73  CartVect p[3]; 74  _mb->get_coords( conn3, 3, (double*)&p[0] ); 75  // need to compute the angles 76  // compute angles and the normal 77  // CartVect p1(&coords[0]), p2(&coords[3]), p3(&coords[6]); 78  79  CartVect AB( p[1] - p[0] ); //(p2 - p1); 80  CartVect BC( p[2] - p[1] ); //(p3 - p2); 81  CartVect normal = AB * BC; 82  totArea += normal.length() / 2; 83  } 84  return totArea; 85 }

References _mb, _triangles, moab::Range::begin(), moab::Range::end(), moab::Interface::get_connectivity(), moab::Interface::get_coords(), and moab::CartVect::length().

◆ bounding_box()

void moab::SmoothFace::bounding_box ( double  box_min[3],
double  box_max[3] 
)
virtual

Definition at line 93 of file SmoothFace.cpp.

94 { 95  96  for( int i = 0; i < 3; i++ ) 97  { 98  box_min[i] = _minim[i]; 99  box_max[i] = _maxim[i]; 100  } 101  // _minim, _maxim 102 }

References _maxim, _minim, box_max(), and box_min().

◆ compute_control_points_on_edges()

ErrorCode moab::SmoothFace::compute_control_points_on_edges ( double  min_dot,
Tag  edgeCtrlTag,
Tag  markTag 
)

Definition at line 147 of file SmoothFace.cpp.

148 { 149  150  _edgeCtrlTag = edgeCtrlTag; 151  _markTag = markTag; 152  153  // now, compute control points for all edges that are not marked already (they are no on the 154  // boundary!) 155  for( Range::iterator it = _edges.begin(); it != _edges.end(); ++it ) 156  { 157  EntityHandle edg = *it; 158  // is the edge marked? already computed 159  unsigned char tagVal = 0; 160  _mb->tag_get_data( _markTag, &edg, 1, &tagVal ); 161  if( tagVal ) continue; 162  // double min_dot; 163  init_bezier_edge( edg, min_dot ); 164  tagVal = 1; 165  _mb->tag_set_data( _markTag, &edg, 1, &tagVal ); 166  } 167  return MB_SUCCESS; 168 }

References _edgeCtrlTag, _edges, _markTag, _mb, moab::Range::begin(), moab::Range::end(), init_bezier_edge(), MB_SUCCESS, moab::Interface::tag_get_data(), and moab::Interface::tag_set_data().

Referenced by moab::FBEngine::initializeSmoothing().

◆ compute_internal_control_points_on_facets()

ErrorCode moab::SmoothFace::compute_internal_control_points_on_facets ( double  min_dot,
Tag  facetCtrlTag,
Tag  facetEdgeCtrlTag 
)

Definition at line 470 of file SmoothFace.cpp.

471 { 472  // collect from each triangle the control points in order 473  // 474  475  _facetCtrlTag = facetCtrlTag; 476  _facetEdgeCtrlTag = facetEdgeCtrlTag; 477  478  for( Range::iterator it = _triangles.begin(); it != _triangles.end(); ++it ) 479  { 480  EntityHandle tri = *it; 481  // first get connectivity, and the edges 482  // we need a fast method to retrieve the adjacent edges to each triangle 483  const EntityHandle* conn3; 484  int nnodes; 485  ErrorCode rval = _mb->get_connectivity( tri, conn3, nnodes ); 486  assert( MB_SUCCESS == rval ); 487  if( MB_SUCCESS != rval ) return rval; 488  assert( 3 == nnodes ); 489  490  // would it be easier to do 491  CartVect vNode[3]; // position at nodes 492  rval = _mb->get_coords( conn3, 3, (double*)&vNode[0] ); 493  assert( MB_SUCCESS == rval ); 494  if( MB_SUCCESS != rval ) return rval; 495  496  // get gradients (normal) at each node of triangle 497  CartVect NN[3]; 498  rval = _mb->tag_get_data( _gradientTag, conn3, 3, &NN[0] ); 499  assert( MB_SUCCESS == rval ); 500  if( MB_SUCCESS != rval ) return rval; 501  502  EntityHandle edges[3]; 503  int orient[3]; // + 1 or -1, if the edge is positive or negative within the face 504  rval = find_edges_orientations( edges, conn3, orient ); // maybe we will set it? 505  assert( MB_SUCCESS == rval ); 506  if( MB_SUCCESS != rval ) return rval; 507  // maybe we will store some tags with edges and their orientation with respect to 508  // a triangle; 509  CartVect P[3][5]; 510  CartVect N[6], G[6]; 511  // create the linear array for control points on edges, for storage (expensive !!!) 512  CartVect CP[9]; 513  int index = 0; 514  // maybe store a tag / entity handle for edges? 515  for( int i = 0; i < 3; i++ ) 516  { 517  // populate P and N with the right vectors 518  int i1 = ( i + 1 ) % 3; // the first node of the edge 519  int i2 = ( i + 2 ) % 3; // the second node of the edge 520  N[2 * i] = NN[i1]; 521  N[2 * i + 1] = NN[i2]; 522  P[i][0] = vNode[i1]; 523  rval = _mb->tag_get_data( _edgeCtrlTag, &edges[i], 1, &( P[i][1] ) ); 524  // if sense is -1, swap 1 and 3 control points 525  if( orient[i] == -1 ) 526  { 527  CartVect tmp; 528  tmp = P[i][1]; 529  P[i][1] = P[i][3]; 530  P[i][3] = tmp; 531  } 532  P[i][4] = vNode[i2]; 533  for( int j = 1; j < 4; j++ ) 534  CP[index++] = P[i][j]; 535  536  // the first edge control points 537  } 538  539  // stat = facet->get_edge_control_points( P ); 540  init_facet_control_points( N, P, G ); 541  // what do we need to store in the tag control points? 542  rval = _mb->tag_set_data( _facetCtrlTag, &tri, 1, &G[0] ); 543  assert( MB_SUCCESS == rval ); 544  if( MB_SUCCESS != rval ) return rval; 545  546  // store here again the 9 control points on the edges 547  rval = _mb->tag_set_data( _facetEdgeCtrlTag, &tri, 1, &CP[0] ); 548  assert( MB_SUCCESS == rval ); 549  if( MB_SUCCESS != rval ) return rval; 550  // look at what we retrieve later 551  552  // adjust the bounding box 553  int j = 0; 554  for( j = 0; j < 3; j++ ) 555  adjust_bounding_box( vNode[j] ); 556  // edge control points 557  for( j = 0; j < 9; j++ ) 558  adjust_bounding_box( CP[j] ); 559  // internal facet control points 560  for( j = 0; j < 6; j++ ) 561  adjust_bounding_box( G[j] ); 562  } 563  return MB_SUCCESS; 564 }

References _edgeCtrlTag, _facetCtrlTag, _facetEdgeCtrlTag, _gradientTag, _mb, _triangles, adjust_bounding_box(), moab::Range::begin(), moab::Range::end(), ErrorCode, find_edges_orientations(), moab::Interface::get_connectivity(), moab::Interface::get_coords(), init_facet_control_points(), MB_SUCCESS, moab::Interface::tag_get_data(), and moab::Interface::tag_set_data().

Referenced by moab::FBEngine::initializeSmoothing().

◆ compute_tangents_for_each_edge()

ErrorCode moab::SmoothFace::compute_tangents_for_each_edge ( )

Definition at line 362 of file SmoothFace.cpp.

364 { 365  double defTangents[6] = { 0., 0., 0., 0., 0., 0. }; 366  ErrorCode rval = 367  _mb->tag_get_handle( "TANGENTS", 6, MB_TYPE_DOUBLE, _tangentsTag, MB_TAG_DENSE | MB_TAG_CREAT, &defTangents ); 368  if( MB_SUCCESS != rval ) return MB_FAILURE; 369  370  // now, compute Tangents for all edges that are not on boundary, so they are not marked 371  for( Range::iterator it = _edges.begin(); it != _edges.end(); ++it ) 372  { 373  EntityHandle edg = *it; 374  375  int nnodes; 376  const EntityHandle* conn2; // 377  _mb->get_connectivity( edg, conn2, nnodes ); 378  assert( nnodes == 2 ); 379  CartVect P[2]; // store the coordinates for the nodes 380  rval = _mb->get_coords( conn2, 2, (double*)&P[0] ); 381  if( MB_SUCCESS != rval ) return rval; 382  assert( rval == MB_SUCCESS ); 383  CartVect T[2]; 384  T[0] = P[1] - P[0]; 385  T[0].normalize(); 386  T[1] = T[0]; // 387  _mb->tag_set_data( _tangentsTag, &edg, 1, 388  (double*)&T[0] ); // set the tangents computed at every edge 389  } 390  return MB_SUCCESS; 391 }

References _edges, _mb, _tangentsTag, moab::Range::begin(), moab::Range::end(), ErrorCode, moab::Interface::get_connectivity(), moab::Interface::get_coords(), MB_SUCCESS, MB_TAG_CREAT, MB_TAG_DENSE, MB_TYPE_DOUBLE, moab::CartVect::normalize(), moab::Interface::tag_get_handle(), and moab::Interface::tag_set_data().

Referenced by moab::FBEngine::initializeSmoothing().

◆ DumpModelControlPoints()

void moab::SmoothFace::DumpModelControlPoints ( )

Definition at line 622 of file SmoothFace.cpp.

623 { 624  // here, we will dump all control points from edges and facets (6 control points for each facet) 625  // we may also create some edges; maybe later... 626  // create a point3D file 627  // output a Point3D file (special visit format) 628  unsigned long setId = _mb->id_from_handle( _set ); 629  char name[50] = { 0 }; 630  snprintf( name, 50, "%lucontrol.Point3D", setId ); // name should be something 2control.Point3D 631  std::ofstream point3DFile; 632  point3DFile.open( name ); //("control.Point3D"); 633  point3DFile << "# x y z \n"; 634  std::ofstream point3DEdgeFile; 635  snprintf( name, 50, "%lucontrolEdge.Point3D", setId ); // 636  point3DEdgeFile.open( name ); //("controlEdge.Point3D"); 637  point3DEdgeFile << "# x y z \n"; 638  std::ofstream smoothPoints; 639  snprintf( name, 50, "%lusmooth.Point3D", setId ); // 640  smoothPoints.open( name ); //("smooth.Point3D"); 641  smoothPoints << "# x y z \n"; 642  CartVect controlPoints[3]; // edge control points 643  for( Range::iterator it = _edges.begin(); it != _edges.end(); ++it ) 644  { 645  EntityHandle edge = *it; 646  647  _mb->tag_get_data( _edgeCtrlTag, &edge, 1, (double*)&controlPoints[0] ); 648  for( int i = 0; i < 3; i++ ) 649  { 650  CartVect& c = controlPoints[i]; 651  point3DEdgeFile << std::setprecision( 11 ) << c[0] << " " << c[1] << " " << c[2] << " \n"; 652  } 653  } 654  CartVect controlTriPoints[6]; // triangle control points 655  CartVect P_facet[3]; // result in 3 "mid" control points 656  for( Range::iterator it2 = _triangles.begin(); it2 != _triangles.end(); ++it2 ) 657  { 658  EntityHandle tri = *it2; 659  660  _mb->tag_get_data( _facetCtrlTag, &tri, 1, (double*)&controlTriPoints[0] ); 661  662  // draw a line of points between pairs of control points 663  int numPoints = 7; 664  for( int n = 0; n < numPoints; n++ ) 665  { 666  double a = 1. * n / ( numPoints - 1 ); 667  double b = 1.0 - a; 668  669  P_facet[0] = a * controlTriPoints[3] + b * controlTriPoints[4]; 670  // 1,2,1 671  P_facet[1] = a * controlTriPoints[0] + b * controlTriPoints[5]; 672  // 1,1,2 673  P_facet[2] = a * controlTriPoints[1] + b * controlTriPoints[2]; 674  for( int i = 0; i < 3; i++ ) 675  { 676  CartVect& c = P_facet[i]; 677  point3DFile << std::setprecision( 11 ) << c[0] << " " << c[1] << " " << c[2] << " \n"; 678  } 679  } 680  681  // evaluate for each triangle a lattice of points 682  int N = 40; 683  for( int k = 0; k <= N; k++ ) 684  { 685  for( int m = 0; m <= N - k; m++ ) 686  { 687  int n = N - m - k; 688  CartVect areacoord( 1. * k / N, 1. * m / N, 1. * n / N ); 689  CartVect pt; 690  eval_bezier_patch( tri, areacoord, pt ); 691  smoothPoints << std::setprecision( 11 ) << pt[0] << " " << pt[1] << " " << pt[2] << " \n"; 692  } 693  } 694  } 695  point3DFile.close(); 696  smoothPoints.close(); 697  point3DEdgeFile.close(); 698  return; 699 }

References _edgeCtrlTag, _edges, _facetCtrlTag, _mb, _set, _triangles, moab::Range::begin(), moab::Range::end(), eval_bezier_patch(), moab::Interface::id_from_handle(), and moab::Interface::tag_get_data().

◆ eval_bezier_patch()

ErrorCode moab::SmoothFace::eval_bezier_patch ( EntityHandle  tri,
CartVect areacoord,
CartVect pt 
)

Definition at line 748 of file SmoothFace.cpp.

749 { 750  // 751  // interpolate internal control points 752  753  CartVect gctrl_pts[6]; 754  // get the control points facet->get_control_points( gctrl_pts ); 755  // init_facet_control_points( N, P, G) ; 756  // what do we need to store in the tag control points? 757  ErrorCode rval = _mb->tag_get_data( _facetCtrlTag, &tri, 1, &gctrl_pts[0] ); // get all 6 control points 758  assert( MB_SUCCESS == rval ); 759  if( MB_SUCCESS != rval ) return rval; 760  const EntityHandle* conn3 = NULL; 761  int nnodes = 0; 762  rval = _mb->get_connectivity( tri, conn3, nnodes ); 763  assert( MB_SUCCESS == rval ); 764  765  CartVect vN[3]; 766  _mb->get_coords( conn3, 3, (double*)&vN[0] ); // fill the coordinates of the vertices 767  768  if( fabs( areacoord[1] + areacoord[2] ) < 1.0e-6 ) 769  { 770  pt = vN[0]; 771  return MB_SUCCESS; 772  } 773  if( fabs( areacoord[0] + areacoord[2] ) < 1.0e-6 ) 774  { 775  pt = vN[0]; 776  return MB_SUCCESS; 777  } 778  if( fabs( areacoord[0] + areacoord[1] ) < 1.0e-6 ) 779  { 780  pt = vN[0]; 781  return MB_SUCCESS; 782  } 783  784  CartVect P_facet[3]; 785  // 2,1,1 786  P_facet[0] = 787  ( 1.0e0 / ( areacoord[1] + areacoord[2] ) ) * ( areacoord[1] * gctrl_pts[3] + areacoord[2] * gctrl_pts[4] ); 788  // 1,2,1 789  P_facet[1] = 790  ( 1.0e0 / ( areacoord[0] + areacoord[2] ) ) * ( areacoord[0] * gctrl_pts[0] + areacoord[2] * gctrl_pts[5] ); 791  // 1,1,2 792  P_facet[2] = 793  ( 1.0e0 / ( areacoord[0] + areacoord[1] ) ) * ( areacoord[0] * gctrl_pts[1] + areacoord[1] * gctrl_pts[2] ); 794  795  // sum the contribution from each of the control points 796  797  pt = CartVect( 0. ); // set all to 0, we start adding / accumulating different parts 798  // first edge is from node 0 to 1, index 2 in 799  800  // retrieve the points, in order, and the control points on edges 801  802  // store here again the 9 control points on the edges 803  CartVect CP[9]; 804  rval = _mb->tag_get_data( _facetEdgeCtrlTag, &tri, 1, &CP[0] ); 805  assert( MB_SUCCESS == rval ); 806  807  // CubitFacetEdge *edge; 808  // edge = facet->edge(2);! start with edge 2, from 0-1 809  int k = 0; 810  CartVect ctrl_pts[5]; 811  // edge->control_points(facet, ctrl_pts); 812  ctrl_pts[0] = vN[0]; // 813  for( k = 1; k < 4; k++ ) 814  ctrl_pts[k] = CP[k + 5]; // for edge index 2 815  ctrl_pts[4] = vN[1]; // 816  817  // i=4; j=0; k=0; 818  double B = mbquart( areacoord[0] ); 819  pt += B * ctrl_pts[0]; 820  821  // i=3; j=1; k=0; 822  B = 4.0 * mbcube( areacoord[0] ) * areacoord[1]; 823  pt += B * ctrl_pts[1]; 824  825  // i=2; j=2; k=0; 826  B = 6.0 * mbsqr( areacoord[0] ) * mbsqr( areacoord[1] ); 827  pt += B * ctrl_pts[2]; 828  829  // i=1; j=3; k=0; 830  B = 4.0 * areacoord[0] * mbcube( areacoord[1] ); 831  pt += B * ctrl_pts[3]; 832  833  // edge = facet->edge(0); 834  // edge->control_points(facet, ctrl_pts); 835  // edge index 0, from 1 to 2 836  ctrl_pts[0] = vN[1]; // 837  for( k = 1; k < 4; k++ ) 838  ctrl_pts[k] = CP[k - 1]; // for edge index 0 839  ctrl_pts[4] = vN[2]; // 840  841  // i=0; j=4; k=0; 842  B = mbquart( areacoord[1] ); 843  pt += B * ctrl_pts[0]; 844  845  // i=0; j=3; k=1; 846  B = 4.0 * mbcube( areacoord[1] ) * areacoord[2]; 847  pt += B * ctrl_pts[1]; 848  849  // i=0; j=2; k=2; 850  B = 6.0 * mbsqr( areacoord[1] ) * mbsqr( areacoord[2] ); 851  pt += B * ctrl_pts[2]; 852  853  // i=0; j=1; k=3; 854  B = 4.0 * areacoord[1] * mbcube( areacoord[2] ); 855  pt += B * ctrl_pts[3]; 856  857  // edge = facet->edge(1); 858  // edge->control_points(facet, ctrl_pts); 859  // edge index 1, from 2 to 0 860  ctrl_pts[0] = vN[2]; // 861  for( k = 1; k < 4; k++ ) 862  ctrl_pts[k] = CP[k + 2]; // for edge index 0 863  ctrl_pts[4] = vN[0]; // 864  865  // i=0; j=0; k=4; 866  B = mbquart( areacoord[2] ); 867  pt += B * ctrl_pts[0]; 868  869  // i=1; j=0; k=3; 870  B = 4.0 * areacoord[0] * mbcube( areacoord[2] ); 871  pt += B * ctrl_pts[1]; 872  873  // i=2; j=0; k=2; 874  B = 6.0 * mbsqr( areacoord[0] ) * mbsqr( areacoord[2] ); 875  pt += B * ctrl_pts[2]; 876  877  // i=3; j=0; k=1; 878  B = 4.0 * mbcube( areacoord[0] ) * areacoord[2]; 879  pt += B * ctrl_pts[3]; 880  881  // i=2; j=1; k=1; 882  B = 12.0 * mbsqr( areacoord[0] ) * areacoord[1] * areacoord[2]; 883  pt += B * P_facet[0]; 884  885  // i=1; j=2; k=1; 886  B = 12.0 * areacoord[0] * mbsqr( areacoord[1] ) * areacoord[2]; 887  pt += B * P_facet[1]; 888  889  // i=1; j=1; k=2; 890  B = 12.0 * areacoord[0] * areacoord[1] * mbsqr( areacoord[2] ); 891  pt += B * P_facet[2]; 892  893  return MB_SUCCESS; 894 }

References _facetCtrlTag, _facetEdgeCtrlTag, _mb, ErrorCode, moab::Interface::get_connectivity(), moab::Interface::get_coords(), MB_SUCCESS, mbcube, mbquart, mbsqr, and moab::Interface::tag_get_data().

Referenced by DumpModelControlPoints(), and project_to_patch().

◆ eval_bezier_patch_normal()

ErrorCode moab::SmoothFace::eval_bezier_patch_normal ( EntityHandle  facet,
CartVect areacoord,
CartVect normal 
)

Definition at line 1710 of file SmoothFace.cpp.

1711 { 1712  // interpolate internal control points 1713  1714  CartVect gctrl_pts[6]; 1715  // facet->get_control_points( gctrl_pts ); 1716  ErrorCode rval = _mb->tag_get_data( _facetCtrlTag, &facet, 1, &gctrl_pts[0] ); 1717  assert( rval == MB_SUCCESS ); 1718  if( MB_SUCCESS != rval ) return rval; 1719  // _gradientTag 1720  // get normals at points 1721  const EntityHandle* conn3 = NULL; 1722  int nnodes = 0; 1723  rval = _mb->get_connectivity( facet, conn3, nnodes ); 1724  if( MB_SUCCESS != rval ) return rval; 1725  1726  CartVect NN[3]; 1727  rval = _mb->tag_get_data( _gradientTag, conn3, 3, &NN[0] ); 1728  assert( rval == MB_SUCCESS ); 1729  if( MB_SUCCESS != rval ) return rval; 1730  1731  if( fabs( areacoord[1] + areacoord[2] ) < 1.0e-6 ) 1732  { 1733  normal = NN[0]; 1734  return MB_SUCCESS; 1735  } 1736  if( fabs( areacoord[0] + areacoord[2] ) < 1.0e-6 ) 1737  { 1738  normal = NN[1]; // facet->point(1)->normal(facet); 1739  return MB_SUCCESS; 1740  } 1741  if( fabs( areacoord[0] + areacoord[1] ) < 1.0e-6 ) 1742  { 1743  normal = NN[2]; // facet->point(2)->normal(facet); 1744  return MB_SUCCESS; 1745  } 1746  1747  // compute the hodograph of the quartic Gregory patch 1748  1749  CartVect Nijk[10]; 1750  // hodograph(facet,areacoord,Nijk); 1751  // start copy from hodograph 1752  // CubitVector gctrl_pts[6]; 1753  // facet->get_control_points( gctrl_pts ); 1754  CartVect P_facet[3]; 1755  1756  // 2,1,1 1757  /*P_facet[0] = (1.0e0 / (areacoord.y() + areacoord.z())) * 1758  (areacoord.y() * gctrl_pts[3] + 1759  areacoord.z() * gctrl_pts[4]);*/ 1760  P_facet[0] = 1761  ( 1.0e0 / ( areacoord[1] + areacoord[2] ) ) * ( areacoord[1] * gctrl_pts[3] + areacoord[2] * gctrl_pts[4] ); 1762  // 1,2,1 1763  /*P_facet[1] = (1.0e0 / (areacoord.x() + areacoord.z())) * 1764  (areacoord.x() * gctrl_pts[0] + 1765  areacoord.z() * gctrl_pts[5]);*/ 1766  P_facet[1] = 1767  ( 1.0e0 / ( areacoord[0] + areacoord[2] ) ) * ( areacoord[0] * gctrl_pts[0] + areacoord[2] * gctrl_pts[5] ); 1768  // 1,1,2 1769  /*P_facet[2] = (1.0e0 / (areacoord.x() + areacoord.y())) * 1770  (areacoord.x() * gctrl_pts[1] + 1771  areacoord.y() * gctrl_pts[2]);*/ 1772  P_facet[2] = 1773  ( 1.0e0 / ( areacoord[0] + areacoord[1] ) ) * ( areacoord[0] * gctrl_pts[1] + areacoord[1] * gctrl_pts[2] ); 1774  1775  // corner control points are just the normals at the points 1776  1777  // 3, 0, 0 1778  Nijk[0] = NN[0]; 1779  // 0, 3, 0 1780  Nijk[3] = NN[1]; 1781  // 0, 0, 3 1782  Nijk[9] = NN[2]; // facet->point(2)->normal(facet); 1783  1784  // fill in the boundary control points. Define as the normal to the local 1785  // triangle formed by the quartic control point lattice 1786  1787  // store here again the 9 control points on the edges 1788  CartVect CP[9]; // 9 control points on the edges, 1789  rval = _mb->tag_get_data( _facetEdgeCtrlTag, &facet, 1, &CP[0] ); 1790  if( MB_SUCCESS != rval ) return rval; 1791  // there are 3 CP for each edge, 0, 1, 2; first edge is 1-2 1792  // CubitFacetEdge *edge; 1793  // edge = facet->edge( 2 ); 1794  // CubitVector ctrl_pts[5]; 1795  // edge->control_points(facet, ctrl_pts); 1796  1797  // 2, 1, 0 1798  // Nijk[1] = (ctrl_pts[2] - ctrl_pts[1]) * (P_facet[0] - ctrl_pts[1]); 1799  Nijk[1] = ( CP[7] - CP[6] ) * ( P_facet[0] - CP[6] ); 1800  Nijk[1].normalize(); 1801  1802  // 1, 2, 0 1803  // Nijk[2] = (ctrl_pts[3] - ctrl_pts[2]) * (P_facet[1] - ctrl_pts[2]); 1804  Nijk[2] = ( CP[8] - CP[7] ) * ( P_facet[1] - CP[7] ); 1805  Nijk[2].normalize(); 1806  1807  // edge = facet->edge( 0 ); 1808  // edge->control_points(facet, ctrl_pts); 1809  1810  // 0, 2, 1 1811  // Nijk[6] = (ctrl_pts[1] - P_facet[1]) * (ctrl_pts[2] - P_facet[1]); 1812  Nijk[6] = ( CP[0] - P_facet[1] ) * ( CP[1] - P_facet[1] ); 1813  Nijk[6].normalize(); 1814  1815  // 0, 1, 2 1816  // Nijk[8] = (ctrl_pts[2] - P_facet[2]) * (ctrl_pts[3] - P_facet[2]); 1817  Nijk[8] = ( CP[1] - P_facet[2] ) * ( CP[2] - P_facet[2] ); 1818  Nijk[8].normalize(); 1819  1820  // edge = facet->edge( 1 ); 1821  // edge->control_points(facet, ctrl_pts); 1822  1823  // 1, 0, 2 1824  // Nijk[7] = (P_facet[2] - ctrl_pts[2]) * (ctrl_pts[1] - ctrl_pts[2]); 1825  Nijk[7] = ( P_facet[2] - CP[4] ) * ( CP[3] - CP[4] ); 1826  Nijk[7].normalize(); 1827  1828  // 2, 0, 1 1829  // Nijk[4] = (P_facet[0] - ctrl_pts[3]) * (ctrl_pts[2] - ctrl_pts[3]); 1830  Nijk[4] = ( P_facet[0] - CP[5] ) * ( CP[4] - CP[5] ); 1831  Nijk[4].normalize(); 1832  1833  // 1, 1, 1 1834  Nijk[5] = ( P_facet[1] - P_facet[0] ) * ( P_facet[2] - P_facet[0] ); 1835  Nijk[5].normalize(); 1836  // end copy from hodograph 1837  1838  // sum the contribution from each of the control points 1839  1840  normal = CartVect( 0.0e0, 0.0e0, 0.0e0 ); 1841  1842  // i=3; j=0; k=0; 1843  // double Bsum = 0.0; 1844  double B = mbcube( areacoord[0] ); 1845  // Bsum += B; 1846  normal += B * Nijk[0]; 1847  1848  // i=2; j=1; k=0; 1849  B = 3.0 * mbsqr( areacoord[0] ) * areacoord[1]; 1850  // Bsum += B; 1851  normal += B * Nijk[1]; 1852  1853  // i=1; j=2; k=0; 1854  B = 3.0 * areacoord[0] * mbsqr( areacoord[1] ); 1855  // Bsum += B; 1856  normal += B * Nijk[2]; 1857  1858  // i=0; j=3; k=0; 1859  B = mbcube( areacoord[1] ); 1860  // Bsum += B; 1861  normal += B * Nijk[3]; 1862  1863  // i=2; j=0; k=1; 1864  B = 3.0 * mbsqr( areacoord[0] ) * areacoord[2]; 1865  // Bsum += B; 1866  normal += B * Nijk[4]; 1867  1868  // i=1; j=1; k=1; 1869  B = 6.0 * areacoord[0] * areacoord[1] * areacoord[2]; 1870  // Bsum += B; 1871  normal += B * Nijk[5]; 1872  1873  // i=0; j=2; k=1; 1874  B = 3.0 * mbsqr( areacoord[1] ) * areacoord[2]; 1875  // Bsum += B; 1876  normal += B * Nijk[6]; 1877  1878  // i=1; j=0; k=2; 1879  B = 3.0 * areacoord[0] * mbsqr( areacoord[2] ); 1880  // Bsum += B; 1881  normal += B * Nijk[7]; 1882  1883  // i=0; j=1; k=2; 1884  B = 3.0 * areacoord[1] * mbsqr( areacoord[2] ); 1885  // Bsum += B; 1886  normal += B * Nijk[8]; 1887  1888  // i=0; j=0; k=3; 1889  B = mbcube( areacoord[2] ); 1890  // Bsum += B; 1891  normal += B * Nijk[9]; 1892  1893  // assert(fabs(Bsum - 1.0) < 1e-9); 1894  1895  normal.normalize(); 1896  1897  return MB_SUCCESS; 1898 }

References _facetCtrlTag, _facetEdgeCtrlTag, _gradientTag, _mb, ErrorCode, moab::Interface::get_connectivity(), MB_SUCCESS, mbcube, mbsqr, moab::CartVect::normalize(), and moab::Interface::tag_get_data().

Referenced by project_to_facets().

◆ eval_counter()

int moab::SmoothFace::eval_counter ( )
inline

Definition at line 125 of file SmoothFace.hpp.

126  { 127  return _evaluationsCounter; 128  }

References _evaluationsCounter.

◆ evaluate_smooth_edge()

ErrorCode moab::SmoothFace::evaluate_smooth_edge ( EntityHandle  eh,
double &  t,
CartVect outv 
)

Definition at line 708 of file SmoothFace.cpp.

709 { 710  CartVect P[2]; // P0 and P1 711  CartVect controlPoints[3]; // edge control points 712  double t4, t3, t2, one_minus_t, one_minus_t2, one_minus_t3, one_minus_t4; 713  714  // project the position to the linear edge 715  // t is from 0 to 1 only!! 716  // double tt = (t + 1) * 0.5; 717  if( tt <= 0.0 ) tt = 0.0; 718  if( tt >= 1.0 ) tt = 1.0; 719  720  int nnodes = 0; 721  const EntityHandle* conn2 = NULL; 722  ErrorCode rval = _mb->get_connectivity( eh, conn2, nnodes ); 723  assert( rval == MB_SUCCESS ); 724  if( MB_SUCCESS != rval ) return rval; 725  726  rval = _mb->get_coords( conn2, 2, (double*)&P[0] ); 727  assert( rval == MB_SUCCESS ); 728  if( MB_SUCCESS != rval ) return rval; 729  730  rval = _mb->tag_get_data( _edgeCtrlTag, &eh, 1, (double*)&controlPoints[0] ); 731  assert( rval == MB_SUCCESS ); 732  if( MB_SUCCESS != rval ) return rval; 733  734  t2 = tt * tt; 735  t3 = t2 * tt; 736  t4 = t3 * tt; 737  one_minus_t = 1. - tt; 738  one_minus_t2 = one_minus_t * one_minus_t; 739  one_minus_t3 = one_minus_t2 * one_minus_t; 740  one_minus_t4 = one_minus_t3 * one_minus_t; 741  742  outv = one_minus_t4 * P[0] + 4. * one_minus_t3 * tt * controlPoints[0] + 6. * one_minus_t2 * t2 * controlPoints[1] + 743  4. * one_minus_t * t3 * controlPoints[2] + t4 * P[1]; 744  745  return MB_SUCCESS; 746 }

References _edgeCtrlTag, _mb, ErrorCode, moab::Interface::get_connectivity(), moab::Interface::get_coords(), MB_SUCCESS, and moab::Interface::tag_get_data().

◆ facet_area_coordinate()

void moab::SmoothFace::facet_area_coordinate ( EntityHandle  facet,
CartVect pt_on_plane,
CartVect areacoord 
)

Definition at line 929 of file SmoothFace.cpp.

930 { 931  932  const EntityHandle* conn3 = NULL; 933  int nnodes = 0; 934  ErrorCode rval = _mb->get_connectivity( facet, conn3, nnodes ); 935  assert( MB_SUCCESS == rval ); 936  if( rval ) 937  { 938  } // empty statement to prevent compiler warning 939  940  // double coords[9]; // store the coordinates for the nodes 941  //_mb->get_coords(conn3, 3, coords); 942  CartVect p[3]; 943  rval = _mb->get_coords( conn3, 3, (double*)&p[0] ); 944  assert( MB_SUCCESS == rval ); 945  if( rval ) 946  { 947  } // empty statement to prevent compiler warning 948  double plane[4]; 949  950  rval = _mb->tag_get_data( _planeTag, &facet, 1, plane ); 951  assert( rval == MB_SUCCESS ); 952  if( rval ) 953  { 954  } // empty statement to prevent compiler warning 955  CartVect normal( &plane[0] ); // just first 3 components are used 956  957  double area2; 958  959  double tol = GEOMETRY_RESABS * 1.e-5; // 1.e-11; 960  961  CartVect v1( p[1] - p[0] ); 962  CartVect v2( p[2] - p[0] ); 963  964  area2 = ( v1 * v2 ).length_squared(); // the same for CartVect 965  if( area2 < 100 * tol ) 966  { 967  tol = .01 * area2; 968  } 969  CartVect absnorm( fabs( normal[0] ), fabs( normal[1] ), fabs( normal[2] ) ); 970  971  // project to the closest coordinate plane so we only have to do this in 2D 972  973  if( absnorm[0] >= absnorm[1] && absnorm[0] >= absnorm[2] ) 974  { 975  area2 = determ3( p[0][1], p[0][2], p[1][1], p[1][2], p[2][1], p[2][2] ); 976  if( fabs( area2 ) < tol ) 977  { 978  areacoord = CartVect( -std::numeric_limits< double >::min() ); // .set( 979  // -std::numeric_limits<double>::min(), 980  // -std::numeric_limits<double>::min(), 981  // -std::numeric_limits<double>::min() ); 982  } 983  else if( within_tolerance( p[0], pt_on_plane, GEOMETRY_RESABS ) ) 984  { 985  areacoord = CartVect( 1., 0., 0. ); //.set( 1.0, 0.0, 0.0 ); 986  } 987  else if( within_tolerance( p[1], pt_on_plane, GEOMETRY_RESABS ) ) 988  { 989  areacoord = CartVect( 0., 1., 0. ); //.set( 0.0, 1.0, 0.0 ); 990  } 991  else if( within_tolerance( p[2], pt_on_plane, GEOMETRY_RESABS ) ) 992  { 993  areacoord = CartVect( 0., 0., 1. ); //.set( 0.0, 0.0, 1.0 ); 994  } 995  else 996  { 997  998  areacoord[0] = determ3( pt_on_plane[1], pt_on_plane[2], p[1][1], p[1][2], p[2][1], p[2][2] ) / area2; 999  1000  areacoord[1] = determ3( p[0][1], p[0][2], pt_on_plane[1], pt_on_plane[2], p[2][1], p[2][2] ) / area2; 1001  1002  areacoord[2] = determ3( p[0][1], p[0][2], p[1][1], p[1][2], pt_on_plane[1], pt_on_plane[2] ) / area2; 1003  } 1004  } 1005  else if( absnorm[1] >= absnorm[0] && absnorm[1] >= absnorm[2] ) 1006  { 1007  1008  area2 = determ3( p[0][0], p[0][2], p[1][0], p[1][2], p[2][0], p[2][2] ); 1009  if( fabs( area2 ) < tol ) 1010  { 1011  areacoord = CartVect( -std::numeric_limits< double >::min() ); //.set( 1012  //-std::numeric_limits<double>::min(), 1013  //-std::numeric_limits<double>::min(), 1014  //-std::numeric_limits<double>::min() ); 1015  } 1016  else if( within_tolerance( p[0], pt_on_plane, GEOMETRY_RESABS ) ) 1017  { 1018  areacoord = CartVect( 1., 0., 0. ); //.set( 1.0, 0.0, 0.0 ); 1019  } 1020  else if( within_tolerance( p[1], pt_on_plane, GEOMETRY_RESABS ) ) 1021  { 1022  areacoord = CartVect( 0., 1., 0. ); //.set( 0.0, 1.0, 0.0 ); 1023  } 1024  else if( within_tolerance( p[2], pt_on_plane, GEOMETRY_RESABS ) ) 1025  { 1026  areacoord = CartVect( 0., 0., 1. ); //.set( 0.0, 0.0, 1.0 ); 1027  } 1028  else 1029  { 1030  1031  areacoord[0] = determ3( pt_on_plane[0], pt_on_plane[2], p[1][0], p[1][2], p[2][0], p[2][2] ) / area2; 1032  1033  areacoord[1] = determ3( p[0][0], p[0][2], pt_on_plane[0], pt_on_plane[2], p[2][0], p[2][2] ) / area2; 1034  1035  areacoord[2] = determ3( p[0][0], p[0][2], p[1][0], p[1][2], pt_on_plane[0], pt_on_plane[2] ) / area2; 1036  } 1037  } 1038  else 1039  { 1040  /*area2 = determ3(pt0->x(), pt0->y(), 1041  pt1->x(), pt1->y(), 1042  pt2->x(), pt2->y());*/ 1043  area2 = determ3( p[0][0], p[0][1], p[1][0], p[1][1], p[2][0], p[2][1] ); 1044  if( fabs( area2 ) < tol ) 1045  { 1046  areacoord = CartVect( -std::numeric_limits< double >::min() ); //.set( 1047  //-std::numeric_limits<double>::min(), 1048  //-std::numeric_limits<double>::min(), 1049  //-std::numeric_limits<double>::min() ); 1050  } 1051  else if( within_tolerance( p[0], pt_on_plane, GEOMETRY_RESABS ) ) 1052  { 1053  areacoord = CartVect( 1., 0., 0. ); //.set( 1.0, 0.0, 0.0 ); 1054  } 1055  else if( within_tolerance( p[1], pt_on_plane, GEOMETRY_RESABS ) ) 1056  { 1057  areacoord = CartVect( 0., 1., 0. ); //.set( 0.0, 1.0, 0.0 ); 1058  } 1059  else if( within_tolerance( p[2], pt_on_plane, GEOMETRY_RESABS ) ) 1060  { 1061  areacoord = CartVect( 0., 0., 1. ); //.set( 0.0, 0.0, 1.0 ); 1062  } 1063  else 1064  { 1065  1066  areacoord[0] = determ3( pt_on_plane[0], pt_on_plane[1], p[1][0], p[1][1], p[2][0], p[2][1] ) / area2; 1067  1068  areacoord[1] = determ3( p[0][0], p[0][1], pt_on_plane[0], pt_on_plane[1], p[2][0], p[2][1] ) / area2; 1069  1070  areacoord[2] = determ3( p[0][0], p[0][1], p[1][0], p[1][1], pt_on_plane[0], pt_on_plane[1] ) / area2; 1071  } 1072  } 1073 }

References _mb, _planeTag, determ3, ErrorCode, GEOMETRY_RESABS, moab::Interface::get_connectivity(), moab::Interface::get_coords(), length_squared(), MB_SUCCESS, moab::Interface::tag_get_data(), and moab::within_tolerance().

Referenced by project_to_facets().

◆ find_edges_orientations()

ErrorCode moab::SmoothFace::find_edges_orientations ( EntityHandle  edges[3],
const EntityHandle conn3,
int  orient[3] 
)
private

Definition at line 436 of file SmoothFace.cpp.

439 { 440  // find the edge that is adjacent to 2 vertices at a time 441  for( int i = 0; i < 3; i++ ) 442  { 443  // edge 0 is 1-2, 1 is 3-1, 2 is 0-1 444  EntityHandle v[2]; 445  v[0] = conn3[( i + 1 ) % 3]; 446  v[1] = conn3[( i + 2 ) % 3]; 447  std::vector< EntityHandle > adjacencies; 448  // generate all edges for these two hexes 449  ErrorCode rval = _mb->get_adjacencies( v, 2, 1, false, adjacencies, Interface::INTERSECT ); 450  if( MB_SUCCESS != rval ) return rval; 451  452  // find the edge connected to both vertices, and then see its orientation 453  assert( adjacencies.size() == 1 ); 454  const EntityHandle* conn2 = NULL; 455  int nnodes = 0; 456  rval = _mb->get_connectivity( adjacencies[0], conn2, nnodes ); 457  assert( rval == MB_SUCCESS ); 458  assert( 2 == nnodes ); 459  edges[i] = adjacencies[0]; 460  // what is the story morning glory? 461  if( conn2[0] == v[0] && conn2[1] == v[1] ) 462  orient[i] = 1; 463  else if( conn2[0] == v[1] && conn2[1] == v[0] ) 464  orient[i] = -1; 465  else 466  return MB_FAILURE; 467  } 468  return MB_SUCCESS; 469 }

References _mb, ErrorCode, moab::Interface::get_adjacencies(), moab::Interface::get_connectivity(), moab::Interface::INTERSECT, and MB_SUCCESS.

Referenced by compute_internal_control_points_on_facets().

◆ get_normals_for_vertices()

ErrorCode moab::SmoothFace::get_normals_for_vertices ( const EntityHandle conn2,
CartVect  N[2] 
)

Definition at line 1900 of file SmoothFace.cpp.

1903 { 1904  // CartVect N[2]; 1905  //_mb->tag_get_data(_gradientTag, conn2, 2, normalVec); 1906  ErrorCode rval = _mb->tag_get_data( _gradientTag, conn2, 2, (double*)&N[0] ); 1907  return rval; 1908 }

References _gradientTag, _mb, ErrorCode, and moab::Interface::tag_get_data().

◆ init_bezier_edge()

ErrorCode moab::SmoothFace::init_bezier_edge ( EntityHandle  edge,
double  min_dot 
)
private

Definition at line 305 of file SmoothFace.cpp.

306 { 307  // min dot was used for angle here 308  // int stat = 0; // CUBIT_SUCCESS; 309  // all boundaries will be simple, initially 310  // we may complicate them afterwards 311  312  CartVect ctrl_pts[3]; 313  int nnodes = 0; 314  const EntityHandle* conn2 = NULL; 315  ErrorCode rval = _mb->get_connectivity( edge, conn2, nnodes ); 316  assert( rval == MB_SUCCESS ); 317  if( MB_SUCCESS != rval ) return rval; 318  319  assert( 2 == nnodes ); 320  // double coords[6]; // store the coordinates for the nodes 321  CartVect P[2]; 322  // ErrorCode rval = _mb->get_coords(conn2, 2, coords); 323  rval = _mb->get_coords( conn2, 2, (double*)&P[0] ); 324  assert( rval == MB_SUCCESS ); 325  if( MB_SUCCESS != rval ) return rval; 326  327  // CartVect P0(&coords[0]); 328  // CartVect P3(&coords[3]); 329  330  // double normalVec[6]; 331  CartVect N[2]; 332  //_mb->tag_get_data(_gradientTag, conn2, 2, normalVec); 333  rval = _mb->tag_get_data( _gradientTag, conn2, 2, (double*)&N[0] ); 334  assert( rval == MB_SUCCESS ); 335  if( MB_SUCCESS != rval ) return rval; 336  337  CartVect T[2]; // T0, T3 338  339  rval = _mb->tag_get_data( _tangentsTag, &edge, 1, &T[0] ); 340  assert( rval == MB_SUCCESS ); 341  if( MB_SUCCESS != rval ) return rval; 342  343  rval = init_edge_control_points( P[0], P[1], N[0], N[1], T[0], T[1], ctrl_pts ); 344  assert( rval == MB_SUCCESS ); 345  if( MB_SUCCESS != rval ) return rval; 346  347  rval = _mb->tag_set_data( _edgeCtrlTag, &edge, 1, &ctrl_pts[0] ); 348  assert( rval == MB_SUCCESS ); 349  if( MB_SUCCESS != rval ) return rval; 350  351  if( debug_surf_eval1 ) 352  { 353  std::cout << "edge: " << _mb->id_from_handle( edge ) << " tangents: " << T[0] << T[1] << std::endl; 354  std::cout << " points: " << P[0] << " " << P[1] << std::endl; 355  std::cout << " normals: " << N[0] << " " << N[1] << std::endl; 356  std::cout << " Control points " << ctrl_pts[0] << " " << ctrl_pts[1] << " " << ctrl_pts[2] << std::endl; 357  } 358  359  return MB_SUCCESS; 360 }

References _edgeCtrlTag, _gradientTag, _mb, _tangentsTag, moab::debug_surf_eval1, ErrorCode, moab::Interface::get_connectivity(), moab::Interface::get_coords(), moab::Interface::id_from_handle(), init_edge_control_points(), MB_SUCCESS, moab::Interface::tag_get_data(), and moab::Interface::tag_set_data().

Referenced by compute_control_points_on_edges().

◆ init_edge_control_points()

ErrorCode moab::SmoothFace::init_edge_control_points ( CartVect P0,
CartVect P3,
CartVect N0,
CartVect N3,
CartVect T0,
CartVect T3,
CartVect Pi 
)

Definition at line 399 of file SmoothFace.cpp.

406 { 407  CartVect Vi[4]; 408  Vi[0] = P0; 409  Vi[3] = P3; 410  CartVect P03( P3 - P0 ); 411  double di = P03.length(); 412  double ai = N0 % N3; // this is the dot operator 413  double ai0 = N0 % T0; 414  double ai3 = N3 % T3; 415  double denom = 4 - ai * ai; 416  if( fabs( denom ) < 1e-20 ) 417  { 418  return MB_FAILURE; // CUBIT_FAILURE; 419  } 420  double row = 6.0e0 * ( 2.0e0 * ai0 + ai * ai3 ) / denom; 421  double omega = 6.0e0 * ( 2.0e0 * ai3 + ai * ai0 ) / denom; 422  Vi[1] = Vi[0] + ( di * ( ( ( 6.0e0 * T0 ) - ( ( 2.0e0 * row ) * N0 ) + ( omega * N3 ) ) / 18.0e0 ) ); 423  Vi[2] = Vi[3] - ( di * ( ( ( 6.0e0 * T3 ) + ( row * N0 ) - ( ( 2.0e0 * omega ) * N3 ) ) / 18.0e0 ) ); 424  // CartVect Wi[3]; 425  // Wi[0] = Vi[1] - Vi[0]; 426  // Wi[1] = Vi[2] - Vi[1]; 427  // Wi[2] = Vi[3] - Vi[2]; 428  429  Pi[0] = 0.25 * Vi[0] + 0.75 * Vi[1]; 430  Pi[1] = 0.50 * Vi[1] + 0.50 * Vi[2]; 431  Pi[2] = 0.75 * Vi[2] + 0.25 * Vi[3]; 432  433  return MB_SUCCESS; 434 }

References moab::CartVect::length(), and MB_SUCCESS.

Referenced by init_bezier_edge().

◆ init_facet_control_points()

ErrorCode moab::SmoothFace::init_facet_control_points ( CartVect  N[6],
CartVect  P[3][5],
CartVect  G[6] 
)
private

Definition at line 580 of file SmoothFace.cpp.

583 { 584  CartVect Di[4], Ai[3], N0, N3, Vi[4], Wi[3]; 585  double denom; 586  double lambda[2], mu[2]; 587  588  ErrorCode rval = MB_SUCCESS; 589  590  for( int i = 0; i < 3; i++ ) 591  { 592  N0 = N[i * 2]; 593  N3 = N[i * 2 + 1]; 594  Vi[0] = P[i][0]; 595  Vi[1] = ( P[i][1] - 0.25 * P[i][0] ) / 0.75; 596  Vi[2] = ( P[i][3] - 0.25 * P[i][4] ) / 0.75; 597  Vi[3] = P[i][4]; 598  Wi[0] = Vi[1] - Vi[0]; 599  Wi[1] = Vi[2] - Vi[1]; 600  Wi[2] = Vi[3] - Vi[2]; 601  Di[0] = P[( i + 2 ) % 3][3] - 0.5 * ( P[i][1] + P[i][0] ); 602  Di[3] = P[( i + 1 ) % 3][1] - 0.5 * ( P[i][4] + P[i][3] ); 603  Ai[0] = ( N0 * Wi[0] ) / Wi[0].length(); 604  Ai[2] = ( N3 * Wi[2] ) / Wi[2].length(); 605  Ai[1] = Ai[0] + Ai[2]; 606  denom = Ai[1].length(); 607  Ai[1] /= denom; 608  lambda[0] = ( Di[0] % Wi[0] ) / ( Wi[0] % Wi[0] ); 609  lambda[1] = ( Di[3] % Wi[2] ) / ( Wi[2] % Wi[2] ); 610  mu[0] = ( Di[0] % Ai[0] ); 611  mu[1] = ( Di[3] % Ai[2] ); 612  G[i * 2] = 0.5 * ( P[i][1] + P[i][2] ) + 0.66666666666666 * lambda[0] * Wi[1] + 613  0.33333333333333 * lambda[1] * Wi[0] + 0.66666666666666 * mu[0] * Ai[1] + 614  0.33333333333333 * mu[1] * Ai[0]; 615  G[i * 2 + 1] = 0.5 * ( P[i][2] + P[i][3] ) + 0.33333333333333 * lambda[0] * Wi[2] + 616  0.66666666666666 * lambda[1] * Wi[1] + 0.33333333333333 * mu[0] * Ai[2] + 617  0.66666666666666 * mu[1] * Ai[1]; 618  } 619  return rval; 620 }

References ErrorCode, moab::CartVect::length(), length(), and MB_SUCCESS.

Referenced by compute_internal_control_points_on_facets().

◆ init_gradient()

int moab::SmoothFace::init_gradient ( )

Definition at line 170 of file SmoothFace.cpp.

171 { 172  // first, create a Tag for gradient (or normal) 173  // loop over all triangles in set, and modify the normals according to the angle as weight 174  // get all the edges from this subset 175  if( NULL == _mb ) return 1; // fail 176  _triangles.clear(); 177  ErrorCode rval = _mb->get_entities_by_type( _set, MBTRI, _triangles ); 178  if( MB_SUCCESS != rval ) return 1; 179  // get a new range of edges, and decide the loops from here 180  _edges.clear(); 181  rval = _mb->get_adjacencies( _triangles, 1, true, _edges, Interface::UNION ); 182  assert( rval == MB_SUCCESS ); 183  184  rval = _mb->get_adjacencies( _triangles, 0, false, _nodes, Interface::UNION ); 185  assert( rval == MB_SUCCESS ); 186  187  // initialize bounding box limits 188  CartVect vert1; 189  EntityHandle v1 = _nodes[0]; // first vertex 190  _mb->get_coords( &v1, 1, (double*)&vert1 ); 191  _minim = vert1; 192  _maxim = vert1; 193  194  double defNormal[] = { 0., 0., 0. }; 195  // look for a tag name here that is definitely unique. We do not want the tags to interfere with 196  // each other this normal will be for each node in a face some nodes have multiple normals, if 197  // they are at the feature edges 198  unsigned long setId = _mb->id_from_handle( _set ); 199  char name[50] = { 0 }; 200  snprintf( name, 50, "GRADIENT%lu", 201  setId ); // name should be something like GRADIENT29, where 29 is the set ID of the face 202  rval = _mb->tag_get_handle( name, 3, MB_TYPE_DOUBLE, _gradientTag, MB_TAG_DENSE | MB_TAG_CREAT, &defNormal ); 203  assert( rval == MB_SUCCESS ); 204  205  double defPlane[4] = { 0., 0., 1., 0. }; 206  // also define a plane tag ; this will be for each triangle 207  char namePlaneTag[50] = { 0 }; 208  snprintf( namePlaneTag, 50, "PLANE%lu", setId ); 209  rval = _mb->tag_get_handle( "PLANE", 4, MB_TYPE_DOUBLE, _planeTag, MB_TAG_DENSE | MB_TAG_CREAT, &defPlane ); 210  assert( rval == MB_SUCCESS ); 211  // the fourth double is for weight, accumulated at each vertex so far 212  // maybe not needed in the end 213  for( Range::iterator it = _triangles.begin(); it != _triangles.end(); ++it ) 214  { 215  EntityHandle tria = *it; 216  const EntityHandle* conn3; 217  int nnodes; 218  _mb->get_connectivity( tria, conn3, nnodes ); 219  if( nnodes != 3 ) return 1; // error 220  // double coords[9]; // store the coordinates for the nodes 221  //_mb->get_coords(conn3, 3, coords); 222  CartVect p[3]; 223  _mb->get_coords( conn3, 3, (double*)&p[0] ); 224  // need to compute the angles 225  // compute angles and the normal 226  // CartVect p1(&coords[0]), p2(&coords[3]), p3(&coords[6]); 227  228  CartVect AB( p[1] - p[0] ); //(p2 - p1); 229  CartVect BC( p[2] - p[1] ); //(p3 - p2); 230  CartVect CA( p[0] - p[2] ); //(p1 - p3); 231  double a[3]; 232  a[1] = angle( AB, -BC ); // angle at B (p2), etc. 233  a[2] = angle( BC, -CA ); 234  a[0] = angle( CA, -AB ); 235  CartVect normal = -AB * CA; 236  normal.normalize(); 237  double plane[4]; 238  239  const double* coordNormal = normal.array(); 240  241  plane[0] = coordNormal[0]; 242  plane[1] = coordNormal[1]; 243  plane[2] = coordNormal[2]; 244  plane[3] = -normal % p[0]; // dot product 245  // set the plane 246  rval = _mb->tag_set_data( _planeTag, &tria, 1, plane ); 247  assert( rval == MB_SUCCESS ); 248  249  // add to each vertex the tag value the normal multiplied by the angle 250  double values[9]; 251  252  _mb->tag_get_data( _gradientTag, conn3, 3, values ); 253  for( int i = 0; i < 3; i++ ) 254  { 255  // values[4*i]+=a[i]; // first is the weight, which we do not really need 256  values[3 * i + 0] += a[i] * coordNormal[0]; 257  values[3 * i + 1] += a[i] * coordNormal[1]; 258  values[3 * i + 2] += a[i] * coordNormal[2]; 259  } 260  261  // reset those values 262  _mb->tag_set_data( _gradientTag, conn3, 3, values ); 263  } 264  // normalize the gradients at each node; maybe not needed here? 265  // no, we will do it, it is important 266  int numNodes = _nodes.size(); 267  double* normalVal = new double[3 * numNodes]; 268  _mb->tag_get_data( _gradientTag, _nodes, 269  normalVal ); // get all the normal values at the _nodes 270  for( int i = 0; i < numNodes; i++ ) 271  { 272  CartVect p1( &normalVal[3 * i] ); 273  p1.normalize(); 274  p1.get( &normalVal[3 * i] ); 275  } 276  277  // reset the normal values after normalization 278  _mb->tag_set_data( _gradientTag, _nodes, normalVal ); 279  // print the loops size and some other stuff 280  if( debug_surf_eval1 ) 281  { 282  std::cout << " normals at " << numNodes << " nodes" << std::endl; 283  int i = 0; 284  for( Range::iterator it = _nodes.begin(); it != _nodes.end(); ++it, i++ ) 285  { 286  EntityHandle node = *it; 287  std::cout << " Node id " << _mb->id_from_handle( node ) << " " << normalVal[3 * i] << " " 288  << normalVal[3 * i + 1] << " " << normalVal[3 * i + 2] << std::endl; 289  } 290  } 291  292  delete[] normalVal; 293  294  return 0; 295 }

References _edges, _gradientTag, _maxim, _mb, _minim, _nodes, _planeTag, _set, _triangles, moab::angle(), moab::CartVect::array(), moab::Range::begin(), moab::Range::clear(), moab::debug_surf_eval1, moab::Range::end(), ErrorCode, moab::CartVect::get(), moab::Interface::get_adjacencies(), moab::Interface::get_connectivity(), moab::Interface::get_coords(), moab::Interface::get_entities_by_type(), moab::Interface::id_from_handle(), MB_SUCCESS, MB_TAG_CREAT, MB_TAG_DENSE, MB_TYPE_DOUBLE, MBTRI, moab::CartVect::normalize(), moab::Range::size(), moab::Interface::tag_get_data(), moab::Interface::tag_get_handle(), moab::Interface::tag_set_data(), and moab::Interface::UNION.

Referenced by moab::FBEngine::initializeSmoothing().

◆ is_at_vertex()

bool moab::SmoothFace::is_at_vertex ( EntityHandle  facet,
CartVect pt,
CartVect ac,
double  compare_tol,
CartVect eval_pt,
CartVect eval_norm_ptr 
)

Definition at line 1576 of file SmoothFace.cpp.

1582 { 1583  double dist; 1584  CartVect vert_loc; 1585  const double actol = 0.1; 1586  // get coordinates get_coords 1587  const EntityHandle* conn3 = NULL; 1588  int nnodes = 0; 1589  _mb->get_connectivity( facet, conn3, nnodes ); 1590  // 1591  // double coords[9]; // store the coordinates for the nodes 1592  //_mb->get_coords(conn3, 3, coords); 1593  CartVect p[3]; 1594  _mb->get_coords( conn3, 3, (double*)&p[0] ); 1595  // also get the normals at nodes 1596  CartVect NN[3]; 1597  _mb->tag_get_data( _gradientTag, conn3, 3, (double*)&NN[0] ); 1598  if( fabs( ac[0] ) < actol && fabs( ac[1] ) < actol ) 1599  { 1600  vert_loc = p[2]; 1601  dist = ( pt - vert_loc ).length(); // pt.distance_between( vert_loc ); 1602  if( dist <= compare_tol ) 1603  { 1604  eval_pt = vert_loc; 1605  if( eval_norm_ptr ) 1606  { 1607  *eval_norm_ptr = NN[2]; 1608  } 1609  return true; 1610  } 1611  } 1612  1613  if( fabs( ac[0] ) < actol && fabs( ac[2] ) < actol ) 1614  { 1615  vert_loc = p[1]; 1616  dist = ( pt - vert_loc ).length(); // pt.distance_between( vert_loc ); 1617  if( dist <= compare_tol ) 1618  { 1619  eval_pt = vert_loc; 1620  if( eval_norm_ptr ) 1621  { 1622  *eval_norm_ptr = NN[1]; // facet->point(1)->normal( facet ); 1623  } 1624  return true; 1625  } 1626  } 1627  1628  if( fabs( ac[1] ) < actol && fabs( ac[2] ) < actol ) 1629  { 1630  vert_loc = p[0]; 1631  dist = ( pt - vert_loc ).length(); // pt.distance_between( vert_loc ); 1632  if( dist <= compare_tol ) 1633  { 1634  eval_pt = vert_loc; 1635  if( eval_norm_ptr ) 1636  { 1637  *eval_norm_ptr = NN[0]; 1638  } 1639  return true; 1640  } 1641  } 1642  1643  return false; 1644 }

References _gradientTag, _mb, moab::Interface::get_connectivity(), moab::Interface::get_coords(), length(), and moab::Interface::tag_get_data().

Referenced by project_to_patch().

◆ move_ac_inside()

bool moab::SmoothFace::move_ac_inside ( CartVect ac,
double  tol 
)
private

Definition at line 1654 of file SmoothFace.cpp.

1655 { 1656  int nout = 0; 1657  if( ac[0] < -tol ) 1658  { 1659  ac[0] = 0.0; 1660  ac[1] = ac[1] / ( ac[1] + ac[2] ); //( ac.y() / (ac.y() + ac.z()) ; 1661  ac[2] = 1. - ac[1]; // ac.z( 1.0 - ac.y() ); 1662  nout++; 1663  } 1664  if( ac[1] < -tol ) 1665  { 1666  ac[1] = 0.; // ac.y( 0.0 ); 1667  ac[0] = ac[0] / ( ac[0] + ac[2] ); // ac.x( ac.x() / (ac.x() + ac.z()) ); 1668  ac[2] = 1. - ac[0]; // ac.z( 1.0 - ac.x() ); 1669  nout++; 1670  } 1671  if( ac[2] < -tol ) 1672  { 1673  ac[2] = 0.; // ac.z( 0.0 ); 1674  ac[0] = ac[0] / ( ac[0] + ac[1] ); // ac.x( ac.x() / (ac.x() + ac.y()) ); 1675  ac[1] = 1. - ac[0]; // ac.y( 1.0 - ac.x() ); 1676  nout++; 1677  } 1678  return ( nout > 0 ) ? true : false; 1679 }

Referenced by project_to_patch().

◆ move_to_surface()

void moab::SmoothFace::move_to_surface ( double &  x,
double &  y,
double &  z 
)
virtual

Definition at line 104 of file SmoothFace.cpp.

105 { 106  107  CartVect loc2( x, y, z ); 108  bool trim = false; // is it needed? 109  bool outside = true; 110  CartVect closestPoint; 111  112  ErrorCode rval = project_to_facets_main( loc2, trim, outside, &closestPoint, NULL ); 113  if( MB_SUCCESS != rval ) return; 114  assert( rval == MB_SUCCESS ); 115  x = closestPoint[0]; 116  y = closestPoint[1]; 117  z = closestPoint[2]; 118 }

References ErrorCode, MB_SUCCESS, and project_to_facets_main().

Referenced by moab::FBEngine::getEntClosestPt(), and moab::FBEngine::smooth_new_intx_points().

◆ normal_at()

bool moab::SmoothFace::normal_at ( double  x,
double  y,
double  z,
double &  nx,
double &  ny,
double &  nz 
)
virtual

Definition at line 127 of file SmoothFace.cpp.

128 { 129  130  CartVect loc2( x, y, z ); 131  132  bool trim = false; // is it needed? 133  bool outside = true; 134  // CartVect closestPoint;// not needed 135  // not interested in normal 136  CartVect normal; 137  ErrorCode rval = project_to_facets_main( loc2, trim, outside, NULL, &normal ); 138  if( MB_SUCCESS != rval ) return false; 139  assert( rval == MB_SUCCESS ); 140  nx = normal[0]; 141  ny = normal[1]; 142  nz = normal[2]; 143  144  return true; 145 }

References ErrorCode, MB_SUCCESS, and project_to_facets_main().

Referenced by moab::FBEngine::getEntNrmlXYZ().

◆ project_to_facet()

ErrorCode moab::SmoothFace::project_to_facet ( EntityHandle  facet,
CartVect pt,
CartVect areacoord,
CartVect close_point,
bool &  outside_facet,
double  compare_tol 
)

Definition at line 1545 of file SmoothFace.cpp.

1551 { 1552  const EntityHandle* conn3 = NULL; 1553  int nnodes = 0; 1554  _mb->get_connectivity( facet, conn3, nnodes ); 1555  // 1556  // double coords[9]; // store the coordinates for the nodes 1557  //_mb->get_coords(conn3, 3, coords); 1558  CartVect p[3]; 1559  _mb->get_coords( conn3, 3, (double*)&p[0] ); 1560  1561  int edge_id = -1; 1562  ErrorCode stat = project_to_patch( facet, areacoord, pt, close_point, NULL, outside_facet, compare_tol, edge_id ); 1563  /* } 1564  break; 1565  }*/ 1566  1567  return stat; 1568 }

References _mb, ErrorCode, moab::Interface::get_connectivity(), moab::Interface::get_coords(), and project_to_patch().

Referenced by project_to_facets().

◆ project_to_facet_plane()

void moab::SmoothFace::project_to_facet_plane ( EntityHandle  tri,
CartVect pt,
CartVect point_on_plane,
double &  dist_to_plane 
)

Definition at line 902 of file SmoothFace.cpp.

906 { 907  double plane[4]; 908  909  ErrorCode rval = _mb->tag_get_data( _planeTag, &tri, 1, plane ); 910  if( MB_SUCCESS != rval ) return; 911  assert( rval == MB_SUCCESS ); 912  // _planeTag 913  CartVect normal( &plane[0] ); // just first 3 components are used 914  915  double dist = normal % pt + plane[3]; // coeff d is saved!!! 916  dist_to_plane = fabs( dist ); 917  point_on_plane = pt - dist * normal; 918  919  return; 920 }

References _mb, _planeTag, ErrorCode, MB_SUCCESS, and moab::Interface::tag_get_data().

Referenced by project_to_facets().

◆ project_to_facets()

ErrorCode moab::SmoothFace::project_to_facets ( std::vector< EntityHandle > &  facet_list,
EntityHandle lastFacet,
int  interpOrder,
double  compareTol,
CartVect this_point,
bool  trim,
bool &  outside,
CartVect closest_point_ptr,
CartVect normal_ptr 
)

best_facet

Definition at line 1101 of file SmoothFace.cpp.

1110 { 1111  1112  bool outside_facet = false; 1113  bool best_outside_facet = true; 1114  double mindist = 1.e20; 1115  CartVect close_point, best_point( mindist, mindist, mindist ), best_areacoord; 1116  EntityHandle best_facet = 0L; // no best facet found yet 1117  EntityHandle facet; 1118  assert( facet_list.size() > 0 ); 1119  1120  double big_dist = compareTol * 1.0e3; 1121  1122  // from the list of close facets, determine the closest point 1123  for( size_t i = 0; i < facet_list.size(); i++ ) 1124  { 1125  facet = facet_list[i]; 1126  CartVect pt_on_plane; 1127  double dist_to_plane; 1128  project_to_facet_plane( facet, this_point, pt_on_plane, dist_to_plane ); 1129  1130  CartVect areacoord; 1131  // CartVect close_point; 1132  facet_area_coordinate( facet, pt_on_plane, areacoord ); 1133  if( interpOrder != 0 ) 1134  { 1135  1136  // modify the areacoord - project to the bezier patch- snaps to the 1137  // edge of the patch if necessary 1138  1139  if( project_to_facet( facet, this_point, areacoord, close_point, outside_facet, compareTol ) != MB_SUCCESS ) 1140  { 1141  return MB_FAILURE; 1142  } 1143  // if (closest_point_ptr) 1144  //*closest_point_ptr = close_point; 1145  } 1146  // keep track of the minimum distance 1147  1148  double dist = ( close_point - this_point ).length(); // close_point.distance_between(this_point); 1149  if( ( best_outside_facet == outside_facet && dist < mindist ) || 1150  ( best_outside_facet && !outside_facet && ( dist < big_dist || best_facet == 0L /*!best_facet*/ ) ) ) 1151  { 1152  mindist = dist; 1153  best_point = close_point; 1154  best_facet = facet; 1155  best_areacoord = areacoord; 1156  best_outside_facet = outside_facet; 1157  1158  if( dist < compareTol ) 1159  { 1160  break; 1161  } 1162  big_dist = 10.0 * mindist; 1163  } 1164  // facet->marked(1); 1165  // used_facet_list.append(facet); 1166  } 1167  1168  if( normal_ptr ) 1169  { 1170  CartVect normal; 1171  if( eval_bezier_patch_normal( best_facet, best_areacoord, normal ) != MB_SUCCESS ) 1172  { 1173  return MB_FAILURE; 1174  } 1175  *normal_ptr = normal; 1176  } 1177  1178  if( closest_point_ptr ) 1179  { 1180  *closest_point_ptr = best_point; 1181  } 1182  1183  outside = best_outside_facet; 1184  lastFacet = best_facet; 1185  1186  return MB_SUCCESS; 1187  // end copy 1188 }

References eval_bezier_patch_normal(), facet_area_coordinate(), length(), MB_SUCCESS, project_to_facet(), and project_to_facet_plane().

Referenced by project_to_facets_main().

◆ project_to_facets_main()

ErrorCode moab::SmoothFace::project_to_facets_main ( CartVect this_point,
bool  trim,
bool &  outside,
CartVect closest_point_ptr = NULL,
CartVect normal_ptr = NULL 
)

Definition at line 1075 of file SmoothFace.cpp.

1080 { 1081  1082  // if there are a lot of facets on this surface - use the OBB search first 1083  // to narrow the selection 1084  1085  _evaluationsCounter++; 1086  double tolerance = 1.e-5; 1087  std::vector< EntityHandle > facets_out; 1088  // we will start with a list of facets anyway, the best among them wins 1089  ErrorCode rval = 1090  _my_geomTopoTool->obb_tree()->closest_to_location( (double*)&this_point, _obb_root, tolerance, facets_out ); 1091  if( MB_SUCCESS != rval ) return rval; 1092  1093  int interpOrder = 4; 1094  double compareTol = 1.e-5; 1095  EntityHandle lastFacet = facets_out.front(); 1096  rval = project_to_facets( facets_out, lastFacet, interpOrder, compareTol, this_point, trim, outside, 1097  closest_point_ptr, normal_ptr ); 1098  1099  return rval; 1100 }

References _evaluationsCounter, _my_geomTopoTool, _obb_root, moab::OrientedBoxTreeTool::closest_to_location(), ErrorCode, MB_SUCCESS, moab::GeomTopoTool::obb_tree(), project_to_facets(), and moab::tolerance.

Referenced by move_to_surface(), normal_at(), and ray_intersection_correct().

◆ project_to_patch()

ErrorCode moab::SmoothFace::project_to_patch ( EntityHandle  facet,
CartVect ac,
CartVect pt,
CartVect eval_pt,
CartVect eval_norm,
bool &  outside,
double  compare_tol,
int  edge_id 
)

Definition at line 1199 of file SmoothFace.cpp.

1208 { 1209  ErrorCode status = MB_SUCCESS; 1210  1211  // see if we are at a vertex 1212  1213 #define INCR 0.01 1214  const double tol = compare_tol; 1215  1216  if( is_at_vertex( facet, pt, ac, compare_tol, eval_pt, eval_norm ) ) 1217  { 1218  outside = false; 1219  return MB_SUCCESS; 1220  } 1221  1222  // check if the start ac is inside the patch -if not, then move it there 1223  1224  int nout = 0; 1225  const double atol = 0.001; 1226  if( move_ac_inside( ac, atol ) ) nout++; 1227  1228  int diverge = 0; 1229  int iter = 0; 1230  CartVect newpt; 1231  eval_bezier_patch( facet, ac, newpt ); 1232  CartVect move = pt - newpt; 1233  double lastdist = move.length(); 1234  double bestdist = lastdist; 1235  CartVect bestac = ac; 1236  CartVect bestpt = newpt; 1237  CartVect bestnorm( 0, 0, 0 ); 1238  1239  // If we are already close enough, then return now 1240  1241  if( lastdist <= tol && !eval_norm && nout == 0 ) 1242  { 1243  eval_pt = pt; 1244  outside = false; 1245  return status; 1246  } 1247  1248  double ratio, mag, umove, vmove, det, distnew, movedist; 1249  CartVect lastpt = newpt; 1250  CartVect lastac = ac; 1251  CartVect norm; 1252  CartVect xpt, ypt, zpt, xac, yac, zac, xvec, yvec, zvec; 1253  CartVect du, dv, newac; 1254  bool done = false; 1255  while( !done ) 1256  { 1257  1258  // We will be locating the projected point within the u,v,w coordinate 1259  // system of the triangular bezier patch. Since u+v+w=1, the components 1260  // are not linearly independent. We will choose only two of the 1261  // coordinates to use and compute the third. 1262  1263  int system; 1264  if( lastac[0] >= lastac[1] && lastac[0] >= lastac[2] ) 1265  { 1266  system = 0; 1267  } 1268  else if( lastac[1] >= lastac[2] ) 1269  { 1270  system = 1; 1271  } 1272  else 1273  { 1274  system = 2; 1275  } 1276  1277  // compute the surface derivatives with respect to each 1278  // of the barycentric coordinates 1279  1280  if( system == 1 || system == 2 ) 1281  { 1282  xac[0] = lastac[0] + INCR; // xac.x( lastac.x() + INCR ); 1283  if( lastac[1] + lastac[2] == 0.0 ) return MB_FAILURE; 1284  ratio = lastac[2] / ( lastac[1] + lastac[2] ); // ratio = lastac.z() / (lastac.y() + lastac.z()); 1285  xac[1] = ( 1.0 - xac[0] ) * ( 1.0 - ratio ); // xac.y( (1.0 - xac.x()) * (1.0 - ratio) ); 1286  xac[2] = 1.0 - xac[0] - xac[1]; // xac.z( 1.0 - xac.x() - xac.y() ); 1287  eval_bezier_patch( facet, xac, xpt ); 1288  xvec = xpt - lastpt; 1289  xvec /= INCR; 1290  } 1291  if( system == 0 || system == 2 ) 1292  { 1293  yac[1] = ( lastac[1] + INCR ); // yac.y( lastac.y() + INCR ); 1294  if( lastac[0] + lastac[2] == 0.0 ) // if (lastac.x() + lastac.z() == 0.0) 1295  return MB_FAILURE; 1296  ratio = lastac[2] / ( lastac[0] + lastac[2] ); // ratio = lastac.z() / (lastac.x() + lastac.z()); 1297  yac[0] = ( ( 1.0 - yac[1] ) * ( 1.0 - ratio ) ); // yac.x( (1.0 - yac.y()) * (1.0 - ratio) ); 1298  yac[2] = ( 1.0 - yac[0] - yac[1] ); // yac.z( 1.0 - yac.x() - yac.y() ); 1299  eval_bezier_patch( facet, yac, ypt ); 1300  yvec = ypt - lastpt; 1301  yvec /= INCR; 1302  } 1303  if( system == 0 || system == 1 ) 1304  { 1305  zac[2] = ( lastac[2] + INCR ); // zac.z( lastac.z() + INCR ); 1306  if( lastac[0] + lastac[1] == 0.0 ) // if (lastac.x() + lastac.y() == 0.0) 1307  return MB_FAILURE; 1308  ratio = lastac[1] / ( lastac[0] + lastac[1] ); // ratio = lastac.y() / (lastac.x() + lastac.y()); 1309  zac[0] = ( ( 1.0 - zac[2] ) * ( 1.0 - ratio ) ); // zac.x( (1.0 - zac.z()) * (1.0 - ratio) ); 1310  zac[1] = ( 1.0 - zac[0] - zac[2] ); // zac.y( 1.0 - zac.x() - zac.z() ); 1311  eval_bezier_patch( facet, zac, zpt ); 1312  zvec = zpt - lastpt; 1313  zvec /= INCR; 1314  } 1315  1316  // compute the surface normal 1317  1318  switch( system ) 1319  { 1320  case 0: 1321  du = yvec; 1322  dv = zvec; 1323  break; 1324  case 1: 1325  du = zvec; 1326  dv = xvec; 1327  break; 1328  case 2: 1329  du = xvec; 1330  dv = yvec; 1331  break; 1332  } 1333  norm = du * dv; 1334  mag = norm.length(); 1335  if( mag < DBL_EPSILON ) 1336  { 1337  return MB_FAILURE; 1338  // do something else here (it is likely a flat triangle - 1339  // so try evaluating just an edge of the bezier patch) 1340  } 1341  norm /= mag; 1342  if( iter == 0 ) bestnorm = norm; 1343  1344  // project the move vector to the tangent plane 1345  1346  move = ( norm * move ) * norm; 1347  1348  // compute an equivalent u-v-w vector 1349  1350  CartVect absnorm( fabs( norm[0] ), fabs( norm[1] ), fabs( norm[2] ) ); 1351  if( absnorm[2] >= absnorm[1] && absnorm[2] >= absnorm[0] ) 1352  { 1353  det = du[0] * dv[1] - dv[0] * du[1]; 1354  if( fabs( det ) <= DBL_EPSILON ) 1355  { 1356  return MB_FAILURE; // do something else here 1357  } 1358  umove = ( move[0] * dv[1] - dv[0] * move[1] ) / det; 1359  vmove = ( du[0] * move[1] - move[0] * du[1] ) / det; 1360  } 1361  else if( absnorm[1] >= absnorm[2] && absnorm[1] >= absnorm[0] ) 1362  { 1363  det = du[0] * dv[2] - dv[0] * du[2]; 1364  if( fabs( det ) <= DBL_EPSILON ) 1365  { 1366  return MB_FAILURE; 1367  } 1368  umove = ( move[0] * dv[2] - dv[0] * move[2] ) / det; 1369  vmove = ( du[0] * move[2] - move[0] * du[2] ) / det; 1370  } 1371  else 1372  { 1373  det = du[1] * dv[2] - dv[1] * du[2]; 1374  if( fabs( det ) <= DBL_EPSILON ) 1375  { 1376  return MB_FAILURE; 1377  } 1378  umove = ( move[1] * dv[2] - dv[1] * move[2] ) / det; 1379  vmove = ( du[1] * move[2] - move[1] * du[2] ) / det; 1380  } 1381  1382  /* === compute the new u-v coords and evaluate surface at new location */ 1383  1384  switch( system ) 1385  { 1386  case 0: 1387  newac[1] = ( lastac[1] + umove ); // newac.y( lastac.y() + umove ); 1388  newac[2] = ( lastac[2] + vmove ); // newac.z( lastac.z() + vmove ); 1389  newac[0] = ( 1.0 - newac[1] - newac[2] ); // newac.x( 1.0 - newac.y() - newac.z() ); 1390  break; 1391  case 1: 1392  newac[2] = ( lastac[2] + umove ); // newac.z( lastac.z() + umove ); 1393  newac[0] = ( lastac[0] + vmove ); // newac.x( lastac.x() + vmove ); 1394  newac[1] = ( 1.0 - newac[2] - newac[0] ); // newac.y( 1.0 - newac.z() - newac.x() ); 1395  break; 1396  case 2: 1397  newac[0] = ( lastac[0] + umove ); // newac.x( lastac.x() + umove ); 1398  newac[1] = ( lastac[1] + vmove ); // newac.y( lastac.y() + vmove ); 1399  newac[2] = ( 1.0 - newac[0] - newac[1] ); // newac.z( 1.0 - newac.x() - newac.y() ); 1400  break; 1401  } 1402  1403  // Keep it inside the patch 1404  1405  if( newac[0] >= -atol && newac[1] >= -atol && newac[2] >= -atol ) 1406  { 1407  nout = 0; 1408  } 1409  else 1410  { 1411  if( move_ac_inside( newac, atol ) ) nout++; 1412  } 1413  1414  // Evaluate at the new location 1415  1416  if( edge_id != -1 ) ac_at_edge( newac, newac, edge_id ); // move to edge first 1417  eval_bezier_patch( facet, newac, newpt ); 1418  1419  // Check for convergence 1420  1421  distnew = ( pt - newpt ).length(); // pt.distance_between(newpt); 1422  move = newpt - lastpt; 1423  movedist = move.length(); 1424  if( movedist < tol || distnew < tol ) 1425  { 1426  done = true; 1427  if( distnew < bestdist ) 1428  { 1429  bestdist = distnew; 1430  bestac = newac; 1431  bestpt = newpt; 1432  bestnorm = norm; 1433  } 1434  } 1435  else 1436  { 1437  1438  // don't allow more than 30 iterations 1439  1440  iter++; 1441  if( iter > 30 ) 1442  { 1443  // if (movedist > tol * 100.0) nout=1; 1444  done = true; 1445  } 1446  1447  // Check for divergence - don't allow more than 5 divergent 1448  // iterations 1449  1450  if( distnew > lastdist ) 1451  { 1452  diverge++; 1453  if( diverge > 10 ) 1454  { 1455  done = true; 1456  // if (movedist > tol * 100.0) nout=1; 1457  } 1458  } 1459  1460  // Check if we are continuing to project outside the facet. 1461  // If so, then stop now 1462  1463  if( nout > 3 ) 1464  { 1465  done = true; 1466  } 1467  1468  // set up for next iteration 1469  1470  if( !done ) 1471  { 1472  if( distnew < bestdist ) 1473  { 1474  bestdist = distnew; 1475  bestac = newac; 1476  bestpt = newpt; 1477  bestnorm = norm; 1478  } 1479  lastdist = distnew; 1480  lastpt = newpt; 1481  lastac = newac; 1482  move = pt - lastpt; 1483  } 1484  } 1485  } 1486  1487  eval_pt = bestpt; 1488  if( eval_norm ) 1489  { 1490  *eval_norm = bestnorm; 1491  } 1492  outside = ( nout > 0 ) ? true : false; 1493  ac = bestac; 1494  1495  return status; 1496 }

References ac_at_edge(), ErrorCode, eval_bezier_patch(), INCR, is_at_vertex(), moab::CartVect::length(), length(), MB_SUCCESS, and move_ac_inside().

Referenced by project_to_facet().

◆ ray_intersection_correct()

ErrorCode moab::SmoothFace::ray_intersection_correct ( EntityHandle  facet,
CartVect pt,
CartVect ray,
CartVect eval_pt,
double &  distance,
bool &  outside 
)

Definition at line 1910 of file SmoothFace.cpp.

1916 { 1917  // find a point on the smooth surface 1918  CartVect currentPoint = eval_pt; 1919  int numIter = 0; 1920  double improvement = 1.e20; 1921  CartVect diff; 1922  while( numIter++ < 5 && improvement > 0.01 ) 1923  { 1924  CartVect newPos; 1925  1926  bool trim = false; // is it needed? 1927  outside = true; 1928  CartVect closestPoint; 1929  CartVect normal; 1930  1931  ErrorCode rval = project_to_facets_main( currentPoint, trim, outside, &newPos, &normal ); 1932  if( MB_SUCCESS != rval ) return rval; 1933  assert( rval == MB_SUCCESS ); 1934  diff = newPos - currentPoint; 1935  improvement = diff.length(); 1936  // ( pt + t * ray - closest ) % normal = 0; 1937  // intersect tangent plane that goes through closest point with the direction 1938  // t = normal%(closest-pt) / normal%ray; 1939  double dot = normal % ray; // if it is 0, get out while we can 1940  if( dot < 0.00001 ) 1941  { 1942  // bad convergence, get out, do not modify anything 1943  return MB_SUCCESS; 1944  } 1945  double t = ( ( newPos - pt ) % normal ) / ( dot ); 1946  currentPoint = pt + t * ray; 1947  } 1948  eval_pt = currentPoint; 1949  diff = currentPoint - pt; 1950  distance = diff.length(); 1951  return MB_SUCCESS; 1952 }

References moab::dot(), ErrorCode, moab::CartVect::length(), MB_SUCCESS, and project_to_facets_main().

Referenced by moab::FBEngine::getPntRayIntsct().

Member Data Documentation

◆ _edgeCtrlTag

◆ _edges

Range moab::SmoothFace::_edges
private

◆ _evaluationsCounter

long moab::SmoothFace::_evaluationsCounter
private

Definition at line 237 of file SmoothFace.hpp.

Referenced by eval_counter(), and project_to_facets_main().

◆ _facetCtrlTag

Tag moab::SmoothFace::_facetCtrlTag
private

◆ _facetEdgeCtrlTag

Tag moab::SmoothFace::_facetEdgeCtrlTag
private

◆ _gradientTag

◆ _markTag

Tag moab::SmoothFace::_markTag
private

Definition at line 194 of file SmoothFace.hpp.

Referenced by compute_control_points_on_edges().

◆ _maxim

CartVect moab::SmoothFace::_maxim
private

Definition at line 177 of file SmoothFace.hpp.

Referenced by adjust_bounding_box(), bounding_box(), and init_gradient().

◆ _mb

◆ _minim

CartVect moab::SmoothFace::_minim
private

Definition at line 176 of file SmoothFace.hpp.

Referenced by adjust_bounding_box(), bounding_box(), and init_gradient().

◆ _my_geomTopoTool

GeomTopoTool* moab::SmoothFace::_my_geomTopoTool
private

Definition at line 234 of file SmoothFace.hpp.

Referenced by project_to_facets_main(), and SmoothFace().

◆ _nodes

Range moab::SmoothFace::_nodes
private

Definition at line 181 of file SmoothFace.hpp.

Referenced by init_gradient().

◆ _obb_root

EntityHandle moab::SmoothFace::_obb_root
private

Definition at line 235 of file SmoothFace.hpp.

Referenced by project_to_facets_main(), and SmoothFace().

◆ _planeTag

Tag moab::SmoothFace::_planeTag
private

◆ _set

EntityHandle moab::SmoothFace::_set
private

Definition at line 233 of file SmoothFace.hpp.

Referenced by DumpModelControlPoints(), init_gradient(), and SmoothFace().

◆ _tangentsTag

Tag moab::SmoothFace::_tangentsTag
private

Definition at line 204 of file SmoothFace.hpp.

Referenced by compute_tangents_for_each_edge(), and init_bezier_edge().

◆ _triangles

Range moab::SmoothFace::_triangles
private

The documentation for this class was generated from the following files: