1 /* ***************************************************************** 2 MESQUITE -- The Mesh Quality Improvement Toolkit 3 4 Copyright 2007 Sandia National Laboratories. Developed at the 5 University of Wisconsin--Madison under SNL contract number 6 624796. The U.S. Government and the University of Wisconsin 7 retain certain rights to 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 (2007) kraftche@cae.wisc.edu 24 25 ***************************************************************** */ 26 27 28 /** \file MsqIMesh.hpp 29 * \brief Adaptor for ITAPS iMesh interface 30 * \author Jason Kraftcheck 31 */ 32 33 #ifndef MSQ_I_MESH_HPP 34 #define MSQ_I_MESH_HPP 35 36 #include "MeshInterface.hpp" 37 #include "iMesh.h" 38 39 namespace MBMesquite { 40 41 /** The name of the tag (integer) that Mesquite will use 42 * to store internal data 43 */ 44 const char* const VERTEX_BYTE_TAG_NAME = "MesquiteVertexByte"; 45 46 /**\class MsqIMesh 47 *\brief Mesquite iMesh Adapter 48 * 49 * Adpater for interfacing Mesquite with an application that provides 50 * the ITAPS iMesh interface for interacting with mesh data. 51 */ 52 class MsqIMesh : virtual public MBMesquite::Mesh 53 { 54 public: 55 //********* Functions that are NOT inherited ************ 56 57 MsqIMesh(); 58 virtual ~MsqIMesh(); 59 60 /**\brief Create iMesh adaptor instance 61 *\param imesh The iMesh instance to interact with 62 *\param meshset The set of elements for which to optimize the quality 63 * 64 *\param element_dimension Optimize the subset of the elements in 65 * 'meshset' with this dimension. Pass iBase_ALL_TYPES 66 * for both iBase_FACE and iBase_REGION elements. 67 * If 'meshset' is the root set, then this argument is 68 * typically either iBase_FACE or iBase_REGION. 69 * 70 *\param fixed_tag A pointer to the tag handle designating a tag 71 * containing fixed flags for vertices. The tag must 72 * have size==1 and type==iBase_INTEGER or iBase_BYTES. 73 * A value of one for a vertex indicates that the vertex 74 * position is fixed. A value of zero indicates a free 75 * vertex (a vertex that Mesquite may move to improve 76 * mesh quality.) If this tag is not specified, then 77 * the boundary constraints of the optimization must be 78 * specified using an MsqIRel instance. 79 * 80 *\param slaved_tag A pointer to the tag handle designating a tag 81 * containing slaved flags for vertices. The tag must 82 * have size==1 and type==iBase_INTEGER or iBase_BYTES. 83 * This tag value is ignored for corner vertices of 84 * elements. The concept of 'slaved' is applicable only 85 * to non-corner vertices in higher-order elements. A 86 * value of one for a vertex indicates that the vertex 87 * position should is a fucntion of the element shape 88 * function, while a zero value indicates that the 89 * element shape function is a function of the vertex 90 * position. 91 */ 92 MsqIMesh( iMesh_Instance imesh, 93 iBase_EntitySetHandle meshset, 94 iBase_EntityType element_dimension, 95 MsqError& err, 96 const iBase_TagHandle* fixed_tag = 0, 97 const iBase_TagHandle* slaved_tag= 0 ); 98 99 /**\brief Create iMesh adaptor instance 100 * 101 * This constructor is provided for the creation of an MsqIMesh instance 102 * that is to be re-used for multiple optimization calls for different 103 * sets of elements. set_active_set must be called to define the 104 * subset of the mesh to optimize before an instance constructed with 105 * this constructor may be used in an optimization. 106 * 107 *\param imesh The iMesh instance to interact with 108 * 109 *\param element_dimension Optimize the subset of the elements in 110 * root set with this dimension. Pass iBase_ALL_TYPES 111 * for both iBase_FACE and iBase_REGION elements. 112 * If 'meshset' is the root set, then this argument is 113 * typically either iBase_FACE or iBase_REGION. 114 * 115 *\param fixed_tag A pointer to the tag handle designating a tag 116 * containing fixed flags for vertices. The tag must 117 * have size==1 and type==iBase_INTEGER or iBase_BYTES. 118 * A value of one for a vertex indicates that the vertex 119 * position is fixed. A value of zero indicates a free 120 * vertex (a vertex that Mesquite may move to improve 121 * mesh quality.) If this tag is not specified, then 122 * the boundary constraints of the optimization must be 123 * specified using an MsqIRel instance. 124 * 125 *\param slaved_tag A pointer to the tag handle designating a tag 126 * containing slaved flags for vertices. The tag must 127 * have size==1 and type==iBase_INTEGER or iBase_BYTES. 128 * This tag value is ignored for corner vertices of 129 * elements. The concept of 'slaved' is applicable only 130 * to non-corner vertices in higher-order elements. A 131 * value of one for a vertex indicates that the vertex 132 * position should is a fucntion of the element shape 133 * function, while a zero value indicates that the 134 * element shape function is a function of the vertex 135 * position. 136 */ 137 MsqIMesh( iMesh_Instance imesh, 138 iBase_EntityType element_dimension, 139 MsqError& err, 140 const iBase_TagHandle* fixed_tag = 0, 141 const iBase_TagHandle* slaved_tag= 0 ); 142 143 /** \brief set mesh to be smoothed. 144 * 145 * Set the mesh which Mesquite is to smooth. Optionally 146 * specify fixed vertices. 147 * NOTE: If an active set is not specified, the default 148 * is to use the global set (the ENTIRE mesh.) 149 * 150 *\param element_set ITAPS entity set handle for set containing 151 * mesh elements and vertices for which quality 152 * is to be improved. 153 */ 154 void set_active_set( iBase_EntitySetHandle meshset, 155 iBase_EntityType element_dimension, 156 MsqError& err ); 157 158 void set_fixed_tag( iBase_TagHandle tag, MsqError& err ); //!< Set tag for vertex fixed flag 159 void set_slaved_tag( iBase_TagHandle tag, MsqError& err );//!< Set tag for vertex slaved flag 160 void clear_fixed_tag(); //!< No tag for vertex fixed flag 161 void clear_slaved_tag(); //!< No tag for vertex fixed flag 162 const iBase_TagHandle* get_fixed_tag() const; //!< Get tag for vertex fixed flag 163 const iBase_TagHandle* get_slaved_tag() const; //!< Get tag for vertex slaved flag 164 165 virtual iMesh_Instance get_imesh_instance() const; 166 virtual iBase_EntitySetHandle get_entity_set() const; 167 168 //********* Functions that ARE inherited ************ 169 170 /**\brief Get dimension of vertex coordinates (2D vs. 3D). */ 171 virtual int get_geometric_dimension(MBMesquite::MsqError &/*err*/); 172 173 /** \brief Get handles for all elemnents */ 174 virtual void get_all_elements( std::vector<ElementHandle>& elements, 175 MsqError& err ); 176 177 /** \brief Get handles for all vertices */ 178 virtual void get_all_vertices( std::vector<VertexHandle>& vertices, 179 MsqError& err ); 180 181 /**\brief Query "fixed" flag for a vertex */ 182 virtual void vertices_get_fixed_flag( const VertexHandle vert_array[], 183 std::vector<bool>& fixed_flag_array, 184 size_t num_vtx, 185 MsqError &err); 186 187 virtual void vertices_get_slaved_flag( const VertexHandle vert_array[], 188 std::vector<bool>& slaved_flag_array, 189 size_t num_vtx, 190 MsqError &err ); 191 192 /**\brief Get vertex coordinates */ 193 virtual void vertices_get_coordinates( const VertexHandle vert_array[], 194 MsqVertex* coordinates, 195 size_t num_vtx, 196 MsqError &err); 197 /**\brief Set vertex coordinates */ 198 virtual void vertex_set_coordinates( VertexHandle vertex, 199 const Vector3D &coordinates, 200 MsqError &err); 201 202 /**\brief Set vertex mark */ 203 virtual void vertex_set_byte( VertexHandle vertex, 204 unsigned char byte, 205 MsqError &err); 206 /**\brief Set vertex mark */ 207 virtual void vertices_set_byte( const VertexHandle *vert_array, 208 const unsigned char *byte_array, 209 size_t array_size, 210 MsqError &err); 211 212 /**\brief Get vertex mark */ 213 virtual void vertex_get_byte( VertexHandle vertex, 214 unsigned char *byte, 215 MsqError &err); 216 /**\brief Get vertex mark */ 217 virtual void vertices_get_byte( const VertexHandle *vert_array, 218 unsigned char *byte_array, 219 size_t array_size, 220 MsqError &err); 221 222 /**\brief Get vertex-to-element adjacencies */ 223 virtual void vertices_get_attached_elements( const VertexHandle* vertex_array, 224 size_t num_vertices, 225 std::vector<ElementHandle>& elements, 226 std::vector<size_t>& offsets, 227 MsqError& err ); 228 229 /**\brief Get element connectivity */ 230 virtual void elements_get_attached_vertices( const ElementHandle *elem_handles, 231 size_t num_elems, 232 std::vector<VertexHandle>& vertices, 233 std::vector<size_t>& offsets, 234 MsqError& err ); 235 236 237 /**\brief Return topology type enum for an array of elements */ 238 virtual void elements_get_topologies( const ElementHandle *element_handle_array, 239 EntityTopology *element_topologies, 240 size_t num_elements, 241 MsqError &err ); 242 243 //**************** Memory Management **************** 244 /**\brief no-op */ 245 virtual void release_entity_handles( const EntityHandle *handle_array, 246 size_t num_handles, 247 MsqError &err ); 248 249 // Instead of deleting a Mesh when you think you are done, 250 // call release(). In simple cases, the implementation could 251 // just call the destructor. More sophisticated implementations 252 // may want to keep the Mesh object to live longer than Mesquite 253 // is using it. 254 virtual void release(); 255 256 //*************** Tags *********** 257 258 /** \brief Create a tag 259 * 260 * Create a user-defined data type that can be attached 261 * to any element or vertex in the mesh. For an opaque or 262 * undefined type, use type=BYTE and length=sizeof(..). 263 * 264 * \param tag_name A unique name for the data object 265 * \param type The type of the data 266 * \param length Number of values per entity (1->scalar, >1 ->vector) 267 * \param default_value Default value to assign to all entities - may be NULL 268 * \return - Handle for tag definition 269 */ 270 virtual TagHandle tag_create( const std::string& tag_name, 271 TagType type, unsigned length, 272 const void* default_value, 273 MsqError &err); 274 275 /** \brief Remove a tag and all corresponding data 276 * 277 * Delete a tag. 278 */ 279 virtual void tag_delete( TagHandle handle, MsqError& err ); 280 281 282 /** \brief Get handle for existing tag, by name. */ 283 virtual TagHandle tag_get( const std::string& name, 284 MsqError& err ); 285 286 /** \brief Get properites of tag 287 * 288 * Get data type and number of values per entity for tag. 289 * \param handle Tag to get properties of. 290 * \param name_out Passed back tag name. 291 * \param type_out Passed back tag type. 292 * \param length_out Passed back number of values per entity. 293 */ 294 virtual void tag_properties( TagHandle handle, 295 std::string& name_out, 296 TagType& type_out, 297 unsigned& length_out, 298 MsqError& err ); 299 300 /** \brief Set tag values on elements 301 * 302 * Set the value of a tag for a list of mesh elements. 303 * \param handle The tag 304 * \param num_elems Length of elem_array 305 * \param elem_array Array of elements for which to set the tag value. 306 * \param tag_data Tag data for each element, contiguous in memory. 307 * This data is expected to be 308 309 * num_elems*tag_length*sizeof(tag_type) bytes. 310 */ 311 virtual void tag_set_element_data( TagHandle handle, 312 size_t num_elems, 313 const ElementHandle* elem_array, 314 const void* tag_data, 315 MsqError& err ); 316 317 /** \brief Set tag values on vertices 318 * 319 * Set the value of a tag for a list of mesh vertices. 320 * \param handle The tag 321 * \param num_elems Length of node_array 322 * \param node_array Array of vertices for which to set the tag value. 323 * \param tag_data Tag data for each element, contiguous in memory. 324 * This data is expected to be 325 * num_elems*tag_length*sizeof(tag_type) bytes. 326 */ 327 virtual void tag_set_vertex_data ( TagHandle handle, 328 size_t num_elems, 329 const VertexHandle* node_array, 330 const void* tag_data, 331 MsqError& err ); 332 333 334 /** \brief Get tag values on elements 335 * 336 * Get the value of a tag for a list of mesh elements. 337 * \param handle The tag 338 * \param num_elems Length of elem_array 339 * \param elem_array Array of elements for which to get the tag value. 340 * \param tag_data Return buffer in which to copy tag data, contiguous 341 * in memory. This data is expected to be 342 * num_elems*tag_length*sizeof(tag_type) bytes. 343 */ 344 virtual void tag_get_element_data( TagHandle handle, 345 size_t num_elems, 346 const ElementHandle* elem_array, 347 void* tag_data, 348 MsqError& err ); 349 350 /** \brief Get tag values on vertices. 351 * 352 * Get the value of a tag for a list of mesh vertices. 353 * \param handle The tag 354 * \param num_elems Length of elem_array 355 * \param elem_array Array of vertices for which to get the tag value. 356 * \param tag_data Return buffer in which to copy tag data, contiguous 357 * in memory. This data is expected to be 358 * num_elems*tag_length*sizeof(tag_type) bytes. 359 */ 360 virtual void tag_get_vertex_data ( TagHandle handle, 361 size_t num_elems, 362 const VertexHandle* node_array, 363 void* tag_data, 364 MsqError& err ); 365 366 367 368 protected: 369 370 iBase_TagValueType check_valid_flag_tag( iBase_TagHandle tag, 371 const char* which_flag, 372 MsqError& err ); 373 374 void set_int_tag( void* tag, void* meshset, int value, MsqError& err ); 375 376 /** \brief Call TSTTM::Arr::getEntArrAdj 377 * 378 * Common code for \ref vertices_get_attached_elements and 379 * \ref elements_get_attached_vertices 380 * 381 *\param source Array of handles of source entities to query from 382 *\param num_source The length of \ref source 383 *\param target_type The type of entity to query for 384 *\param target The output list of adjacent entities 385 *\param offsets For each entity in \ref source, the offset in 386 * \ref target at which the corresponding adjacent 387 * entities are stored. (output) 388 */ 389 void get_adjacent_entities( const iBase_EntityHandle* source, 390 size_t num_source, 391 iBase_EntityType target_type, 392 std::vector<EntityHandle>& target, 393 std::vector<size_t>& offsets, 394 MsqError& err ); 395 396 /** The IMesh instance */ 397 iMesh_Instance meshInstance; 398 399 private: 400 401 void init_active_mesh( iMesh_Instance mesh, 402 MsqError& err, 403 const iBase_TagHandle* fixed_tag, 404 const iBase_TagHandle* slaved_tag ); 405 406 void get_flag_data( iBase_TagHandle tag, 407 bool have_tag, 408 iBase_TagValueType type, 409 const VertexHandle vert_array[], 410 std::vector<bool>& flag_array, 411 size_t num_vtx, 412 MsqError& err ); 413 414 /** \brief Set tag values */ 415 void tag_set_data ( TagHandle handle, 416 size_t num_elems, 417 const EntityHandle* handle_array, 418 const void* tag_data, 419 MsqError& err ); 420 421 /** \brief Get tag values */ 422 void tag_get_data( TagHandle handle, 423 size_t num_elems, 424 const EntityHandle* handle_array, 425 void* tag_data, 426 MsqError& err ); 427 428 /** Have mesh */ 429 bool haveMesh; 430 /** ITAPS entity set handle for elements to improve */ 431 //iBase_EntitySetHandle elementSet; 432 /** ITAPS entity set handle for nodes to move */ 433 //iBase_EntitySetHandle nodeSet; 434 /** std::set containing elements in elementSet, used 435 * to constrain vertex->element adjaceny queries to 436 * only those elements that are in the input element set. 437 */ 438 //std::vector<iBase_EntityHandle> inputElements; 439 440 /** The type of elements contained in the input element set. 441 * Should be one of: 442 * - iBase_REGION - volume elements 443 * - iBase_FACE - face/2d elements 444 * - iBase_ALL_TYPES - mixed volume and face elements 445 */ 446 iBase_EntityType inputSetType; 447 /** The meshset containing the elements to optimize */ 448 iBase_EntitySetHandle inputSet; 449 450 /** Handle for tag used to hold vertex byte */ 451 iBase_TagHandle byteTag; 452 /** Tag was created in constructor */ 453 bool createdByteTag; 454 /** Handle for tag used to hold vertex-fixed flag */ 455 iBase_TagHandle fixedTag; 456 /** fixedTag handle is valid */ 457 bool haveFixedTag; 458 /** iBase_TYPE for fixed tag */ 459 iBase_TagValueType fixedTagType; 460 /** Handle for tag used to hold vertex-slaved flag */ 461 iBase_TagHandle slavedTag; 462 /** slavedTag handle is valid */ 463 bool haveSlavedTag; 464 /** iBase_TYPE for slaved tag */ 465 iBase_TagValueType slavedTagType; 466 /** Dimension is queried once during create and cached */ 467 int geometricDimension; 468 /** Map iMesh_EntityTopology to MBMesquite::EntityTopology */ 469 EntityTopology topologyMap[iMesh_ALL_TOPOLOGIES+1]; 470 }; 471 472 } // namespace Mesquite 473 474 #endif 475