Branch data Line data Source code
1 : : /* *****************************************************************
2 : : MESQUITE -- The Mesh Quality Improvement Toolkit
3 : :
4 : : Copyright 2004 Lawrence Livermore National Laboratory. Under
5 : : the terms of Contract B545069 with the University of Wisconsin --
6 : : Madison, Lawrence Livermore National Laboratory retains certain
7 : : rights in this software.
8 : :
9 : : This library is free software; you can redistribute it and/or
10 : : modify it under the terms of the GNU Lesser General Public
11 : : License as published by the Free Software Foundation; either
12 : : version 2.1 of the License, or (at your option) any later version.
13 : :
14 : : This library is distributed in the hope that it will be useful,
15 : : but WITHOUT ANY WARRANTY; without even the implied warranty of
16 : : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 : : Lesser General Public License for more details.
18 : :
19 : : You should have received a copy of the GNU Lesser General Public License
20 : : (lgpl.txt) along with this library; if not, write to the Free Software
21 : : Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 : :
23 : : [email protected]
24 : :
25 : : ***************************************************************** */
26 : :
27 : : #include "MeshImplData.hpp"
28 : : #include "TopologyInfo.hpp"
29 : : #include "MsqError.hpp"
30 : :
31 : : // NOTE: If this is defined, the normal vertex query functions
32 : : // will not return mid-nodes.
33 : : #undef SEPARATE_MID_NODES
34 : :
35 : : namespace MBMesquite
36 : : {
37 : :
38 : 32 : const std::vector< size_t > dummy_list;
39 : 32 : const Vector3D dummy_vtx;
40 : :
41 : 455 : size_t MeshImplData::num_vertices() const
42 : : {
43 : 455 : size_t count = 0;
44 [ + - ][ + - ]: 150026 : for( std::vector< Vertex >::const_iterator iter = vertexList.begin(); iter != vertexList.end(); ++iter )
[ + + ]
45 : : #ifdef SEPARATE_MID_NODES
46 : : if( iter->valid && iter->midcount < iter->adjacencies.size() )
47 : : #else
48 [ + - ][ + - ]: 149571 : if( iter->valid )
49 : : #endif
50 : 149571 : ++count;
51 : 455 : return count;
52 : : }
53 : :
54 : 409 : size_t MeshImplData::num_elements() const
55 : : {
56 : 409 : return elementList.size() - deletedElementList.size();
57 : : }
58 : :
59 : 61 : size_t MeshImplData::num_vertex_uses() const
60 : : {
61 : 61 : size_t result = 0;
62 [ + - ][ + - ]: 48991 : for( std::vector< Element >::const_iterator iter = elementList.begin(); iter != elementList.end(); ++iter )
[ + + ]
63 : : {
64 : : #ifdef SEPARATE_MID_NODES
65 : : unsigned from_topo = TopologyInfo::corners( iter->topology );
66 : : result += from_topo ? from_topo : iter->connectivity.size();
67 : : #else
68 [ + - ]: 48930 : result += iter->connectivity.size();
69 : : #endif
70 : : }
71 : 61 : return result;
72 : : }
73 : :
74 : 16004603 : const Vector3D& MeshImplData::get_vertex_coords( size_t index, MsqError& err ) const
75 : : {
76 [ - + ]: 16004603 : if( !is_vertex_valid( index ) )
77 : : {
78 [ # # ]: 0 : MSQ_SETERR( err )( "Invalid vertex handle", MsqError::INVALID_ARG );
79 : 0 : return dummy_vtx;
80 : : }
81 : :
82 : 16004603 : return vertexList[index].coords;
83 : : }
84 : :
85 : 221135 : bool MeshImplData::vertex_is_fixed( size_t index, MsqError& err ) const
86 : : {
87 [ - + ]: 221135 : if( !is_vertex_valid( index ) )
88 : : {
89 [ # # ]: 0 : MSQ_SETERR( err )( "Invalid vertex handle", MsqError::INVALID_ARG );
90 : 0 : return false;
91 : : }
92 : :
93 : 221135 : return vertexList[index].fixed;
94 : : }
95 : :
96 : 1125 : bool MeshImplData::vertex_is_slaved( size_t index, MsqError& err ) const
97 : : {
98 [ - + ]: 1125 : if( !is_vertex_valid( index ) )
99 : : {
100 [ # # ]: 0 : MSQ_SETERR( err )( "Invalid vertex handle", MsqError::INVALID_ARG );
101 : 0 : return false;
102 : : }
103 [ - + ]: 1125 : if( !have_slaved_flags() )
104 : : {
105 [ # # ]: 0 : MSQ_SETERR( err )( "Slave flags not set", MsqError::INVALID_STATE );
106 : 0 : return false;
107 : : }
108 : :
109 : 1125 : return vertexList[index].slaved;
110 : : }
111 : :
112 : 54707 : void MeshImplData::fix_vertex( size_t index, bool flag, MsqError& err )
113 : : {
114 [ - + ]: 54707 : if( !is_vertex_valid( index ) )
115 : : {
116 [ # # ]: 0 : MSQ_SETERR( err )( "Invalid vertex handle", MsqError::INVALID_ARG );
117 : 54707 : return;
118 : : }
119 : :
120 : 54707 : vertexList[index].fixed = flag;
121 : : }
122 : :
123 : 484 : void MeshImplData::slave_vertex( size_t index, bool flag, MsqError& err )
124 : : {
125 [ - + ]: 484 : if( !is_vertex_valid( index ) )
126 : : {
127 [ # # ]: 0 : MSQ_SETERR( err )( "Invalid vertex handle", MsqError::INVALID_ARG );
128 : 484 : return;
129 : : }
130 : :
131 : 484 : vertexList[index].slaved = flag;
132 : 484 : haveSlavedFlags = true;
133 : : }
134 : :
135 : 9885277 : unsigned char MeshImplData::get_vertex_byte( size_t index, MsqError& err ) const
136 : : {
137 [ - + ]: 9885277 : if( !is_vertex_valid( index ) )
138 : : {
139 [ # # ]: 0 : MSQ_SETERR( err )( "Invalid vertex handle", MsqError::INVALID_ARG );
140 : 0 : return 0;
141 : : }
142 : :
143 : 9885277 : return vertexList[index].byte;
144 : : }
145 : :
146 : 9321560 : void MeshImplData::set_vertex_byte( size_t index, unsigned char value, MsqError& err )
147 : : {
148 [ - + ]: 9321560 : if( !is_vertex_valid( index ) )
149 : : {
150 [ # # ]: 0 : MSQ_SETERR( err )( "Invalid vertex handle", MsqError::INVALID_ARG );
151 : 9321560 : return;
152 : : }
153 : :
154 : 9321560 : vertexList[index].byte = value;
155 : : }
156 : :
157 : 4475862 : EntityTopology MeshImplData::element_topology( size_t index, MsqError& err ) const
158 : : {
159 [ - + ]: 4475862 : if( !is_element_valid( index ) )
160 : : {
161 [ # # ]: 0 : MSQ_SETERR( err )( "Invalid element handle", MsqError::INVALID_ARG );
162 : 0 : return MIXED;
163 : : }
164 : :
165 : 4475862 : return elementList[index].topology;
166 : : }
167 : :
168 : 116294 : void MeshImplData::element_topology( size_t index, EntityTopology type, MsqError& err )
169 : : {
170 [ - + ]: 116294 : if( !is_element_valid( index ) )
171 : : {
172 [ # # ]: 0 : MSQ_SETERR( err )( "Invalid element handle", MsqError::INVALID_ARG );
173 : 116294 : return;
174 : : }
175 : :
176 : : unsigned i, numvert;
177 : :
178 : 116294 : numvert = TopologyInfo::corners( elementList[index].topology );
179 [ - + ]: 116294 : if( numvert )
180 [ # # ]: 0 : for( i = numvert; i < elementList[index].connectivity.size(); ++i )
181 : 0 : --vertexList[elementList[index].connectivity[i]].midcount;
182 : :
183 : 116294 : elementList[index].topology = type;
184 : :
185 : 116294 : numvert = TopologyInfo::corners( elementList[index].topology );
186 [ + + ]: 116294 : if( numvert )
187 [ + + ]: 117018 : for( i = numvert; i < elementList[index].connectivity.size(); ++i )
188 : 760 : ++vertexList[elementList[index].connectivity[i]].midcount;
189 : : }
190 : :
191 : 4483078 : const std::vector< size_t >& MeshImplData::element_connectivity( size_t index, MsqError& err ) const
192 : : {
193 [ - + ]: 4483078 : if( !is_element_valid( index ) )
194 : : {
195 [ # # ]: 0 : MSQ_SETERR( err )( "Invalid element handle", MsqError::INVALID_ARG );
196 : 0 : return dummy_list;
197 : : }
198 : :
199 : 4483078 : return elementList[index].connectivity;
200 : : }
201 : :
202 : 867911 : const std::vector< size_t >& MeshImplData::vertex_adjacencies( size_t index, MsqError& err ) const
203 : : {
204 [ - + ]: 867911 : if( !is_vertex_valid( index ) )
205 : : {
206 [ # # ]: 0 : MSQ_SETERR( err )( "Invalid vertex handle", MsqError::INVALID_ARG );
207 : 0 : return dummy_list;
208 : : }
209 : :
210 : 867911 : return vertexList[index].adjacencies;
211 : : }
212 : :
213 : 168 : void MeshImplData::clear()
214 : : {
215 : 168 : vertexList.clear();
216 : 168 : elementList.clear();
217 : 168 : deletedVertexList.clear();
218 : 168 : deletedElementList.clear();
219 : 168 : haveSlavedFlags = false;
220 : 168 : }
221 : :
222 : 149 : void MeshImplData::allocate_vertices( size_t count, MsqError& err )
223 : : {
224 [ - + ]: 149 : if( vertexList.size() )
225 : : {
226 [ # # ]: 0 : MSQ_SETERR( err )( MsqError::INVALID_STATE );
227 : 149 : return;
228 : : }
229 : :
230 : 149 : vertexList.resize( count );
231 : : }
232 : :
233 : 149 : void MeshImplData::allocate_elements( size_t count, MsqError& err )
234 : : {
235 [ - + ]: 149 : if( elementList.size() )
236 : : {
237 [ # # ]: 0 : MSQ_SETERR( err )( MsqError::INVALID_STATE );
238 : 149 : return;
239 : : }
240 : :
241 : 149 : elementList.resize( count );
242 : : }
243 : :
244 : 863023 : void MeshImplData::set_vertex_coords( size_t index, const Vector3D& coords, MsqError& err )
245 : : {
246 [ - + ]: 863023 : if( !is_vertex_valid( index ) )
247 : : {
248 [ # # ]: 0 : MSQ_SETERR( err )( "Invalid vertex handle", MsqError::INVALID_ARG );
249 : 863023 : return;
250 : : }
251 : :
252 : 863023 : vertexList[index].coords = coords;
253 : : }
254 : :
255 : 65751 : void MeshImplData::reset_vertex( size_t index, const Vector3D& coords, bool fixed, MsqError& err )
256 : : {
257 [ - + ]: 65751 : if( index >= vertexList.size() )
258 : : {
259 [ # # ]: 0 : MSQ_SETERR( err )( "Invalid vertex handle", MsqError::INVALID_ARG );
260 : 0 : return;
261 : : }
262 : :
263 : 65751 : Vertex& vert = vertexList[index];
264 : :
265 [ - + ]: 65751 : if( !vert.adjacencies.empty() )
266 : : {
267 [ # # ]: 0 : MSQ_SETERR( err )( "Cannot overwrite referenced vertex", MsqError::INVALID_STATE );
268 : 0 : return;
269 : : }
270 : :
271 : 65751 : vert.coords = coords;
272 : 65751 : vert.fixed = fixed;
273 : 65751 : vert.valid = true;
274 : : }
275 : :
276 : 116306 : void MeshImplData::reset_element( size_t index, const std::vector< long >& vertices, EntityTopology topology,
277 : : MsqError& err )
278 : : {
279 [ - + ][ # # ]: 116306 : clear_element( index, err );MSQ_ERRRTN( err );
[ - + ]
280 [ - + ][ # # ]: 116306 : set_element( index, vertices, topology, err );MSQ_ERRRTN( err );
[ - + ]
281 : : }
282 : :
283 : 12 : void MeshImplData::reset_element( size_t index, const std::vector< size_t >& vertices, EntityTopology topology,
284 : : MsqError& err )
285 : : {
286 [ - + ][ # # ]: 12 : clear_element( index, err );MSQ_ERRRTN( err );
[ - + ]
287 [ - + ][ # # ]: 12 : set_element( index, vertices, topology, err );MSQ_ERRRTN( err );
[ - + ]
288 : : }
289 : :
290 : 116318 : void MeshImplData::clear_element( size_t index, MsqError& err )
291 : : {
292 [ - + ]: 116318 : if( index >= elementList.size() )
293 : : {
294 [ # # ]: 0 : MSQ_SETERR( err )( "Invalid element handle", MsqError::INVALID_ARG );
295 : 116318 : return;
296 : : }
297 : :
298 : 116318 : unsigned numvert = TopologyInfo::corners( elementList[index].topology );
299 [ - + ]: 116318 : if( numvert )
300 [ # # ]: 0 : for( unsigned i = numvert; i < elementList[index].connectivity.size(); ++i )
301 : 0 : --vertexList[elementList[index].connectivity[i]].midcount;
302 : :
303 : 116318 : std::vector< size_t >& conn = elementList[index].connectivity;
304 [ + - ][ + - ]: 116390 : for( std::vector< size_t >::iterator iter = conn.begin(); iter != conn.end(); ++iter )
[ + + ]
305 : : {
306 [ + - ][ + - ]: 72 : std::vector< size_t >& adj = vertexList[*iter].adjacencies;
307 [ # # ][ + - ]: 72 : for( std::vector< size_t >::iterator iter2 = adj.begin(); iter2 != adj.end(); ++iter2 )
[ + - ]
308 : : {
309 [ + - ][ + - ]: 72 : if( *iter2 == index )
310 : : {
311 [ + - ]: 72 : adj.erase( iter2 );
312 : 72 : break;
313 : : }
314 : : }
315 : : }
316 : 116318 : conn.clear();
317 : : }
318 : :
319 : 232612 : void MeshImplData::set_element( size_t index, const std::vector< long >& vertices, EntityTopology topology,
320 : : MsqError& err )
321 : : {
322 : : if( sizeof( long ) == sizeof( size_t ) )
323 : 116306 : set_element( index, *reinterpret_cast< const std::vector< size_t >* >( &vertices ), topology, err );
324 : : else
325 : : {
326 : : std::vector< size_t > conn( vertices.size() );
327 : : std::copy( vertices.begin(), vertices.end(), conn.begin() );
328 : : set_element( index, conn, topology, err );
329 : : }
330 : 116306 : }
331 : :
332 : 116318 : void MeshImplData::set_element( size_t index, const std::vector< size_t >& vertices, EntityTopology topology,
333 : : MsqError& err )
334 : : {
335 [ - + ]: 116318 : if( index >= elementList.size() )
336 : : {
337 [ # # ]: 0 : MSQ_SETERR( err )( "Invalid element handle", MsqError::INVALID_ARG );
338 : 0 : return;
339 : : }
340 : :
341 : 116318 : elementList[index].connectivity = vertices;
342 : 116318 : elementList[index].topology = topology;
343 : :
344 [ + - ][ + - ]: 588741 : for( std::vector< size_t >::const_iterator iter = vertices.begin(); iter != vertices.end(); ++iter )
[ + + ]
345 : : {
346 [ + - ][ + - ]: 472423 : if( !is_vertex_valid( *iter ) )
[ - + ]
347 : : {
348 [ # # ][ # # ]: 0 : MSQ_SETERR( err )( "Invalid vertex handle", MsqError::INVALID_ARG );
349 : 0 : return;
350 : : }
351 : :
352 [ + - ][ + - ]: 472423 : std::vector< size_t >& adj = vertexList[*iter].adjacencies;
353 [ + - ][ + - ]: 3556464 : for( std::vector< size_t >::iterator iter2 = adj.begin(); iter2 != adj.end(); ++iter2 )
[ + + ]
354 [ + - ][ - + ]: 3084041 : if( *iter2 == index ) return;
355 : :
356 [ + - ]: 472423 : adj.push_back( index );
357 : : }
358 : :
359 : 116318 : unsigned numvert = TopologyInfo::corners( elementList[index].topology );
360 [ + + ]: 116318 : if( numvert )
361 [ - + ]: 116318 : for( unsigned i = numvert; i < elementList[index].connectivity.size(); ++i )
362 : 0 : ++vertexList[elementList[index].connectivity[i]].midcount;
363 : : }
364 : :
365 : 0 : size_t MeshImplData::add_vertex( const Vector3D& coords, bool fixed, MsqError& err )
366 : : {
367 : : size_t index;
368 : :
369 [ # # ]: 0 : if( !deletedVertexList.empty() )
370 : : {
371 : 0 : index = deletedVertexList[deletedVertexList.size() - 1];
372 : 0 : deletedVertexList.pop_back();
373 : 0 : reset_vertex( index, coords, fixed, err );
374 [ # # ][ # # ]: 0 : MSQ_ERRZERO( err );
[ # # ]
375 : : }
376 : : else
377 : : {
378 : 0 : index = vertexList.size();
379 [ # # ]: 0 : vertexList.push_back( Vertex( coords, fixed ) );
380 : : }
381 : :
382 : 0 : return index;
383 : : }
384 : :
385 : 0 : size_t MeshImplData::add_element( const std::vector< long >& vertices, EntityTopology topology, MsqError& err )
386 : : {
387 : : size_t index;
388 [ # # ]: 0 : if( !deletedElementList.empty() )
389 : : {
390 : 0 : index = deletedElementList[deletedElementList.size() - 1];
391 : 0 : deletedElementList.pop_back();
392 : : }
393 : : else
394 : : {
395 : 0 : index = elementList.size();
396 : 0 : elementList.resize( elementList.size() + 1 );
397 : : }
398 : :
399 : 0 : set_element( index, vertices, topology, err );
400 [ # # ][ # # ]: 0 : MSQ_ERRZERO( err );
[ # # ]
401 : 0 : return index;
402 : : }
403 : :
404 : 0 : size_t MeshImplData::add_element( const std::vector< size_t >& vertices, EntityTopology topology, MsqError& err )
405 : : {
406 : : size_t index;
407 [ # # ]: 0 : if( !deletedElementList.empty() )
408 : : {
409 : 0 : index = deletedElementList[deletedElementList.size() - 1];
410 : 0 : deletedElementList.pop_back();
411 : : }
412 : : else
413 : : {
414 : 0 : index = elementList.size();
415 : 0 : elementList.resize( elementList.size() + 1 );
416 : : }
417 : :
418 : 0 : set_element( index, vertices, topology, err );
419 [ # # ][ # # ]: 0 : MSQ_ERRZERO( err );
[ # # ]
420 : 0 : return index;
421 : : }
422 : :
423 : 0 : void MeshImplData::delete_vertex( size_t index, MsqError& err )
424 : : {
425 [ # # ]: 0 : if( !is_vertex_valid( index ) )
426 : : {
427 [ # # ]: 0 : MSQ_SETERR( err )( "Invalid vertex handle", MsqError::INVALID_ARG );
428 : 0 : return;
429 : : }
430 : :
431 : 0 : vertexList[index].valid = false;
432 : 0 : deletedVertexList.push_back( index );
433 : : }
434 : :
435 : 0 : void MeshImplData::delete_element( size_t index, MsqError& err )
436 : : {
437 [ # # ][ # # ]: 0 : clear_element( index, err );MSQ_ERRRTN( err );
[ # # ]
438 : 0 : deletedElementList.push_back( index );
439 : : }
440 : :
441 : 0 : void MeshImplData::copy_mesh( size_t* vertex_handle_array, size_t* element_handle_array, size_t* element_conn_offsets,
442 : : size_t* element_conn_indices )
443 : : {
444 [ # # ]: 0 : std::vector< size_t > vertex_map( vertexList.size() );
445 : 0 : size_t vh_index = 0;
446 [ # # ]: 0 : for( size_t v = 0; v < vertexList.size(); ++v )
447 : : {
448 [ # # ][ # # ]: 0 : if( vertexList[v].valid
449 : : #ifdef SEPARATE_MID_NODES
450 : : && vertexList[v].midcount < vertexList[v].adjacencies.size()
451 : : #endif
452 : : )
453 : : {
454 : 0 : vertex_handle_array[vh_index] = v;
455 [ # # ]: 0 : vertex_map[v] = vh_index;
456 : 0 : ++vh_index;
457 : : }
458 : : else
459 : : {
460 [ # # ]: 0 : vertex_map[v] = vertexList.size();
461 : : }
462 : : }
463 : :
464 : 0 : size_t offset = 0;
465 [ # # ]: 0 : for( size_t e = 0; e < elementList.size(); ++e )
466 : : {
467 [ # # ]: 0 : Element& elem = elementList[e];
468 : : size_t cl;
469 : : #ifdef SEPARATE_MID_NODES
470 : : cl = TopologyInfo::corners( elem.topology );
471 : : if( !cl )
472 : : #endif
473 : 0 : cl = elem.connectivity.size();
474 [ # # ]: 0 : if( cl )
475 : : {
476 : 0 : *element_handle_array = e;
477 : 0 : ++element_handle_array;
478 : :
479 : 0 : *element_conn_offsets = offset;
480 : 0 : ++element_conn_offsets;
481 : 0 : offset += cl;
482 : :
483 : 0 : std::vector< size_t >::iterator conn = elem.connectivity.begin();
484 [ # # ]: 0 : std::vector< size_t >::iterator end = conn + cl;
485 [ # # ][ # # ]: 0 : while( conn != end )
486 : : {
487 [ # # ][ # # ]: 0 : *element_conn_indices = vertex_map[*conn];
488 : 0 : ++element_conn_indices;
489 [ # # ]: 0 : ++conn;
490 : : }
491 : : }
492 : : }
493 : 0 : *element_conn_offsets = offset;
494 : 0 : }
495 : :
496 : 0 : void MeshImplData::copy_higher_order( std::vector< size_t >& mid_nodes, std::vector< size_t >& vertices,
497 : : std::vector< size_t >& vertex_indices, std::vector< size_t >& index_offsets,
498 : : MsqError& err )
499 : : {
500 : 0 : mid_nodes.clear();
501 : 0 : vertices.clear();
502 : 0 : vertex_indices.clear();
503 : 0 : index_offsets.clear();
504 : :
505 : : // Create a map of from vertex handle to index in "vertices"
506 : : // Use vertexList.size() to mean uninitialized.
507 : : size_t v;
508 [ # # ]: 0 : std::vector< size_t > vert_map( vertexList.size() );
509 [ # # ]: 0 : for( v = 0; v < vertexList.size(); ++v )
510 [ # # ]: 0 : vert_map[v] = vertexList.size();
511 : :
512 : : // Loop over all mid-side vertices
513 [ # # ]: 0 : for( v = 0; v < vertexList.size(); ++v )
514 : : {
515 [ # # ]: 0 : const Vertex& vert = vertexList[v];
516 : :
517 : : // Not a mid-side vertex, skip it
518 [ # # ][ # # ]: 0 : if( !vert.valid || !vert.midcount ) continue;
519 : :
520 : : // Populate "verts" with the handles of all adjacent corner vertices
521 [ # # ]: 0 : assert( vert.adjacencies.size() ); // shouldn't be able to fail if vert.midcount > 0
522 [ # # ]: 0 : int elem_indx = vert.adjacencies[0];
523 [ # # ]: 0 : Element& elem = elementList[elem_indx];
524 : :
525 : : // Find index of node in elem's connectivity list
526 : : unsigned index;
527 [ # # ]: 0 : for( index = 0; index < elem.connectivity.size(); ++index )
528 [ # # ][ # # ]: 0 : if( elem.connectivity[index] == v ) break;
529 [ # # ]: 0 : if( index == elem.connectivity.size() )
530 : : {
531 [ # # ][ # # ]: 0 : MSQ_SETERR( err )( "Inconsistent data.", MsqError::INTERNAL_ERROR );
532 : 0 : return;
533 : : }
534 : :
535 : : // Given the index in the element's connectivity list,
536 : : // get the side of the element containing the mid-node.
537 : : unsigned side_dim, side_num;
538 [ # # ][ # # ]: 0 : TopologyInfo::side_number( elem.topology, elem.connectivity.size(), index, side_dim, side_num, err );MSQ_ERRRTN( err );
[ # # ][ # # ]
[ # # ][ # # ]
539 : :
540 [ # # ]: 0 : if( !side_dim ) // Not a mid-side node
541 : : {
542 [ # # ][ # # ]: 0 : MSQ_SETERR( err )( MsqError::INVALID_STATE, "Improperly connected mesh." );
543 : 0 : return;
544 : : }
545 : :
546 : : // Get the adjacent corner vertices from the element side.
547 : : unsigned num_corners;
548 : : const unsigned* corner_indices =
549 [ # # ][ # # ]: 0 : TopologyInfo::side_vertices( elem.topology, side_dim, side_num, num_corners, err );MSQ_ERRRTN( err );
[ # # ][ # # ]
[ # # ][ # # ]
550 : :
551 : : // Add the mid-side node to the output list
552 [ # # ]: 0 : mid_nodes.push_back( v );
553 : : // Store offset at which the indices of the corner
554 : : // vertices adjacent to this mid-side node will be
555 : : // stored in "vertex_indices".
556 [ # # ]: 0 : index_offsets.push_back( vertex_indices.size() );
557 : : // For each adjacent corner vertex, if the vertex is not
558 : : // already in "vertices" add it, and add the index to
559 : : // the adjacency list for this mid-side node.
560 [ # # ]: 0 : for( unsigned i = 0; i < num_corners; ++i )
561 : : {
562 [ # # ]: 0 : size_t vert_idx = elem.connectivity[corner_indices[i]];
563 [ # # ][ # # ]: 0 : assert( is_vertex_valid( vert_idx ) );
564 : :
565 [ # # ][ # # ]: 0 : if( vert_map[vert_idx] == vertexList.size() )
566 : : {
567 [ # # ]: 0 : vert_map[vert_idx] = vertices.size();
568 [ # # ]: 0 : vertices.push_back( vert_idx );
569 : : }
570 [ # # ][ # # ]: 0 : vertex_indices.push_back( vert_map[vert_idx] );
571 : : }
572 : : }
573 [ # # ][ # # ]: 0 : index_offsets.push_back( vertex_indices.size() );
574 : : }
575 : :
576 : 0 : bool MeshImplData::is_mid_node( size_t index ) const
577 : : {
578 [ # # ][ # # ]: 0 : return is_vertex_valid( index ) && vertexList[index].midcount > 0;
579 : : }
580 : :
581 : 0 : bool MeshImplData::is_corner_node( size_t index ) const
582 : : {
583 [ # # ][ # # ]: 0 : return is_vertex_valid( index ) && vertexList[index].midcount < vertexList[index].adjacencies.size();
584 : : }
585 : :
586 : 666 : void MeshImplData::all_vertices( std::vector< size_t >& list, MsqError& ) const
587 : : {
588 : 666 : list.clear();
589 [ + + ]: 387727 : for( size_t idx = 0; idx < vertexList.size(); ++idx )
590 [ + - ][ + - ]: 387061 : if( vertexList[idx].valid ) list.push_back( idx );
[ + - ]
591 : 666 : }
592 : :
593 : 598 : void MeshImplData::all_elements( std::vector< size_t >& list, MsqError& ) const
594 : : {
595 : 598 : list.clear();
596 [ + + ]: 909242 : for( size_t idx = 0; idx < elementList.size(); ++idx )
597 [ + - ][ + - ]: 908644 : if( !elementList[idx].connectivity.empty() ) list.push_back( idx );
[ + - ]
598 : 598 : }
599 : :
600 : 0 : void MeshImplData::get_adjacent_elements( std::vector< size_t >::const_iterator node_iter,
601 : : std::vector< size_t >::const_iterator node_end, std::vector< size_t >& elems,
602 : : MsqError& err )
603 : : {
604 [ # # ][ # # ]: 0 : if( node_iter == node_end || !is_vertex_valid( *node_iter ) )
[ # # ]
605 : : {
606 [ # # ]: 0 : MSQ_SETERR( err )( MsqError::INVALID_ARG );
607 : 0 : return;
608 : : }
609 : :
610 : : // Get list of elements adjacent to first node
611 : 0 : elems = vertexList[*node_iter].adjacencies;
612 : :
613 : : // For each aditional node, intersect elems with elements adjacent to node
614 [ # # ]: 0 : for( ++node_iter; node_iter != node_end; ++node_iter )
615 : : {
616 : 0 : std::vector< size_t >::iterator elem_iter = elems.begin();
617 [ # # ][ # # ]: 0 : while( elem_iter != elems.end() )
618 : : {
619 [ # # ][ # # ]: 0 : std::vector< size_t >::const_iterator adj_iter = vertexList[*node_iter].adjacencies.begin();
[ # # ]
620 [ # # ][ # # ]: 0 : const std::vector< size_t >::const_iterator adj_end = vertexList[*node_iter].adjacencies.end();
[ # # ]
621 [ # # ][ # # ]: 0 : for( ; adj_iter != adj_end; ++adj_iter )
[ # # ]
622 [ # # ][ # # ]: 0 : if( *elem_iter == *adj_iter ) break;
[ # # ]
623 : :
624 [ # # ][ # # ]: 0 : if( adj_iter == adj_end )
625 : : {
626 [ # # ][ # # ]: 0 : *elem_iter = elems[elems.size() - 1];
627 [ # # ]: 0 : elems.pop_back();
628 : : }
629 : : else
630 : : {
631 [ # # ]: 0 : ++elem_iter;
632 : : }
633 : : }
634 : : }
635 : : }
636 : :
637 : 0 : bool MeshImplData::has_adjacent_elements( size_t elem, const std::vector< size_t >& nodes, MsqError& err )
638 : : {
639 [ # # ]: 0 : std::vector< size_t > adj_elems;
640 [ # # ][ # # ]: 0 : const unsigned dim = TopologyInfo::dimension( elementList[elem].topology );
641 [ # # ]: 0 : get_adjacent_elements( nodes.begin(), nodes.end(), adj_elems, err );
642 : :
643 : 0 : std::vector< size_t >::iterator iter;
644 [ # # ][ # # ]: 0 : for( iter = adj_elems.begin(); iter != adj_elems.end(); ++iter )
[ # # ]
645 [ # # ][ # # ]: 0 : if( *iter != elem && TopologyInfo::dimension( elementList[*iter].topology ) == dim ) break;
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
646 : :
647 [ # # ]: 0 : return iter != adj_elems.end();
648 : : }
649 : :
650 : 0 : void MeshImplData::skin( std::vector< size_t >& sides, MsqError& err )
651 : : {
652 [ # # ]: 0 : std::vector< size_t > side_nodes;
653 : :
654 : : // For each element in mesh
655 [ # # ][ # # ]: 0 : for( size_t elem = 0; elem < elementList.size(); ++elem )
656 : : {
657 [ # # ][ # # ]: 0 : if( !is_element_valid( elem ) ) continue;
658 : :
659 : : // For each side of the element, check if there
660 : : // are any adjacent elements.
661 [ # # ]: 0 : const EntityTopology topo = elementList[elem].topology;
662 [ # # ]: 0 : std::vector< size_t >& conn = elementList[elem].connectivity;
663 [ # # # ]: 0 : switch( topo )
664 : : {
665 : : // For normal elements (not poly****)
666 : : default: {
667 [ # # ]: 0 : unsigned num = TopologyInfo::sides( topo );
668 [ # # ]: 0 : unsigned dim = TopologyInfo::dimension( topo ) - 1;
669 : : // For each side
670 [ # # ]: 0 : for( unsigned side = 0; side < num; ++side )
671 : : {
672 : : // Get list of vertices defining the side
673 : : unsigned count;
674 [ # # ][ # # ]: 0 : const unsigned* indices = TopologyInfo::side_vertices( topo, dim, side, count, err );MSQ_ERRRTN( err );
[ # # ][ # # ]
[ # # ][ # # ]
675 : 0 : side_nodes.clear();
676 [ # # ]: 0 : for( unsigned k = 0; k < count; ++k )
677 [ # # ][ # # ]: 0 : side_nodes.push_back( conn[indices[k]] );
678 : :
679 : : // If no adjacent element, add side to output list
680 [ # # ][ # # ]: 0 : bool adj = has_adjacent_elements( elem, side_nodes, err );MSQ_ERRRTN( err );
[ # # ][ # # ]
[ # # ][ # # ]
681 [ # # ]: 0 : if( !adj )
682 : : {
683 [ # # ]: 0 : sides.push_back( elem );
684 [ # # ]: 0 : sides.push_back( side );
685 : : }
686 : : }
687 : : }
688 : 0 : break;
689 : :
690 : : case POLYGON: {
691 [ # # ]: 0 : for( unsigned side = 0, next = 1; next < conn.size(); ++side, ++next )
692 : : {
693 : 0 : side_nodes.clear();
694 [ # # ][ # # ]: 0 : side_nodes.push_back( conn[side] );
695 [ # # ][ # # ]: 0 : side_nodes.push_back( conn[next] );
696 : :
697 : : // If no adjacent element, add side to output list
698 [ # # ][ # # ]: 0 : bool adj = has_adjacent_elements( elem, side_nodes, err );MSQ_ERRRTN( err );
[ # # ][ # # ]
[ # # ][ # # ]
699 [ # # ]: 0 : if( !adj )
700 : : {
701 [ # # ]: 0 : sides.push_back( elem );
702 [ # # ]: 0 : sides.push_back( side );
703 : : }
704 : : }
705 : : }
706 : 0 : break;
707 : :
708 : : case POLYHEDRON: {
709 [ # # ]: 0 : for( unsigned side = 0; side < conn.size(); ++side )
710 : : {
711 [ # # ][ # # ]: 0 : side_nodes = elementList[conn[side]].connectivity;
[ # # ]
712 : :
713 : : // If no adjacent element, add side to output list
714 [ # # ][ # # ]: 0 : bool adj = has_adjacent_elements( elem, side_nodes, err );MSQ_ERRRTN( err );
[ # # ][ # # ]
[ # # ][ # # ]
715 [ # # ]: 0 : if( !adj )
716 : : {
717 [ # # ]: 0 : sides.push_back( elem );
718 [ # # ]: 0 : sides.push_back( side );
719 : : }
720 : : }
721 : : }
722 : 0 : break;
723 : : } // switch(topo)
724 : 0 : } // for (elementList)
725 : : }
726 : :
727 [ # # ]: 0 : MeshImplVertIter::~MeshImplVertIter() {}
728 : :
729 : 0 : void MeshImplVertIter::restart()
730 : : {
731 : 0 : index = 0;
732 [ # # ]: 0 : if( !mesh->is_vertex_valid( index ) ) operator++();
733 : 0 : }
734 : :
735 : 0 : void MeshImplVertIter::operator++()
736 : : {
737 : 0 : ++index;
738 [ # # ][ # # ]: 0 : while( index < mesh->max_vertex_index() && ( !mesh->is_vertex_valid( index ) || !mesh->is_corner_node( index ) ) )
[ # # ][ # # ]
739 : 0 : ++index;
740 : 0 : }
741 : :
742 : 0 : Mesh::VertexHandle MeshImplVertIter::operator*() const
743 : : {
744 : 0 : return reinterpret_cast< Mesh::VertexHandle >( index );
745 : : }
746 : :
747 : 0 : bool MeshImplVertIter::is_at_end() const
748 : : {
749 : 0 : return index >= mesh->max_vertex_index();
750 : : }
751 : :
752 [ # # ]: 0 : MeshImplElemIter::~MeshImplElemIter() {}
753 : :
754 : 0 : void MeshImplElemIter::restart()
755 : : {
756 : 0 : index = 0;
757 [ # # ]: 0 : if( !mesh->is_element_valid( index ) ) operator++();
758 : 0 : }
759 : :
760 : 0 : void MeshImplElemIter::operator++()
761 : : {
762 : 0 : ++index;
763 [ # # ][ # # ]: 0 : while( index < mesh->max_element_index() && !mesh->is_element_valid( index ) )
[ # # ]
764 : 0 : ++index;
765 : 0 : }
766 : :
767 : 0 : Mesh::ElementHandle MeshImplElemIter::operator*() const
768 : : {
769 : 0 : return reinterpret_cast< Mesh::ElementHandle >( index );
770 : : }
771 : :
772 : 0 : bool MeshImplElemIter::is_at_end() const
773 : : {
774 : 0 : return index >= mesh->max_element_index();
775 : : }
776 : :
777 [ + - ][ + - ]: 128 : } // namespace MBMesquite
|