GemaCoreLib
The GeMA Core library
Loading...
Searching...
No Matches
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#include <QDataStream>
30
31class GmPCR;
32
35{
41 //------------------------
42 // Please do not change this enumeration without also changing the static
43 // GmSegmentCellIntersection::kindToStr() method
45};
46
47
61{
62public:
64
65 // Intersection point data
67 {
71 int _border;
72
73 IntersectionPoint() : _kind(GM_NO_INTERSECTION), _border(-1) {}
74 void set(const GmVector& cc, GmSegmentCellIntersectionPointKind kind, int border)
75 {
76 _cartCoord = cc;
77 _kind = kind;
78 _border = border;
79 }
80 };
81
82 int _cellId;
84
87
88 int _edge;
89 int _face;
91 bool _single;
93
94 static const char* kindToStr(GmSegmentCellIntersectionPointKind kind);
95
96 void print(const GmPCR* pcr, const GmLogCategory& logger, GmLogLevel level) const;
97};
98
109{
110public:
112
114 int cellId() const { return _cellId; }
115
125 SegmentId segmentId() const { return _segmentId; }
126
128 void setSegmentIdIndex(int index) { _segmentId.second = index; }
129
132 {
133 assert(i == 0 || i == 1);
134 if(i == 0)
135 return (GmSegmentCellIntersectionPointKind)(_kindAndFlags & 0x07);
136 else
137 return (GmSegmentCellIntersectionPointKind)((_kindAndFlags >> 3) & 0x07);
138 }
139
143 int border(int i) const { assert(i == 0 || i == 1); return _border[i]; }
144
146 int edge() const
147 {
148 // Since the edge can be -1, for the code below to work we need a signed right shift
149 // to be an arithmetic shift.
150 // Until c++ 20, right shifts on signed numbers where implementation defined behaviour,
151 // but implemented as expected in every sane compiler (using two's complement)
152 // The assert below checks that so we can have peace of mind.
153 // 01010101 >> 1 == 00101010 10101010 >> 1 == 11010101
154 static_assert(((qint8)0x55 >> 1 == (qint8)0x2A) && ((qint8)0xAA >> 1 == (qint8)0xD5), "signed right shift is NOT an arithmetic shift");
155 return (qint8)_edgeAndNatSize >> 2;
156 }
157
165 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; }
166
168 const double* rawCartCoord(int i) const { assert(i == 0 || i == 1); return &_cartCoord[2*i]; }
169
171 GmVector natCoord(int i) const
172 {
173 assert(i == 0 || i == 1);
174 int n = numNatCoordinates();
175 const double* ncptr = _natCoord + hasIntersectionElementId();
176
177 GmVector v(n);
178 for(int j = 0; j < n; j++)
179 v[j] = ncptr[n*i + j];
180 return v;
181 }
182
183 GmVector normal() const { return GmVector({ _normal[0], _normal[1] }); }
184
186 bool continuous() const { return _kindAndFlags & 0x40; }
187
189 void setContinuous(bool mode)
190 {
191 if(mode)
192 _kindAndFlags |= 0x40; // Set bit 7
193 else
194 _kindAndFlags &= (~0x40); // Clear bit 7
195 }
196
198 bool segmentIntersection() const { return _kindAndFlags & 0x80; }
199
201 void setSegmentIntersection() { _kindAndFlags |= 0x80; }
202
204 bool hasIntersectionElementId() const { return _edgeAndNatSize & 0x02; }
205
206 // Returns the stored intersection element id or -1 if not stored
207 int intersectionElementId() const { return hasIntersectionElementId() ? _natCoord[0] : -1; }
208
210 void setIntersectionElementId(int id) { assert(hasIntersectionElementId()); _natCoord[0] = id; }
211
212 void updateOutputData(const GmCompact2DSegmentCellIntersection* out, int edge);
213 void updateOutputData(const GmVector& cartCoord, const GmVector& natCoord, GmSegmentCellIntersectionPointKind kind, int border);
214
215 void print(const GmPCR* pcr, const GmLogCategory& logger, GmLogLevel level) const;
216
218 size_t memSize() const {
219 size_t elemIdSize = hasIntersectionElementId() ? 1 : 0;
220 return sizeof(GmCompact2DSegmentCellIntersection) + (2 * numNatCoordinates() - 1 + elemIdSize) * sizeof(double);
221 }
222
223 static GmCompact2DSegmentCellIntersection* instance(const GmSegmentCellIntersection& data, int segmentIndex, bool hasIntElementId);
224
225 void operator delete(void* ptr);
226 void operator delete(void* ptr, int, bool);
227
228private:
230
232 GmCompact2DSegmentCellIntersection(const GmSegmentCellIntersection& data, int segmentIndex, bool hasIntElementId);
233
234 void* operator new(std::size_t count, int nnatural, bool hasIntElementId);
235
237 void updateNormal(const GmCompact2DSegmentCellIntersection* out);
238
240 int numNatCoordinates() const { return 2 + (_edgeAndNatSize & 0x01); }
241
244
245 // The above fields are stored in 3 ints, or 12 bytes. For an 8 bytes alignment, before the coordinate
246 // vectors (storing doubles), we have a 4 bytes zone that will be filled with the remaining data.
247 // - Both in and out intersection kinds will be compacted in the 6 lower bits. The remaining two high
248 // bits are used to store flags for continuous segments (bit 7) and for segments belonging to an inter
249 // segments intersection (bit 8).
250 // - Each in and out border value will get its own byte. We could compact them in a single byte
251 // (taking care with the value sign since it can store -1) but since we have 4 bytes to spend
252 // we leave each one in its own field
253 // - The edge field is stored in the six most significant bits of the fourth byte. We use the
254 // two lower bits to store whether we have a third natural coordinate (bit 1 set to 1) and
255 // whether we have an associated intersection element id stored "as contraband" in the
256 // begining of the _natCoord flexible array (bit 2 set to 1). By doing that we get the flexibility
257 // of paying the price for storing the id only if needed. Please keep in mind that, due to 8 bytes
258 // alignment, adding an extra int id field after _edgeAndNatSize, would take the same 8 bytes
259 // space as the double used to store it in the _natCoord vector.
260
265
267 qint8 _border[2];
268
274
276 double _cartCoord[4];
277
279 double _normal[2];
280
287 double _natCoord[1];
288
289 //QT serialization operators
292};
293
294
295
296
297#endif // _GEMA_SEGMENT_CELL_INTERSECT_H_
A (much more) compact version of GmSegmentCellIntersection for 2d intersections only....
Definition gmSegmentCellIntersection.h:109
bool hasIntersectionElementId() const
Returns true if this object was created with the option to store an intersection element id.
Definition gmSegmentCellIntersection.h:204
void setSegmentIdIndex(int index)
Updates the segment index part of the segment Id.
Definition gmSegmentCellIntersection.h:128
int _cellId
The cell id.
Definition gmSegmentCellIntersection.h:242
bool continuous() const
Returns true if this intersection segment start point is the same as the last point for the previous ...
Definition gmSegmentCellIntersection.h:186
quint8 _edgeAndNatSize
6 most significant bits store the edge number, if the segment lies over an edge, or -1 otherwise....
Definition gmSegmentCellIntersection.h:273
GmSegmentCellIntersectionPointKind kind(int i) const
Returns the intersection kind for the given intersection point (0 = first, 1 = second).
Definition gmSegmentCellIntersection.h:131
int numNatCoordinates() const
Returns the number of entries in a natural coordinate for the element cell type.
Definition gmSegmentCellIntersection.h:240
quint8 _kindAndFlags
The kind enum value for both intersection points compacted at bits 1-3 (first) / 4-6 (second)....
Definition gmSegmentCellIntersection.h:264
SegmentId segmentId() const
Returns the segment id (discontinuity index in the set + segment index in the intersection list)
Definition gmSegmentCellIntersection.h:125
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:143
void setIntersectionElementId(int id)
Updates the stored intersection element id. Can only be called if hasIntersectionElementId() returns ...
Definition gmSegmentCellIntersection.h:210
bool segmentIntersection() const
Returns true if this intersection segment takes part in an inter segments intersection.
Definition gmSegmentCellIntersection.h:198
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:168
QPair< int, int > SegmentId
Discontinuity index, segment index in the intersection list.
Definition gmSegmentCellIntersection.h:111
int cellId() const
Returns the cell id.
Definition gmSegmentCellIntersection.h:114
SegmentId _segmentId
The segment id (discontinuity id + segment index)
Definition gmSegmentCellIntersection.h:243
size_t memSize() const
Returns the (computed) memory size allocated for this class when ::instace was called.
Definition gmSegmentCellIntersection.h:218
GmVector cartCoord(int i) const
Returns the cartesian coordinate for the given intersection point (0 = first, 1 = second),...
Definition gmSegmentCellIntersection.h:165
void setSegmentIntersection()
Mark this intersection as taking part in an inter segments intersection.
Definition gmSegmentCellIntersection.h:201
GmVector natCoord(int i) const
Returns the natural coordinate for the given intersection point (0 = first, 1 = second).
Definition gmSegmentCellIntersection.h:171
int edge() const
If the segment lies over an edge, returns the intersected edge number. -1 otherwise.
Definition gmSegmentCellIntersection.h:146
void setContinuous(bool mode)
Updates the continuous flag.
Definition gmSegmentCellIntersection.h:189
Class representing a category with multiple logging levels.
Definition gmLog.h:58
Base interface class for Partition-Color-Renumber object plugins.
Definition gmPCR.h:54
#define GMC_API_EXPORT
Macro for controlling if the class is being exported (GEMA_CORE_LIB defined) or imported (GEMA_CORE_L...
Definition gmCoreConfig.h:35
Declaration of support functions and macros for information logging.
GmLogLevel
Available log levels list.
Definition gmLog.h:36
GmSegmentCellIntersectionPointKind
Intersection point type between a segment and a 2D or 3D cell.
Definition gmSegmentCellIntersection.h:35
@ GM_NODE_INTERSECTION
The intersection occurrs at one of the cell nodes.
Definition gmSegmentCellIntersection.h:37
@ GM_INTERNAL_INTERSECTION
The intersected segment starts or ends inside the cell.
Definition gmSegmentCellIntersection.h:40
@ GM_FACE_INTERSECTION
The intersection occurrs at one of the cell faces (3D only)
Definition gmSegmentCellIntersection.h:39
@ GM_NUM_INTERSECTION_POINT_KIND
The number of entries in this enum.
Definition gmSegmentCellIntersection.h:44
@ GM_NO_INTERSECTION
There is no intersection. Used by the default constructor to identify an invalid object.
Definition gmSegmentCellIntersection.h:36
@ GM_EDGE_INTERSECTION
The intersection occurrs at one of the cell edges.
Definition gmSegmentCellIntersection.h:38
Declaration of the GmVector class.
arma::vec GmVector
The basic type for a GeMA vector object. Currently based on an Armadillo vector.
Definition gmVector.h:34
Definition gmSegmentCellIntersection.h:67
int _border
The local node / edge / face index if _kind is not INTERNAL. -1 if it is.
Definition gmSegmentCellIntersection.h:71
GmVector _cartCoord
The cartesian coordinate of the intersection point.
Definition gmSegmentCellIntersection.h:68
GmSegmentCellIntersectionPointKind _kind
The kind of the intersection point.
Definition gmSegmentCellIntersection.h:70
GmVector _natCoord
The natural coordinate of the intersection point.
Definition gmSegmentCellIntersection.h:69
Representation for the intersection between a polyline segment and a mesh cell. Can be used both in 2...
Definition gmSegmentCellIntersection.h:61
int _cellId
The cell id.
Definition gmSegmentCellIntersection.h:82
int _face
In 3D, if the segment lies over a face, stores the face number. -1 otherwise.
Definition gmSegmentCellIntersection.h:89
GmVector _normal
Approximated normal from original segment.
Definition gmSegmentCellIntersection.h:92
IntersectionPoint _out
The data for the second intersection point in the polyline direction.
Definition gmSegmentCellIntersection.h:86
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:90
bool _single
A flag set to true if in & out where collapsed into a single point.
Definition gmSegmentCellIntersection.h:91
IntersectionPoint _in
The data for the first intersection point in the polyline direction.
Definition gmSegmentCellIntersection.h:85
int _edge
In 2D or 3D, if the segment lies over an edge, stores the edge number. -1 otherwise.
Definition gmSegmentCellIntersection.h:88
SegmentId _segmentId
The segment id (discontinuity id + segment index in the original discontinuity info)
Definition gmSegmentCellIntersection.h:83
QPair< int, int > SegmentId
Discontinuity index, segment index in the original discontinuity info.
Definition gmSegmentCellIntersection.h:63