Go to the documentation of this file. 1 #include <iostream>
2 #include <cstdlib>
3 #include "MBCore.hpp"
4 #include "MBRange.hpp"
5 #include "MBTagConventions.hpp"
6
7
8 struct edge
9 {
10 MBEntityHandle v0;
11 MBEntityHandle v1;
12 };
13
14
15
16 int compare_edge( const void* a, const void* b )
17 {
18 struct edge* ia = (struct edge*)a;
19 struct edge* ib = (struct edge*)b;
20 if( ia->v0 == ib->v0 )
21 {
22 return (int)( 100.f * ia->v1 - 100.f * ib->v1 );
23 }
24 else
25 {
26 return (int)( 100.f * ia->v0 - 100.f * ib->v0 );
27 }
28 }
29
30
31
32 MBErrorCode skin_tris( MBInterface* mb, MBRange tris, MBRange& skin_edges )
33 {
34
35
36 skin_edges.clear();
37 if( tris.empty() ) return MB_ENTITY_NOT_FOUND;
38 if( !tris.all_of_type( MBTRI ) ) return MB_FAILURE;
39
40
41 int n_edges;
42 MBErrorCode rval = mb->get_number_entities_by_type( 0, MBEDGE, n_edges );
43 if( MB_SUCCESS != rval ) return rval;
44 if( 0 != n_edges )
45 {
46 std::cerr << "skin_tris: failed because " << n_edges << " edges exist in the MOAB instance" << std::endl;
47 return MB_FAILURE;
48 }
49
50
51 edge* edges = new edge[3 * tris.size()];
52 int n_verts;
53 int ii = 0;
54 for( MBRange::iterator i = tris.begin(); i != tris.end(); ++i )
55 {
56 const MBEntityHandle* conn;
57 rval = mb->get_connectivity( *i, conn, n_verts );
58 if( MB_SUCCESS != rval ) return rval;
59 if( 3 != n_verts ) return MB_FAILURE;
60
61 if( conn[0] == conn[1] || conn[1] == conn[2] || conn[2] == conn[0] )
62 {
63 std::cerr << "skin_tris: degenerate triangle" << std::endl;
64 return MB_FAILURE;
65 }
66
67
68 edges[3 * ii + 0].v0 = conn[0];
69 edges[3 * ii + 0].v1 = conn[1];
70 edges[3 * ii + 1].v0 = conn[1];
71 edges[3 * ii + 1].v1 = conn[2];
72 edges[3 * ii + 2].v0 = conn[2];
73 edges[3 * ii + 2].v1 = conn[0];
74 ii++;
75 }
76
77
78 for( unsigned int i = 0; i < 3 * tris.size(); ++i )
79 {
80 if( edges[i].v0 > edges[i].v1 )
81 {
82 MBEntityHandle temp = edges[i].v0;
83 edges[i].v0 = edges[i].v1;
84 edges[i].v1 = temp;
85 }
86 }
87
88
89 qsort( edges, 3 * tris.size(), sizeof( struct edge ), compare_edge );
90
91
92 for( unsigned int i = 0; i < 3 * tris.size(); i++ )
93 {
94
95
96 if( 3 * tris.size() - 1 == i )
97 {
98 const MBEntityHandle conn[2] = { edges[i].v0, edges[i].v1 };
99 MBEntityHandle edge;
100 rval = mb->create_element( MBEDGE, conn, 2, edge );
101 if( MB_SUCCESS != rval ) return rval;
102 skin_edges.insert( edge );
103
104
105 }
106 else if( edges[i].v0 == edges[i + 1].v0 && edges[i].v1 == edges[i + 1].v1 )
107 {
108 i++;
109
110 while( edges[i].v0 == edges[i + 1].v0 && edges[i].v1 == edges[i + 1].v1 )
111 {
112 std::cout << "find_skin WARNING: non-manifold edge" << std::endl;
113 mb->list_entity( edges[i].v0 );
114 mb->list_entity( edges[i].v1 );
115 ++i;
116 }
117
118 }
119 else
120 {
121 const MBEntityHandle conn[2] = { edges[i].v0, edges[i].v1 };
122 MBEntityHandle edge;
123 rval = mb->create_element( MBEDGE, conn, 2, edge );
124 if( MB_SUCCESS != rval ) return rval;
125 skin_edges.insert( edge );
126 }
127 }
128 delete[] edges;
129 return MB_SUCCESS;
130 }
131
132
133
134 int main( int argc, char** argv )
135 {
136 if( 1 == argc )
137 {
138 std::cout << "Usage: " << argv[0] << " <filename>" << std::endl;
139 return 0;
140 }
141
142
143 MBCore* mb = new MBCore();
144 MBErrorCode rval = mb->load_file( argv[1] );
145 if( MB_SUCCESS != rval ) return 0;
146
147
148 MBRange edges;
149 rval = mb->get_entities_by_type( 0, MBEDGE, edges );
150 if( MB_SUCCESS != rval ) return 0;
151 if( !edges.empty() ) std::cout << "Warning: deleting all MBEdges" << std::endl;
152 rval = mb->delete_entities( edges );
153 if( MB_SUCCESS != rval ) return 0;
154
155
156 MBTag geom_tag;
157 rval = mb->tag_get_handle( GEOM_DIMENSION_TAG_NAME, 1, MB_TYPE_INTEGER, geom_tag );
158 if( MB_SUCCESS != rval ) return 0;
159 MBRange surf_sets;
160 int two = 2;
161 void* dim[] = { &two };
162 rval = mb->get_entities_by_type_and_tag( 0, MBENTITYSET, &geom_tag, dim, 1, surf_sets );
163 if( MB_SUCCESS != rval ) return 0;
164
165
166 for( MBRange::iterator i = surf_sets.begin(); i != surf_sets.end(); ++i )
167 {
168
169
170 MBRange tris;
171 rval = mb->get_entities_by_type( *i, MBTRI, tris );
172 if( MB_SUCCESS != rval ) return 0;
173
174
175 MBRange skin_edges;
176 rval = skin_tris( mb, tris, skin_edges );
177 if( MB_SUCCESS != rval ) return 0;
178
179
180 std::cout << "surface has " << skin_edges.size() << " skin edges" << std::endl;
181
182
183 rval = mb->delete_entities( skin_edges );
184 if( MB_SUCCESS != rval ) return 0;
185 }
186 }