MeshTopoUtil contains general mesh utility functions. More...
#include <MeshTopoUtil.hpp>
Public Member Functions | |
MeshTopoUtil (Interface *impl) | |
~MeshTopoUtil () | |
ErrorCode | construct_aentities (const Range &vertices) |
generate all the AEntities bounding the vertices More... | |
ErrorCode | get_average_position (Range &entities, double *avg_position) |
given an entity, get its average position (avg vertex locations) More... | |
ErrorCode | get_average_position (const EntityHandle entity, double *avg_position) |
given an entity, get its average position (avg vertex locations) More... | |
ErrorCode | get_average_position (const EntityHandle *entities, const int num_entities, double *avg_position) |
given a set of entities, get their average position (avg vertex locations) More... | |
ErrorCode | get_manifold (const EntityHandle star_entity, const int target_dim, Range &manifold) |
get (target_dim)-dimensional manifold entities connected to star_entity; that is, the entities with <= 1 connected (target_dim+2)-dimensional adjacent entities; for target_dim=3, just return all of them just insert into the list, w/o clearing manifold list first More... | |
ErrorCode | star_entities (const EntityHandle star_center, std::vector< EntityHandle > &star_entities, bool &bdy_entity, const EntityHandle starting_star_entity=0, std::vector< EntityHandle > *star_entities_dp1=NULL, Range *star_entities_candidates_dp1=NULL) |
given an entity, find the entities of next higher dimension around that entity, ordered by connection through next higher dimension entities; if any of the star entities is in only entity of next higher dimension, on_boundary is returned true More... | |
ErrorCode | star_entities_nonmanifold (const EntityHandle star_entity, std::vector< std::vector< EntityHandle > > &stars, std::vector< bool > *bdy_flags=NULL, std::vector< std::vector< EntityHandle > > *dp2_stars=NULL) |
Get a series of (d+1)-dimensional stars around a d-dimensional entity, such that each star is on a (d+2)-manifold containing the d-dimensional entity; each star is either open or closed, and also defines a (d+2)-star whose entities are bounded by (d+1)-entities on the star and on the (d+2)-manifold. More... | |
ErrorCode | star_next_entity (const EntityHandle star_center, const EntityHandle last_entity, const EntityHandle last_dp1, Range *star_candidates_dp1, EntityHandle &next_entity, EntityHandle &next_dp1) |
given a star_center, a last_entity (whose dimension should be 1 greater than center) and last_dp1 (dimension 2 higher than center), returns the next star entity across last_dp1, and the next dp1 entity sharing next_entity; if star_candidates is non-empty, star must come from those More... | |
ErrorCode | get_bridge_adjacencies (Range &from_entities, int bridge_dim, int to_dim, Range &to_ents, int num_layers=1) |
get "bridge" or "2nd order" adjacencies, going through dimension bridge_dim More... | |
ErrorCode | get_bridge_adjacencies (const EntityHandle from_entity, const int bridge_dim, const int to_dim, Range &to_adjs) |
get "bridge" or "2nd order" adjacencies, going through dimension bridge_dim More... | |
EntityHandle | common_entity (const EntityHandle ent1, const EntityHandle ent2, const int dim) |
return a common entity of the specified dimension, or 0 if there isn't one More... | |
ErrorCode | opposite_entity (const EntityHandle parent, const EntityHandle child, EntityHandle &opposite_element) |
return the opposite side entity given a parent and bounding entity. This function is only defined for certain types of parent/child types; See MBCN.hpp::OppositeSide for details. More... | |
ErrorCode | split_entity_nonmanifold (EntityHandle split_ent, Range &old_adjs, Range &new_adjs, EntityHandle &new_entity) |
split entity which is non-manifold, that is, which has > 2 connected entities of next higher dimension; assumes that there are >= 2 connected regions of (d+2)-dimensional entities; a new d-entity is created for each region after the first, and it's made explicitly-adjacent to the region to which it corresponds More... | |
ErrorCode | split_entities_manifold (Range &entities, Range &new_entities, Range *fill_entities) |
split entities that are manifold (shared by two or less entities of each higher dimension), optionally creating an entity of next higher dimension to fill the gap More... | |
ErrorCode | split_entities_manifold (EntityHandle *entities, const int num_entities, EntityHandle *new_entities, Range *fill_entities, EntityHandle *gowith_ents=NULL) |
split entities that are manifold (shared by two or less entities of each higher dimension), optionally creating an entity of next higher dimension to fill the gap More... | |
bool | equivalent_entities (const EntityHandle entity, Range *equiv_ents=NULL) |
return whether entity is equivalent to any other of same type and same vertices; if equivalent entity is found, it's returned in equiv_ents and return value is true, false otherwise. More... | |
Private Attributes | |
Interface * | mbImpl |
MeshTopoUtil contains general mesh utility functions.
Definition at line 30 of file MeshTopoUtil.hpp.
|
inline |
Definition at line 33 of file MeshTopoUtil.hpp.
33 : mbImpl( impl ) {}
|
inline |
Definition at line 35 of file MeshTopoUtil.hpp.
35 {}
EntityHandle moab::MeshTopoUtil::common_entity | ( | const EntityHandle | ent1, |
const EntityHandle | ent2, | ||
const int | dim | ||
) |
return a common entity of the specified dimension, or 0 if there isn't one
Definition at line 541 of file MeshTopoUtil.cpp.
542 {
543 Range tmp_range, tmp_range2;
544 tmp_range.insert( ent1 );
545 tmp_range.insert( ent2 );
546 ErrorCode result = mbImpl->get_adjacencies( tmp_range, dim, false, tmp_range2 );
547 if( MB_SUCCESS != result || tmp_range2.empty() )
548 return 0;
549 else
550 return *tmp_range2.begin();
551 }
References moab::Range::begin(), dim, moab::Range::empty(), ErrorCode, moab::Interface::get_adjacencies(), moab::Range::insert(), MB_SUCCESS, and mbImpl.
Referenced by moab::DualTool::foc_get_ents(), moab::DualTool::fs_check_quad_sense(), moab::AEntityFactory::get_element(), moab::DualTool::get_opposite_verts(), split_entity_nonmanifold(), moab::DualTool::split_pair_nonmanifold(), and star_next_entity().
generate all the AEntities bounding the vertices
Definition at line 37 of file MeshTopoUtil.cpp.
38 {
39 Range out_range;
40 ErrorCode result;
41 result = mbImpl->get_adjacencies( vertices, 1, true, out_range, Interface::UNION );
42 if( MB_SUCCESS != result ) return result;
43 out_range.clear();
44 result = mbImpl->get_adjacencies( vertices, 2, true, out_range, Interface::UNION );
45 if( MB_SUCCESS != result ) return result;
46 out_range.clear();
47 result = mbImpl->get_adjacencies( vertices, 3, true, out_range, Interface::UNION );
48
49 return result;
50 }
References moab::Range::clear(), ErrorCode, moab::Interface::get_adjacencies(), MB_SUCCESS, mbImpl, and moab::Interface::UNION.
Referenced by SphereDecomp::build_sphere_mesh(), and moab::DualTool::construct_dual().
bool moab::MeshTopoUtil::equivalent_entities | ( | const EntityHandle | entity, |
Range * | equiv_ents = NULL |
||
) |
return whether entity is equivalent to any other of same type and same vertices; if equivalent entity is found, it's returned in equiv_ents and return value is true, false otherwise.
Definition at line 978 of file MeshTopoUtil.cpp.
979 {
980 const EntityHandle* connect = NULL;
981 int num_connect = 0;
982 ErrorCode result = mbImpl->get_connectivity( entity, connect, num_connect );
983 if( MB_SUCCESS != result ) return false;
984
985 Range dum;
986 result = mbImpl->get_adjacencies( connect, num_connect, mbImpl->dimension_from_handle( entity ), false, dum );
987 dum.erase( entity );
988
989 if( NULL != equiv_ents )
990 {
991 equiv_ents->swap( dum );
992 }
993
994 if( !dum.empty() )
995 return true;
996 else
997 return false;
998 }
References moab::Interface::dimension_from_handle(), moab::dum, ErrorCode, moab::Interface::get_adjacencies(), moab::Interface::get_connectivity(), MB_SUCCESS, mbImpl, and moab::Range::swap().
Referenced by moab::DualTool::face_shrink(), moab::DualTool::rev_face_shrink(), and split_entities_manifold().
ErrorCode moab::MeshTopoUtil::get_average_position | ( | const EntityHandle * | entities, |
const int | num_entities, | ||
double * | avg_position | ||
) |
given a set of entities, get their average position (avg vertex locations)
given an entity, get its average position (avg vertex locations)
Definition at line 61 of file MeshTopoUtil.cpp.
64 {
65 double dum_pos[3];
66 avg_position[0] = avg_position[1] = avg_position[2] = 0.0;
67
68 Range connect;
69 ErrorCode result = mbImpl->get_adjacencies( entities, num_entities, 0, false, connect, Interface::UNION );
70 if( MB_SUCCESS != result ) return result;
71
72 if( connect.empty() ) return MB_FAILURE;
73
74 for( Range::iterator rit = connect.begin(); rit != connect.end(); ++rit )
75 {
76 result = mbImpl->get_coords( &( *rit ), 1, dum_pos );
77 if( MB_SUCCESS != result ) return result;
78 avg_position[0] += dum_pos[0];
79 avg_position[1] += dum_pos[1];
80 avg_position[2] += dum_pos[2];
81 }
82 avg_position[0] /= (double)connect.size();
83 avg_position[1] /= (double)connect.size();
84 avg_position[2] /= (double)connect.size();
85
86 return MB_SUCCESS;
87 }
References moab::Range::begin(), moab::Range::empty(), moab::Range::end(), entities, ErrorCode, moab::Interface::get_adjacencies(), moab::Interface::get_coords(), MB_SUCCESS, mbImpl, moab::Range::size(), and moab::Interface::UNION.
ErrorCode moab::MeshTopoUtil::get_average_position | ( | const EntityHandle | entity, |
double * | avg_position | ||
) |
given an entity, get its average position (avg vertex locations)
Definition at line 90 of file MeshTopoUtil.cpp.
91 {
92 const EntityHandle* connect = NULL;
93 int num_connect = 0;
94 if( MBVERTEX == mbImpl->type_from_handle( entity ) ) return mbImpl->get_coords( &entity, 1, avg_position );
95
96 ErrorCode result = mbImpl->get_connectivity( entity, connect, num_connect );
97 if( MB_SUCCESS != result ) return result;
98
99 return get_average_position( connect, num_connect, avg_position );
100 }
References ErrorCode, get_average_position(), moab::Interface::get_connectivity(), moab::Interface::get_coords(), MB_SUCCESS, mbImpl, MBVERTEX, and moab::Interface::type_from_handle().
given an entity, get its average position (avg vertex locations)
Definition at line 53 of file MeshTopoUtil.cpp.
54 {
55 std::vector< EntityHandle > ent_vec;
56 std::copy( entities.begin(), entities.end(), std::back_inserter( ent_vec ) );
57 return get_average_position( &ent_vec[0], ent_vec.size(), avg_position );
58 }
References entities.
Referenced by moab::DualTool::add_graphics_point(), MetisPartitioner::assemble_graph(), ZoltanPartitioner::assemble_graph(), MetisPartitioner::assemble_taggedsets_graph(), SphereDecomp::compute_nodes(), moab::DualTool::construct_dual_edges(), moab::DualTool::construct_dual_faces(), moab::DualTool::construct_dual_vertex(), get_average_position(), and ZoltanPartitioner::partition_owned_cells().
ErrorCode moab::MeshTopoUtil::get_bridge_adjacencies | ( | const EntityHandle | from_entity, |
const int | bridge_dim, | ||
const int | to_dim, | ||
Range & | to_adjs | ||
) |
get "bridge" or "2nd order" adjacencies, going through dimension bridge_dim
Definition at line 448 of file MeshTopoUtil.cpp.
452 {
453 // get pointer to connectivity for this entity
454 const EntityHandle* connect;
455 int num_connect;
456 ErrorCode result = MB_SUCCESS;
457 EntityType from_type = TYPE_FROM_HANDLE( from_entity );
458 if( from_type == MBVERTEX )
459 {
460 connect = &from_entity;
461 num_connect = 1;
462 }
463 else
464 {
465 result = mbImpl->get_connectivity( from_entity, connect, num_connect );
466 if( MB_SUCCESS != result ) return result;
467 }
468
469 if( from_type >= MBENTITYSET ) return MB_FAILURE;
470
471 int from_dim = CN::Dimension( from_type );
472
473 Range to_ents;
474
475 if( bridge_dim < from_dim )
476 {
477 // looping over each sub-entity of dimension bridge_dim...
478 if( MBPOLYGON == from_type )
479 {
480 for( int i = 0; i < num_connect; i++ )
481 {
482 // loop over edges, and get the vertices
483 EntityHandle verts_on_edge[2] = { connect[i], connect[( i + 1 ) % num_connect] };
484 to_ents.clear();
485 ErrorCode tmp_result =
486 mbImpl->get_adjacencies( verts_on_edge, 2, to_dim, false, to_ents, Interface::INTERSECT );
487 if( MB_SUCCESS != tmp_result ) result = tmp_result;
488 to_adjs.merge( to_ents );
489 }
490 }
491 else
492 {
493 EntityHandle bridge_verts[MAX_SUB_ENTITIES];
494 int bridge_indices[MAX_SUB_ENTITIES];
495 for( int i = 0; i < CN::NumSubEntities( from_type, bridge_dim ); i++ )
496 {
497
498 // get the vertices making up this sub-entity
499 int num_bridge_verts = CN::VerticesPerEntity( CN::SubEntityType( from_type, bridge_dim, i ) );
500 assert( num_bridge_verts >= 0 && num_bridge_verts <= MAX_SUB_ENTITIES );
501 CN::SubEntityVertexIndices( from_type, bridge_dim, i, bridge_indices );
502 for( int j = 0; j < num_bridge_verts; ++j )
503 {
504 if( bridge_indices[j] >= 0 && bridge_indices[j] < num_connect )
505 bridge_verts[j] = connect[bridge_indices[j]];
506 else
507 bridge_verts[j] = 0;
508 }
509 // CN::SubEntityConn(connect, from_type, bridge_dim, i, &bridge_verts[0],
510 // num_bridge_verts);
511
512 // get the to_dim entities adjacent
513 to_ents.clear();
514 ErrorCode tmp_result = mbImpl->get_adjacencies( bridge_verts, num_bridge_verts, to_dim, false, to_ents,
515 Interface::INTERSECT );
516 if( MB_SUCCESS != tmp_result ) result = tmp_result;
517
518 to_adjs.merge( to_ents );
519 }
520 }
521 }
522
523 // now get the direct ones too, or only in the case where we're
524 // going to higher dimension for bridge
525 Range bridge_ents, tmp_ents;
526 tmp_ents.insert( from_entity );
527 ErrorCode tmp_result = mbImpl->get_adjacencies( tmp_ents, bridge_dim, false, bridge_ents, Interface::UNION );
528 if( MB_SUCCESS != tmp_result ) return tmp_result;
529
530 tmp_result = mbImpl->get_adjacencies( bridge_ents, to_dim, false, to_adjs, Interface::UNION );
531 if( MB_SUCCESS != tmp_result ) return tmp_result;
532
533 // if to_dimension is same as that of from_entity, make sure from_entity isn't
534 // in list
535 if( to_dim == from_dim ) to_adjs.erase( from_entity );
536
537 return result;
538 }
References moab::Range::clear(), moab::CN::Dimension(), moab::Range::erase(), ErrorCode, moab::Interface::get_adjacencies(), moab::Interface::get_connectivity(), moab::Range::insert(), moab::Interface::INTERSECT, moab::MAX_SUB_ENTITIES, MB_SUCCESS, MBENTITYSET, mbImpl, MBPOLYGON, MBVERTEX, moab::Range::merge(), moab::CN::NumSubEntities(), moab::CN::SubEntityType(), moab::CN::SubEntityVertexIndices(), moab::TYPE_FROM_HANDLE(), moab::Interface::UNION, and moab::CN::VerticesPerEntity().
ErrorCode moab::MeshTopoUtil::get_bridge_adjacencies | ( | Range & | from_entities, |
int | bridge_dim, | ||
int | to_dim, | ||
Range & | to_ents, | ||
int | num_layers = 1 |
||
) |
get "bridge" or "2nd order" adjacencies, going through dimension bridge_dim
Definition at line 402 of file MeshTopoUtil.cpp.
407 {
408 Range bridge_ents, accum_layers, new_toents( from_entities );
409 ErrorCode result;
410 if( 0 == num_layers || from_entities.empty() ) return MB_FAILURE;
411
412 // for each layer, get bridge-adj entities and accumulate
413 for( int nl = 0; nl < num_layers; nl++ )
414 {
415 Range new_bridges;
416 // get bridge ents
417 result = mbImpl->get_adjacencies( new_toents, bridge_dim, true, new_bridges, Interface::UNION );
418 if( MB_SUCCESS != result ) return result;
419
420 // get to_dim adjacencies, merge into to_ents
421 Range new_layer;
422 if( -1 == to_dim )
423 {
424 result = mbImpl->get_adjacencies( new_bridges, 3, false, new_layer, Interface::UNION );
425 if( MB_SUCCESS != result ) return result;
426 for( int d = 2; d >= 1; d-- )
427 {
428 result = mbImpl->get_adjacencies( to_ents, d, true, new_layer, Interface::UNION );
429 if( MB_SUCCESS != result ) return result;
430 }
431 }
432 else
433 {
434 result = mbImpl->get_adjacencies( new_bridges, to_dim, false, new_layer, Interface::UNION );
435 if( MB_SUCCESS != result ) return result;
436 }
437
438 // subtract last_toents to get new_toents
439 accum_layers.merge( new_layer );
440 if( nl < num_layers - 1 ) new_toents = subtract( new_layer, new_toents );
441 }
442 to_ents.merge( accum_layers );
443
444 return MB_SUCCESS;
445 }
References moab::Range::empty(), ErrorCode, moab::Interface::get_adjacencies(), MB_SUCCESS, mbImpl, moab::Range::merge(), nl, moab::subtract(), and moab::Interface::UNION.
Referenced by MetisPartitioner::assemble_graph(), ZoltanPartitioner::assemble_graph(), moab::TempestOnlineMap::ComputeAdjacencyRelations(), moab::DualTool::face_shrink(), moab::DualTool::foc_delete_dual(), moab::ParallelComm::get_ghosted_entities(), iMOAB_GetNeighborElements(), moab::DualTool::next_loop_vertex(), ZoltanPartitioner::partition_owned_cells(), and moab::DualTool::traverse_hyperplane().
ErrorCode moab::MeshTopoUtil::get_manifold | ( | const EntityHandle | star_entity, |
const int | target_dim, | ||
Range & | manifold | ||
) |
get (target_dim)-dimensional manifold entities connected to star_entity; that is, the entities with <= 1 connected (target_dim+2)-dimensional adjacent entities; for target_dim=3, just return all of them just insert into the list, w/o clearing manifold list first
Definition at line 372 of file MeshTopoUtil.cpp.
373 {
374 // get all the entities of target dimension connected to star
375 Range tmp_range;
376 ErrorCode result = mbImpl->get_adjacencies( &star_entity, 1, target_dim, false, tmp_range );
377 if( MB_SUCCESS != result ) return result;
378
379 // now save the ones which are (target_dim+1)-dimensional manifold;
380 // for target_dim=3, just return whole range, since we don't do 4d
381 if( target_dim == 3 )
382 {
383 manifold.merge( tmp_range );
384 return MB_SUCCESS;
385 }
386
387 for( Range::iterator rit = tmp_range.begin(); rit != tmp_range.end(); ++rit )
388 {
389 Range dum_range;
390 // get (target_dim+1)-dimensional entities
391 result = mbImpl->get_adjacencies( &( *rit ), 1, target_dim + 1, false, dum_range );
392 if( MB_SUCCESS != result ) return result;
393
394 // if there are only 1 or zero, add to manifold list
395 if( 1 >= dum_range.size() ) manifold.insert( *rit );
396 }
397
398 return MB_SUCCESS;
399 }
References moab::Range::begin(), moab::Range::end(), ErrorCode, moab::Interface::get_adjacencies(), moab::Range::insert(), MB_SUCCESS, mbImpl, moab::Range::merge(), and moab::Range::size().
Referenced by star_entities_nonmanifold().
ErrorCode moab::MeshTopoUtil::opposite_entity | ( | const EntityHandle | parent, |
const EntityHandle | child, | ||
EntityHandle & | opposite_element | ||
) |
return the opposite side entity given a parent and bounding entity. This function is only defined for certain types of parent/child types; See MBCN.hpp::OppositeSide for details.
return the opposite side entity given a parent and bounding entity. This function is only defined for certain types of parent/child types; See CN.hpp::OppositeSide for details.
parent | The parent element |
child | The child element |
opposite_element | The index of the opposite element |
Definition at line 560 of file MeshTopoUtil.cpp.
563 {
564 // get the side no.
565 int side_no, offset, sense;
566 ErrorCode result = mbImpl->side_number( parent, child, side_no, offset, sense );
567 if( MB_SUCCESS != result ) return result;
568
569 // get the child index from CN
570 int opposite_index, opposite_dim;
571 int status = CN::OppositeSide( mbImpl->type_from_handle( parent ), side_no, mbImpl->dimension_from_handle( child ),
572 opposite_index, opposite_dim );
573 if( 0 != status ) return MB_FAILURE;
574
575 // now get the side element from MOAB
576 result = mbImpl->side_element( parent, opposite_dim, opposite_index, opposite_element );
577 if( MB_SUCCESS != result ) return result;
578
579 return MB_SUCCESS;
580 }
References child, moab::Interface::dimension_from_handle(), ErrorCode, MB_SUCCESS, mbImpl, moab::CN::OppositeSide(), moab::Interface::side_element(), moab::Interface::side_number(), and moab::Interface::type_from_handle().
Referenced by moab::ReadCCMIO::create_cell_from_faces(), and moab::DualTool::foc_get_ents().
ErrorCode moab::MeshTopoUtil::split_entities_manifold | ( | EntityHandle * | entities, |
const int | num_entities, | ||
EntityHandle * | new_entities, | ||
Range * | fill_entities, | ||
EntityHandle * | gowith_ents = NULL |
||
) |
split entities that are manifold (shared by two or less entities of each higher dimension), optionally creating an entity of next higher dimension to fill the gap
entities | The entities to be split |
new_entities | New entities, in order of correspondence to that of entities |
fill_entities | If non-NULL, create an entity of next higher dimension to fill the gap, passing it back in *fill_entities |
gowith_ents | If non-NULL, each of the new entities will adj to the corresponding gowith entities after the split; this parameter is ignored for boundary split entities; in that case, the split entity remains on the boundary (i.e. not adj to any entity of higher dimension). Dimension of gowith_ents must be the same as entities. |
Definition at line 606 of file MeshTopoUtil.cpp.
611 {
612 // split entities by duplicating them; splitting manifold means that there is at
613 // most two higher-dimension entities bounded by a given entity; after split, the
614 // new entity bounds one and the original entity bounds the other
615
616 #define ITERATE_RANGE( range, it ) for( Range::iterator it = ( range ).begin(); ( it ) != ( range ).end(); ++( it ) )
617 #define GET_CONNECT_DECL( ent, connect, num_connect ) \
618 const EntityHandle* connect = NULL; \
619 int num_connect = 0; \
620 { \
621 ErrorCode connect_result = mbImpl->get_connectivity( ent, connect, num_connect ); \
622 if( MB_SUCCESS != connect_result ) return connect_result; \
623 }
624 #define GET_CONNECT( ent, connect, num_connect ) \
625 { \
626 ErrorCode connect_result = mbImpl->get_connectivity( ent, connect, num_connect ); \
627 if( MB_SUCCESS != connect_result ) return connect_result; \
628 }
629 #define TC \
630 if( MB_SUCCESS != tmp_result ) \
631 { \
632 result = tmp_result; \
633 continue; \
634 }
635
636 ErrorCode result = MB_SUCCESS;
637 for( int i = 0; i < num_entities; i++ )
638 {
639 ErrorCode tmp_result;
640
641 // get original higher-dimensional bounding entities
642 Range up_adjs[4];
643 // can only do a split_manifold if there are at most 2 entities of each
644 // higher dimension; otherwise it's a split non-manifold
645 bool valid_up_adjs = true;
646 for( int dim = 1; dim <= 3; dim++ )
647 {
648 tmp_result = mbImpl->get_adjacencies( entities + i, 1, dim, false, up_adjs[dim] );
649 TC;
650 if( dim > CN::Dimension( TYPE_FROM_HANDLE( entities[i] ) ) && up_adjs[dim].size() > 2 )
651 {
652 valid_up_adjs = false;
653 break;
654 }
655 }
656 if( !valid_up_adjs ) return MB_FAILURE;
657
658 // ok to split; create the new entity, with connectivity of the original
659 GET_CONNECT_DECL( entities[i], connect, num_connect );
660 EntityHandle new_entity;
661 result = mbImpl->create_element( mbImpl->type_from_handle( entities[i] ), connect, num_connect, new_entity );
662 TC;
663
664 // by definition, new entity and original will be equivalent; need to add explicit
665 // adjs to distinguish them; don't need to check if there's already one there,
666 // 'cuz add_adjacency does that for us
667 for( int dim = 1; dim <= 3; dim++ )
668 {
669 if( up_adjs[dim].empty() || dim == CN::Dimension( TYPE_FROM_HANDLE( entities[i] ) ) ) continue;
670
671 if( dim < CN::Dimension( TYPE_FROM_HANDLE( entities[i] ) ) )
672 {
673 // adjacencies from other entities to this one; if any of those are equivalent
674 // entities, need to make explicit adjacency to new entity too
675 for( Range::iterator rit = up_adjs[dim].begin(); rit != up_adjs[dim].end(); ++rit )
676 {
677 if( equivalent_entities( *rit ) ) result = mbImpl->add_adjacencies( *rit, &new_entity, 1, false );
678 }
679 }
680 else
681 {
682
683 // get the two up-elements
684 EntityHandle up_elem1 = *( up_adjs[dim].begin() ),
685 up_elem2 = ( up_adjs[dim].size() > 1 ? *( up_adjs[dim].rbegin() ) : 0 );
686
687 // if two, and a gowith entity was input, make sure the new entity goes with
688 // that one
689 if( gowith_ents && up_elem2 && gowith_ents[i] != up_elem1 && gowith_ents[i] == up_elem2 )
690 {
691 EntityHandle tmp_elem = up_elem1;
692 up_elem1 = up_elem2;
693 up_elem2 = tmp_elem;
694 }
695
696 mbImpl->remove_adjacencies( entities[i], &up_elem1, 1 );
697 // (ok if there's an error, that just means there wasn't an explicit adj)
698
699 tmp_result = mbImpl->add_adjacencies( new_entity, &up_elem1, 1, false );
700 TC;
701 if( !up_elem2 ) continue;
702
703 // add adj to other up_adj
704 tmp_result = mbImpl->add_adjacencies( entities[i], &up_elem2, 1, false );
705 TC;
706 }
707 }
708
709 // if we're asked to build a next-higher-dimension object, do so
710 EntityHandle fill_entity = 0;
711 EntityHandle tmp_ents[2];
712 if( NULL != fill_entities )
713 {
714 // how to do this depends on dimension
715 switch( CN::Dimension( TYPE_FROM_HANDLE( entities[i] ) ) )
716 {
717 case 0:
718 tmp_ents[0] = entities[i];
719 tmp_ents[1] = new_entity;
720 tmp_result = mbImpl->create_element( MBEDGE, tmp_ents, 2, fill_entity );
721 TC;
722 break;
723 case 1:
724 tmp_result = mbImpl->create_element( MBPOLYGON, connect, 2, fill_entity );
725 TC;
726 // need to create explicit adj in this case
727 tmp_result = mbImpl->add_adjacencies( entities[i], &fill_entity, 1, false );
728 TC;
729 tmp_result = mbImpl->add_adjacencies( new_entity, &fill_entity, 1, false );
730 TC;
731 break;
732 case 2:
733 tmp_ents[0] = entities[i];
734 tmp_ents[1] = new_entity;
735 tmp_result = mbImpl->create_element( MBPOLYHEDRON, tmp_ents, 2, fill_entity );
736 TC;
737 break;
738 }
739 if( 0 == fill_entity )
740 {
741 result = MB_FAILURE;
742 continue;
743 }
744 fill_entities->insert( fill_entity );
745 }
746
747 new_entities[i] = new_entity;
748
749 } // end for over input entities
750
751 return result;
752 }
References moab::Interface::add_adjacencies(), moab::Range::begin(), moab::Interface::create_element(), dim, moab::CN::Dimension(), moab::Range::end(), entities, equivalent_entities(), ErrorCode, moab::Interface::get_adjacencies(), GET_CONNECT_DECL, moab::Range::insert(), MB_SUCCESS, MBEDGE, mbImpl, MBPOLYGON, MBPOLYHEDRON, moab::Range::rbegin(), moab::Interface::remove_adjacencies(), size, TC, moab::Interface::type_from_handle(), and moab::TYPE_FROM_HANDLE().
ErrorCode moab::MeshTopoUtil::split_entities_manifold | ( | Range & | entities, |
Range & | new_entities, | ||
Range * | fill_entities | ||
) |
split entities that are manifold (shared by two or less entities of each higher dimension), optionally creating an entity of next higher dimension to fill the gap
entities | The entities to be split |
new_entities | New entities, in order of correspondence to that of entities |
fill_entities | If non-NULL, create an entity of next higher dimension to fill the gap, passing it back in *fill_entities |
Definition at line 582 of file MeshTopoUtil.cpp.
583 {
584 Range tmp_range, *tmp_ptr_fill_entity;
585 if( NULL != fill_entities )
586 tmp_ptr_fill_entity = &tmp_range;
587 else
588 tmp_ptr_fill_entity = NULL;
589
590 for( Range::iterator rit = entities.begin(); rit != entities.end(); ++rit )
591 {
592 EntityHandle new_entity;
593 if( NULL != tmp_ptr_fill_entity ) tmp_ptr_fill_entity->clear();
594
595 EntityHandle this_ent = *rit;
596 ErrorCode result = split_entities_manifold( &this_ent, 1, &new_entity, tmp_ptr_fill_entity );
597 if( MB_SUCCESS != result ) return result;
598
599 new_entities.insert( new_entity );
600 if( NULL != fill_entities ) fill_entities->merge( *tmp_ptr_fill_entity );
601 }
602
603 return MB_SUCCESS;
604 }
References moab::Range::clear(), entities, ErrorCode, moab::Range::insert(), MB_SUCCESS, and moab::Range::merge().
Referenced by moab::DualTool::split_pair_nonmanifold().
ErrorCode moab::MeshTopoUtil::split_entity_nonmanifold | ( | EntityHandle | split_ent, |
Range & | old_adjs, | ||
Range & | new_adjs, | ||
EntityHandle & | new_entity | ||
) |
split entity which is non-manifold, that is, which has > 2 connected entities of next higher dimension; assumes that there are >= 2 connected regions of (d+2)-dimensional entities; a new d-entity is created for each region after the first, and it's made explicitly-adjacent to the region to which it corresponds
Definition at line 754 of file MeshTopoUtil.cpp.
758 {
759 // split an entity into two entities; new entity gets explicit adj to new_adjs,
760 // old to old_adjs
761
762 // make new entities and add adjacencies
763 // create the new entity
764 EntityType split_type = mbImpl->type_from_handle( split_ent );
765
766 ErrorCode result;
767 if( MBVERTEX == split_type )
768 {
769 double coords[3];
770 result = mbImpl->get_coords( &split_ent, 1, coords );RR;
771 result = mbImpl->create_vertex( coords, new_entity );RR;
772 }
773 else
774 {
775 const EntityHandle* connect;
776 int num_connect;
777 result = mbImpl->get_connectivity( split_ent, connect, num_connect );RR;
778 result = mbImpl->create_element( split_type, connect, num_connect, new_entity );RR;
779
780 // remove any explicit adjacencies between new_adjs and split entity
781 for( Range::iterator rit = new_adjs.begin(); rit != new_adjs.end(); ++rit )
782 mbImpl->remove_adjacencies( split_ent, &( *rit ), 1 );
783 }
784
785 if( MBVERTEX != split_type )
786 {
787 // add adj's between new_adjs & new entity, old_adjs & split_entity
788 for( Range::iterator rit = new_adjs.begin(); rit != new_adjs.end(); ++rit )
789 mbImpl->add_adjacencies( new_entity, &( *rit ), 1, true );
790 for( Range::iterator rit = old_adjs.begin(); rit != old_adjs.end(); ++rit )
791 mbImpl->add_adjacencies( split_ent, &( *rit ), 1, true );
792 }
793 else if( split_ent != new_entity )
794 {
795 // in addition to explicit adjs, need to check if vertex is part of any
796 // other entities, and check those entities against ents in old and new adjs
797 Range other_adjs;
798 for( int i = 1; i < 4; i++ )
799 {
800 result = mbImpl->get_adjacencies( &split_ent, 1, i, false, other_adjs, Interface::UNION );RR;
801 }
802 other_adjs = subtract( other_adjs, old_adjs );
803 other_adjs = subtract( other_adjs, new_adjs );
804 for( Range::iterator rit1 = other_adjs.begin(); rit1 != other_adjs.end(); ++rit1 )
805 {
806 // find an adjacent lower-dimensional entity in old_ or new_ adjs
807 bool found = false;
808 for( Range::iterator rit2 = old_adjs.begin(); rit2 != old_adjs.end(); ++rit2 )
809 {
810 if( mbImpl->dimension_from_handle( *rit1 ) != mbImpl->dimension_from_handle( *rit2 ) &&
811 common_entity( *rit1, *rit2, mbImpl->dimension_from_handle( *rit1 ) ) )
812 {
813 found = true;
814 old_adjs.insert( *rit1 );
815 break;
816 }
817 }
818 if( found ) continue;
819 for( Range::iterator rit2 = new_adjs.begin(); rit2 != new_adjs.end(); ++rit2 )
820 {
821 if( mbImpl->dimension_from_handle( *rit1 ) != mbImpl->dimension_from_handle( *rit2 ) &&
822 common_entity( *rit1, *rit2, mbImpl->dimension_from_handle( *rit1 ) ) )
823 {
824 found = true;
825 new_adjs.insert( *rit1 );
826 break;
827 }
828 }
829 if( !found ) return MB_FAILURE;
830 }
831
832 // instead of adjs replace in connectivity
833 std::vector< EntityHandle > connect;
834 for( Range::iterator rit = new_adjs.begin(); rit != new_adjs.end(); ++rit )
835 {
836 connect.clear();
837 result = mbImpl->get_connectivity( &( *rit ), 1, connect );RR;
838 std::replace( connect.begin(), connect.end(), split_ent, new_entity );
839 result = mbImpl->set_connectivity( *rit, &connect[0], connect.size() );RR;
840 }
841 }
842
843 return result;
844
845 /*
846
847 Commented out for now, because I decided to do a different implementation
848 for the sake of brevity. However, I still think this function is the right
849 way to do it, if I ever get the time. Sigh.
850
851 // split entity d, producing entity nd; generates various new entities,
852 // see algorithm description in notes from 2/25/05
853 const EntityHandle split_types = {MBEDGE, MBPOLYGON, MBPOLYHEDRON};
854 ErrorCode result = MB_SUCCESS;
855 const int dim = CN::Dimension(TYPE_FROM_HANDLE(d));
856 MeshTopoUtil mtu(this);
857
858 // get all (d+2)-, (d+1)-cells connected to d
859 Range dp2s, dp1s, dp1s_manif, dp2s_manif;
860 result = get_adjacencies(&d, 1, dim+2, false, dp2s); RR;
861 result = get_adjacencies(&d, 1, dim+1, false, dp1s); RR;
862
863 // also get (d+1)-cells connected to d which are manifold
864 get_manifold_dp1s(d, dp1s_manif);
865 get_manifold_dp2s(d, dp2s_manif);
866
867 // make new cell nd, then ndp1
868 result = copy_entity(d, nd); RR;
869 EntityHandle tmp_connect[] = {d, nd};
870 EntityHandle ndp1;
871 result = create_element(split_types[dim],
872 tmp_connect, 2, ndp1); RR;
873
874 // modify (d+2)-cells, depending on what type they are
875 ITERATE_RANGE(dp2s, dp2) {
876 // first, get number of connected manifold (d+1)-entities
877 Range tmp_range, tmp_range2(dp1s_manif);
878 tmp_range.insert(*dp2);
879 tmp_range.insert(d);
880 tmp_result = get_adjacencies(tmp_range, 1, false, tmp_range2); TC;
881 EntityHandle ndp2;
882
883 // a. manif (d+1)-cells is zero
884 if (tmp_range2.empty()) {
885 // construct new (d+1)-cell
886 EntityHandle ndp1a;
887 EntityHandle tmp_result = create_element(split_types[dim],
888 tmp_connect, 2, ndp1a); TC;
889 // now make new (d+2)-cell
890 EntityHandle tmp_connect2[] = {ndp1, ndp1a};
891 tmp_result = create_element(split_types[dim+1],
892 tmp_connect2, 2, ndp2); TC;
893 // need to add explicit adjacencies, since by definition ndp1, ndp1a will be equivalent
894 tmp_result = add_adjacencies(ndp1a, &dp2, 1, false); TC;
895 tmp_result = add_adjacencies(ndp1a, &ndp2, 1, false); TC;
896 tmp_result = add_adjacencies(ndp1, &ndp2, 1, false); TC;
897
898 // now insert nd into connectivity of dp2, right after d if dim < 1
899 std::vector<EntityHandle> connect;
900 tmp_result = get_connectivity(&dp2, 1, connect); TC;
901 if (dim < 1) {
902 std::vector<EntityHandle>::iterator vit = std::find(connect.begin(), connect.end(), d);
903 if (vit == connect.end()) {
904 result = MB_FAILURE;
905 continue;
906 }
907 connect.insert(vit, nd);
908 }
909 else
910 connect.push_back(nd);
911 tmp_result = set_connectivity(dp2, connect); TC;
912
913 // if dim < 1, need to add explicit adj from ndp2 to higher-dim ents, since it'll
914 // be equiv to other dp2 entities
915 if (dim < 1) {
916 Range tmp_dp3s;
917 tmp_result = get_adjacencies(&dp2, 1, dim+3, false, tmp_dp3s); TC;
918 tmp_result = add_adjacencies(ndp2, tmp_dp3s, false); TC;
919 }
920 } // end if (tmp_range2.empty())
921
922 // b. single manifold (d+1)-cell, which isn't adjacent to manifold (d+2)-cell
923 else if (tmp_range2.size() == 1) {
924 // b1. check validity, and skip if not valid
925
926 // only change if not dp1-adjacent to manifold dp2cell; check that...
927 Range tmp_adjs(dp2s_manif);
928 tmp_result = get_adjacencies(&(*tmp_range2.begin()), 1, dim+2, false, tmp_adjs); TC;
929 if (!tmp_adjs.empty()) continue;
930
931 EntityHandle dp1 = *tmp_range2.begin();
932
933 // b2. make new (d+1)- and (d+2)-cell next to dp2
934
935 // get the (d+2)-cell on the other side of dp1
936 tmp_result = get_adjacencies(&dp1, 1, dim+2, false, tmp_adjs); TC;
937 EntityHandle odp2 = *tmp_adjs.begin();
938 if (odp2 == dp2) odp2 = *tmp_adjs.rbegin();
939
940 // get od, the d-cell on dp1_manif which isn't d
941 tmp_result = get_adjacencies(&dp1_manif, 1, dim, false, tmp_adjs); TC;
942 tmp_adjs.erase(d);
943 if (tmp_adjs.size() != 1) {
944 result = MB_FAILURE;
945 continue;
946 }
947 EntityHandle od = *tmp_adjs.begin();
948
949 // make a new (d+1)-cell from od and nd
950 tmp_adjs.insert(nd);
951 tmp_result = create_element(split_types[1], tmp_adjs, ndp1a); TC;
952
953 // construct new (d+2)-cell from dp1, ndp1, ndp1a
954 tmp_adjs.clear();
955 tmp_adjs.insert(dp1); tmp_adjs.insert(ndp1); tmp_adjs.insert(ndp1a);
956 tmp_result = create_element(split_types[2], tmp_adjs, ndp2); TC;
957
958 // b3. replace d, dp1 in connect/adjs of odp2
959 std::vector<EntityHandle> connect;
960 tmp_result = get_connectivity(&odp2, 1, connect); TC;
961 if (dim == 0) {
962 *(std::find(connect.begin(), connect.end(), d)) = nd;
963 remove_adjacency(dp1, odp2);
964
965
966
967 // if dp1 was explicitly adj to odp2, remove it
968 remove_adjacency
969
970 ...
971
972 */
973 }
References moab::Interface::add_adjacencies(), moab::Range::begin(), common_entity(), moab::Interface::create_element(), moab::Interface::create_vertex(), moab::Interface::dimension_from_handle(), moab::Range::end(), ErrorCode, moab::Interface::get_adjacencies(), moab::Interface::get_connectivity(), moab::Interface::get_coords(), moab::Range::insert(), mbImpl, MBVERTEX, moab::Interface::remove_adjacencies(), RR, moab::Interface::set_connectivity(), moab::subtract(), moab::Interface::type_from_handle(), and moab::Interface::UNION.
Referenced by moab::DualTool::split_pair_nonmanifold().
ErrorCode moab::MeshTopoUtil::star_entities | ( | const EntityHandle | star_center, |
std::vector< EntityHandle > & | star_entities, | ||
bool & | bdy_entity, | ||
const EntityHandle | starting_star_entity = 0 , |
||
std::vector< EntityHandle > * | star_entities_dp1 = NULL , |
||
Range * | star_entities_candidates_dp1 = NULL |
||
) |
given an entity, find the entities of next higher dimension around that entity, ordered by connection through next higher dimension entities; if any of the star entities is in only entity of next higher dimension, on_boundary is returned true
Definition at line 106 of file MeshTopoUtil.cpp.
112 {
113 // now start the traversal
114 bdy_entity = false;
115 EntityHandle last_entity = starting_star_entity, last_dp2 = 0, next_entity, next_dp2;
116 std::vector< EntityHandle > star_dp2;
117 ErrorCode result;
118 int center_dim = mbImpl->dimension_from_handle( star_center );
119
120 Range tmp_candidates_dp2;
121 if( NULL != star_candidates_dp2 )
122 tmp_candidates_dp2 = *star_candidates_dp2;
123 else
124 {
125 result = mbImpl->get_adjacencies( &star_center, 1, center_dim + 2, false, tmp_candidates_dp2 );
126 if( MB_SUCCESS != result ) return result;
127 }
128
129 do
130 {
131 // get the next star entity
132 result = star_next_entity( star_center, last_entity, last_dp2, &tmp_candidates_dp2, next_entity, next_dp2 );
133 if( MB_SUCCESS != result ) return result;
134
135 // special case: if starting_star_entity isn't connected to any entities of next
136 // higher dimension, it's the only entity in the star; put it on the list and return
137 if( star_ents.empty() && next_entity == 0 && next_dp2 == 0 )
138 {
139 star_ents.push_back( last_entity );
140 bdy_entity = true;
141 return MB_SUCCESS;
142 }
143
144 // if we're at a bdy and bdy_entity hasn't been set yet, we're at the
145 // first bdy; reverse the lists and start traversing in the other direction; but,
146 // pop the last star entity off the list and find it again, so that we properly
147 // check for next_dp2
148 if( 0 == next_dp2 && !bdy_entity )
149 {
150 star_ents.push_back( next_entity );
151 bdy_entity = true;
152 std::reverse( star_ents.begin(), star_ents.end() );
153 star_ents.pop_back();
154 last_entity = star_ents.back();
155 if( !star_dp2.empty() )
156 {
157 std::reverse( star_dp2.begin(), star_dp2.end() );
158 last_dp2 = star_dp2.back();
159 }
160 }
161 // else if we're not on the bdy and next_entity is already in star, that means
162 // we've come all the way around; don't put next_entity on list again, and
163 // zero out last_dp2 to terminate while loop
164 else if( !bdy_entity && std::find( star_ents.begin(), star_ents.end(), next_entity ) != star_ents.end() &&
165 ( std::find( star_dp2.begin(), star_dp2.end(), next_dp2 ) != star_dp2.end() || !next_dp2 ) )
166 {
167 last_dp2 = 0;
168 }
169
170 // else, just assign last entities seen and go on to next iteration
171 else
172 {
173 if( std::find( star_ents.begin(), star_ents.end(), next_entity ) == star_ents.end() )
174 star_ents.push_back( next_entity );
175 if( 0 != next_dp2 )
176 {
177 star_dp2.push_back( next_dp2 );
178 tmp_candidates_dp2.erase( next_dp2 );
179 }
180 last_entity = next_entity;
181 last_dp2 = next_dp2;
182 }
183 } while( 0 != last_dp2 );
184
185 // copy over the star_dp2 list, if requested
186 if( NULL != star_entities_dp2 ) ( *star_entities_dp2 ).swap( star_dp2 );
187
188 return MB_SUCCESS;
189 }
References moab::Interface::dimension_from_handle(), moab::Range::erase(), ErrorCode, moab::Interface::get_adjacencies(), MB_SUCCESS, mbImpl, and star_next_entity().
Referenced by moab::DualTool::foc_get_stars(), moab::DualTool::get_radial_dverts(), and star_entities_nonmanifold().
ErrorCode moab::MeshTopoUtil::star_entities_nonmanifold | ( | const EntityHandle | star_entity, |
std::vector< std::vector< EntityHandle > > & | stars, | ||
std::vector< bool > * | bdy_flags = NULL , |
||
std::vector< std::vector< EntityHandle > > * | dp2_stars = NULL |
||
) |
Get a series of (d+1)-dimensional stars around a d-dimensional entity, such that each star is on a (d+2)-manifold containing the d-dimensional entity; each star is either open or closed, and also defines a (d+2)-star whose entities are bounded by (d+1)-entities on the star and on the (d+2)-manifold.
Definition at line 264 of file MeshTopoUtil.cpp.
268 {
269 // Get a series of (d+1)-dimensional stars around a d-dimensional entity, such that
270 // each star is on a (d+2)-manifold containing the d-dimensional entity; each star
271 // is either open or closed, and also defines a (d+2)-star whose entities are bounded by
272 // (d+1)-entities on the star and on the (d+2)-manifold
273 //
274 // Algorithm:
275 // get the (d+2)-manifold entities; for d=1 / d+2=3, just assume all connected elements, since
276 // we don't do 4d yet
277 // get intersection of (d+1)-entities adjacent to star entity and union of (d+1)-entities
278 // adjacent to (d+2)-manifold entities; these will be the entities in the star
279 // while (d+1)-entities
280 // remove (d+1)-entity from (d+1)-entities
281 // get the (d+1)-star and (d+2)-star around that (d+1)-entity (using star_entities)
282 // save that star to the star list, and the bdy flag and (d+2)-star if requested
283 // remove (d+2)-entities from the (d+2)-manifold entities
284 // remove (d+1)-entities from the (d+1)-entities
285 // (end while)
286
287 int this_dim = mbImpl->dimension_from_handle( star_entity );
288 if( 3 <= this_dim || 0 > this_dim ) return MB_FAILURE;
289
290 // get the (d+2)-manifold entities; for d=1 / d+2=3, just assume all connected elements, since
291 // we don't do 4d yet
292 Range dp2_manifold;
293 ErrorCode result = get_manifold( star_entity, this_dim + 2, dp2_manifold );
294 if( MB_SUCCESS != result ) return result;
295
296 // get intersection of (d+1)-entities adjacent to star and union of (d+1)-entities
297 // adjacent to (d+2)-manifold entities; also add manifold (d+1)-entities, to catch
298 // any not connected to (d+2)-entities
299 Range dp1_manifold;
300 result = mbImpl->get_adjacencies( dp2_manifold, this_dim + 1, false, dp1_manifold, Interface::UNION );
301 if( MB_SUCCESS != result ) return result;
302
303 result = mbImpl->get_adjacencies( &star_entity, 1, this_dim + 1, false, dp1_manifold );
304 if( MB_SUCCESS != result ) return result;
305
306 result = get_manifold( star_entity, this_dim + 1, dp1_manifold );
307 if( MB_SUCCESS != result ) return result;
308
309 // while (d+1)-entities
310 while( !dp1_manifold.empty() )
311 {
312
313 // get (d+1)-entity from (d+1)-entities (don't remove it until after star,
314 // since the star entities must come from dp1_manifold)
315 EntityHandle this_ent = *dp1_manifold.begin();
316
317 // get the (d+1)-star and (d+2)-star around that (d+1)-entity (using star_entities)
318 std::vector< EntityHandle > this_star_dp1, this_star_dp2;
319 bool on_bdy;
320 result = star_entities( star_entity, this_star_dp1, on_bdy, this_ent, &this_star_dp2, &dp2_manifold );
321 if( MB_SUCCESS != result ) return result;
322
323 // if there's no star entities, it must mean this_ent isn't bounded by any dp2
324 // entities (wasn't put into star in star_entities 'cuz we're passing in non-null
325 // dp2_manifold above); put it in
326 if( this_star_dp1.empty() )
327 {
328 Range dum_range;
329 result = mbImpl->get_adjacencies( &this_ent, 1, this_dim + 2, false, dum_range );
330 if( MB_SUCCESS != result ) return result;
331 if( dum_range.empty() ) this_star_dp1.push_back( this_ent );
332 }
333
334 // now we can remove it
335 dp1_manifold.erase( dp1_manifold.begin() );
336
337 // save that star to the star list, and the bdy flag and (d+2)-star if requested
338 if( !this_star_dp1.empty() )
339 {
340 stars.push_back( this_star_dp1 );
341 if( NULL != bdy_flags ) bdy_flags->push_back( on_bdy );
342 if( NULL != dp2_stars ) dp2_stars->push_back( this_star_dp2 );
343 }
344
345 // remove (d+2)-entities from the (d+2)-manifold entities
346 for( std::vector< EntityHandle >::iterator vit = this_star_dp2.begin(); vit != this_star_dp2.end(); ++vit )
347 dp2_manifold.erase( *vit );
348
349 // remove (d+1)-entities from the (d+1)-entities
350 for( std::vector< EntityHandle >::iterator vit = this_star_dp1.begin(); vit != this_star_dp1.end(); ++vit )
351 dp1_manifold.erase( *vit );
352
353 // (end while)
354 }
355
356 // check for leftover dp2 manifold entities, these should be in one of the
357 // stars
358 if( !dp2_manifold.empty() )
359 {
360 for( Range::iterator rit = dp2_manifold.begin(); rit != dp2_manifold.end(); ++rit )
361 {
362 }
363 }
364
365 return MB_SUCCESS;
366 }
References moab::Range::begin(), moab::Interface::dimension_from_handle(), moab::Range::empty(), moab::Range::end(), moab::Range::erase(), ErrorCode, moab::Interface::get_adjacencies(), get_manifold(), MB_SUCCESS, mbImpl, star_entities(), and moab::Interface::UNION.
ErrorCode moab::MeshTopoUtil::star_next_entity | ( | const EntityHandle | star_center, |
const EntityHandle | last_entity, | ||
const EntityHandle | last_dp1, | ||
Range * | star_candidates_dp1, | ||
EntityHandle & | next_entity, | ||
EntityHandle & | next_dp1 | ||
) |
given a star_center, a last_entity (whose dimension should be 1 greater than center) and last_dp1 (dimension 2 higher than center), returns the next star entity across last_dp1, and the next dp1 entity sharing next_entity; if star_candidates is non-empty, star must come from those
Definition at line 191 of file MeshTopoUtil.cpp.
197 {
198 // given a star_center, a last_entity (whose dimension should be 1 greater than center)
199 // and last_dp1 (dimension 2 higher than center), returns the next star entity across
200 // last_dp1, and the next dp1 entity sharing next_entity; if star_candidates is non-empty,
201 // star must come from those
202 Range from_ents, to_ents;
203 from_ents.insert( star_center );
204 if( 0 != last_dp1 ) from_ents.insert( last_dp1 );
205
206 int dim = mbImpl->dimension_from_handle( star_center );
207
208 ErrorCode result = mbImpl->get_adjacencies( from_ents, dim + 1, true, to_ents );
209 if( MB_SUCCESS != result ) return result;
210
211 // remove last_entity from result, and should only have 1 left, if any
212 if( 0 != last_entity ) to_ents.erase( last_entity );
213
214 // if no last_dp1, contents of to_ents should share dp1-dimensional entity with last_entity
215 if( 0 != last_entity && 0 == last_dp1 )
216 {
217 Range tmp_to_ents;
218 for( Range::iterator rit = to_ents.begin(); rit != to_ents.end(); ++rit )
219 {
220 if( 0 != common_entity( last_entity, *rit, dim + 2 ) ) tmp_to_ents.insert( *rit );
221 }
222 to_ents = tmp_to_ents;
223 }
224
225 if( 0 == last_dp1 && to_ents.size() > 1 && NULL != star_candidates_dp1 && !star_candidates_dp1->empty() )
226 {
227 // if we have a choice of to_ents and no previous dp1 and there are dp1 candidates,
228 // the one we choose needs to be adjacent to one of the candidates
229 result = mbImpl->get_adjacencies( *star_candidates_dp1, dim + 1, true, from_ents, Interface::UNION );
230 if( MB_SUCCESS != result ) return result;
231 to_ents = intersect( to_ents, from_ents );
232 }
233
234 if( !to_ents.empty() )
235 next_entity = *to_ents.begin();
236 else
237 {
238 next_entity = 0;
239 next_dp1 = 0;
240 return MB_SUCCESS;
241 }
242
243 // get next_dp1
244 if( 0 != star_candidates_dp1 )
245 to_ents = *star_candidates_dp1;
246 else
247 to_ents.clear();
248
249 result = mbImpl->get_adjacencies( &next_entity, 1, dim + 2, true, to_ents );
250 if( MB_SUCCESS != result ) return result;
251
252 // can't be last one
253 if( 0 != last_dp1 ) to_ents.erase( last_dp1 );
254
255 if( !to_ents.empty() ) next_dp1 = *to_ents.begin();
256
257 // could be zero, means we're at bdy
258 else
259 next_dp1 = 0;
260
261 return MB_SUCCESS;
262 }
References moab::Range::begin(), moab::Range::clear(), common_entity(), dim, moab::Interface::dimension_from_handle(), moab::Range::empty(), moab::Range::end(), moab::Range::erase(), ErrorCode, moab::Interface::get_adjacencies(), moab::Range::insert(), moab::intersect(), MB_SUCCESS, mbImpl, moab::Range::size(), and moab::Interface::UNION.
Referenced by star_entities().
|
private |
Definition at line 155 of file MeshTopoUtil.hpp.
Referenced by common_entity(), construct_aentities(), equivalent_entities(), get_average_position(), get_bridge_adjacencies(), get_manifold(), opposite_entity(), split_entities_manifold(), split_entity_nonmanifold(), star_entities(), star_entities_nonmanifold(), and star_next_entity().