GemaCoreLib
The GeMA Core library
gmSegmentCellIntersection.h
Go to the documentation of this file.
1 /************************************************************************
2 **
3 ** Copyright (C) 2023 by Carlos Augusto Teixeira Mendes
4 ** All rights reserved.
5 **
6 ** This file is part of the "GeMA" software. It's use should respect
7 ** the terms in the license agreement that can be found together
8 ** with this source code.
9 ** It is provided AS IS, with NO WARRANTY OF ANY KIND,
10 ** INCLUDING THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR
11 ** A PARTICULAR PURPOSE.
12 **
13 ************************************************************************/
14 
24 #ifndef _GEMA_SEGMENT_CELL_INTERSECT_H_
25 #define _GEMA_SEGMENT_CELL_INTERSECT_H_
26 
27 #include "gmLog.h"
28 #include "gmVector.h"
29 
30 
33 {
39  //------------------------
40  // Please do not change this enumeration without also changing the static
41  // GmSegmentCellIntersection::kindToStr() method
43 };
44 
45 
59 {
60 public:
62 
63  // Intersection point data
65  {
69  int _border;
70 
71  IntersectionPoint() : _kind(GM_NO_INTERSECTION), _border(-1) {}
72  void set(const GmVector& cc, GmSegmentCellIntersectionPointKind kind, int border)
73  {
74  _cartCoord = cc;
75  _kind = kind;
76  _border = border;
77  }
78  };
79 
80  int _cellId;
82 
85 
86  int _edge;
87  int _face;
88  bool _continuous;
89  bool _single;
90 
91  static const char* kindToStr(GmSegmentCellIntersectionPointKind kind);
92 
93  void print(const GmLogCategory& logger, GmLogLevel level) const;
94 };
95 
106 {
107 public:
109 
111  int cellId() const { return _cellId; }
112 
122  SegmentId segmentId() const { return _segmentId; }
123 
125  void setSegmentIdIndex(int index) { _segmentId.second = index; }
126 
129  {
130  assert(i == 0 || i == 1);
131  if(i == 0)
132  return (GmSegmentCellIntersectionPointKind)(_kindAndFlags & 0x07);
133  else
134  return (GmSegmentCellIntersectionPointKind)((_kindAndFlags >> 3) & 0x07);
135  }
136 
140  int border(int i) const { assert(i == 0 || i == 1); return _border[i]; }
141 
143  int edge() const
144  {
145  // Since the edge can be -1, for the code bellow to work we need a signed right shift
146  // to be an arithmetic shift.
147  // Until c++ 20, right shifts on signed numbers where implementation defined behaviour,
148  // but implemented as expected in every sane compiler (using two's complement)
149  // The assert bellow checks that so we can have peace of mind.
150  // 01010101 >> 1 == 00101010 10101010 >> 1 == 11010101
151  static_assert(((qint8)0x55 >> 1 == (qint8)0x2A) && ((qint8)0xAA >> 1 == (qint8)0xD5), "signed right shift is NOT an arithmetic shift");
152  return (qint8)_edgeAndNatSize >> 2;
153  }
154 
162  GmVector cartCoord(int i) const { assert(i == 0 || i == 1); GmVector v(2); v[0] = _cartCoord[2*i]; v[1] = _cartCoord[2*i+1]; return v; }
163 
165  const double* rawCartCoord(int i) const { assert(i == 0 || i == 1); return &_cartCoord[2*i]; }
166 
168  GmVector natCoord(int i) const
169  {
170  assert(i == 0 || i == 1);
171  int n = numNatCoordinates();
172  const double* ncptr = _natCoord + hasIntersectionElementId();
173 
174  GmVector v(n);
175  for(int j = 0; j < n; j++)
176  v[j] = ncptr[n*i + j];
177  return v;
178  }
179 
181  bool continuous() const { return _kindAndFlags & 0x40; }
182 
184  void setContinuous(bool mode)
185  {
186  if(mode)
187  _kindAndFlags |= 0x40; // Set bit 7
188  else
189  _kindAndFlags &= (~0x40); // Clear bit 7
190  }
191 
193  bool segmentIntersection() const { return _kindAndFlags & 0x80; }
194 
196  void setSegmentIntersection() { _kindAndFlags |= 0x80; }
197 
199  bool hasIntersectionElementId() const { return _edgeAndNatSize & 0x02; }
200 
201  // Returns the stored intersection element id or -1 if not stored
202  int intersectionElementId() const { return hasIntersectionElementId() ? _natCoord[0] : -1; }
203 
205  void setIntersectionElementId(int id) { assert(hasIntersectionElementId()); _natCoord[0] = id; }
206 
207  void updateOutputData(const GmCompact2DSegmentCellIntersection* out, int edge);
208  void updateOutputData(const GmVector& cartCoord, const GmVector& natCoord, GmSegmentCellIntersectionPointKind kind, int border);
209 
210  void print(const GmLogCategory& logger, GmLogLevel level) const;
211 
212  static GmCompact2DSegmentCellIntersection* instance(const GmSegmentCellIntersection& data, int segmentIndex, bool hasIntElementId);
213 
214  void operator delete(void* ptr);
215  void operator delete(void* ptr, int, bool);
216 
217 private:
218  Q_DISABLE_COPY(GmCompact2DSegmentCellIntersection);
219 
221  GmCompact2DSegmentCellIntersection(const GmSegmentCellIntersection& data, int segmentIndex, bool hasIntElementId);
222 
223  void* operator new(std::size_t count, int nnatural, bool hasIntElementId);
224 
226  int numNatCoordinates() const { return 2 + (_edgeAndNatSize & 0x01); }
227 
228  int _cellId;
230 
231  // The above fields are stored in 3 ints, or 12 bytes. For an 8 bytes alignment, before the coordinate
232  // vectors (storing doubles), we have a 4 bytes zone that will be filled with the remaining data.
233  // - Both in and out intersection kinds will be compacted in the 6 lower bits. The remaining two high
234  // bits are used to store flags for continuous segments (bit 7) and for segments belonging to an inter
235  // segments intersection (bit 8).
236  // - Each in and out border value will get its own byte. We could compact them in a single byte
237  // (taking care with the value sign since it can store -1) but since we have 4 bytes to spend
238  // we leave each one in its own field
239  // - The edge field is stored in the six most significant bits of the fourth byte. We use the
240  // two lower bits to store whether we have a third natural coordinate (bit 1 set to 1) and
241  // whether we have an associated intersection element id stored "as contraband" in the
242  // begining of the _natCoord flexible array (bit 2 set to 1). By doing that we get the flexibility
243  // of paying the price for storing the id only if needed. Please keep in mind that, due to 8 bytes
244  // alignment, adding an extra int id field after _edgeAndNatSize, would take the same 8 bytes
245  // space as the double used to store it in the _natCoord vector.
246 
250  quint8 _kindAndFlags;
251 
253  qint8 _border[2];
254 
260 
262  double _cartCoord[4];
263 
270  double _natCoord[1];
271 };
272 
273 
274 #endif // _GEMA_SEGMENT_CELL_INTERSECT_H_
SegmentId _segmentId
The segment id (discontinuity id + segment index)
Definition: gmSegmentCellIntersection.h:229
GmSegmentCellIntersectionPointKind kind(int i) const
Returns the intersection kind for the given intersection point (0 = first, 1 = second).
Definition: gmSegmentCellIntersection.h:128
Representation for the intersection between a polyline segment and a mesh cell. Can be used both in 2...
Definition: gmSegmentCellIntersection.h:58
GmSegmentCellIntersectionPointKind
Intersection point type between a segment and a 2D or 3D cell.
Definition: gmSegmentCellIntersection.h:32
The intersection occurrs at one of the cell faces (3D only)
Definition: gmSegmentCellIntersection.h:37
int _cellId
The cell id.
Definition: gmSegmentCellIntersection.h:80
IntersectionPoint _out
The data for the second intersection point in the polyline direction.
Definition: gmSegmentCellIntersection.h:84
int _edge
In 2D or 3D, if the segment lies over an edge, stores the edge number. -1 otherwise.
Definition: gmSegmentCellIntersection.h:86
GmSegmentCellIntersectionPointKind _kind
The kind of the intersection point.
Definition: gmSegmentCellIntersection.h:68
GmVector natCoord(int i) const
Returns the natural coordinate for the given intersection point (0 = first, 1 = second).
Definition: gmSegmentCellIntersection.h:168
quint8 _kindAndFlags
The kind enum value for both intersection points compacted at bits 1-3 (first) / 4-6 (second)....
Definition: gmSegmentCellIntersection.h:250
int border(int i) const
If kind(i) is not INTERNAL, returns the local node / edge index for the given intersection point (0 =...
Definition: gmSegmentCellIntersection.h:140
void setSegmentIntersection()
Mark this intersection as taking part in an inter segments intersection.
Definition: gmSegmentCellIntersection.h:196
The intersection occurrs at one of the cell nodes.
Definition: gmSegmentCellIntersection.h:35
There is no intersection. Used by the default constructor to identify an invalid object.
Definition: gmSegmentCellIntersection.h:34
bool continuous() const
Returns true if this intersection segment start point is the same as the last point for the previous ...
Definition: gmSegmentCellIntersection.h:181
void setContinuous(bool mode)
Updates the continuous flag.
Definition: gmSegmentCellIntersection.h:184
quint8 _edgeAndNatSize
6 most significant bits store the edge number, if the segment lies over an edge, or -1 otherwise....
Definition: gmSegmentCellIntersection.h:259
int _face
In 3D, if the segment lies over a face, stores the face number. -1 otherwise.
Definition: gmSegmentCellIntersection.h:87
bool segmentIntersection() const
Returns true if this intersection segment takes part in an inter segments intersection.
Definition: gmSegmentCellIntersection.h:193
int _border
The local node / edge / face index if _kind is not INTERNAL. -1 if it is.
Definition: gmSegmentCellIntersection.h:69
void print(const GmMatrix &m, const GmLogCategory &logger, GmLogLevel level, int fieldWidth, char format, int precision)
Prints the matrix using the specified logger, level and precision fields.
Definition: gmMatrixUtils.cpp:34
SegmentId segmentId() const
Returns the segment id (discontinuity index in the set + segment index in the intersection list)
Definition: gmSegmentCellIntersection.h:122
Declaration of the GmVector class.
#define GMC_API_EXPORT
Macro for controling if the class is being exported (GEMA_CORE_LIB defined) or imported (GEMA_CORE_LI...
Definition: gmCoreConfig.h:35
int numNatCoordinates() const
Returns the number of entries in a natural coordinate for the element cell type.
Definition: gmSegmentCellIntersection.h:226
QPair< int, int > SegmentId
Discontinuity index, segment index in the intersection list.
Definition: gmSegmentCellIntersection.h:108
bool _continuous
A flag set to true if this intersection segment start point is the same as the last point for the pre...
Definition: gmSegmentCellIntersection.h:88
A (much more) compact version of GmSegmentCellIntersection for 2d intersections only....
Definition: gmSegmentCellIntersection.h:105
GmVector _natCoord
The natural coordinate of the intersection point.
Definition: gmSegmentCellIntersection.h:67
GmLogLevel
Available log levels list.
Definition: gmLog.h:36
The number of entries in this enum.
Definition: gmSegmentCellIntersection.h:42
GmVector _cartCoord
The cartesian coordinate of the intersection point.
Definition: gmSegmentCellIntersection.h:66
SegmentId _segmentId
The segment id (discontinuity id + segment index in the original discontinuity info)
Definition: gmSegmentCellIntersection.h:81
Class representing a category with multiple logging levels.
Definition: gmLog.h:58
The intersection occurrs at one of the cell edges.
Definition: gmSegmentCellIntersection.h:36
QPair< int, int > SegmentId
Discontinuity index, segment index in the original discontinuity info.
Definition: gmSegmentCellIntersection.h:61
int cellId() const
Returns the cell id.
Definition: gmSegmentCellIntersection.h:111
IntersectionPoint _in
The data for the first intersection point in the polyline direction.
Definition: gmSegmentCellIntersection.h:83
Definition: gmSegmentCellIntersection.h:64
int edge() const
If the segment lies over an edge, returns the intersected edge number. -1 otherwise.
Definition: gmSegmentCellIntersection.h:143
GmVector cartCoord(int i) const
Returns the cartesian coordinate for the given intersection point (0 = first, 1 = second),...
Definition: gmSegmentCellIntersection.h:162
bool hasIntersectionElementId() const
Returns true if this object was created with the option to store an intersection element id.
Definition: gmSegmentCellIntersection.h:199
int _cellId
The cell id.
Definition: gmSegmentCellIntersection.h:228
const double * rawCartCoord(int i) const
Same as cartCoord(i) but returning a pointer to the internal buffer. No cdata copy to construct a GmV...
Definition: gmSegmentCellIntersection.h:165
void setIntersectionElementId(int id)
Updates the stored intersection element id. Can only be called if hasIntersectionElementId() returns ...
Definition: gmSegmentCellIntersection.h:205
bool _single
A flag set to true if in & out where collapsed into a single point.
Definition: gmSegmentCellIntersection.h:89
The intersected segment starts or ends inside the cell.
Definition: gmSegmentCellIntersection.h:38
arma::vec GmVector
The basic type for a GeMA vector object. Currently based on an Armadillo vector.
Definition: gmVector.h:34
void setSegmentIdIndex(int index)
Updates the segment index part of the segment Id.
Definition: gmSegmentCellIntersection.h:125
Declaration of support functions and macros for information logging.