MOAB: Mesh Oriented datABase
(version 5.4.1)
|
00001 /** 00002 * MOAB, a Mesh-Oriented datABase, is a software component for creating, 00003 * storing and accessing finite element mesh data. 00004 * 00005 * Copyright 2004 Sandia Corporation. Under the terms of Contract 00006 * DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government 00007 * retains certain rights in this software. 00008 * 00009 * This library is free software; you can redistribute it and/or 00010 * modify it under the terms of the GNU Lesser General Public 00011 * License as published by the Free Software Foundation; either 00012 * version 2.1 of the License, or (at your option) any later version. 00013 * 00014 */ 00015 00016 #ifndef MOAB_SKINNER_HPP 00017 #define MOAB_SKINNER_HPP 00018 00019 #include "moab/Forward.hpp" 00020 #include "moab/Range.hpp" 00021 #include <vector> 00022 00023 namespace moab 00024 { 00025 00026 class ScdBox; 00027 00028 /** \class Skinner 00029 * \brief Class for constructing and querying skin of a mesh 00030 * Class for constructing and querying skin of a mesh, defined as the outside lower-dimensional 00031 * boundary of a mesh or a given set of entities. This class provides options for finding the 00032 * forward- and reverse-oriented members of the skin. Several methods are available for computing 00033 * the skin, e.g. using geometric topology sets, vertex-entity adjacencies, or directly from 00034 * (n-1)-dimensional entities. 00035 */ 00036 class Skinner 00037 { 00038 00039 enum direction 00040 { 00041 FORWARD = 1, 00042 REVERSE = -1 00043 }; 00044 00045 protected: 00046 //! the MB instance that this works with 00047 Interface* thisMB; 00048 00049 Tag mDeletableMBTag; 00050 Tag mAdjTag; 00051 int mTargetDim; 00052 00053 public: 00054 //! constructor, takes mdb instance 00055 Skinner( Interface* mdb ) : thisMB( mdb ), mDeletableMBTag( 0 ), mAdjTag( 0 ), mTargetDim( 0 ) {} 00056 00057 //! destructor 00058 ~Skinner(); 00059 00060 ErrorCode find_geometric_skin( const EntityHandle meshset, Range& forward_target_entities ); 00061 00062 /**\brief will accept entities all of one dimension and 00063 * return entities of n-1 dimension; NOTE: get_vertices argument controls whether 00064 * vertices or entities of n-1 dimension are returned, and only one of these is allowed 00065 * (i.e. this function returns only vertices or (n-1)-dimensional entities, but not both) 00066 * \param entities The elements for which to find the skin 00067 * \param get_vertices If true, vertices on the skin are returned 00068 * in the range, otherwise elements are returned 00069 * \param output_handles Range holding skin entities returned 00070 * \param output_reverse_handles Range holding entities on skin which 00071 * are reversed wrt entities 00072 * \param create_vert_elem_adjs If true, this function will cause 00073 * vertex-element adjacencies to be generated 00074 * \param create_skin_elements If true, this function will cause creation 00075 * of skin entities, otherwise only skin entities already extant 00076 * will be returned 00077 */ 00078 ErrorCode find_skin( const EntityHandle meshset, 00079 const Range& entities, 00080 bool get_vertices, 00081 Range& output_handles, 00082 Range* output_reverse_handles = 0, 00083 bool create_vert_elem_adjs = false, 00084 bool create_skin_elements = true, 00085 bool look_for_scd = false ); 00086 00087 /**\brief will accept entities all of one dimension and 00088 * return entities of n-1 dimension; NOTE: get_vertices argument controls whether 00089 * vertices or entities of n-1 dimension are returned, and only one of these is allowed 00090 * (i.e. this function returns only vertices or (n-1)-dimensional entities, but not both) 00091 * \param entities Pointer to elements for which to find the skin 00092 * \param num_entities Number of entities in vector 00093 * \param get_vertices If true, vertices on the skin are returned 00094 * in the range, otherwise elements are returned 00095 * \param output_handles Range holding skin entities returned 00096 * \param output_reverse_handles Range holding entities on skin which 00097 * are reversed wrt entities 00098 * \param create_vert_elem_adjs If true, this function will cause 00099 * vertex-element adjacencies to be generated 00100 * \param create_skin_elements If true, this function will cause creation 00101 * of skin entities, otherwise only skin entities already extant 00102 * will be returned 00103 */ 00104 ErrorCode find_skin( const EntityHandle this_set, 00105 const EntityHandle* entities, 00106 int num_entities, 00107 bool get_vertices, 00108 Range& output_handles, 00109 Range* output_reverse_handles = 0, 00110 bool create_vert_elem_adjs = false, 00111 bool create_skin_elements = true, 00112 bool look_for_scd = false ); 00113 00114 /**\brief get skin entities of prescribed dimension 00115 * \param entities The elements for which to find the skin 00116 * \param dim Dimension of skin entities requested 00117 * \param skin_entities Range holding skin entities returned 00118 * \param create_vert_elem_adjs If true, this function will cause 00119 * vertex-element adjacencies to be generated 00120 */ 00121 ErrorCode find_skin( const EntityHandle this_set, 00122 const Range& entities, 00123 int dim, 00124 Range& skin_entities, 00125 bool create_vert_elem_adjs = false, 00126 bool create_skin_elements = true ); 00127 00128 ErrorCode classify_2d_boundary( const Range& boundary, 00129 const Range& bar_elements, 00130 EntityHandle boundary_edges, 00131 EntityHandle inferred_edges, 00132 EntityHandle non_manifold_edges, 00133 EntityHandle other_edges, 00134 int& number_boundary_nodes ); 00135 00136 //! given a skin of dimension 2, will classify and return edges 00137 //! as boundary, inferred, and non-manifold, and the rest (other) 00138 ErrorCode classify_2d_boundary( const Range& boundary, 00139 const Range& mesh_1d_elements, 00140 Range& boundary_edges, 00141 Range& inferred_edges, 00142 Range& non_manifold_edges, 00143 Range& other_edges, 00144 int& number_boundary_nodes ); 00145 00146 protected: 00147 ErrorCode initialize(); 00148 00149 ErrorCode deinitialize(); 00150 00151 ErrorCode find_skin_noadj( const Range& source_entities, 00152 Range& forward_target_entities, 00153 Range& reverse_target_entities ); 00154 00155 ErrorCode add_adjacency( EntityHandle entity ); 00156 00157 void add_adjacency( EntityHandle entity, const EntityHandle* conn, const int num_nodes ); 00158 00159 ErrorCode remove_adjacency( EntityHandle entity ); 00160 00161 bool entity_deletable( EntityHandle entity ); 00162 00163 void find_match( EntityType type, 00164 const EntityHandle* conn, 00165 const int num_nodes, 00166 EntityHandle& match, 00167 Skinner::direction& direct ); 00168 00169 bool connectivity_match( const EntityHandle* conn1, 00170 const EntityHandle* conn2, 00171 const int num_verts, 00172 Skinner::direction& direct ); 00173 00174 void find_inferred_edges( Range& skin_boundary, 00175 Range& candidate_edges, 00176 Range& inferred_edges, 00177 double reference_angle_degrees ); 00178 00179 bool has_larger_angle( EntityHandle& entity1, EntityHandle& entity2, double reference_angle_cosine ); 00180 00181 /**\brief Find vertices on the skin of a set of mesh entities. 00182 *\param entities The elements for which to find the skin. Range 00183 * may NOT contain vertices, polyhedra, or entity sets. 00184 * All elements in range must be of the same dimension. 00185 *\param skin_verts Output: the vertices on the skin. 00186 *\param skin_elems Optional output: elements representing sides of entities 00187 * that are on the skin 00188 *\param create_if_missing If skin_elemts is non-null and this is true, 00189 * create new elements representing the sides of 00190 * entities on the skin. If this is false, skin_elems 00191 * will contain only those skin elements that already 00192 * exist. 00193 */ 00194 ErrorCode find_skin_vertices( const EntityHandle this_set, 00195 const Range& entities, 00196 Range* skin_verts = 0, 00197 Range* skin_elems = 0, 00198 Range* rev_elems = 0, 00199 bool create_if_missing = true, 00200 bool corners_only = false ); 00201 00202 /**\brief Skin edges 00203 * 00204 * Return any vertices adjacent to exactly one of the input edges. 00205 */ 00206 ErrorCode find_skin_vertices_1D( Tag tag, const Range& edges, Range& skin_verts ); 00207 00208 /**\brief Skin faces 00209 * 00210 * For the set of face sides (logical edges), return 00211 * vertices on such sides and/or edges equivalent to such sides. 00212 *\param faces Set of toplogically 2D entities to skin. 00213 *\param skin_verts If non-NULL, skin vertices will be added to this container. 00214 *\param skin_edges If non-NULL, skin edges will be added to this container 00215 *\param reverse_edges If skin_edges is not NULL and this is not NULL, then 00216 * any existing skin edges that are reversed with respect 00217 * to the skin side will be placed in this range instead of 00218 * skin_edges. Note: this argument is ignored if skin_edges 00219 * is NULL. 00220 *\param create_edges If true, edges equivalent to face sides on the skin 00221 * that don't already exist will be created. Note: this 00222 * parameter is honored regardless of whether or not skin 00223 * edges or vertices are returned. 00224 *\param corners_only If true, only skin vertices that correspond to the 00225 * corners of sides will be returned (i.e. no higher-order 00226 * nodes.) This argument is ignored if skin_verts is NULL. 00227 */ 00228 ErrorCode find_skin_vertices_2D( const EntityHandle this_set, 00229 Tag tag, 00230 const Range& faces, 00231 Range* skin_verts = 0, 00232 Range* skin_edges = 0, 00233 Range* reverse_edges = 0, 00234 bool create_edges = false, 00235 bool corners_only = false ); 00236 00237 /**\brief Skin volume mesh 00238 * 00239 * For the set of element sides (logical faces), return 00240 * vertices on such sides and/or faces equivalent to such sides. 00241 *\param entities Set of toplogically 3D entities to skin. 00242 *\param skin_verts If non-NULL, skin vertices will be added to this container. 00243 *\param skin_faces If non-NULL, skin faces will be added to this container 00244 *\param reverse_faces If skin_faces is not NULL and this is not NULL, then 00245 * any existing skin faces that are reversed with respect 00246 * to the skin side will be placed in this range instead of 00247 * skin_faces. Note: this argument is ignored if skin_faces 00248 * is NULL. 00249 *\param create_faces If true, face equivalent to sides on the skin 00250 * that don't already exist will be created. Note: this 00251 * parameter is honored regardless of whether or not skin 00252 * faces or vertices are returned. 00253 *\param corners_only If true, only skin vertices that correspond to the 00254 * corners of sides will be returned (i.e. no higher-order 00255 * nodes.) This argument is ignored if skin_verts is NULL. 00256 */ 00257 ErrorCode find_skin_vertices_3D( const EntityHandle this_set, 00258 Tag tag, 00259 const Range& entities, 00260 Range* skin_verts = 0, 00261 Range* skin_faces = 0, 00262 Range* reverse_faces = 0, 00263 bool create_faces = false, 00264 bool corners_only = false ); 00265 00266 ErrorCode create_side( const EntityHandle this_set, 00267 EntityHandle element, 00268 EntityType side_type, 00269 const EntityHandle* side_corners, 00270 EntityHandle& side_elem_handle_out ); 00271 00272 bool edge_reversed( EntityHandle face, const EntityHandle edge_ends[2] ); 00273 bool face_reversed( EntityHandle region, const EntityHandle* face_conn, EntityType face_type ); 00274 00275 //! look for structured box comprising source_entities, and if one is found use 00276 //! structured information to find the skin 00277 ErrorCode find_skin_scd( const Range& source_entities, 00278 bool get_vertices, 00279 Range& output_handles, 00280 bool create_skin_elements ); 00281 00282 //! skin a structured box, taking advantage of structured information 00283 ErrorCode skin_box( ScdBox* box, bool get_vertices, Range& output_handles, bool create_skin_elements ); 00284 }; 00285 00286 inline ErrorCode Skinner::find_skin( const EntityHandle this_set, 00287 const EntityHandle* entities, 00288 int num_entities, 00289 bool get_vertices, 00290 Range& output_handles, 00291 Range* output_reverse_handles, 00292 bool create_vert_elem_adjs, 00293 bool create_skin_elements, 00294 bool look_for_scd ) 00295 { 00296 Range ents; 00297 std::copy( entities, entities + num_entities, range_inserter( ents ) ); 00298 return find_skin( this_set, ents, get_vertices, output_handles, output_reverse_handles, create_vert_elem_adjs, 00299 create_skin_elements, look_for_scd ); 00300 } 00301 00302 } // namespace moab 00303 00304 #endif