1/**
2 * MOAB, a Mesh-Oriented datABase, is a software component for creating,
3 * storing and accessing finite element mesh data.
4 *
5 * Copyright 2004 Sandia Corporation. Under the terms of Contract
6 * DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government
7 * retains certain rights in 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 */1516#ifndef MOAB_DUAL_TOOL_HPP17#define MOAB_DUAL_TOOL_HPP1819#include"moab/Forward.hpp"2021#include"moab/win32_config.h"2223namespace moab
24 {
2526/*!
27 * \authors Tim Tautges
28 * \date 2/04
29 * \brief Tools for constructing and working with mesh duals (both tet- and hex-based,
30 * though some functions may not make sense for tet duals)
31 *
32 */33classDualTool34 {
35public:
36//! tag name for dual surfaces37static MOAB_EXPORT constchar* DUAL_SURFACE_TAG_NAME;
3839//! tag name for dual curves40static MOAB_EXPORT constchar* DUAL_CURVE_TAG_NAME;
4142//! tag name for dual cells43staticconstchar* IS_DUAL_CELL_TAG_NAME;
4445//! tag name for dual entitys46staticconstchar* DUAL_ENTITY_TAG_NAME;
4748//! tag name for dual entitys49staticconstchar* EXTRA_DUAL_ENTITY_TAG_NAME;
5051//! tag name for dual entitys52staticconstchar* DUAL_GRAPHICS_POINT_TAG_NAME;
5354//! struct for storing a graphics pt55classGraphicsPoint56 {
57public:
58GraphicsPoint()
59 {
60 xyz[0] = 0.0;
61 xyz[1] = 0.0;
62 xyz[2] = 0.0;
63 id = -1;
64 }
6566GraphicsPoint( float xi, float yi, float zi, int idi )
67 {
68 xyz[0] = xi;
69 xyz[1] = yi;
70 xyz[2] = zi;
71 id = idi;
72 }
7374GraphicsPoint( float xyzi[3], int idi )
75 {
76 xyz[0] = xyzi[0];
77 xyz[1] = xyzi[1];
78 xyz[2] = xyzi[2];
79 id = idi;
80 }
8182GraphicsPoint( double xyzi[3], int idi )
83 {
84 xyz[0] = xyzi[0];
85 xyz[1] = xyzi[1];
86 xyz[2] = xyzi[2];
87 id = idi;
88 }
8990GraphicsPoint( const GraphicsPoint& gp )
91 {
92 xyz[0] = gp.xyz[0];
93 xyz[1] = gp.xyz[1];
94 xyz[2] = gp.xyz[2];
95 id = gp.id;
96 }
9798 GraphicsPoint& operator=( GraphicsPoint const& gp )
99 {
100for( unsigned i = 0; i < 3; ++i )
101 xyz[i] = gp.xyz[i];
102 id = gp.id;
103return *this;
104 }
105106float xyz[3];
107int id;
108 };
109110DualTool( Interface* impl );
111112 ~DualTool();
113114//! construct the dual entities for the entire mesh115ErrorCode construct_dual( EntityHandle* entities, constint num_entities );
116117//! construct the dual entities for a hex mesh, including dual surfaces & curves118ErrorCode construct_hex_dual( EntityHandle* entities, constint num_entities );
119120//! construct the dual entities for a hex mesh, including dual surfaces & curves121ErrorCode construct_hex_dual( Range& entities );
122123//! get the dual entities; if non-null, only dual of entities passed in are returned124ErrorCode get_dual_entities( constint dim, EntityHandle* entities, constint num_entities, Range& dual_ents );
125126//! get the dual entities; if non-null, only dual of entities passed in are returned127ErrorCode get_dual_entities( constint dim,
128 EntityHandle* entities,
129constint num_entities,
130 std::vector< EntityHandle >& dual_ents );
131132//! return the corresponding dual entity133EntityHandle get_dual_entity( const EntityHandle this_ent )const;
134135//! return the corresponding extra dual entity136EntityHandle get_extra_dual_entity( const EntityHandle this_ent );
137138//! get the d-dimensional hyperplane sets; static 'cuz it's easy to do without an active139//! dualtool140static ErrorCode get_dual_hyperplanes( const Interface* impl, constint dim, Range& dual_ents );
141142//! get the graphics points for single entity (dual_ent CAN'T be a set);143//! returns multiple facets, each with npts[i] points144ErrorCode get_graphics_points( EntityHandle dual_ent,
145 std::vector< int >& npts,
146 std::vector< GraphicsPoint >& gpoints );
147148//! get the graphics points for a range of entities or sets (if set, the149//! entities in those sets); optionally reset ids on points150ErrorCode get_graphics_points( const Range& in_range,
151 std::vector< GraphicsPoint >& gpoints,
152constbool assign_ids = false,
153constint start_id = 0 );
154155//! given a last_v (possibly zero) and this_v, find the next loop vertex on156//! this dual surface157EntityHandle next_loop_vertex( const EntityHandle last_v, const EntityHandle this_v, const EntityHandle dual_surf );
158159//! get/set the tag for dual surfaces160Tag dualSurface_tag()const;
161ErrorCode dualSurface_tag( const Tag tag );
162163//! get/set the tag for dual curves164Tag dualCurve_tag()const;
165ErrorCode dualCurve_tag( const Tag tag );
166167//! get/set the tag for dual cells168Tag isDualCell_tag()const;
169ErrorCode isDualCell_tag( const Tag tag );
170171//! get/set the tag for dual entities172Tag dualEntity_tag()const;
173ErrorCode dualEntity_tag( const Tag tag );
174175//! get/set the tag for dual entities176Tag extraDualEntity_tag()const;
177ErrorCode extraDualEntity_tag( const Tag tag );
178179//! get/set the tag for dual entities180Tag dualGraphicsPoint_tag()const;
181ErrorCode dualGraphicsPoint_tag( const Tag tag );
182183//! get/set the global id tag184Tag globalId_tag()const;
185ErrorCode globalId_tag( const Tag tag );
186187//! given an entity, return any dual surface or curve it's in188EntityHandle get_dual_hyperplane( const EntityHandle ncell );
189190//! returns true if first & last vertices are dual to hexes (not faces)191boolis_blind( const EntityHandle chord );
192193//! set the dual surface or curve for an entity194ErrorCode set_dual_surface_or_curve( EntityHandle entity, const EntityHandle dual_hyperplane, constint dimension );
195196//! effect atomic pillow operation197ErrorCode atomic_pillow( EntityHandle odedge, EntityHandle& quad1, EntityHandle& quad2 );
198199//! effect reverse atomic pillow operation200ErrorCode rev_atomic_pillow( EntityHandle pillow, Range& chords );
201202//! effect face shrink operation203ErrorCode face_shrink( EntityHandle odedge );
204205//! effect reverse atomic pillow operation206ErrorCode rev_face_shrink( EntityHandle edge );
207208//! effect a face open-collapse operation209ErrorCode face_open_collapse( EntityHandle ocl, EntityHandle ocr );
210211//! given the two 1-cells involved in the foc, get entities associated with212//! the quads being opened/collapsed; see implementation for more details213ErrorCode foc_get_ents( EntityHandle ocl,
214 EntityHandle ocr,
215 EntityHandle* quads,
216 EntityHandle* split_edges,
217 EntityHandle* split_nodes,
218 Range& hexes,
219 EntityHandle* other_edges,
220 EntityHandle* other_nodes );
221222//! given a 1-cell and a chord, return the neighboring vertices on the223//! chord, in the same order as the 1-cell's vertices224ErrorCode get_opposite_verts( const EntityHandle middle_edge, const EntityHandle chord, EntityHandle* verts );
225226//! given a dual surface or curve, return the 2-cells, 1-cells, 0-cells, and227//! loop 0/1-cells, if requested; any of those range pointers can be NULL,228//! in which case that range isn't returned229ErrorCode get_dual_entities( const EntityHandle dual_ent,
230 Range* dcells,
231 Range* dedges,
232 Range* dverts,
233 Range* dverts_loop,
234 Range* dedges_loop );
235236ErrorCode list_entities( const Range& entities )const;
237ErrorCode list_entities( const EntityHandle* entities, constint num_entities )const;
238239//! delete all the dual data240ErrorCode delete_whole_dual();
241242//! check dual-primal adjacencies243ErrorCode check_dual_adjs();
244245private:
246//! construct dual vertices for specified regions247ErrorCode construct_dual_vertices( const Range& all_regions, Range& new_dual_ents );
248249//! construct dual edges for specified faces250ErrorCode construct_dual_edges( const Range& all_faces, Range& new_dual_ents );
251252//! construct dual faces for specified edges253ErrorCode construct_dual_faces( const Range& all_edges, Range& new_dual_ents );
254255//! construct dual cells for specified vertices256ErrorCode construct_dual_cells( const Range& all_verts, Range& new_dual_ents );
257258//! traverse dual faces of input dimension, constructing259//! dual hyperplanes of them in sets as it goes260ErrorCode construct_dual_hyperplanes( constint dim, EntityHandle* entities, constint num_entities );
261262//! order 1cells on a chord263ErrorCode order_chord( EntityHandle chord_set );
264265//! make a new dual hyperplane with the specified id; if the id specified is -1,266//! set the new one's id to the max found267ErrorCode construct_new_hyperplane( constint dim, EntityHandle& new_hyperplane, int& id );
268269//! traverse the cells of a dual hyperplane, starting with this_ent (dimension270//! of this_ent determines hyperplane dimension)271//! simpler method for traversing hyperplane, using same basic algorithm but272//! using MeshTopoUtil::get_bridge_adjacencies273ErrorCode traverse_hyperplane( const Tag hp_tag, EntityHandle& this_hp, EntityHandle this_ent );
274275//! connect dual surfaces with dual curves using parent/child connections276ErrorCode construct_hp_parent_child();
277278//! given an edge handle, return a list of dual vertices in radial order279//! around the edge; also returns whether this edge is on the boundary280ErrorCode get_radial_dverts( const EntityHandle edge, std::vector< EntityHandle >& rad_verts, bool& bdy_edge );
281282ErrorCode construct_dual_vertex( EntityHandle entity,
283 EntityHandle& dual_ent,
284constbool extra = false,
285constbool add_graphics_pt = true );
286287//! add a graphics point to an entity (on a tag)288ErrorCode add_graphics_point( EntityHandle entity, double* avg_pos = NULL );
289290//! get points defining facets of a 2cell291ErrorCode get_cell_points( EntityHandle dual_ent, std::vector< int >& npts, std::vector< GraphicsPoint >& points );
292293//! if this_ent is an edge, is a dual entity, and has quads as294//! its vertices' dual entities, return true, otherwise false295boolcheck_1d_loop_edge( EntityHandle this_ent );
296297//! go through potential dual equivalent edges (edges whose nodes define298//! multiple edges), and add explicit adjacencies to corrent 2cells299ErrorCode check_dual_equiv_edges( Range& dual_edges );
300301//! delete a dual entity; updates primal to no longer point to it302ErrorCode delete_dual_entities( EntityHandle* entities, constint num_entities );
303304//! delete a range of dual entities; updates primal to no longer point to them305ErrorCode delete_dual_entities( Range& entities );
306307//! check sense of connect arrays, and reverse/rotate if necessary308ErrorCode fs_check_quad_sense( EntityHandle hex0, EntityHandle quad0, std::vector< EntityHandle >* connects );
309310//! get the three quads for a face shrink, the two hexes, and the connectivity311//! of the three quads312ErrorCode fs_get_quads( EntityHandle odedge,
313 EntityHandle* quads,
314 EntityHandle* hexes,
315 std::vector< EntityHandle >* connects );
316317//! get loops of quads around 2 hexes, ordered similarly to vertex loops318ErrorCode fs_get_quad_loops( EntityHandle* hexes,
319 std::vector< EntityHandle >* connects,
320 std::vector< EntityHandle >* side_quads );
321322//! given connectivity of first 3 quads for reverse face shrink,323//! get fourth (outer 4 verts to be shared by two inner hexes) and quads324//! around the side of the structure325ErrorCode fsr_get_fourth_quad( std::vector< EntityHandle >* connects, std::vector< EntityHandle >* side_quads );
326327/*
328 //! get pairs of entities to be merged as part of foc operation
329 ErrorCode foc_get_merge_ents(EntityHandle *quads, EntityHandle *new_quads,
330 Range &edge, Range &new_edge,
331 std::vector<EntityHandle> &merge_ents);
332 */333334//! function for deleting dual prior to foc operation; special because in335//! many cases need to delete a sheet in preparation for merging onto another336ErrorCode foc_delete_dual( EntityHandle* split_quads, EntityHandle* split_edges, Range& hexes );
337338//! split a pair of quads and the edge(s) shared by them339ErrorCode split_pair_nonmanifold( EntityHandle* split_quads,
340 EntityHandle* split_edges,
341 EntityHandle* split_nodes,
342 std::vector< EntityHandle >* star_dp1,
343 std::vector< EntityHandle >* star_dp2,
344 EntityHandle* other_edges,
345 EntityHandle* other_nodes,
346 EntityHandle* new_quads,
347 EntityHandle* new_edges,
348 EntityHandle* new_nodes );
349350//! for foc's splitting two shared edges, there might be additional entities351//! connected to the split node that also have to be updated352ErrorCode foc_get_addl_ents( std::vector< EntityHandle >* star_dp1,
353 std::vector< EntityHandle >* star_dp2,
354 EntityHandle* split_edges,
355 EntityHandle split_node,
356 Range* addl_ents );
357358//! given the split quads and edges, get the face and hex stars around the359//! edge(s), separated into halves, each of which goes with the new or old entities360//! after the split361ErrorCode foc_get_stars( EntityHandle* split_quads,
362 EntityHandle* split_edges,
363 std::vector< EntityHandle >* star_dp1,
364 std::vector< EntityHandle >* star_dp2 );
365366voidprint_cell( EntityHandle cell );
367368//! private copy of interface *369 Interface* mbImpl;
370371//! static constant number of points bounding any cell372enum373 {
374 GP_SIZE = 20375 };
376377//! tags used for dual surfaces, curves, cells, entities378 Tag dualCurveTag;
379 Tag dualSurfaceTag;
380 Tag isDualCellTag;
381 Tag dualEntityTag;
382 Tag extraDualEntityTag;
383 Tag dualGraphicsPointTag;
384 Tag categoryTag;
385 Tag globalIdTag;
386387int maxHexId;
388 };
389390inline Tag DualTool::dualSurface_tag()const
391 {
392return dualSurfaceTag;
393 }
394395inline Tag DualTool::dualCurve_tag()const
396 {
397return dualCurveTag;
398 }
399400inline Tag DualTool::isDualCell_tag()const
401 {
402return isDualCellTag;
403 }
404405inline Tag DualTool::dualEntity_tag()const
406 {
407return dualEntityTag;
408 }
409410inline Tag DualTool::extraDualEntity_tag()const
411 {
412return extraDualEntityTag;
413 }
414415inline Tag DualTool::dualGraphicsPoint_tag()const
416 {
417return dualGraphicsPointTag;
418 }
419420inline Tag DualTool::globalId_tag()const
421 {
422return globalIdTag;
423 }
424425//! get/set the tag for dual surfaces426inline ErrorCode DualTool::dualSurface_tag( const Tag tag )
427 {
428 ErrorCode result = MB_FAILURE;
429if( ( 0 == dualSurfaceTag && tag ) || dualSurfaceTag != tag )
430 {
431 dualSurfaceTag = tag;
432 result = MB_SUCCESS;
433 }
434435return result;
436 }
437438//! get/set the tag for dual curves439inline ErrorCode DualTool::dualCurve_tag( const Tag tag )
440 {
441 ErrorCode result = MB_FAILURE;
442if( ( 0 == dualCurveTag && tag ) || dualCurveTag != tag )
443 {
444 dualCurveTag = tag;
445 result = MB_SUCCESS;
446 }
447448return result;
449 }
450451//! get/set the tag for dual cells452inline ErrorCode DualTool::isDualCell_tag( const Tag tag )
453 {
454 ErrorCode result = MB_FAILURE;
455if( ( 0 == isDualCellTag && tag ) || isDualCellTag != tag )
456 {
457 isDualCellTag = tag;
458 result = MB_SUCCESS;
459 }
460461return result;
462 }
463464//! get/set the tag for dual entities465inline ErrorCode DualTool::dualEntity_tag( const Tag tag )
466 {
467 ErrorCode result = MB_FAILURE;
468if( ( 0 == dualEntityTag && tag ) || dualEntityTag != tag )
469 {
470 dualEntityTag = tag;
471 result = MB_SUCCESS;
472 }
473474return result;
475 }
476477//! get/set the tag for dual entities478inline ErrorCode DualTool::extraDualEntity_tag( const Tag tag )
479 {
480 ErrorCode result = MB_FAILURE;
481if( ( 0 == extraDualEntityTag && tag ) || extraDualEntityTag != tag )
482 {
483 extraDualEntityTag = tag;
484 result = MB_SUCCESS;
485 }
486487return result;
488 }
489490//! get/set the tag for dual entities491inline ErrorCode DualTool::dualGraphicsPoint_tag( const Tag tag )
492 {
493 ErrorCode result = MB_FAILURE;
494if( ( 0 == dualGraphicsPointTag && tag ) || dualGraphicsPointTag != tag )
495 {
496 dualGraphicsPointTag = tag;
497 result = MB_SUCCESS;
498 }
499500return result;
501 }
502503//! get/set the tag for dual entities504inline ErrorCode DualTool::globalId_tag( const Tag tag )
505 {
506 ErrorCode result = MB_FAILURE;
507if( ( 0 == globalIdTag && tag ) || globalIdTag != tag )
508 {
509 globalIdTag = tag;
510 result = MB_SUCCESS;
511 }
512513return result;
514 }
515516 } // namespace moab517518#endif