17 #pragma warning( disable : 4786 )
21 #define _USE_MATH_DEFINES
40 #define SKINNER_PI M_PI
42 #define SKINNER_PI 3.1415926535897932384626
62 void* null_ptr = NULL;
76 for( type = target_ent_types.first; type <= target_ent_types.second; ++type )
85 for( iter =
entities.begin(); iter != end_iter; ++iter )
87 unsigned char bit = 0x1;
108 std::vector< std::vector< EntityHandle >* > adj_arr;
109 std::vector< std::vector< EntityHandle >* >::iterator i;
118 for( i = adj_arr.begin(); i != adj_arr.end(); ++i )
131 std::vector< EntityHandle >* adj = NULL;
135 const EntityHandle* iter = std::min_element( nodes, nodes + num_nodes );
137 if( iter == nodes + num_nodes )
return MB_SUCCESS;
142 adj->push_back( entity );
147 adj =
new std::vector< EntityHandle >;
148 adj->push_back( entity );
157 std::vector< EntityHandle >* adj = NULL;
158 const EntityHandle* iter = std::min_element( nodes, nodes + num_nodes );
160 if( iter == nodes + num_nodes )
return;
169 adj->push_back( entity );
174 adj =
new std::vector< EntityHandle >;
175 adj->push_back( entity );
196 const void* two_ptr = &two;
202 else if( face_sets.
empty() )
207 if(
debug ) std::cout <<
"Found " << face_sets.
size() <<
" face sets total..." << std::endl;
209 for( it = face_sets.
begin(); it != face_sets.
end(); ++it )
215 else if( num_parents == 1 )
219 if(
debug ) std::cout <<
"Found " << skin_sets.
size() <<
" 1-parent face sets..." << std::endl;
221 if( skin_sets.
empty() )
return MB_FAILURE;
224 for( it = skin_sets.
begin(); it != skin_sets.
end(); ++it )
234 const Range& source_entities,
236 Range& output_handles,
237 Range* output_reverse_handles,
238 bool create_vert_elem_adjs,
239 bool create_skin_elements,
255 return find_skin_vertices( meshset, source_entities, get_vertices ? &output_handles : 0,
256 get_vertices ? 0 : &output_handles, output_reverse_handles, create_skin_elements );
261 Range& output_handles,
262 bool create_skin_elements )
267 if( !scdi )
return MB_FAILURE;
271 std::vector< ScdBox* > boxes, myboxes;
275 for( std::vector< ScdBox* >::iterator bit = boxes.begin(); bit != boxes.end(); ++bit )
277 Range belems( ( *bit )->start_element(), ( *bit )->start_element() + ( *bit )->num_elements() - 1 );
278 if( source_entities.
contains( belems ) )
280 myboxes.push_back( *bit );
281 myrange.
merge( belems );
284 if( myboxes.empty() || myrange.
size() != source_entities.
size() )
return MB_FAILURE;
287 for( std::vector< ScdBox* >::iterator bit = boxes.begin(); bit != boxes.end(); ++bit )
289 rval =
skin_box( *bit, get_vertices, output_handles, create_skin_elements );
301 if( bmin.
j() == bmax.j() && bmin.
k() == bmax.k() )
return MB_FAILURE;
303 int dim = ( bmin.
k() == bmax.k() ? 1 : 2 );
309 for(
int k = bmin.
k(); k < bmax.k(); k++ )
311 for(
int j = bmin.
j(); j < bmax.j(); j++ )
316 if( ent ) output_handles.
insert( ent );
320 for(
int k = bmin.
k(); k < bmax.k(); k++ )
322 for(
int j = bmin.
j(); j < bmax.j(); j++ )
327 if( ent ) output_handles.
insert( ent );
331 for(
int k = bmin.
k(); k < bmax.k(); k++ )
333 for(
int i = bmin.
i(); i < bmax.i(); i++ )
338 if( ent ) output_handles.
insert( ent );
342 for(
int k = bmin.
k(); k < bmax.k(); k++ )
344 for(
int i = bmin.
i(); i < bmax.i(); i++ )
349 if( ent ) output_handles.
insert( ent );
353 for(
int j = bmin.
j(); j < bmax.j(); j++ )
355 for(
int i = bmin.
i(); i < bmax.i(); i++ )
360 if( ent ) output_handles.
insert( ent );
364 for(
int j = bmin.
j(); j < bmax.j(); j++ )
366 for(
int i = bmin.
i(); i < bmax.i(); i++ )
371 if( ent ) output_handles.
insert( ent );
380 output_handles.
merge( verts );
387 Range &forward_target_entities,
388 Range &reverse_target_entities
391 if( source_entities.
empty() )
return MB_FAILURE;
399 if( mTargetDim < 0 || source_dim > 3 )
return MB_FAILURE;
404 end_iter = source_entities.
end();
413 std::vector< EntityHandle > tmp_conn_vec;
414 int num_nodes, num_sub_nodes, num_sides;
420 for( iter = source_entities.
begin(); iter != end_iter; ++iter )
423 int actual_num_nodes_polygon = 0;
435 actual_num_nodes_polygon = num_nodes;
436 while( actual_num_nodes_polygon >= 3 &&
437 conn[actual_num_nodes_polygon - 1] == conn[actual_num_nodes_polygon - 2] )
438 actual_num_nodes_polygon--;
439 num_sides = actual_num_nodes_polygon;
445 for(
int i = 0; i < num_sides; i++ )
449 sub_conn[0] = conn[i];
450 sub_conn[1] = conn[i + 1];
451 if( i + 1 == actual_num_nodes_polygon ) sub_conn[1] = conn[0];
456 assert( (
size_t)num_sub_nodes <=
sizeof( sub_indices ) /
sizeof( sub_indices[0] ) );
457 for(
int j = 0; j < num_sub_nodes; j++ )
458 sub_conn[j] = conn[sub_indices[j]];
463 find_match( sub_type, sub_conn, num_sub_nodes, match, direct );
480 for(
int j = 0; j < num_new_nodes; j++ )
481 sub_conn[j] = conn[indices[j]];
486 forward_target_entities.
insert( tmphndl );
492 if( ( seek_iter = forward_target_entities.
find( match ) ) != forward_target_entities.
end() )
494 forward_target_entities.
erase( seek_iter );
502 else if( ( seek_iter = reverse_target_entities.
find( match ) ) != reverse_target_entities.
end() )
504 reverse_target_entities.
erase( seek_iter );
516 forward_target_entities.
insert( match );
520 reverse_target_entities.
insert( match );
547 const EntityHandle* iter = std::min_element( conn, conn + num_nodes );
549 std::vector< EntityHandle >* adj = NULL;
552 if( result == MB_FAILURE || adj == NULL )
557 std::vector< EntityHandle >::iterator jter, end_jter;
558 end_jter = adj->end();
563 for( jter = adj->begin(); jter != end_jter; ++jter )
568 if( type != tmp_type )
continue;
587 const EntityHandle* iter = std::find( conn2, conn2 + num_verts, conn1[0] );
588 if( iter == conn2 + num_verts )
return false;
590 bool they_match =
true;
593 unsigned int j = iter - conn2;
596 for( i = 1; i < num_verts; ++i )
598 if( conn1[i] != conn2[( j + i ) % num_verts] )
605 if( they_match ==
true )
616 for( i = 1; i < num_verts; )
618 if( conn1[i] != conn2[( j - i ) % num_verts] )
634 std::vector< EntityHandle > nodes, *adj = NULL;
636 std::vector< EntityHandle >::iterator iter = std::min_element( nodes.begin(), nodes.end() );
638 if( iter == nodes.end() )
return MB_FAILURE;
643 iter = std::find( adj->begin(), adj->end(), entity );
644 if( iter != adj->end() ) adj->erase( iter );
652 unsigned char deletable = 0;
655 if(
MB_SUCCESS == result && deletable == 1 )
return false;
660 const Range& bar_elements,
665 int& number_boundary_nodes )
667 Range bedges, iedges, nmedges, oedges;
688 const Range& bar_elements,
689 Range& boundary_edges,
690 Range& inferred_edges,
691 Range& non_manifold_edges,
693 int& number_boundary_nodes )
698 boundary_edges.
clear();
699 inferred_edges.
clear();
700 non_manifold_edges.
clear();
703 number_boundary_nodes = 0;
706 if( boundary.
empty() )
716 if( source_dim != 2 )
730 int default_count = 0;
735 end_iter = boundary.
end();
737 std::vector< EntityHandle > conn;
742 Range boundary_nodes;
746 int num_edge, num_sub_ent_vert;
747 const short* edge_verts;
751 for( iter = boundary.
begin(); iter != end_iter; ++iter )
766 for(
int i = 0; i < num_edge; i++ )
769 assert( sub_type ==
MBEDGE && num_sub_ent_vert == 2 );
770 sub_conn[0] = conn[edge_verts[0]];
771 sub_conn[1] = conn[edge_verts[1]];
786 for(
int j = 0; j < num_new_nodes; j++ )
787 sub_conn[j] = conn[indices[j]];
793 edge_list.
insert( tmphndl );
817 edge_list.
insert( match );
828 if( !bar_elements.
empty() )
831 for( iter = bar_elements.
begin(); iter != bar_elements.
end(); ++iter )
834 bar_iter = edge_list.
find( handle );
835 if( bar_iter != edge_list.
end() )
838 edge_list.
erase( bar_iter );
839 non_manifold_edges.
insert( handle );
844 boundary_edges.
insert( handle );
853 edge_end_iter = edge_list.
end();
855 for( edge_iter = edge_list.
begin(); edge_iter != edge_end_iter; ++edge_iter )
862 boundary_edges.
insert( *edge_iter );
864 else if( count == 2 )
866 other_edges.
insert( *edge_iter );
870 non_manifold_edges.
insert( *edge_iter );
876 double min_angle_degrees = 20.0;
883 std::set_difference( other_edges.
begin(), other_edges.
end(), inferred_edges.
begin(), inferred_edges.
end(),
886 other_edges = temp_range;
895 number_boundary_nodes = boundary_nodes.
size();
901 Range& candidate_edges,
902 Range& inferred_edges,
903 double reference_angle_degrees )
910 unsigned char bit =
true;
916 double reference_cosine = cos( reference_angle_degrees *
SKINNER_PI / 180.0 );
921 std::vector< EntityHandle > adjacencies;
922 std::vector< EntityHandle >::iterator adj_iter;
925 for( iter = candidate_edges.
begin(); iter != end_iter; ++iter )
937 for( adj_iter = adjacencies.begin(); adj_iter != adjacencies.end() && faces_found < 2; ++adj_iter )
940 unsigned char is_marked = 0;
945 face[faces_found] = *adj_iter;
951 if( 2 != faces_found )
continue;
957 inferred_edges.
insert( *iter );
974 double cosine = norm[0][0] * norm[1][0] + norm[0][1] * norm[1][1] + norm[0][2] * norm[1][2];
976 if( cosine < reference_angle_cosine )
988 Range& skin_entities,
989 bool create_vert_elem_adjs,
990 bool create_skin_elements )
994 find_skin( this_set,
entities, (
dim == 0 ), tmp_skin, 0, create_vert_elem_adjs, create_skin_elements );
999 if( skin_entities.
empty() )
1000 skin_entities.
swap( tmp_skin );
1002 skin_entities.
merge( tmp_skin );
1017 Range* skin_rev_elems,
1018 bool create_skin_elems,
1032 bool all = ( count == (size_t)num_total );
1040 char bit = all ? 1 : 0;
1047 std::vector< unsigned char > vect( count, 1 );
1061 else if( skin_elems )
1068 create_skin_elems, corners_only );
1072 create_skin_elems, corners_only );
1109 std::vector< char > tag_vals;
1110 std::vector< EntityHandle > adj;
1118 if( adj.empty() )
continue;
1121 tag_vals.resize( adj.size() );
1124 #ifdef MOAB_OLD_STD_COUNT
1126 std::count( tag_vals.begin(), tag_vals.end(),
'\001' );
1128 n = std::count( tag_vals.begin(), tag_vals.end(),
'\001' );
1133 hint = skin_verts.
insert( hint, *it );
1143 template <
unsigned CORNERS >
1188 handles[1] = array[( idx + 2 ) % CORNERS];
1191 if( 3 == CORNERS )
handles[1] = array[( idx + 2 ) % CORNERS];
1192 if( 2 <= CORNERS )
handles[0] = array[( idx + 1 ) % CORNERS];
1216 handles[1] = array[indices[( idx + 2 ) % CORNERS]];
1219 if( 3 == CORNERS )
handles[1] = array[indices[( idx + 2 ) % CORNERS]];
1220 if( 2 <= CORNERS )
handles[0] = array[indices[( idx + 1 ) % CORNERS]];
1251 typedef typename std::vector< Side >::iterator
iterator;
1255 return data.begin();
1269 return data.empty();
1293 Side side( handles, skip_idx, adj_elem, elem_side );
1295 if( p ==
data.end() )
1297 data.push_back( side );
1300 else if( p->adj_elem )
1326 unsigned short elem_side,
1327 const short* indices )
1329 Side side( handles, skip_idx, adj_elem, elem_side, indices );
1331 if( p ==
data.end() )
1333 data.push_back( side );
1336 else if( p->adj_elem )
1357 Side s( other, skip_index, 0, 0 );
1359 if( p ==
data.end() || !p->adj_elem )
1363 elem_out = p->adj_elem;
1380 const unsigned int CORNERS = 4;
1381 handles[2] = array[( idx + 3 ) % CORNERS];
1382 handles[1] = array[( idx + 2 ) % CORNERS];
1383 handles[0] = array[( idx + 1 ) % CORNERS];
1400 const unsigned int CORNERS = 4;
1401 handles[2] = array[indices[( idx + 3 ) % CORNERS]];
1402 handles[1] = array[indices[( idx + 2 ) % CORNERS]];
1403 handles[0] = array[indices[( idx + 1 ) % CORNERS]];
1412 return handles[0] == other.
handles[0] && handles[1] == other.
handles[1] && handles[2] == other.
handles[2];
1434 EntityType side_type,
1438 const int max_side = 9;
1440 int len, side_len, side, sense, offset, indices[max_side];
1445 std::vector< EntityHandle > storage;
1448 rval = thisMB->get_connectivity( elem, conn, len,
false, &storage );
1457 for( i = 0; i < len; i++ )
1459 if( conn[i] == side_conn[0] )
break;
1461 if( len == i )
return MB_FAILURE;
1464 int prevIndex = ( i + len - 1 ) % len;
1465 int nextIndex = ( i + 1 ) % len;
1467 if( conn[nextIndex] == conn[i] )
1473 EntityHandle conn2[2] = { side_conn[0], side_conn[1] };
1474 if( conn[prevIndex] == side_conn[1] )
1477 conn2[0] = side_conn[1];
1478 conn2[1] = side_conn[0];
1480 else if( conn[nextIndex] != side_conn[1] )
1483 rval = thisMB->create_element(
MBEDGE, conn2, 2, side_elem );
MB_CHK_ERR( rval );
1486 rval = thisMB->add_entities( this_set, &side_elem, 1 );
MB_CHK_ERR( rval );
1492 CN::SideNumber( type, conn, side_conn, ncorner, d, side, sense, offset );
1494 assert( side_len <= max_side );
1495 assert( side_type == tmp_type );
1501 for(
int i = 0; i < side_len; ++i )
1502 side_conn_full[i] = conn[indices[i]];
1504 rval = thisMB->create_element( side_type, side_conn_full, side_len, side_elem );
MB_CHK_ERR( rval );
1507 rval = thisMB->add_entities( this_set, &side_elem, 1 );
MB_CHK_ERR( rval );
1519 ErrorCode rval = thisMB->get_connectivity(
face, conn, len,
true );
1525 idx = std::find( conn, conn + len, edge_ends[0] ) - conn;
1531 return ( edge_ends[1] == conn[( idx + len - 1 ) % len] );
1540 int len, side, sense, offset;
1541 ErrorCode rval = thisMB->get_connectivity( region, conn, len,
true );
1550 return ( !r && sense == -1 );
1558 Range* reversed_edges,
1578 std::vector< EntityHandle >::iterator i, j;
1580 if( skin_verts ) hint = skin_verts->
begin();
1581 std::vector< EntityHandle > storage;
1584 bool find_edges = skin_edges || create_edges;
1585 bool printed_nonconformal_ho_warning =
false;
1592 rval = thisMB->get_connectivity( faces, verts,
true );
1595 std::vector< char > tag_vals;
1596 std::vector< EntityHandle > adj;
1600 bool higher_order =
false;
1604 rval = thisMB->get_adjacencies( &*it, 1, 2,
false, adj );
1606 if( adj.empty() )
continue;
1609 i = j = adj.begin();
1610 tag_vals.resize( adj.size() );
1611 rval = thisMB->tag_get_data( tag, &adj[0], adj.size(), &tag_vals[0] );
1614 i = j = adj.begin();
1615 for( ; i != adj.end(); ++i )
1616 if( tag_vals[i - adj.begin()] ) *( j++ ) = *i;
1617 adj.erase( j, adj.end() );
1621 for( i = adj.begin(); i != adj.end(); ++i )
1623 rval = thisMB->get_connectivity( *i, conn, len,
false, &storage );
1631 const int idx = std::find( conn, conn + len, *it ) - conn;
1632 assert( idx != len );
1637 higher_order =
true;
1640 if( !printed_nonconformal_ho_warning )
1642 printed_nonconformal_ho_warning =
true;
1643 std::cerr <<
"Non-conformal higher-order mesh detected in skinner: "
1645 <<
"some elements and a higher-order node in others" << std::endl;
1653 higher_order =
true;
1656 if( !printed_nonconformal_ho_warning )
1658 printed_nonconformal_ho_warning =
true;
1659 std::cerr <<
"Non-conformal higher-order mesh detected in skinner: "
1661 <<
"some elements and a higher-order node in others" << std::endl;
1668 const int prev_idx = ( idx + len - 1 ) % len;
1669 prev = conn[prev_idx];
1670 next = conn[( idx + 1 ) % len];
1671 if( next == conn[idx] )
1675 adj_edges.
insert( &prev, 1, *i, prev_idx );
1676 adj_edges.
insert( &next, 1, *i, idx );
1683 if( 0 == adj_edges.
num_skin() )
continue;
1689 hint = skin_verts->
insert( hint, *it );
1692 if( !corners_only && higher_order )
1701 rval = thisMB->get_connectivity(
face, conn, len,
false );
1706 int side, sense, offset;
1709 assert( offset >= 0 && offset < len );
1710 skin_verts->
insert( conn[offset] );
1721 rval = thisMB->get_adjacencies( &*it, 1, 1,
false, adj );
1723 for( i = adj.begin(); i != adj.end(); ++i )
1725 rval = thisMB->get_connectivity( *i, conn, len,
true );
1737 if( reversed_edges && edge_reversed(
face, conn ) )
1738 reversed_edges->
insert( *i );
1740 skin_edges->
insert( *i );
1748 if( create_edges && adj_edges.
num_skin() )
1756 rval = create_side( this_set, p->adj_elem,
MBEDGE, ec,
edge );
1773 Range* reversed_faces,
1809 std::vector< EntityHandle >::iterator i, j;
1811 if( skin_verts ) hint = skin_verts->
begin();
1812 std::vector< EntityHandle > storage, storage2;
1815 bool find_faces = skin_faces || create_faces;
1816 int clen, side, sense, offset, indices[9];
1817 EntityType face_type;
1819 bool printed_nonconformal_ho_warning =
false;
1825 rval = thisMB->get_connectivity(
entities, verts,
true );
1835 rval = thisMB->get_connectivity( pfaces, verts,
true );
1845 std::vector< char > tag_vals;
1846 std::vector< EntityHandle > adj;
1849 bool higher_order =
false;
1853 rval = thisMB->get_adjacencies( &*it, 1, 3,
false, adj );
1855 if( adj.empty() )
continue;
1858 i = j = adj.begin();
1859 tag_vals.resize( adj.size() );
1860 rval = thisMB->tag_get_data( tag, &adj[0], adj.size(), &tag_vals[0] );
1862 for( ; i != adj.end(); ++i )
1863 if( tag_vals[i - adj.begin()] ) *( j++ ) = *i;
1864 adj.erase( j, adj.end() );
1871 for( i = adj.begin(); i != adj.end(); ++i )
1878 rval = thisMB->get_connectivity( *i, conn, len );
1880 for(
int k = 0; k < len; ++k )
1882 rval = thisMB->get_connectivity( conn[k], conn2, len2,
true, &storage2 );
1884 idx = std::find( conn2, conn2 + len2, *it ) - conn2;
1894 adj_tris.
insert( conn2, idx, *i, k );
1897 adj_quads.
insert( conn2, idx, *i, k );
1900 adj_poly.
insert( conn + k, 1, *i, k );
1907 rval = thisMB->get_connectivity( *i, conn, len,
false, &storage );
1910 idx = std::find( conn, conn + len, *it ) - conn;
1911 assert( idx != len );
1915 higher_order =
true;
1919 if( !printed_nonconformal_ho_warning )
1921 printed_nonconformal_ho_warning =
true;
1922 std::cerr <<
"Non-conformal higher-order mesh detected in skinner: "
1924 <<
"some elements and a higher-order node in others" << std::endl;
1932 for(
int f = 0; f < num_faces; ++f )
1936 const short face_idx = std::find( face_indices, face_indices + num_vtx, (
short)idx ) - face_indices;
1938 if( face_idx == num_vtx )
continue;
1940 assert( num_vtx <= 4 );
1944 adj_tris.
insert( conn, face_idx, *i, f, face_indices );
1947 adj_quads.
insert( conn, face_idx, *i, f, face_indices );
1963 hint = skin_verts->
insert( hint, *it );
1966 if( !corners_only && higher_order )
1975 rval = thisMB->get_connectivity( elem, conn, len,
false );
1979 EntityHandle ec[3] = { *it, t->handles[0], t->handles[1] };
1982 assert(
MBTRI == face_type );
1983 for(
int k = 3; k < clen; ++k )
1984 skin_verts->
insert( conn[indices[k]] );
1994 rval = thisMB->get_connectivity( elem, conn, len,
false );
1998 EntityHandle ec[4] = { *it, q->handles[0], q->handles[1], q->handles[2] };
2001 assert(
MBQUAD == face_type );
2002 for(
int k = 4; k < clen; ++k )
2003 skin_verts->
insert( conn[indices[k]] );
2015 rval = thisMB->get_adjacencies( &*it, 1, 2,
false, adj );
2018 for( i = adj.begin(); i != adj.end(); ++i )
2020 rval = thisMB->get_connectivity( *i, conn, len,
true );
2022 const int idx2 = std::find( conn, conn + len, *it ) - conn;
2025 assert( printed_nonconformal_ho_warning );
2037 if( reversed_faces && face_reversed( elem, conn,
MBTRI ) )
2038 reversed_faces->
insert( *i );
2040 skin_faces->
insert( *i );
2047 if( reversed_faces && face_reversed( elem, conn,
MBQUAD ) )
2048 reversed_faces->
insert( *i );
2050 skin_faces->
insert( *i );
2064 if( !create_faces )
continue;
2068 assert( 0 == adj_poly.
num_skin() );
2077 EntityHandle tri, c[3] = { *it, t->handles[0], t->handles[1] };
2078 rval = create_side( this_set, t->adj_elem,
MBTRI, c, tri );
2080 if( skin_faces ) skin_faces->
insert( tri );
2092 EntityHandle quad, c[4] = { *it, q->handles[0], q->handles[1], q->handles[2] };
2093 rval = create_side( this_set, q->adj_elem,
MBQUAD, c, quad );
2095 if( skin_faces ) skin_faces->
insert( quad );