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;
78 for( type = target_ent_types.first; type <= target_ent_types.second; ++type )
86 end_iter = entities.
end();
87 for( iter = entities.
begin(); iter != end_iter; ++iter )
89 unsigned char bit = 0x1;
111 std::vector< std::vector< EntityHandle >* > adj_arr;
112 std::vector< std::vector< EntityHandle >* >::iterator i;
120 adj_arr.resize( entities.
size() );
123 for( i = adj_arr.begin(); i != adj_arr.end(); ++i )
137 std::vector< EntityHandle >* adj = NULL;
142 const EntityHandle* iter = std::min_element( nodes, nodes + num_nodes );
144 if( iter == nodes + num_nodes )
return MB_SUCCESS;
149 adj->push_back( entity );
154 adj =
new std::vector< EntityHandle >;
155 adj->push_back( entity );
165 std::vector< EntityHandle >* adj = NULL;
166 const EntityHandle* iter = std::min_element( nodes, nodes + num_nodes );
168 if( iter == nodes + num_nodes )
return;
177 adj->push_back( entity );
182 adj =
new std::vector< EntityHandle >;
183 adj->push_back( entity );
204 const void* two_ptr = &two;
210 else if( face_sets.
empty() )
215 if(
debug ) std::cout <<
"Found " << face_sets.
size() <<
" face sets total..." << std::endl;
217 for( it = face_sets.
begin(); it != face_sets.
end(); ++it )
223 else if( num_parents == 1 )
227 if(
debug ) std::cout <<
"Found " << skin_sets.
size() <<
" 1-parent face sets..." << std::endl;
229 if( skin_sets.
empty() )
return MB_FAILURE;
232 for( it = skin_sets.
begin(); it != skin_sets.
end(); ++it )
242 const Range& source_entities,
244 Range& output_handles,
245 Range* output_reverse_handles,
246 bool create_vert_elem_adjs,
247 bool create_skin_elements,
263 return find_skin_vertices( meshset, source_entities, get_vertices ? &output_handles : 0,
264 get_vertices ? 0 : &output_handles, output_reverse_handles, create_skin_elements );
269 Range& output_handles,
270 bool create_skin_elements )
275 if( !scdi )
return MB_FAILURE;
279 std::vector< ScdBox* > boxes, myboxes;
283 for( std::vector< ScdBox* >::iterator bit = boxes.begin(); bit != boxes.end(); ++bit )
285 Range belems( ( *bit )->start_element(), ( *bit )->start_element() + ( *bit )->num_elements() - 1 );
286 if( source_entities.
contains( belems ) )
288 myboxes.push_back( *bit );
289 myrange.
merge( belems );
292 if( myboxes.empty() || myrange.
size() != source_entities.
size() )
return MB_FAILURE;
295 for( std::vector< ScdBox* >::iterator bit = boxes.begin(); bit != boxes.end(); ++bit )
297 rval =
skin_box( *bit, get_vertices, output_handles, create_skin_elements );
309 if( bmin.
j() == bmax.j() && bmin.
k() == bmax.k() )
return MB_FAILURE;
311 int dim = ( bmin.
k() == bmax.k() ? 1 : 2 );
317 for(
int k = bmin.
k(); k < bmax.k(); k++ )
319 for(
int j = bmin.
j(); j < bmax.j(); j++ )
324 if( ent ) output_handles.
insert( ent );
328 for(
int k = bmin.
k(); k < bmax.k(); k++ )
330 for(
int j = bmin.
j(); j < bmax.j(); j++ )
335 if( ent ) output_handles.
insert( ent );
339 for(
int k = bmin.
k(); k < bmax.k(); k++ )
341 for(
int i = bmin.
i(); i < bmax.i(); i++ )
346 if( ent ) output_handles.
insert( ent );
350 for(
int k = bmin.
k(); k < bmax.k(); k++ )
352 for(
int i = bmin.
i(); i < bmax.i(); i++ )
357 if( ent ) output_handles.
insert( ent );
361 for(
int j = bmin.
j(); j < bmax.j(); j++ )
363 for(
int i = bmin.
i(); i < bmax.i(); i++ )
368 if( ent ) output_handles.
insert( ent );
372 for(
int j = bmin.
j(); j < bmax.j(); j++ )
374 for(
int i = bmin.
i(); i < bmax.i(); i++ )
379 if( ent ) output_handles.
insert( ent );
388 output_handles.
merge( verts );
395 Range &forward_target_entities,
396 Range &reverse_target_entities
399 if( source_entities.
empty() )
return MB_FAILURE;
407 if( mTargetDim < 0 || source_dim > 3 )
return MB_FAILURE;
412 end_iter = source_entities.
end();
421 std::vector< EntityHandle > tmp_conn_vec;
422 int num_nodes, num_sub_nodes, num_sides;
428 for( iter = source_entities.
begin(); iter != end_iter; ++iter )
431 int actual_num_nodes_polygon = 0;
443 actual_num_nodes_polygon = num_nodes;
444 while( actual_num_nodes_polygon >= 3 &&
445 conn[actual_num_nodes_polygon - 1] == conn[actual_num_nodes_polygon - 2] )
446 actual_num_nodes_polygon--;
447 num_sides = actual_num_nodes_polygon;
453 for(
int i = 0; i < num_sides; i++ )
457 sub_conn[0] = conn[i];
458 sub_conn[1] = conn[i + 1];
459 if( i + 1 == actual_num_nodes_polygon ) sub_conn[1] = conn[0];
464 assert( (
size_t)num_sub_nodes <=
sizeof( sub_indices ) /
sizeof( sub_indices[0] ) );
465 for(
int j = 0; j < num_sub_nodes; j++ )
466 sub_conn[j] = conn[sub_indices[j]];
471 find_match( sub_type, sub_conn, num_sub_nodes, match, direct );
488 for(
int j = 0; j < num_new_nodes; j++ )
489 sub_conn[j] = conn[indices[j]];
494 forward_target_entities.
insert( tmphndl );
500 if( ( seek_iter = forward_target_entities.
find( match ) ) != forward_target_entities.
end() )
502 forward_target_entities.
erase( seek_iter );
510 else if( ( seek_iter = reverse_target_entities.
find( match ) ) != reverse_target_entities.
end() )
512 reverse_target_entities.
erase( seek_iter );
524 forward_target_entities.
insert( match );
528 reverse_target_entities.
insert( match );
555 const EntityHandle* iter = std::min_element( conn, conn + num_nodes );
557 std::vector< EntityHandle >* adj = NULL;
560 if( result == MB_FAILURE || adj == NULL )
565 std::vector< EntityHandle >::iterator jter, end_jter;
566 end_jter = adj->end();
571 for( jter = adj->begin(); jter != end_jter; ++jter )
576 if( type != tmp_type )
continue;
595 const EntityHandle* iter = std::find( conn2, conn2 + num_verts, conn1[0] );
596 if( iter == conn2 + num_verts )
return false;
598 bool they_match =
true;
601 unsigned int j = iter - conn2;
604 for( i = 1; i < num_verts; ++i )
606 if( conn1[i] != conn2[( j + i ) % num_verts] )
613 if( they_match ==
true )
624 for( i = 1; i < num_verts; )
626 if( conn1[i] != conn2[( j - i ) % num_verts] )
642 std::vector< EntityHandle > nodes, *adj = NULL;
645 std::vector< EntityHandle >::iterator iter = std::min_element( nodes.begin(), nodes.end() );
647 if( iter == nodes.end() )
return MB_FAILURE;
652 iter = std::find( adj->begin(), adj->end(), entity );
653 if( iter != adj->end() ) adj->erase( iter );
661 unsigned char deletable = 0;
664 if(
MB_SUCCESS == result && deletable == 1 )
return false;
669 const Range& bar_elements,
674 int& number_boundary_nodes )
676 Range bedges, iedges, nmedges, oedges;
678 classify_2d_boundary( boundary, bar_elements, bedges, iedges, nmedges, oedges, number_boundary_nodes );
706 const Range& bar_elements,
707 Range& boundary_edges,
708 Range& inferred_edges,
709 Range& non_manifold_edges,
711 int& number_boundary_nodes )
716 boundary_edges.
clear();
717 inferred_edges.
clear();
718 non_manifold_edges.
clear();
721 number_boundary_nodes = 0;
724 if( boundary.
empty() )
734 if( source_dim != 2 )
748 int default_count = 0;
754 end_iter = boundary.
end();
756 std::vector< EntityHandle > conn;
761 Range boundary_nodes;
765 int num_edge, num_sub_ent_vert;
766 const short* edge_verts;
770 for( iter = boundary.
begin(); iter != end_iter; ++iter )
785 for(
int i = 0; i < num_edge; i++ )
788 assert( sub_type ==
MBEDGE && num_sub_ent_vert == 2 );
789 sub_conn[0] = conn[edge_verts[0]];
790 sub_conn[1] = conn[edge_verts[1]];
805 for(
int j = 0; j < num_new_nodes; j++ )
806 sub_conn[j] = conn[indices[j]];
812 edge_list.
insert( tmphndl );
836 edge_list.
insert( match );
847 if( !bar_elements.
empty() )
850 for( iter = bar_elements.
begin(); iter != bar_elements.
end(); ++iter )
853 bar_iter = edge_list.
find( handle );
854 if( bar_iter != edge_list.
end() )
857 edge_list.
erase( bar_iter );
858 non_manifold_edges.
insert( handle );
863 boundary_edges.
insert( handle );
872 edge_end_iter = edge_list.
end();
874 for( edge_iter = edge_list.
begin(); edge_iter != edge_end_iter; ++edge_iter )
881 boundary_edges.
insert( *edge_iter );
883 else if( count == 2 )
885 other_edges.
insert( *edge_iter );
889 non_manifold_edges.
insert( *edge_iter );
895 double min_angle_degrees = 20.0;
902 std::set_difference( other_edges.
begin(), other_edges.
end(), inferred_edges.
begin(), inferred_edges.
end(),
905 other_edges = temp_range;
914 number_boundary_nodes = boundary_nodes.
size();
920 Range& candidate_edges,
921 Range& inferred_edges,
922 double reference_angle_degrees )
929 unsigned char bit =
true;
935 double reference_cosine = cos( reference_angle_degrees *
SKINNER_PI / 180.0 );
940 std::vector< EntityHandle > adjacencies;
941 std::vector< EntityHandle >::iterator adj_iter;
944 for( iter = candidate_edges.
begin(); iter != end_iter; ++iter )
956 for( adj_iter = adjacencies.begin(); adj_iter != adjacencies.end() && faces_found < 2; ++adj_iter )
959 unsigned char is_marked = 0;
964 face[faces_found] = *adj_iter;
970 if( 2 != faces_found )
continue;
976 inferred_edges.
insert( *iter );
993 double cosine = norm[0][0] * norm[1][0] + norm[0][1] * norm[1][1] + norm[0][2] * norm[1][2];
995 if( cosine < reference_angle_cosine )
1005 const Range& entities,
1007 Range& skin_entities,
1008 bool create_vert_elem_adjs,
1009 bool create_skin_elements )
1013 find_skin( this_set, entities, ( dim == 0 ), tmp_skin, 0, create_vert_elem_adjs, create_skin_elements );
1018 if( skin_entities.
empty() )
1019 skin_entities.
swap( tmp_skin );
1021 skin_entities.
merge( tmp_skin );
1034 const Range& entities,
1037 Range* skin_rev_elems,
1038 bool create_skin_elems,
1048 size_t count = entities.
size();
1052 bool all = ( count == (size_t)num_total );
1060 char bit = all ? 1 : 0;
1067 std::vector< unsigned char > vect( count, 1 );
1081 else if( skin_elems )
1088 create_skin_elems, corners_only );
1092 create_skin_elems, corners_only );
1129 std::vector< char > tag_vals;
1130 std::vector< EntityHandle > adj;
1138 if( adj.empty() )
continue;
1141 tag_vals.resize( adj.size() );
1144 #ifdef MOAB_OLD_STD_COUNT
1146 std::count( tag_vals.begin(), tag_vals.end(),
'\001' );
1148 n = std::count( tag_vals.begin(), tag_vals.end(),
'\001' );
1153 hint = skin_verts.
insert( hint, *it );
1163 template <
unsigned CORNERS >
1208 handles[1] = array[( idx + 2 ) % CORNERS];
1211 if( 3 == CORNERS )
handles[1] = array[( idx + 2 ) % CORNERS];
1212 if( 2 <= CORNERS )
handles[0] = array[( idx + 1 ) % CORNERS];
1236 handles[1] = array[indices[( idx + 2 ) % CORNERS]];
1239 if( 3 == CORNERS )
handles[1] = array[indices[( idx + 2 ) % CORNERS]];
1240 if( 2 <= CORNERS )
handles[0] = array[indices[( idx + 1 ) % CORNERS]];
1271 typedef typename std::vector< Side >::iterator
iterator;
1275 return data.begin();
1289 return data.empty();
1313 Side side( handles, skip_idx, adj_elem, elem_side );
1315 if( p ==
data.end() )
1317 data.push_back( side );
1320 else if( p->adj_elem )
1346 unsigned short elem_side,
1347 const short* indices )
1349 Side side( handles, skip_idx, adj_elem, elem_side, indices );
1351 if( p ==
data.end() )
1353 data.push_back( side );
1356 else if( p->adj_elem )
1377 Side s( other, skip_index, 0, 0 );
1379 if( p ==
data.end() || !p->adj_elem )
1383 elem_out = p->adj_elem;
1400 const unsigned int CORNERS = 4;
1401 handles[2] = array[( idx + 3 ) % CORNERS];
1402 handles[1] = array[( idx + 2 ) % CORNERS];
1403 handles[0] = array[( idx + 1 ) % CORNERS];
1420 const unsigned int CORNERS = 4;
1421 handles[2] = array[indices[( idx + 3 ) % CORNERS]];
1422 handles[1] = array[indices[( idx + 2 ) % CORNERS]];
1423 handles[0] = array[indices[( idx + 1 ) % CORNERS]];
1432 return handles[0] == other.
handles[0] && handles[1] == other.
handles[1] && handles[2] == other.
handles[2];
1454 EntityType side_type,
1458 const int max_side = 9;
1460 int len, side_len, side, sense, offset, indices[max_side];
1465 std::vector< EntityHandle > storage;
1468 rval = thisMB->get_connectivity( elem, conn, len,
false, &storage );
1477 for( i = 0; i < len; i++ )
1479 if( conn[i] == side_conn[0] )
break;
1481 if( len == i )
return MB_FAILURE;
1484 int prevIndex = ( i + len - 1 ) % len;
1485 int nextIndex = ( i + 1 ) % len;
1487 if( conn[nextIndex] == conn[i] )
1493 EntityHandle conn2[2] = { side_conn[0], side_conn[1] };
1494 if( conn[prevIndex] == side_conn[1] )
1497 conn2[0] = side_conn[1];
1498 conn2[1] = side_conn[0];
1500 else if( conn[nextIndex] != side_conn[1] )
1506 MB_CHK_ERR( thisMB->add_entities( this_set, &side_elem, 1 ) );
1512 CN::SideNumber( type, conn, side_conn, ncorner, d, side, sense, offset );
1514 assert( side_len <= max_side );
1515 assert( side_type == tmp_type );
1521 for(
int i = 0; i < side_len; ++i )
1522 side_conn_full[i] = conn[indices[i]];
1524 MB_CHK_ERR( thisMB->create_element( side_type, side_conn_full, side_len, side_elem ) );
1527 MB_CHK_ERR( thisMB->add_entities( this_set, &side_elem, 1 ) );
1539 ErrorCode rval = thisMB->get_connectivity(
face, conn, len,
true );
1545 idx = std::find( conn, conn + len, edge_ends[0] ) - conn;
1551 return ( edge_ends[1] == conn[( idx + len - 1 ) % len] );
1560 int len, side, sense, offset;
1561 ErrorCode rval = thisMB->get_connectivity( region, conn, len,
true );
1570 return ( !r && sense == -1 );
1578 Range* reversed_edges,
1598 std::vector< EntityHandle >::iterator i, j;
1600 if( skin_verts ) hint = skin_verts->
begin();
1601 std::vector< EntityHandle > storage;
1604 bool find_edges = skin_edges || create_edges;
1605 bool printed_nonconformal_ho_warning =
false;
1612 rval = thisMB->get_connectivity( faces, verts,
true );
1615 std::vector< char > tag_vals;
1616 std::vector< EntityHandle > adj;
1620 bool higher_order =
false;
1624 rval = thisMB->get_adjacencies( &*it, 1, 2,
false, adj );
1626 if( adj.empty() )
continue;
1629 i = j = adj.begin();
1630 tag_vals.resize( adj.size() );
1631 rval = thisMB->tag_get_data( tag, &adj[0], adj.size(), &tag_vals[0] );
1634 i = j = adj.begin();
1635 for( ; i != adj.end(); ++i )
1636 if( tag_vals[i - adj.begin()] ) *( j++ ) = *i;
1637 adj.erase( j, adj.end() );
1641 for( i = adj.begin(); i != adj.end(); ++i )
1643 rval = thisMB->get_connectivity( *i, conn, len,
false, &storage );
1651 const int idx = std::find( conn, conn + len, *it ) - conn;
1652 assert( idx != len );
1657 higher_order =
true;
1660 if( !printed_nonconformal_ho_warning )
1662 printed_nonconformal_ho_warning =
true;
1663 std::cerr <<
"Non-conformal higher-order mesh detected in skinner: "
1665 <<
"some elements and a higher-order node in others" << std::endl;
1673 higher_order =
true;
1676 if( !printed_nonconformal_ho_warning )
1678 printed_nonconformal_ho_warning =
true;
1679 std::cerr <<
"Non-conformal higher-order mesh detected in skinner: "
1681 <<
"some elements and a higher-order node in others" << std::endl;
1688 const int prev_idx = ( idx + len - 1 ) % len;
1689 prev = conn[prev_idx];
1690 next = conn[( idx + 1 ) % len];
1691 if( next == conn[idx] )
1695 adj_edges.
insert( &prev, 1, *i, prev_idx );
1696 adj_edges.
insert( &next, 1, *i, idx );
1703 if( 0 == adj_edges.
num_skin() )
continue;
1709 hint = skin_verts->
insert( hint, *it );
1712 if( !corners_only && higher_order )
1721 rval = thisMB->get_connectivity(
face, conn, len,
false );
1726 int side, sense, offset;
1729 assert( offset >= 0 && offset < len );
1730 skin_verts->
insert( conn[offset] );
1741 rval = thisMB->get_adjacencies( &*it, 1, 1,
false, adj );
1743 for( i = adj.begin(); i != adj.end(); ++i )
1745 rval = thisMB->get_connectivity( *i, conn, len,
true );
1757 if( reversed_edges && edge_reversed(
face, conn ) )
1758 reversed_edges->
insert( *i );
1760 skin_edges->
insert( *i );
1768 if( create_edges && adj_edges.
num_skin() )
1776 rval = create_side( this_set, p->adj_elem,
MBEDGE, ec,
edge );
1790 const Range& entities,
1793 Range* reversed_faces,
1829 std::vector< EntityHandle >::iterator i, j;
1831 if( skin_verts ) hint = skin_verts->
begin();
1832 std::vector< EntityHandle > storage, storage2;
1835 bool find_faces = skin_faces || create_faces;
1836 int clen, side, sense, offset, indices[9];
1837 EntityType face_type;
1839 bool printed_nonconformal_ho_warning =
false;
1845 rval = thisMB->get_connectivity( entities, verts,
true );
1855 rval = thisMB->get_connectivity( pfaces, verts,
true );
1865 std::vector< char > tag_vals;
1866 std::vector< EntityHandle > adj;
1869 bool higher_order =
false;
1873 rval = thisMB->get_adjacencies( &*it, 1, 3,
false, adj );
1875 if( adj.empty() )
continue;
1878 i = j = adj.begin();
1879 tag_vals.resize( adj.size() );
1880 rval = thisMB->tag_get_data( tag, &adj[0], adj.size(), &tag_vals[0] );
1882 for( ; i != adj.end(); ++i )
1883 if( tag_vals[i - adj.begin()] ) *( j++ ) = *i;
1884 adj.erase( j, adj.end() );
1891 for( i = adj.begin(); i != adj.end(); ++i )
1898 rval = thisMB->get_connectivity( *i, conn, len );
1900 for(
int k = 0; k < len; ++k )
1902 rval = thisMB->get_connectivity( conn[k], conn2, len2,
true, &storage2 );
1904 idx = std::find( conn2, conn2 + len2, *it ) - conn2;
1914 adj_tris.
insert( conn2, idx, *i, k );
1917 adj_quads.
insert( conn2, idx, *i, k );
1920 adj_poly.
insert( conn + k, 1, *i, k );
1927 rval = thisMB->get_connectivity( *i, conn, len,
false, &storage );
1930 idx = std::find( conn, conn + len, *it ) - conn;
1931 assert( idx != len );
1935 higher_order =
true;
1939 if( !printed_nonconformal_ho_warning )
1941 printed_nonconformal_ho_warning =
true;
1942 std::cerr <<
"Non-conformal higher-order mesh detected in skinner: "
1944 <<
"some elements and a higher-order node in others" << std::endl;
1952 for(
int f = 0; f < num_faces; ++f )
1956 const short face_idx = std::find( face_indices, face_indices + num_vtx, (
short)idx ) - face_indices;
1958 if( face_idx == num_vtx )
continue;
1960 assert( num_vtx <= 4 );
1964 adj_tris.
insert( conn, face_idx, *i, f, face_indices );
1967 adj_quads.
insert( conn, face_idx, *i, f, face_indices );
1983 hint = skin_verts->
insert( hint, *it );
1986 if( !corners_only && higher_order )
1995 rval = thisMB->get_connectivity( elem, conn, len,
false );
1999 EntityHandle ec[3] = { *it, t->handles[0], t->handles[1] };
2002 assert(
MBTRI == face_type );
2003 for(
int k = 3; k < clen; ++k )
2004 skin_verts->
insert( conn[indices[k]] );
2014 rval = thisMB->get_connectivity( elem, conn, len,
false );
2018 EntityHandle ec[4] = { *it, q->handles[0], q->handles[1], q->handles[2] };
2021 assert(
MBQUAD == face_type );
2022 for(
int k = 4; k < clen; ++k )
2023 skin_verts->
insert( conn[indices[k]] );
2035 rval = thisMB->get_adjacencies( &*it, 1, 2,
false, adj );
2038 for( i = adj.begin(); i != adj.end(); ++i )
2040 rval = thisMB->get_connectivity( *i, conn, len,
true );
2042 const int idx2 = std::find( conn, conn + len, *it ) - conn;
2045 assert( printed_nonconformal_ho_warning );
2057 if( reversed_faces && face_reversed( elem, conn,
MBTRI ) )
2058 reversed_faces->
insert( *i );
2060 skin_faces->
insert( *i );
2067 if( reversed_faces && face_reversed( elem, conn,
MBQUAD ) )
2068 reversed_faces->
insert( *i );
2070 skin_faces->
insert( *i );
2084 if( !create_faces )
continue;
2088 assert( 0 == adj_poly.
num_skin() );
2097 EntityHandle tri, c[3] = { *it, t->handles[0], t->handles[1] };
2098 rval = create_side( this_set, t->adj_elem,
MBTRI, c, tri );
2100 if( skin_faces ) skin_faces->
insert( tri );
2112 EntityHandle quad, c[4] = { *it, q->handles[0], q->handles[1], q->handles[2] };
2113 rval = create_side( this_set, q->adj_elem,
MBQUAD, c, quad );
2115 if( skin_faces ) skin_faces->
insert( quad );