4 #define _USE_MATH_DEFINES
54 intersections.push_back( std::numeric_limits< double >::max() );
67 double abs_dist = fabs( dist );
77 search_win.first = &
pos;
78 search_win.second = &
neg;
167 const std::vector< EntityHandle >& close_tris,
168 const std::vector< int >& close_senses,
170 std::vector< EntityHandle >* neighborhood_tris = 0 );
177 const double ray_point[3],
178 const double ray_dir[3],
180 int min_tolerance_intersections,
183 const Tag* sense_tag,
184 const int* desired_orient,
185 const std::vector< EntityHandle >* prev_facets )
213 std::cerr <<
"error: desired orientation must be 1 (forward) or -1 (reverse)" << std::endl;
217 "failed to get sense tag data" );
218 if( vols[0] == vols[1] )
220 std::cerr <<
"error: surface has positive and negative sense wrt same volume" << std::endl;
245 return (
prevFacets && ( ( *prevFacets ).end() != find( ( *prevFacets ).begin(), ( *prevFacets ).end(), tri ) ) );
250 bool same_neighborhood =
false;
255 same_neighborhood =
true;
259 return same_neighborhood;
277 const std::vector< EntityHandle >& close_tris,
278 const std::vector< int >& close_senses,
280 std::vector< EntityHandle >* neighborhood_tris )
288 if( 3 != len )
return false;
291 std::vector< EntityHandle > adj_tris;
292 std::vector< int > adj_senses;
308 for(
unsigned i = 0; i < close_tris.size(); ++i )
312 if( 3 != len )
return false;
314 if( node == con[0] || node == con[1] || node == con[2] )
316 adj_tris.push_back( close_tris[i] );
317 adj_senses.push_back( close_senses[i] );
320 if( adj_tris.empty() )
322 std::cerr <<
"error: no tris are adjacent to the node" << std::endl;
349 for(
unsigned i = 0; i < close_tris.size(); ++i )
353 if( 3 != len )
return false;
356 if( ( endpts[0] == con[0] && endpts[1] == con[1] ) || ( endpts[0] == con[1] && endpts[1] == con[0] ) ||
357 ( endpts[0] == con[1] && endpts[1] == con[2] ) || ( endpts[0] == con[2] && endpts[1] == con[1] ) ||
358 ( endpts[0] == con[2] && endpts[1] == con[0] ) || ( endpts[0] == con[0] && endpts[1] == con[2] ) )
360 adj_tris.push_back( close_tris[i] );
361 adj_senses.push_back( close_senses[i] );
365 if( 2 != adj_tris.size() )
367 std::cerr <<
"error: edge of a manifold must be topologically adjacent to exactly 2 tris" << std::endl;
368 MBI->list_entities( endpts, 2 );
374 std::cerr <<
"error: special case not an node/edge intersection" << std::endl;
380 if( neighborhood_tris ) ( *neighborhood_tris ).assign( adj_tris.begin(), adj_tris.end() );
387 for(
unsigned i = 0; i < adj_tris.size(); ++i )
391 if( 3 != len )
return false;
397 CartVect v0 = coords[1] - coords[0];
398 CartVect v1 = coords[2] - coords[0];
399 CartVect norm = adj_senses[i] * ( v0 * v1 );
400 double dot_prod = norm % ray_dir;
403 if( 0 == sign && 0 != dot_prod )
413 if( 0 != sign && 0 > sign * dot_prod )
return false;
442 std::vector< EntityHandle > close_tris;
443 std::vector< int > close_senses;
445 close_tris, close_senses ),
446 "failed to get close triangles" );
468 sets.push_back( set );
469 facets.push_back( facet );
513 if( dist < -*( search_win.second ) )
533 if( search_win.second && search_win.first )
547 if( minTolInt < 0 && dist > -
tol )
559 if( search_win.first && search_win.first >= &
intersections[0] &&
577 search_win.first = &
tol;
599 else if( len_idx >= 0 )
601 if( dist <= *search_win.first )
620 bool p_rootSets_vector,
621 bool restore_rootSets,
623 double overlap_thickness,
624 double numerical_precision )
625 :
verbose( false ), owns_gtt( true )
645 double overlap_thickness,
646 double numerical_precision )
647 :
verbose( false ), owns_gtt( false )
693 if( prev_facets.size() > 1 )
695 prev_facets[0] = prev_facets.back();
696 prev_facets.resize( 1 );
702 if( prev_facets.size() ) prev_facets.pop_back();
707 if( prev_facets.size() > 0 )
709 last_facet_hit = prev_facets.back();
720 return std::find( prev_facets.begin(), prev_facets.end(), ent ) != prev_facets.end();
725 prev_facets.push_back( ent );
729 const double point[3],
732 double& next_surf_dist,
734 double user_dist_limit,
750 std::cout <<
"ray_fire:"
751 <<
" xyz=" << point[0] <<
" " << point[1] <<
" " << point[2] <<
" uvw=" << dir[0] <<
" " << dir[1] <<
" "
752 << dir[2] <<
" entity_handle=" << volume << std::endl;
755 const double huge_val = std::numeric_limits< double >::max();
756 double dist_limit = huge_val;
757 if( user_dist_limit > 0 ) dist_limit = user_dist_limit;
760 std::vector< double > dists;
761 std::vector< EntityHandle > surfs;
762 std::vector< EntityHandle > facets;
779 double nonneg_ray_len = dist_limit;
783 if( nonneg_ray_len < -neg_ray_len ) nonneg_ray_len = -neg_ray_len;
784 if( 0 > nonneg_ray_len || 0 <= neg_ray_len )
786 MB_SET_ERR( MB_FAILURE,
"Incorrect ray length provided" );
790 const int min_tolerance_intersections = 0;
795 &root, &volume, &
senseTag, &ray_orientation,
800 dir, search_win, int_reg_ctxt, stats ),
801 "Ray query failed" );
811 std::cout <<
" next_surf=0 dist=(undef)" << std::endl;
819 if( 2 != dists.size() || 2 != facets.size() )
821 MB_SET_ERR( MB_FAILURE,
"Incorrect number of facets/distances" );
823 if( 0.0 < dists[0] || 0.0 > dists[1] )
825 MB_SET_ERR( MB_FAILURE,
"Invalid intersection distance signs" );
830 if( ( 0 != facets[0] && 0 != facets[1] ) && ( -dists[0] > dists[1] ) )
832 MB_SET_ERR( MB_FAILURE,
"Invalid intersection distance values" );
841 std::vector< EntityHandle > vols;
844 if( 2 != vols.size() )
846 MB_SET_ERR( MB_FAILURE,
"Invaid number of parent volumes found" );
848 if( vols.front() == volume )
850 nx_vol = vols.back();
854 nx_vol = vols.front();
862 if( 1 == result ) exit_idx = 0;
866 if( -1 == exit_idx && 0 != facets[1] ) exit_idx = 1;
873 std::cout <<
"next surf hit = 0, dist = (undef)" << std::endl;
879 next_surf = surfs[exit_idx];
880 next_surf_dist = ( 0 > dists[exit_idx] ? 0 : dists[exit_idx] );
884 history->
prev_facets.push_back( facets[exit_idx] );
888 if( 0 > dists[exit_idx] )
890 std::cout <<
" OVERLAP track length=" << dists[exit_idx] << std::endl;
892 std::cout <<
" next_surf = " << next_surf
893 <<
", dist = " << next_surf_dist <<
" new_pt=";
894 for(
int i = 0; i < 3; ++i )
896 std::cout << point[i] + dir[i] * next_surf_dist <<
" ";
898 std::cout << std::endl;
928 std::vector< double > dists;
929 std::vector< EntityHandle > surfs;
930 std::vector< EntityHandle > facets;
931 std::vector< int > dirs;
934 double u = 0, v = 0, w = 0;
939 v = uvw[1], w = uvw[2];
942 if( u == 0 && v == 0 && w == 0 )
947 const double magnitude = sqrt( u * u + v * v + w * w );
953 const double ray_direction[] = { u, v, w };
956 const double large = 1e15;
957 double ray_length = large;
962 int min_tolerance_intersections;
965 min_tolerance_intersections = -1;
970 min_tolerance_intersections = 1;
976 min_tolerance_intersections, &root, &volume, &
senseTag, NULL,
981 ray_direction, search_win, int_reg_ctxt ),
982 "Ray fire query failed" );
987 dirs.resize( dists.size() );
988 for(
unsigned i = 0; i < dists.size(); ++i )
991 "Failed to resolve boundary case" );
998 for(
unsigned i = 0; i < dirs.size(); ++i )
1002 else if( 0 == dirs[i] )
1004 else if( -1 == dirs[i] )
1006 std::cout <<
"direction==tangent" << std::endl;
1011 MB_SET_ERR( MB_FAILURE,
"Error: unknown direction" );
1035 int smallest = std::min_element( dists.begin(), dists.end() ) - dists.begin();
1036 if( 1 == dirs[smallest] )
1038 else if( 0 == dirs[smallest] )
1040 else if( -1 == dirs[smallest] )
1044 std::cerr <<
"direction==tangent" << std::endl;
1049 MB_SET_ERR( MB_FAILURE,
"Error: unknown direction" );
1055 std::cout <<
"pt_in_vol: result=" << result <<
" xyz=" << xyz[0] <<
" " << xyz[1] <<
" " << xyz[2] <<
" uvw=" << u
1056 <<
" " << v <<
" " << w <<
" vol_id=" << volume
1073 "Failed to get the bounding coordinates of the volume" );
1076 if( point[0] > maxpt[0] || point[0] < minpt[0] )
1081 if( point[1] > maxpt[1] || point[1] < minpt[1] )
1086 if( point[2] > maxpt[2] || point[2] < minpt[2] )
1097 const double xyz[3],
1098 const double uvw[3],
1108 "Failed to resolve the boundary case" );
1123 "Failed to find the closest point to location" );
1126 "Failed to resolve the boundary case" );
1138 std::vector< EntityHandle > surfs;
1139 std::vector< int > senses;
1145 senses.resize( surfs.size() );
1147 "Failed to get the volume's surface senses" );
1149 for(
unsigned i = 0; i < surfs.size(); ++i )
1154 double surf_area = 0.0, face_area;
1157 "Failed to get the surface entities by dimension" );
1163 surf_area += face_area;
1166 sum += senses[i] * surf_area;
1169 result = fabs(
sum ) > 2.0 * M_PI;
1183 "Failed to get the implicit complement handle" );
1186 if( ic_result == 0 )
1193 if( !global_surf_tree_root )
1218 const double huge_val = std::numeric_limits< double >::max();
1219 double pos_ray_len = huge_val;
1220 double neg_ray_len = -huge_val;
1223 std::vector< double > dists;
1224 std::vector< EntityHandle > surfs;
1225 std::vector< EntityHandle > facets;
1231 find_vol_reg_ctxt ),
1232 "Failed in global tree ray fire" );
1235 if( surfs.size() == 0 || surfs[0] == 0 )
1251 parent_vols[0] = fwd_vol;
1252 parent_vols[1] = bwd_vol;
1255 std::vector< EntityHandle > conn;
1261 CartVect normal = ( coords[1] - coords[0] ) * ( coords[2] - coords[0] );
1272 double dot_prod = uvw % normal;
1273 int idx = dot_prod > 0.0 ? 0 : 1;
1275 if( dot_prod == 0.0 )
1277 std::cerr <<
"Tangent dot product in find_volume. Shouldn't be here." << std::endl;
1282 volume = parent_vols[idx];
1296 for( it = all_vols.
begin(); it != all_vols.
end(); it++ )
1310 const double coords[3],
1325 "Failed to get the closest intersection to location" );
1327 result = ( point - nearest ).
length();
1335 std::vector< EntityHandle > surfaces;
1349 std::vector< int > senses( surfaces.size() );
1351 "Failed to retrieve surface-volume sense data. Cannot calculate volume" );
1353 for(
unsigned i = 0; i < surfaces.size(); ++i )
1356 if( !senses[i] )
continue;
1361 "Failed to get the surface triangles" );
1365 std::cout <<
"WARNING: Surface " << surfaces[i]
1366 <<
" contains non-triangle elements. Volume calculation may be incorrect." << std::endl;
1369 "Failed to get the surface triangles" );
1373 double surf_sum = 0.0;
1380 "Failed to get the connectivity of the current triangle" );
1383 MB_SET_ERR( MB_FAILURE,
"Incorrect connectivity length for triangle" );
1386 "Failed to get the coordinates of the current triangle's vertices" );
1388 coords[1] -= coords[0];
1389 coords[2] -= coords[0];
1390 surf_sum += ( coords[0] % ( coords[1] * coords[2] ) );
1392 result += senses[i] * surf_sum;
1407 std::cout <<
"WARNING: Surface " << surface
1408 <<
" contains non-triangle elements. Area calculation may be incorrect." << std::endl;
1411 "Failed to the surface's triangle entities" );
1422 "Failed to get the current triangle's connectivity" );
1425 MB_SET_ERR( MB_FAILURE,
"Incorrect connectivity length for triangle" );
1428 "Failed to get the current triangle's vertex coordinates" );
1431 CartVect v1 = coords[1] - coords[0];
1432 CartVect v2 = coords[2] - coords[0];
1441 const double in_pt[3],
1448 std::vector< EntityHandle > facets;
1451 if( !history || ( history->
prev_facets.size() == 0 ) )
1454 "Failed to get closest intersection to location" );
1465 for(
unsigned i = 0; i < facets.size(); ++i )
1470 MB_SET_ERR( MB_FAILURE,
"Incorrect connectivity length for triangle" );
1475 coords[1] -= coords[0];
1476 coords[2] -= coords[0];
1477 normal += coords[1] * coords[2];
1502 if( u <= 1.0 && v <= 1.0 && w <= 1.0 )
1505 const CartVect ray_vector( u, v, w );
1513 MB_SET_ERR( MB_FAILURE,
"Incorrect connectivity length for triangle" );
1519 "Failed to get the surface's sense with respect to it's volume" );
1521 coords[1] -= coords[0];
1522 coords[2] -= coords[0];
1523 normal = sense_out * ( coords[1] * coords[2] );
1525 double sense = ray_vector % normal;
1531 else if( sense > 0.0 )
1535 else if( sense == 0.0 )
1542 MB_SET_ERR( MB_FAILURE,
"Failed to resolve boundary case" );
1573 std::vector< CartVect > coords_dynamic;
1575 if( (
unsigned)len > (
sizeof( coords_static ) /
sizeof( coords_static[0] ) ) )
1577 coords_dynamic.resize( len );
1578 coords = &coords_dynamic[0];
1583 "Failed to get the coordinates of the polygon vertices" );
1586 CartVect norm( 0.0 ), v1, v0 = coords[1] - coords[0];
1587 for(
int i = 2; i < len; ++i )
1589 v1 = coords[i] - coords[0];
1597 CartVect r, n1, n2, b, a = coords[len - 1] - coords[0];
1598 for(
int i = 0; i < len; ++i )
1600 r = coords[i] - point;
1601 b = coords[( i + 1 ) % len] - coords[i];
1604 s = ( n1 % n2 ) / ( n1.length() * n2.
length() );
1605 ang = s <= -1.0 ? M_PI : s >= 1.0 ? 0.0 : acos( s );
1606 s = ( b * a ) % norm;
1607 area += s > 0.0 ? M_PI - ang : M_PI + ang;
1611 area -= M_PI * ( len - 2 );
1612 if( ( norm % r ) > 0 ) area = -area;
1618 if( new_thickness < 0 || new_thickness > 100 )
1620 std::cerr <<
"Invalid overlap_thickness = " << new_thickness << std::endl;
1631 if( new_precision <= 0 || new_precision > 1 )