GemaMesh
The GeMA Mesh Plugin
Loading...
Searching...
No Matches
UibhmTopology< Geometry > Class Template Reference

#include <uibhmTopology.h>

Inheritance diagram for UibhmTopology< Geometry >:
Collaboration diagram for UibhmTopology< Geometry >:

Classes

struct  BSIterator
 The internal context returned by borderSurfaceIterator() and consumed by nextBorderSurface() More...
 
struct  V3
 
struct  V4
 

Public Types

using HalfSide = quint32
 The integer type used to represent a half-side index.
 
using HSVT = typename Geometry::template VectorType<HalfSide>
 Let HSVT be the same vector type used by Geometry storing a half-side value.
 
using IVT = typename Geometry::template VectorType<int>
 Let IVT be the same vector type used by Geometry storing an integer.
 
- Public Types inherited from UibhmTopologyBase
enum  CheckOptions {
  BasicCheck , SimpleCheck , FullCheck , FirstWarnOption ,
  BasicCheckWarn = FirstWarnOption , SimpleCheckWarn , FullCheckWarn
}
 Check options for mesh initialization. More...
 

Public Member Functions

 UibhmTopology (typename Geometry::NodeData *nodeData, typename Geometry::CellData *cellData, const GmPCR *pcr, const GmLogCategory &logger)
 Basic constructor. The internal structure is built by a required call to init() that returns true or false if the operation was successful or not.
 
virtual bool init (bool buildEdgeMap, CheckOptions extraChecks)
 Builds the topology structure. Returns false on errors. The flag controls whether the edge-handle map should be built for solid meshes (this is by large the biggest stored structure, and so should only be built if needed). Ignored for surface meshes. The extra checks asks us to conduct extra testing on the mesh data.
 
virtual bool addNewCells ()
 Adjusts the topological structure to include the cells appended to the mesh since the last time that the topological structure was built. Assumes that those cells are connected to the mesh by previous mesh borders (or are not connected to the mesh at all).
 
virtual bool cellIsIndexed (int cellId)
 Returns true if the cell already was indexed by the topological structure by the last call to init() or addNewCells()
 
void printParameters (const GmLogCategory &logger, GmLogLevel level) const
 Prints a summary of the topological structure in a way to be integrated with the mesh printed by GmCellMesh::printParameters()
 
void print (const GmLogCategory &logger, GmLogLevel level) const
 Prints the topological structure FULL information to the specified logger/level.
 
size_t printMemoryStatistics (const GmLogCategory &logger, GmLogLevel level) const
 Prints memory usage for this topological structure to the given logger. Returns the used memory as reported by usedMemory()
 
size_t usedMemory () const
 Returns an estimate of the used memory by the topology structure. This does not includes fixed (small) sizes like the template vector or the small matrices with template data inside each template information.
 
void hsBreak (HalfSide hs, int *cellId, int *side) const
 Breaks the half-side into its components. In debug mode, checks their validity as actual cells and sides.
 
int linearHs (int cellId, int side) const
 Returns the linear half-side index used to index the opposite table for the given (cell, side) pair.
 
int linearHs (HalfSide hs) const
 Returns the linear half-side index used to index the opposite table.
 
HalfSide oppositeHs (int cellId, int side) const
 Returns the opposite half-side to the given (cell, side) pair.
 
HalfSide oppositeHs (HalfSide hs) const
 Returns the opposite half-side to the given half-side.
 
bool isBorderHs (int cellId, int side) const
 Returns true if the given (cell, side) pair corresponds to a border half-side.
 
bool isBorderHs (HalfSide hs) const
 Returns true if the given (valid) half-side is a border half-side.
 
bool isNonInterfaceBorderHs (int cellId, int side) const
 Returns true if the given (cell, side) pair corresponds to a border half-side that IS NOT an internal hole artificially created by interface element intersections.
 
bool isNonInterfaceBorderHs (HalfSide hs) const
 Returns true if the given (valid) half-side is a border half-side that IS NOT an internal hole artificially created by interface element intersections.
 
bool isInterfaceBorderHs (HalfSide hs) const
 Returns true if the given (valid) half-side is a border half-side that IS part of an internal hole artificially created by interface element intersections.
 
void fillBorderKind (int cellId, int side, bool *isExtBorder, bool *isInterfaceBorder)
 Given a (cellId, side) pair fills isExtBorder with the result of isNonInterfaceBorderHs() and isInterfaceBorder with the result of isInterfaceBorder(). Calculates the opposite only once.
 
HalfSide firstHs (int cellId) const
 Returns the index of the first half side for the given cell.
 
HalfSide nextHs (HalfSide hs) const
 Returns the index of the next half side in the cell associated with the given half side.
 
HalfSide prevHs (HalfSide hs) const
 Returns the index of the previous half side in the cell associated with the given half side.
 
HalfSide adjacentHf (HalfSide hf, int faceEdge) const
 Given a half face (this method should NOT be used for surface meshes) and the local index of an edge in this half face, returns the index of the adjacent half-face, sharing the given edge, from the same element.
 
HalfSide radialHf (HalfSide hf, int faceEdge) const
 Given a half face (this method should NOT be used for surface meshes) and the local index of an edge in this half face, returns the index of the adjacent half-face, sharing the given edge, from a neighbor element in such a way that successive calls to radialHf() will traverse all the elements sharing that edge (for that to be true for border edges, the starting half-face should be the border half-face). Returns GMP_UIBHM_INVALID_VALUE if the adjacent half-face is a border face.
 
- Public Member Functions inherited from UibhmTopologyBase
virtual ~UibhmTopologyBase ()
 Virtual destructor.
 

Static Public Member Functions

static HalfSide hsMake (int cellId, int side)
 Creates a half-side index from a cellId and side components.
 
static HalfSide hsMakeSpecial (int id, int side)
 Creates a half-side index to represent a border or a mid surface/volume node.
 
static int hsCell (HalfSide hs)
 Extracts the cellId from the half-side index.
 
static int hsSide (HalfSide hs)
 Extracts the side from the half-side index.
 
static bool hsIsValid (HalfSide hs)
 Returns true for a standard half-side. Returns false for special half-sides used to represent borders or mid surface/volume nodes.
 
static bool hsIsMidElement (HalfSide hs)
 Returns true if the given half-side represents a special hs used to store the element for a quadratic mid surface/volume node.
 

Protected Member Functions

bool doInit ()
 Workhorse for init.
 
bool doAddNewCells ()
 Workhorse for addNewCells()
 
int buildOffsetTable ()
 Builds the side offset table from each cell's template information. Returns the number of half-sides if successful or 0 on error.
 
int updateOffsetTable (int numAddedCells)
 Updates the side offset table from each cell's template information. Returns the TOTAL number of half-sides if successful or 0 on error.
 
bool buildOppositeTable ()
 Build the opposite table from the geometric data. Border sides are initialized with GMP_UIBHM_INVALID_VALUE. Border indices will be updated later by buildSurfaceBordersTable() or by adjustSolidInterfaceElementBorders() + buildSolidBordersTable()
 
bool updateOppositeTable (int numAddedCells)
 Updates the opposite table assuming numAddedCells where "appended" to the mesh. See remaining assumptions on the comments for addNewCells().
 
template<class Key , class MakeKey >
bool oppositeTableTraverseCells (MakeKey makeKey, int first, int last, QMap< Key, HalfSide > &adjMap)
 The work horse for both build & updateOppositeTable(), templated on the key type used to uniquely identify a cell side. The function parameter should be a function able to transform the given list of cell vertices into a key. First and last define the range of cells to be traversed and adjMap is the map used by the function to store and look for opposite sides.
 
bool buildVertexHalfSideTable ()
 Builds the VH table from the geometry data and the opposite table.
 
bool updateVertexHalfSideTable (int numAddedCells, QVector< HalfSide > &borderToIntBorderList)
 Updates the vertex half-side table assuming numAddedCells where "appended" to the mesh. See remaining assumptions on the comments for addNewCells().
 
void vertexHalfSideTableTraverseCells (int first, int last, const QSet< int > &oldCells=QSet< int >())
 Workhorse for both build& updateVertexHalfSideTable(). Besides traversing all cells in the [first, last] range, traverse elements in the optional oldCells set.
 
bool buildEdgeHalfFaceMap ()
 Builds the EH table from the geometry data and the opposite table.
 
bool updateEdgeHalfFaceMap (int numAddedCells)
 Updates the edge half-face table assuming numAddedCells where "appended" to the mesh. See remaining assumptions on the comments for addNewCells().
 
bool edgeHalfFaceMapTraverseCells (int first, int last)
 Workhorse for both build & updateEdgeHalfFaceMap()
 
bool adjustSolidInterfaceElementBorders ()
 Search for borders created by the intersection of solid mesh interface elements and mark them as such with the GMP_UIBHM_INTERFACE_BORDER special opposite flag.
 
bool updateSolidInterfaceElementBorders (int numAddedCells, QVector< HalfSide > &borderToIntBorderList)
 Search for new borders created by the intersection of solid mesh interface elements, assuming numAddedCells where "appended" to the mesh. See remaining assumptions on the comments for addNewCells().
 
bool solidInterfaceElementBordersTraverseCells (int first, int last, QVector< HalfSide > &borderToIntBorderList)
 Workhorse for both adjust & updateSolidInterfaceElementBorders(). See comments on the later for borderToIntBorderList.
 
bool buildSurfaceBordersTable ()
 Builds the borders table from the geometry data, the opposite table and the the Vertex Half-sides table for a surface mesh. It also patches _O to adjust the stored GMP_UIBHM_INVALID_VALUE values to the border index or to GMP_UIBHM_INTERFACE_BORDER for borders generated by interface element intersections.
 
bool updateSurfaceBordersTable (int numAddedCells)
 Updates the border table assuming numAddedCells where "appended" to the mesh. See remaining assumptions on the comments for addNewCells().
 
bool buildSolidBordersTable ()
 Builds the borders table from the geometry data, the opposite table and the the Vertex Half-sides table for a solid mesh. Assumes that eventual holes created by interface element intersections where already processed by adjustSolidInterfaceElementBorders() and are marked as GMP_UIBHM_INTERFACE_BORDER. It also patches _O to adjust the stored GMP_UIBHM_INVALID_VALUE values to the correct border index.
 
bool updateSolidBordersTable (int numAddedCells)
 Updates the border table assuming numAddedCells where "appended" to the mesh. See remaining assumptions on the comments for addNewCells().
 
BSIteratorborderSurfaceIterator (int borderIndex)
 Creates and returns the context needed for iterating over a solid mesh surface boundary by repeated calls to nextBorderSurface(). Returned pointer should be deleted after the iteration finished. Returns NULL on errors.
 
HalfSide nextBorderSurface (BSIterator *context)
 Iterates over a solid mesh border surface. Each call returns a new face. Returns GMP_UIBHM_INVALID_VALUE when there are no more faces to return.
 
bool numNodesDifferentFromNumEdges () const
 Aux function to check, for a surface mesh, whether any of the element types has the number of nodes different from the number of edges (can happen for quadratic or for some kinds of interface elements)
 
bool checkLimits (int ncells)
 Perform some consistency checks to guarantee that every used type conforms with UIBHM limits.
 
bool checkOppositeSides (HalfSide s1, HalfSide s2)
 Given two half sides, check that they have the same node incidence but oriented in opposite directions. If false, adds a message to _extraCheckErrors.
 
template<class Key >
bool checkOppositeMap (const QMap< Key, int > &countMap)
 Checks that every traversed side durring opposite table building was found at most twice.
 
bool fullNodeCheck ()
 Traverses each node from each (non strange) mesh cell, creating a mapping with the cells that share each node. Then executes a nodeAdjacentCells query and checks that the results match.
 
bool logError (QString msg)
 Logs an error (or a warning depending on check options). If we are building the structure and this is the first found error, also logs an initial message about the structure state. As a convenience, always returns false.
 
bool logFindFaceEdgeError (int cellId, int face, int v1, int v2, bool bidir=false)
 Logs an appropriate log message for findFaceEdge returning -1.
 
bool logFindNodeIndexError (int cellId, int v)
 Logs an appropriate log message for findNodeIndex returning -1.
 

Static Protected Member Functions

static size_t makeSurfaceKey (QVarLengthArray< int, 10 > &vertexList)
 Creates a map key from two vertices.
 
static V3 makeSolidKey3 (QVarLengthArray< int, 10 > &vertexList)
 Creates a map key from the 3 face vertices with smaller index. vertexList is sorted as a side effect.
 
static V4 makeSolidKey4 (QVarLengthArray< int, 10 > &vertexList)
 Creates a map key from up to 4 face vertices. vertexList is sorted as a side effect.
 

Protected Attributes

int _nhalf
 The number of half-sides in the mesh (either half-edges or half-faces)
 
int _lastAddedCells
 The number of mesh cells added to the topology when the structure was built / last updated.
 
bool _hasOffset
 Do we have a built offset table? Equal to (!_Of.isEmpty()). Stored since linearHs() is called quite often.
 
bool _needsEH
 Did the user asked for the EH map? Needed for the special case when the mesh is initialized empty and cells are added later.
 
HSVT _O
 The opposite table with _nhalf entries. For a half-side index 'hs', _O[linearHs(hs)] stores the half_side index of its opposite edge or face. If the half-side is a border side, the stored value will be a value X such that hsSide(X) is equal to GMP_UIBHM_BORDER_SIDE. Also, hsCell(X) will be the index in the _B table of the border that it belongs to, unless that border is generated by interface element intersections when X will be equal to GMP_UIBHM_INTERFACE_BORDER. After the table construction, but before border detection, border sides are all filled with GMP_UIBHM_INVALID_VALUE. Since 'strange' elements have no sides, there is no information for them in _O.
 
IVT _Of
 The side offset table. ONLY EXISTS for hybrid meshes and even though might be empty for surface meshes where, sometimes, the cell offset can be used instead. When present, it has numCells() entries storing the position of the element's first half-side in _O. Each entry is the accumulated sum of the number of sides in the previous cells. For SURFACE hybrid meshes, since the number of element sides (edges) is always equal to the number of element vertices, this table can be replaced by the offset information stored in each cell. Keep in mind that this is not true if we allow the user to add bars (strange cells) to the mesh or for quadratic cells. Strange cells have a number of sides equal to 0, so its position is equal to the next common cell position.
 
HSVT _VH
 The vertex half-side table with numNodes() entries. Each entry stores one half-side that contains that node. If the node belongs to the border, it is a border half-side including that node (for SURFACE meshes, the selected half-edge should start at that node). When checking for borders, priority is given for "true" borders, not belonging to interface element intersections, and then to interface element intersections (this allows for querying both if the node is on a "true" border or on a "topological" border, including those generated by interface element intersections). For quadratic nodes belonging to a half-side, that half-side is stored. For mid surface/volume nodes that do not belong to any side, a special value X is stored to allow for the recovery of the cell that this vertex belongs to. X is created in such a way that hsSide(X) is equal to GMP_UIBHM_MID_SIDE and hsCell(X) is the cell id. Nodes that do not belong to any half-side and are not a quadratic mid node (nodes belonging to strange cells only or not belonging to any cell at all) store the value GMP_UIBHM_INVALID_VALUE (-1 if taken as a signed value).
 
QVector< HalfSide_B
 The border table with one entry per border "curve" (2d) or "surface" (3d). It stores only one half-side from this border. Since we expect B to be a rather small table, which is constructed by calls to append(), we are better off using a QVector instead of our specialized Single / Dual Vector classes.
 
QMap< size_t, HalfSide_EH
 The edge half-face map. Indexed by edge id, it stores one of its incident half-faces. For SOLID meshes only. The edge id key is currently represented by a 64-bits value encoded as (v1 << 32 | v2), with v1 < v2, as defined by Geometry::encodeEdge(). If the edge is on a border, it should be the border half-face containing the v1->v2 half-edge (notice that a border edge belongs to either a "true" exterior border or to an interface element intersection border, never to both, so there is no need to prioritize one of them when selecting a border half-face, as we do when building _VH).
 
CheckOptions _extraChecks
 Should we perfrom extra checks on the mesh data to ensure that the mesh is adequate for the topology?
 
int _checking
 A flag set to 0 during query time, 1 when building the structure and 2 if an error was found while building.
 
const GmLogCategory_checkLogger
 The logger used for check messages.
 

Friends

class UibhmQuery< Geometry >
 
class UibhmSurfaceQuery< Geometry >
 
class UibhmSolidQuery< Geometry >
 

Detailed Description

template<class Geometry>
class UibhmTopology< Geometry >

brief The class storing topology information for the given mesh. The template parameter is the Geometry class that will be used to provide the geometric information from the mesh.

The topology info is based on the half-side (half-edge or half-face) concept. The primary information is the Opposite table storing, for each half-side, its 'twin'. We also have additional tables associating a vertex with a half-side and eventually an edge with a half-side (for solid meshes).

A border description is stored by storing one half-side from each border curve for surface meshes and on e hlaf-side from each border surface for solid meshes. Those seeds can be used to traverse the full set of border edges / faces. Notice that this does NOT allows for neighbor queries over a surface border. One possibility is to store a 2d version of the whole structure to index mesh surfaces.

Differently from the adopted by the CHE/CHF & IBHM implementations, Half-side indices are not a continuous set. Instead they are formed by a 32 bit number where the lower 28 bits are used to store the cell id (for up to 256M elements) and the higher 4 bits are used to store the local face/edge number in the cell. This schema allows for direct recovery of the cell and the side from the half-side index, and is used even for homogeneous meshes.

A side value equal to 1111 is used as a special value to represent border half-sides while a side value equal to 1110 is used to reresent a mid face / volume node (and so the maximum number of sides in a cell is 14 and not 16). For both surface and solid meshes, when the side is 1111, the remaining cellId bits are used to store the border index to which that edge / surface belongs unless that border is generated by interface element intersections. In that case the border is not stored and the cellId bits are set to 1 for all bits except the first, set to 0 (-2 when the value is sign extended). This distinction is necessary for correctly performing queries when interface elements are involved. When the side is 1110, the cellId bits store the cell that contains that mid face / volume node (and this is why we can't have a single special side - we need all bits from the cellId representation to store each possible cellId when storing mid face / volume values).

As a consequence of using non continuous half-side indices, the Opposite vector can not be indexed directly by the half-side index. The solution is to use a side offset table (as already used by IBHM). If we define the 'linearHs(hs)' function as Of[hsElement(hs)] + hsSide(hs), where hsElement(hs) extracts the element id from the lower bits of hs and hsSide(hs) extracts the local side number from the higher bits of hs, we can index O by O[linearHs(hs)].

For homogeneous meshes, the offset table does not need to be stored and each of its entries can be calculated based on the fixed number of element sides.

If a mesh has 'strange' elements, those are NOT added to the topology information. They are handled as if they have no sides at all.

Member Function Documentation

◆ addNewCells()

template<class Geometry >
bool UibhmTopology< Geometry >::addNewCells ( )
virtual

Adjusts the topological structure to include the cells appended to the mesh since the last time that the topological structure was built. Assumes that those cells are connected to the mesh by previous mesh borders (or are not connected to the mesh at all).

This method does NOT give support for editing the mesh (changing the node incidence of existing cells).

Implements UibhmTopologyBase.

◆ cellIsIndexed()

template<class Geometry >
virtual bool UibhmTopology< Geometry >::cellIsIndexed ( int cellId)
inlinevirtual

Returns true if the cell already was indexed by the topological structure by the last call to init() or addNewCells()

Implements UibhmTopologyBase.

◆ init()

template<class Geometry >
bool UibhmTopology< Geometry >::init ( bool buildEdgeMap,
CheckOptions extraChecks )
virtual

Builds the topology structure. Returns false on errors. The flag controls whether the edge-handle map should be built for solid meshes (this is by large the biggest stored structure, and so should only be built if needed). Ignored for surface meshes. The extra checks asks us to conduct extra testing on the mesh data.

Implements UibhmTopologyBase.

◆ updateSolidInterfaceElementBorders()

template<class Geometry >
bool UibhmTopology< Geometry >::updateSolidInterfaceElementBorders ( int numAddedCells,
QVector< HalfSide > & borderToIntBorderList )
protected

Search for new borders created by the intersection of solid mesh interface elements, assuming numAddedCells where "appended" to the mesh. See remaining assumptions on the comments for addNewCells().

The borderToIntBorderList returns, if any, the set of faces that where previously border faces and now are marked as interface element borders. That can happen in very specific cases and must be handled if any of those faces happen to be the value stored in _VH. (See the "Adding green cell + blue interface element" case from the addInterf2HexMesh regression test)

◆ updateVertexHalfSideTable()

template<class Geometry >
bool UibhmTopology< Geometry >::updateVertexHalfSideTable ( int numAddedCells,
QVector< HalfSide > & borderToIntBorderList )
protected

Updates the vertex half-side table assuming numAddedCells where "appended" to the mesh. See remaining assumptions on the comments for addNewCells().

For solid meshes, borderToIntBorderList can include faces that where border faces and became internal interface element border faces (holes created by interface element intersections)


The documentation for this class was generated from the following files: