Mesh Oriented datABase  (version 5.4.1)
Array-based unstructured mesh datastructure
DualTool.hpp
Go to the documentation of this file.
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_DUAL_TOOL_HPP
00017 #define MOAB_DUAL_TOOL_HPP
00018 
00019 #include "moab/Forward.hpp"
00020 
00021 #include "moab/win32_config.h"
00022 
00023 namespace moab
00024 {
00025 
00026 /*!
00027  *  \authors Tim Tautges
00028  *  \date    2/04
00029  *  \brief   Tools for constructing and working with mesh duals (both tet- and hex-based,
00030  *           though some functions may not make sense for tet duals)
00031  *
00032  */
00033 class DualTool
00034 {
00035   public:
00036     //! tag name for dual surfaces
00037     static MOAB_EXPORT const char* DUAL_SURFACE_TAG_NAME;
00038 
00039     //! tag name for dual curves
00040     static MOAB_EXPORT const char* DUAL_CURVE_TAG_NAME;
00041 
00042     //! tag name for dual cells
00043     static const char* IS_DUAL_CELL_TAG_NAME;
00044 
00045     //! tag name for dual entitys
00046     static const char* DUAL_ENTITY_TAG_NAME;
00047 
00048     //! tag name for dual entitys
00049     static const char* EXTRA_DUAL_ENTITY_TAG_NAME;
00050 
00051     //! tag name for dual entitys
00052     static const char* DUAL_GRAPHICS_POINT_TAG_NAME;
00053 
00054     //! struct for storing a graphics pt
00055     class GraphicsPoint
00056     {
00057       public:
00058         GraphicsPoint()
00059         {
00060             xyz[0] = 0.0;
00061             xyz[1] = 0.0;
00062             xyz[2] = 0.0;
00063             id     = -1;
00064         }
00065 
00066         GraphicsPoint( float xi, float yi, float zi, int idi )
00067         {
00068             xyz[0] = xi;
00069             xyz[1] = yi;
00070             xyz[2] = zi;
00071             id     = idi;
00072         }
00073 
00074         GraphicsPoint( float xyzi[3], int idi )
00075         {
00076             xyz[0] = xyzi[0];
00077             xyz[1] = xyzi[1];
00078             xyz[2] = xyzi[2];
00079             id     = idi;
00080         }
00081 
00082         GraphicsPoint( double xyzi[3], int idi )
00083         {
00084             xyz[0] = xyzi[0];
00085             xyz[1] = xyzi[1];
00086             xyz[2] = xyzi[2];
00087             id     = idi;
00088         }
00089 
00090         GraphicsPoint( const GraphicsPoint& gp )
00091         {
00092             xyz[0] = gp.xyz[0];
00093             xyz[1] = gp.xyz[1];
00094             xyz[2] = gp.xyz[2];
00095             id     = gp.id;
00096         }
00097 
00098         GraphicsPoint& operator=( GraphicsPoint const& gp )
00099         {
00100             for( unsigned i = 0; i < 3; ++i )
00101                 xyz[i] = gp.xyz[i];
00102             id = gp.id;
00103             return *this;
00104         }
00105 
00106         float xyz[3];
00107         int id;
00108     };
00109 
00110     DualTool( Interface* impl );
00111 
00112     ~DualTool();
00113 
00114     //! construct the dual entities for the entire mesh
00115     ErrorCode construct_dual( EntityHandle* entities, const int num_entities );
00116 
00117     //! construct the dual entities for a hex mesh, including dual surfaces & curves
00118     ErrorCode construct_hex_dual( EntityHandle* entities, const int num_entities );
00119 
00120     //! construct the dual entities for a hex mesh, including dual surfaces & curves
00121     ErrorCode construct_hex_dual( Range& entities );
00122 
00123     //! get the dual entities; if non-null, only dual of entities passed in are returned
00124     ErrorCode get_dual_entities( const int dim, EntityHandle* entities, const int num_entities, Range& dual_ents );
00125 
00126     //! get the dual entities; if non-null, only dual of entities passed in are returned
00127     ErrorCode get_dual_entities( const int dim,
00128                                  EntityHandle* entities,
00129                                  const int num_entities,
00130                                  std::vector< EntityHandle >& dual_ents );
00131 
00132     //! return the corresponding dual entity
00133     EntityHandle get_dual_entity( const EntityHandle this_ent ) const;
00134 
00135     //! return the corresponding extra dual entity
00136     EntityHandle get_extra_dual_entity( const EntityHandle this_ent );
00137 
00138     //! get the d-dimensional hyperplane sets; static 'cuz it's easy to do without an active
00139     //! dualtool
00140     static ErrorCode get_dual_hyperplanes( const Interface* impl, const int dim, Range& dual_ents );
00141 
00142     //! get the graphics points for single entity (dual_ent CAN'T be a set);
00143     //! returns multiple facets, each with npts[i] points
00144     ErrorCode get_graphics_points( EntityHandle dual_ent,
00145                                    std::vector< int >& npts,
00146                                    std::vector< GraphicsPoint >& gpoints );
00147 
00148     //! get the graphics points for a range of entities or sets (if set, the
00149     //! entities in those sets); optionally reset ids on points
00150     ErrorCode get_graphics_points( const Range& in_range,
00151                                    std::vector< GraphicsPoint >& gpoints,
00152                                    const bool assign_ids = false,
00153                                    const int start_id    = 0 );
00154 
00155     //! given a last_v (possibly zero) and this_v, find the next loop vertex on
00156     //! this dual surface
00157     EntityHandle next_loop_vertex( const EntityHandle last_v, const EntityHandle this_v, const EntityHandle dual_surf );
00158 
00159     //! get/set the tag for dual surfaces
00160     Tag dualSurface_tag() const;
00161     ErrorCode dualSurface_tag( const Tag tag );
00162 
00163     //! get/set the tag for dual curves
00164     Tag dualCurve_tag() const;
00165     ErrorCode dualCurve_tag( const Tag tag );
00166 
00167     //! get/set the tag for dual cells
00168     Tag isDualCell_tag() const;
00169     ErrorCode isDualCell_tag( const Tag tag );
00170 
00171     //! get/set the tag for dual entities
00172     Tag dualEntity_tag() const;
00173     ErrorCode dualEntity_tag( const Tag tag );
00174 
00175     //! get/set the tag for dual entities
00176     Tag extraDualEntity_tag() const;
00177     ErrorCode extraDualEntity_tag( const Tag tag );
00178 
00179     //! get/set the tag for dual entities
00180     Tag dualGraphicsPoint_tag() const;
00181     ErrorCode dualGraphicsPoint_tag( const Tag tag );
00182 
00183     //! get/set the global id tag
00184     Tag globalId_tag() const;
00185     ErrorCode globalId_tag( const Tag tag );
00186 
00187     //! given an entity, return any dual surface or curve it's in
00188     EntityHandle get_dual_hyperplane( const EntityHandle ncell );
00189 
00190     //! returns true if first & last vertices are dual to hexes (not faces)
00191     bool is_blind( const EntityHandle chord );
00192 
00193     //! set the dual surface or curve for an entity
00194     ErrorCode set_dual_surface_or_curve( EntityHandle entity, const EntityHandle dual_hyperplane, const int dimension );
00195 
00196     //! effect atomic pillow operation
00197     ErrorCode atomic_pillow( EntityHandle odedge, EntityHandle& quad1, EntityHandle& quad2 );
00198 
00199     //! effect reverse atomic pillow operation
00200     ErrorCode rev_atomic_pillow( EntityHandle pillow, Range& chords );
00201 
00202     //! effect face shrink operation
00203     ErrorCode face_shrink( EntityHandle odedge );
00204 
00205     //! effect reverse atomic pillow operation
00206     ErrorCode rev_face_shrink( EntityHandle edge );
00207 
00208     //! effect a face open-collapse operation
00209     ErrorCode face_open_collapse( EntityHandle ocl, EntityHandle ocr );
00210 
00211     //! given the two 1-cells involved in the foc, get entities associated with
00212     //! the quads being opened/collapsed; see implementation for more details
00213     ErrorCode foc_get_ents( EntityHandle ocl,
00214                             EntityHandle ocr,
00215                             EntityHandle* quads,
00216                             EntityHandle* split_edges,
00217                             EntityHandle* split_nodes,
00218                             Range& hexes,
00219                             EntityHandle* other_edges,
00220                             EntityHandle* other_nodes );
00221 
00222     //! given a 1-cell and a chord, return the neighboring vertices on the
00223     //! chord, in the same order as the 1-cell's vertices
00224     ErrorCode get_opposite_verts( const EntityHandle middle_edge, const EntityHandle chord, EntityHandle* verts );
00225 
00226     //! given a dual surface or curve, return the 2-cells, 1-cells, 0-cells, and
00227     //! loop 0/1-cells, if requested; any of those range pointers can be NULL,
00228     //! in which case that range isn't returned
00229     ErrorCode get_dual_entities( const EntityHandle dual_ent,
00230                                  Range* dcells,
00231                                  Range* dedges,
00232                                  Range* dverts,
00233                                  Range* dverts_loop,
00234                                  Range* dedges_loop );
00235 
00236     ErrorCode list_entities( const Range& entities ) const;
00237     ErrorCode list_entities( const EntityHandle* entities, const int num_entities ) const;
00238 
00239     //! delete all the dual data
00240     ErrorCode delete_whole_dual();
00241 
00242     //! check dual-primal adjacencies
00243     ErrorCode check_dual_adjs();
00244 
00245   private:
00246     //! construct dual vertices for specified regions
00247     ErrorCode construct_dual_vertices( const Range& all_regions, Range& new_dual_ents );
00248 
00249     //! construct dual edges for specified faces
00250     ErrorCode construct_dual_edges( const Range& all_faces, Range& new_dual_ents );
00251 
00252     //! construct dual faces for specified edges
00253     ErrorCode construct_dual_faces( const Range& all_edges, Range& new_dual_ents );
00254 
00255     //! construct dual cells for specified vertices
00256     ErrorCode construct_dual_cells( const Range& all_verts, Range& new_dual_ents );
00257 
00258     //! traverse dual faces of input dimension, constructing
00259     //! dual hyperplanes of them in sets as it goes
00260     ErrorCode construct_dual_hyperplanes( const int dim, EntityHandle* entities, const int num_entities );
00261 
00262     //! order 1cells on a chord
00263     ErrorCode order_chord( EntityHandle chord_set );
00264 
00265     //! make a new dual hyperplane with the specified id; if the id specified is -1,
00266     //! set the new one's id to the max found
00267     ErrorCode construct_new_hyperplane( const int dim, EntityHandle& new_hyperplane, int& id );
00268 
00269     //! traverse the cells of a dual hyperplane, starting with this_ent (dimension
00270     //! of this_ent determines hyperplane dimension)
00271     //! simpler method for traversing hyperplane, using same basic algorithm but
00272     //! using MeshTopoUtil::get_bridge_adjacencies
00273     ErrorCode traverse_hyperplane( const Tag hp_tag, EntityHandle& this_hp, EntityHandle this_ent );
00274 
00275     //! connect dual surfaces with dual curves using parent/child connections
00276     ErrorCode construct_hp_parent_child();
00277 
00278     //! given an edge handle, return a list of dual vertices in radial order
00279     //! around the edge; also returns whether this edge is on the boundary
00280     ErrorCode get_radial_dverts( const EntityHandle edge, std::vector< EntityHandle >& rad_verts, bool& bdy_edge );
00281 
00282     ErrorCode construct_dual_vertex( EntityHandle entity,
00283                                      EntityHandle& dual_ent,
00284                                      const bool extra           = false,
00285                                      const bool add_graphics_pt = true );
00286 
00287     //! add a graphics point to an entity (on a tag)
00288     ErrorCode add_graphics_point( EntityHandle entity, double* avg_pos = NULL );
00289 
00290     //! get points defining facets of a 2cell
00291     ErrorCode get_cell_points( EntityHandle dual_ent, std::vector< int >& npts, std::vector< GraphicsPoint >& points );
00292 
00293     //! if this_ent is an edge, is a dual entity, and has quads as
00294     //! its vertices' dual entities, return true, otherwise false
00295     bool check_1d_loop_edge( EntityHandle this_ent );
00296 
00297     //! go through potential dual equivalent edges (edges whose nodes define
00298     //! multiple edges), and add explicit adjacencies to corrent 2cells
00299     ErrorCode check_dual_equiv_edges( Range& dual_edges );
00300 
00301     //! delete a dual entity; updates primal to no longer point to it
00302     ErrorCode delete_dual_entities( EntityHandle* entities, const int num_entities );
00303 
00304     //! delete a range of dual entities; updates primal to no longer point to them
00305     ErrorCode delete_dual_entities( Range& entities );
00306 
00307     //! check sense of connect arrays, and reverse/rotate if necessary
00308     ErrorCode fs_check_quad_sense( EntityHandle hex0, EntityHandle quad0, std::vector< EntityHandle >* connects );
00309 
00310     //! get the three quads for a face shrink, the two hexes, and the connectivity
00311     //! of the three quads
00312     ErrorCode fs_get_quads( EntityHandle odedge,
00313                             EntityHandle* quads,
00314                             EntityHandle* hexes,
00315                             std::vector< EntityHandle >* connects );
00316 
00317     //! get loops of quads around 2 hexes, ordered similarly to vertex loops
00318     ErrorCode fs_get_quad_loops( EntityHandle* hexes,
00319                                  std::vector< EntityHandle >* connects,
00320                                  std::vector< EntityHandle >* side_quads );
00321 
00322     //! given connectivity of first 3 quads for reverse face shrink,
00323     //! get fourth (outer 4 verts to be shared by two inner hexes) and quads
00324     //! around the side of the structure
00325     ErrorCode fsr_get_fourth_quad( std::vector< EntityHandle >* connects, std::vector< EntityHandle >* side_quads );
00326 
00327     /*
00328         //! get pairs of entities to be merged as part of foc operation
00329       ErrorCode foc_get_merge_ents(EntityHandle *quads, EntityHandle *new_quads,
00330                                      Range &edge, Range &new_edge,
00331                                      std::vector<EntityHandle> &merge_ents);
00332     */
00333 
00334     //! function for deleting dual prior to foc operation; special because in
00335     //! many cases need to delete a sheet in preparation for merging onto another
00336     ErrorCode foc_delete_dual( EntityHandle* split_quads, EntityHandle* split_edges, Range& hexes );
00337 
00338     //! split a pair of quads and the edge(s) shared by them
00339     ErrorCode split_pair_nonmanifold( EntityHandle* split_quads,
00340                                       EntityHandle* split_edges,
00341                                       EntityHandle* split_nodes,
00342                                       std::vector< EntityHandle >* star_dp1,
00343                                       std::vector< EntityHandle >* star_dp2,
00344                                       EntityHandle* other_edges,
00345                                       EntityHandle* other_nodes,
00346                                       EntityHandle* new_quads,
00347                                       EntityHandle* new_edges,
00348                                       EntityHandle* new_nodes );
00349 
00350     //! for foc's splitting two shared edges, there might be additional entities
00351     //! connected to the split node that also have to be updated
00352     ErrorCode foc_get_addl_ents( std::vector< EntityHandle >* star_dp1,
00353                                  std::vector< EntityHandle >* star_dp2,
00354                                  EntityHandle* split_edges,
00355                                  EntityHandle split_node,
00356                                  Range* addl_ents );
00357 
00358     //! given the split quads and edges, get the face and hex stars around the
00359     //! edge(s), separated into halves, each of which goes with the new or old entities
00360     //! after the split
00361     ErrorCode foc_get_stars( EntityHandle* split_quads,
00362                              EntityHandle* split_edges,
00363                              std::vector< EntityHandle >* star_dp1,
00364                              std::vector< EntityHandle >* star_dp2 );
00365 
00366     void print_cell( EntityHandle cell );
00367 
00368     //! private copy of interface *
00369     Interface* mbImpl;
00370 
00371     //! static constant number of points bounding any cell
00372     enum
00373     {
00374         GP_SIZE = 20
00375     };
00376 
00377     //! tags used for dual surfaces, curves, cells, entities
00378     Tag dualCurveTag;
00379     Tag dualSurfaceTag;
00380     Tag isDualCellTag;
00381     Tag dualEntityTag;
00382     Tag extraDualEntityTag;
00383     Tag dualGraphicsPointTag;
00384     Tag categoryTag;
00385     Tag globalIdTag;
00386 
00387     int maxHexId;
00388 };
00389 
00390 inline Tag DualTool::dualSurface_tag() const
00391 {
00392     return dualSurfaceTag;
00393 }
00394 
00395 inline Tag DualTool::dualCurve_tag() const
00396 {
00397     return dualCurveTag;
00398 }
00399 
00400 inline Tag DualTool::isDualCell_tag() const
00401 {
00402     return isDualCellTag;
00403 }
00404 
00405 inline Tag DualTool::dualEntity_tag() const
00406 {
00407     return dualEntityTag;
00408 }
00409 
00410 inline Tag DualTool::extraDualEntity_tag() const
00411 {
00412     return extraDualEntityTag;
00413 }
00414 
00415 inline Tag DualTool::dualGraphicsPoint_tag() const
00416 {
00417     return dualGraphicsPointTag;
00418 }
00419 
00420 inline Tag DualTool::globalId_tag() const
00421 {
00422     return globalIdTag;
00423 }
00424 
00425 //! get/set the tag for dual surfaces
00426 inline ErrorCode DualTool::dualSurface_tag( const Tag tag )
00427 {
00428     ErrorCode result = MB_FAILURE;
00429     if( ( 0 == dualSurfaceTag && tag ) || dualSurfaceTag != tag )
00430     {
00431         dualSurfaceTag = tag;
00432         result         = MB_SUCCESS;
00433     }
00434 
00435     return result;
00436 }
00437 
00438 //! get/set the tag for dual curves
00439 inline ErrorCode DualTool::dualCurve_tag( const Tag tag )
00440 {
00441     ErrorCode result = MB_FAILURE;
00442     if( ( 0 == dualCurveTag && tag ) || dualCurveTag != tag )
00443     {
00444         dualCurveTag = tag;
00445         result       = MB_SUCCESS;
00446     }
00447 
00448     return result;
00449 }
00450 
00451 //! get/set the tag for dual cells
00452 inline ErrorCode DualTool::isDualCell_tag( const Tag tag )
00453 {
00454     ErrorCode result = MB_FAILURE;
00455     if( ( 0 == isDualCellTag && tag ) || isDualCellTag != tag )
00456     {
00457         isDualCellTag = tag;
00458         result        = MB_SUCCESS;
00459     }
00460 
00461     return result;
00462 }
00463 
00464 //! get/set the tag for dual entities
00465 inline ErrorCode DualTool::dualEntity_tag( const Tag tag )
00466 {
00467     ErrorCode result = MB_FAILURE;
00468     if( ( 0 == dualEntityTag && tag ) || dualEntityTag != tag )
00469     {
00470         dualEntityTag = tag;
00471         result        = MB_SUCCESS;
00472     }
00473 
00474     return result;
00475 }
00476 
00477 //! get/set the tag for dual entities
00478 inline ErrorCode DualTool::extraDualEntity_tag( const Tag tag )
00479 {
00480     ErrorCode result = MB_FAILURE;
00481     if( ( 0 == extraDualEntityTag && tag ) || extraDualEntityTag != tag )
00482     {
00483         extraDualEntityTag = tag;
00484         result             = MB_SUCCESS;
00485     }
00486 
00487     return result;
00488 }
00489 
00490 //! get/set the tag for dual entities
00491 inline ErrorCode DualTool::dualGraphicsPoint_tag( const Tag tag )
00492 {
00493     ErrorCode result = MB_FAILURE;
00494     if( ( 0 == dualGraphicsPointTag && tag ) || dualGraphicsPointTag != tag )
00495     {
00496         dualGraphicsPointTag = tag;
00497         result               = MB_SUCCESS;
00498     }
00499 
00500     return result;
00501 }
00502 
00503 //! get/set the tag for dual entities
00504 inline ErrorCode DualTool::globalId_tag( const Tag tag )
00505 {
00506     ErrorCode result = MB_FAILURE;
00507     if( ( 0 == globalIdTag && tag ) || globalIdTag != tag )
00508     {
00509         globalIdTag = tag;
00510         result      = MB_SUCCESS;
00511     }
00512 
00513     return result;
00514 }
00515 
00516 }  // namespace moab
00517 
00518 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines