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