[MOAB-dev] r3131 - MOAB/trunk
kraftche at cae.wisc.edu
kraftche at cae.wisc.edu
Thu Sep 3 18:48:03 CDT 2009
Author: kraftche
Date: 2009-09-03 18:48:03 -0500 (Thu, 03 Sep 2009)
New Revision: 3131
Modified:
MOAB/trunk/MBWriteUtil.cpp
Log:
Fix issues in MBWriteUtil::gather_nodes_from_elements
- incorrect results for range containing multiple element types
- insufficient error checking (e.g. invalid elem/node handles)
- undefined behavior (probably segfault) if input range contains
handles for vertices or sets.
Modified: MOAB/trunk/MBWriteUtil.cpp
===================================================================
--- MOAB/trunk/MBWriteUtil.cpp 2009-09-03 23:42:42 UTC (rev 3130)
+++ MOAB/trunk/MBWriteUtil.cpp 2009-09-03 23:48:03 UTC (rev 3131)
@@ -26,11 +26,13 @@
#include "TagServer.hpp"
#include "AEntityFactory.hpp"
#include "MBTagConventions.hpp"
+#include "MBRangeSeqIntersectIter.hpp"
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <assert.h>
+#include <iostream>
#ifdef WIN32
# define stat _stat
@@ -502,7 +504,6 @@
{
return MB_NOT_IMPLEMENTED;
}
-
MBErrorCode MBWriteUtil::gather_nodes_from_elements(
@@ -511,10 +512,15 @@
MBRange& nodes
)
{
+ bool printed_warning = false;
if(elements.empty())
return MB_SUCCESS;
+ if (TYPE_FROM_HANDLE(elements.front()) <= MBVERTEX ||
+ TYPE_FROM_HANDLE(elements.back()) >= MBENTITYSET)
+ return MB_TYPE_OUT_OF_RANGE;
+
TagServer* tag_server = mMB->tag_server();
// see if we need to use our own marking tag
@@ -526,88 +532,78 @@
mMB->tag_create("__MBWriteUtil::exporting_nodes", 1, MB_TAG_BIT,
exporting_nodes_tag, NULL);
}
-
- MBRange::const_iterator range_iter = elements.begin();
- MBRange::const_iterator range_iter_end = elements.end();
-
- TypeSequenceManager::const_iterator seq_iter, seq_iter_end;
- MBEntityType current_type = TYPE_FROM_HANDLE(*range_iter);
-
- seq_iter = mMB->sequence_manager()->entity_map(current_type).begin();
- seq_iter_end = mMB->sequence_manager()->entity_map(current_type).end();
-
- // lets find the entity sequence which holds the first entity
- TypeSequenceManager::const_iterator seq_iter_lookahead = seq_iter;
- seq_iter_lookahead++;
- for( ; seq_iter_lookahead != seq_iter_end &&
- (*seq_iter_lookahead)->start_handle() < *range_iter; )
- {
- ++seq_iter;
- ++seq_iter_lookahead;
- }
-
- // a look ahead iterator
- MBRange::const_iterator range_iter_lookahead = range_iter;
-
// the x,y,z tag handles we need
MBEntityHandle lower_bound = ~0, upper_bound = 0;
- // our main loop
- for(; range_iter != range_iter_end && seq_iter != seq_iter_end; /* ++ is handled in loop*/ )
- {
- // find a range that fits in the current entity sequence
- for(; range_iter_lookahead != range_iter_end &&
- *range_iter_lookahead <= (*seq_iter)->end_handle();
- ++range_iter_lookahead)
- {}
+ std::vector<MBEntityHandle> tmp_conn;
- if(current_type != TYPE_FROM_HANDLE(*range_iter))
- {
- current_type = TYPE_FROM_HANDLE(*range_iter);
- seq_iter = mMB->sequence_manager()->entity_map(current_type).begin();
- seq_iter_end = mMB->sequence_manager()->entity_map(current_type).end();
-
- // lets find the entity sequence which holds the first entity of this type
- TypeSequenceManager::const_iterator seq_iter_lookahead = seq_iter;
- seq_iter_lookahead++;
- for( ; seq_iter_lookahead != seq_iter_end &&
- (*seq_iter_lookahead)->start_handle() < *range_iter; )
- {
- ++seq_iter;
- ++seq_iter_lookahead;
+ MBRangeSeqIntersectIter iter( mMB->sequence_manager() );
+ for (MBErrorCode rval = iter.init( elements.begin(), elements.end() );
+ MB_FAILURE != rval; rval = iter.step()) {
+ if (MB_ENTITY_NOT_FOUND == rval) {
+ if (!printed_warning) {
+ std::cerr << "Warning: ignoring invalid element handle(s) in gather_nodes_from_elements" << std::endl;
+ printed_warning = true;
}
+ continue;
}
+
+ ElementSequence* seq = static_cast<ElementSequence*>(iter.get_sequence());
- int i = static_cast<ElementSequence*>(*seq_iter)->nodes_per_element();
-
// get the connectivity array
- MBEntityHandle* conn_array = NULL;
- conn_array = static_cast<ElementSequence*>(*seq_iter)->get_connectivity_array();
+ const MBEntityHandle* conn_array = seq->get_connectivity_array();
+
+ // if unstructed mesh
+ if (conn_array) {
+ assert(iter.get_start_handle() >= seq->start_handle());
+ assert(iter.get_end_handle() <= seq->end_handle());
+ const MBEntityHandle offset = iter.get_start_handle() - seq->start_handle();
+ const MBEntityHandle num_elem = iter.get_end_handle() - iter.get_start_handle() + 1;
+
+ conn_array += offset * seq->nodes_per_element();
+ const MBEntityHandle num_node = num_elem * seq->nodes_per_element();
- MBEntityHandle start_handle = (*seq_iter)->start_handle();
-
- for(MBRange::const_iterator tmp_iter = range_iter;
- tmp_iter != range_iter_lookahead;
- ++tmp_iter)
- {
- // for each node
- for(int j=0; j<i; j++)
+ // for each node
+ for (MBEntityHandle j = 0; j < num_node; j++)
{
- MBEntityHandle node = *(conn_array + j + i*(*tmp_iter - start_handle));
+ MBEntityHandle node = conn_array[j];
if(node < lower_bound)
lower_bound = node;
if(node > upper_bound)
upper_bound = node;
unsigned char bit = 0x1;
- tag_server->set_data(exporting_nodes_tag, &node, 1, &bit);
+ rval = tag_server->set_data(exporting_nodes_tag, &node, 1, &bit);
+ assert(MB_SUCCESS == rval);
+ if (MB_SUCCESS != rval)
+ return rval;
}
}
+ // structured mesh
+ else {
+ for (MBEntityHandle h = iter.get_start_handle();
+ h < iter.get_end_handle(); ++h) {
+ tmp_conn.clear();
+ rval = seq->get_connectivity( h, tmp_conn, false );
+ if (MB_SUCCESS != rval) {
+ if(node_bit_mark_tag == 0)
+ mMB->tag_delete(exporting_nodes_tag);
+ return rval;
+ }
- // go to the next entity sequence
- ++seq_iter;
- // start with the next entities
- range_iter = range_iter_lookahead;
+ // for each node
+ for(size_t j=0; j<tmp_conn.size(); j++)
+ {
+ MBEntityHandle node = tmp_conn[j];
+ if(node < lower_bound)
+ lower_bound = node;
+ if(node > upper_bound)
+ upper_bound = node;
+ unsigned char bit = 0x1;
+ tag_server->set_data(exporting_nodes_tag, &node, 1, &bit);
+ }
+ }
+ }
}
// we can get a REALLY long loop if lower_bound is zero
@@ -624,9 +620,8 @@
// clean up our own marking tag
if(node_bit_mark_tag == 0)
mMB->tag_delete(exporting_nodes_tag);
-
+
return MB_SUCCESS;
-
}
//! assign ids to input elements starting with start_id, written to id_tag
More information about the moab-dev
mailing list