void generate_random_points( Interface& mb, size_t num_points, std::vector<CartVect>& points, std::vector<EntityHandle>& point_elems ) { Range elems; ErrorCode rval; rval = mb.get_entities_by_dimension( 0, 3, elems ); CHK(rval); if (!elems.all_of_type(MBHEX)) { std::cerr << "Warning: ignoring non-hexahedral elements." << std::endl; std::pair< Range::iterator, Range::iterator > p = elems.equal_range(MBHEX); elems.erase( p.second, elems.end() ); elems.erase( elems.begin(), p.first ); } if (elems.empty()) { std::cerr << "Input file contains no hexahedral elements." << std::endl; exit(1); } points.resize( num_points ); point_elems.resize( num_points ); const size_t num_elem = elems.size(); for (size_t i = 0; i < num_points; ++i) { size_t offset = 0; for (size_t x = num_elem; x > 0; x /= RAND_MAX) offset += rand(); offset %= num_elem; point_elems[i] = elems[offset]; points[i] = random_point_in_hex( mb, point_elems[i] ); } }
void remove_type( Range& range, EntityType t ) { std::pair<Range::iterator,Range::iterator> p = range.equal_range(t); range.erase( p.first, p.second ); }
ErrorCode TreeValidator::visit( EntityHandle node, int depth, bool& descend ) { ErrorCode rval; descend = true; Range contents; rval = instance->get_entities_by_handle( node, contents ); if (MB_SUCCESS != rval) return error(node, "Error getting contents of tree node. Corrupt tree?"); entity_count += contents.size(); if (surfaces) { // if no longer in subtree for previous surface, clear if (depth <= surface_depth) surface_depth = -1; EntityHandle surface = 0; Range::iterator surf_iter = contents.lower_bound( MBENTITYSET ); if (surf_iter != contents.end()) { surface = *surf_iter; contents.erase( surf_iter ); } if (surface) { if (surface_depth >=0) { ++multiple_surface_count; print( node, "Multiple surfaces in encountered in same subtree." ); } else { surface_depth = depth; surface_handle = surface; } } } std::vector<EntityHandle> children; rval = tool->get_moab_instance()->get_child_meshsets( node, children ); if (MB_SUCCESS != rval || (!children.empty() && children.size() != 2)) return error(node, "Error getting children. Corrupt tree?"); OrientedBox box; rval = tool->box( node, box ); if (MB_SUCCESS != rval) return error(node, "Error getting oriented box from tree node. Corrupt tree?"); if (children.empty() && contents.empty()) { ++empty_leaf_count; print( node, "Empty leaf node.\n" ); } else if (!children.empty() && !contents.empty()) { ++non_empty_non_leaf_count; print( node, "Non-leaf node is not empty." ); } if (surfaces && children.empty() && surface_depth < 0) { ++missing_surface_count; print( node, "Reached leaf node w/out encountering any surface set."); } double dot_epsilon = epsilon*(box.axis[0]+box.axis[1]+box.axis[2]).length(); if (box.axis[0] % box.axis[1] > dot_epsilon || box.axis[0] % box.axis[2] > dot_epsilon || box.axis[1] % box.axis[2] > dot_epsilon ) { ++non_ortho_count; print (node, "Box axes are not orthogonal"); } if (!children.empty()) { for (int i = 0; i < 2; ++i) { OrientedBox other_box; rval = tool->box( children[i], other_box ); if (MB_SUCCESS != rval) return error( children[i], " Error getting oriented box from tree node. Corrupt tree?" ); // else if (!box.contained( other_box, epsilon )) { // ++child_outside_count; // print( children[i], "Parent box does not contain child box." ); // char string[64]; // sprintf(string, " Volume ratio is %f", other_box.volume()/box.volume() ); // print( children [i], string ); // } else { double vol_ratio = other_box.volume()/box.volume(); if (vol_ratio > 2.0) { char string[64]; sprintf(string, "child/parent volume ratio is %f", vol_ratio ); print( children[i], string ); sprintf(string, " child/parent area ratio is %f", other_box.area()/box.area() ); print( children[i], string ); } } } } bool bad_element = false; bool bad_element_handle = false; bool bad_element_conn = false; bool duplicate_element = false; int num_outside = 0; bool boundary[6] = { false, false, false, false, false, false }; for (Range::iterator it = contents.begin(); it != contents.end(); ++it) { EntityType type = instance->type_from_handle( *it ); int dim = CN::Dimension( type ); if (dim != 2) { bad_element = true; continue; } const EntityHandle* conn; int conn_len; rval = instance->get_connectivity( *it, conn, conn_len ); if (MB_SUCCESS != rval) { bad_element_handle = true; continue; } std::vector<CartVect> coords(conn_len); rval = instance->get_coords( conn, conn_len, coords[0].array() ); if (MB_SUCCESS != rval) { bad_element_conn = true; continue; } bool outside = false; for (std::vector<CartVect>::iterator j = coords.begin(); j != coords.end(); ++j) { if (!box.contained( *j, epsilon )) outside = true; else for (int d = 0; d < 3; ++d) { #if MB_ORIENTED_BOX_UNIT_VECTORS double n = box.axis[d] % (*j - box.center); if (fabs(n - box.length[d]) <= epsilon) boundary[2*d] = true; if (fabs(n + box.length[d]) <= epsilon) boundary[2*d+1] = true; #else double ln = box.axis[d].length(); CartVect v1 = *j - box.center - box.axis[d]; CartVect v2 = *j - box.center + box.axis[d]; if (fabs(v1 % box.axis[d]) <= ln * epsilon) boundary[2*d] = true; if (fabs(v2 % box.axis[d]) <= ln * epsilon) boundary[2*d+1] = true; #endif } } if (outside) ++num_outside; if (!seen.insert(*it).second) { duplicate_element = true; ++duplicate_entity_count; } } CartVect alength( box.axis[0].length(), box.axis[1].length(), box.axis[2].length() ); #if MB_ORIENTED_BOX_UNIT_VECTORS CartVect length = box.length; #else CartVect length = alength; #endif if (length[0] > length[1] || length[0] > length[2] || length[1] > length[2]) { ++unsorted_axis_count; print( node, "Box axes are not ordered from shortest to longest." ); } #if MB_ORIENTED_BOX_UNIT_VECTORS if (fabs(alength[0] - 1.0) > epsilon || fabs(alength[1] - 1.0) > epsilon || fabs(alength[2] - 1.0) > epsilon) { ++non_unit_count; print( node, "Box axes are not unit vectors."); } #endif #if MB_ORIENTED_BOX_OUTER_RADIUS if (fabs(length.length() - box.radius) > tolerance) { ++bad_outer_radius_count; print( node, "Box has incorrect outer radius."); } #endif if (depth+1 < settings.max_depth && contents.size() > (unsigned)(4*settings.max_leaf_entities)) { char string[64]; sprintf(string, "leaf at depth %d with %u entities", depth, (unsigned)contents.size() ); print( node, string ); } bool all_boundaries = true; for (int f = 0; f < 6; ++f) all_boundaries = all_boundaries && boundary[f]; if (bad_element) { ++entity_invalid_count; print( node, "Set contained an entity with an inappropriate dimension." ); } if (bad_element_handle) { ++error_count; print( node, "Error querying face contained in set."); } if (bad_element_conn) { ++error_count; print( node, "Error querying connectivity of element."); } if (duplicate_element) { print( node, "Elements occur in multiple leaves of tree."); } if (num_outside > 0) { ++entity_outside_count; num_entities_outside += num_outside; if (printing) stream << instance->id_from_handle( node ) << ": " << num_outside << " elements outside box." << std::endl; } else if (!all_boundaries && !contents.empty()) { ++loose_box_count; print( node, "Box does not fit contained elements tightly." ); } return MB_SUCCESS; }
ErrorCode WriteVtk::gather_mesh(const EntityHandle* set_list, int num_sets, Range& nodes, Range& elems) { ErrorCode rval; int e; if (!set_list || !num_sets) { Range a; rval = mbImpl->get_entities_by_handle(0, a); if (MB_SUCCESS != rval) return rval; Range::const_iterator node_i, elem_i, set_i; node_i = a.lower_bound(a.begin(), a.end(), CREATE_HANDLE( MBVERTEX, 0, e)); elem_i = a.lower_bound( node_i, a.end(), CREATE_HANDLE( MBEDGE, 0, e)); set_i = a.lower_bound( elem_i, a.end(), CREATE_HANDLE(MBENTITYSET, 0, e)); nodes.merge(node_i, elem_i); elems.merge(elem_i, set_i); // Filter out unsupported element types EntityType et = MBEDGE; for (et++; et < MBENTITYSET; et++) { if (VtkUtil::get_vtk_type(et, CN::VerticesPerEntity(et))) continue; Range::iterator eit = elems.lower_bound(elems.begin(), elems.end(), CREATE_HANDLE(et, 0, e)), ep1it = elems.lower_bound(elems.begin(), elems.end(), CREATE_HANDLE(et + 1, 0, e)); elems.erase(eit, ep1it); } } else { std::set<EntityHandle> visited; std::vector<EntityHandle> sets; sets.reserve(num_sets); std::copy(set_list, set_list + num_sets, std::back_inserter(sets)); while (!sets.empty()) { // Get next set EntityHandle set = sets.back(); sets.pop_back(); // Skip sets we've already done if (!visited.insert(set).second) continue; Range a; rval = mbImpl->get_entities_by_handle(set, a); if (MB_SUCCESS != rval) return rval; Range::const_iterator node_i, elem_i, set_i; node_i = a.lower_bound(a.begin(), a.end(), CREATE_HANDLE( MBVERTEX, 0, e)); elem_i = a.lower_bound( node_i, a.end(), CREATE_HANDLE( MBEDGE, 0, e)); set_i = a.lower_bound( elem_i, a.end(), CREATE_HANDLE(MBENTITYSET, 0, e)); nodes.merge(node_i, elem_i); elems.merge(elem_i, set_i); std::copy(set_i, a.end(), std::back_inserter(sets)); a.clear(); rval = mbImpl->get_child_meshsets(set, a); std::copy(a.begin(), a.end(), std::back_inserter(sets)); } for (Range::const_iterator ei = elems.begin(); ei != elems.end(); ++ei) { std::vector<EntityHandle> connect; rval = mbImpl->get_connectivity(&(*ei), 1, connect); if (MB_SUCCESS != rval) return rval; for (unsigned int i = 0; i < connect.size(); ++i) nodes.insert(connect[i]); } } if (nodes.empty()) { MB_SET_ERR(MB_ENTITY_NOT_FOUND, "Nothing to write"); } return MB_SUCCESS; }