rsvs3D  0.0.0
Codes for the c++ implementation of the 3D RSVS
snake.hpp
Go to the documentation of this file.
1 
9 //===============================================
10 // Include Guards
11 #ifndef SNAKSTRUCT_H_INCLUDED
12 #define SNAKSTRUCT_H_INCLUDED
13 
14 //===============================================
15 // Levels of debuging Guards
16 #ifdef DEBUGLVL2 // All Debugging calls
17 #define DEBUGLVL1
18 
19 #define TEST_SNAKSTRUCT
20 
21 #endif
22 
23 #ifdef DEBUGLVL1 // Debugging of new features.
24 #endif
25 
26 //=================================
27 // forward declared dependencies
28 // class foo; //when you only need a pointer not the actual object
29 // and to avoid circular dependencies
30 
31 //=================================
32 // included dependencies
33 #include <cmath>
34 #include <iostream>
35 #include <unordered_map>
36 #include <vector>
37 
38 #include "arraystructures.hpp"
39 #include "mesh.hpp"
40 
41 //==================================
42 // Code
43 // NOTE: function in a class definition are IMPLICITELY INLINED
44 // ie replaced by their code at compile time
45 
46 class snax;
47 class snaxedge;
48 class snaxsurf;
49 class snaxarray;
50 class snake;
51 
54 
55 class snaxarray : public SnakStruct<snax>
56 {
57  protected:
59  int isOrderedOnEdge = 0;
60 
61  public:
62  friend class snake;
63  friend class snax;
64  friend void SpawnArrivedSnaxelsDir(snake &fullsnake, snake &partSnake, const std::vector<int> &isImpact, int dir);
65 
66  void ReorderOnEdge();
67  void OrderOnEdge();
68  void CalculateTimeStepOnEdge(std::vector<double> &dt, std::vector<bool> &isSnaxDone, int edgeInd);
69  void DetectImpactOnEdge(std::vector<int> &isImpact, std::vector<bool> &isSnaxDone, int edgeInd);
70  // Functions that need modification
71  bool checkready();
72  void ForceArrayReady();
73  void PrepareForUse();
74  void Concatenate(const snaxarray &other);
75  snax &operator[](const int a)
76  {
77  isOrderedOnEdge = 0;
78  return (this->SnakStruct<snax>::operator[](a));
79  }
80 };
81 
82 class snake
83 {
84  // NOTE: *this=other; when adding attributes do not forget to add it to
85  // the assignement operator.
86 
87  private:
88  mesh *privatesnakemesh = NULL;
89  bool snaxDistanceLimit_conserveShape = true;
90  bool isSetStepLimit = false;
91  bool is3D = true;
92  bool isFlipped = false;
93 
94  void SetLastIndex(); // Baaaad function do not use if you're not sure.
95  void OrientSurfaceVolume();
96  void OrientEdgeSurface();
97 
98  public:
99  // Handling of data specific to snake
100  snaxarray snaxs; // properties associated with snakconn verts
101  snaxedgearray snaxedges; // properties associated with snakconn edges
102  snaxsurfarray snaxsurfs; // properties associated with snakconn surfs
103  // Using the mesh container to store connectivity
104  mesh snakeconn;
105  // pointer to snaking mesh
106  mesh *snakemesh() const
107  {
108  return this->privatesnakemesh;
109  };
110 
111  std::vector<bool> isMeshVertIn;
112  std::vector<double> edgeStepLimit;
113  // basic operations grouped from each field
114  void disp() const;
115  void displight() const;
116  bool isready() const;
117  void clear()
118  {
119  this->snaxs.clear();
120  this->snaxedges.clear();
121  this->snaxsurfs.clear();
122  this->snakeconn.clear();
123  this->isMeshVertIn.clear();
124  this->edgeStepLimit.clear();
125  this->isSetStepLimit = false;
126  this->isFlipped = false;
127  }
128  void PrepareForUse(bool needOrder = true);
129  void Init(mesh *snakemeshin, int nSnax, int nEdge, int nSurf, int nVolu);
130  void SetSnakeMesh(mesh *snakemeshin);
131  void reserve(int nSnax, int nEdge, int nSurf, int nVolu);
132  inline void GetMaxIndex(int *nVert, int *nEdge, int *nSurf, int *nVolu) const;
133  void HashArray(); // Not really needed as handled by PrepareForUse
134  void HashArrayNM(); // Not really needed as handled by PrepareForUse
135  void HashParent();
136  void SetMaxIndex(); // Not really needed as handled by PrepareForUse
137  void SetMaxIndexNM(); // SetMaxIndex no mesh
138  void Concatenate(const snake &other, int isInternal = 0);
139  bool Check3D() const
140  {
141  return (is3D);
142  }
143  // Snake merging
144  void MakeCompatible_inplace(snake &other) const;
145  snake MakeCompatible(snake other) const;
146  void ChangeIndices(int nVert, int nEdge, int nSurf, int nVolu);
147  void ChangeIndicesSnakeMesh(int nVert, int nEdge, int nSurf, int nVolu);
148  void ForceCloseContainers();
149  // Snake Movement
150  void UpdateDistance(double dt, double maxDstep = 1.0, bool scaledStep = false);
151  void UpdateDistance(const std::vector<double> &dt, double maxDstep = 1.0, bool scaledStep = false);
152  void CalculateTimeStep(std::vector<double> &dt, double dtDefault, double distDefault = 1.0);
153  double SnaxStepLimit(int snaxSub) const;
154  void SetEdgeStepLimits();
155  void SnaxImpactDetection(std::vector<int> &isImpact);
156  void SnaxAlmostImpactDetection(std::vector<int> &isImpact, double dDlim);
157  void UpdateCoord();
158  void UpdateCoord(const std::vector<int> &snaxInds);
159  void Flip(); // reverses snake directions
160  grid::limits Scale(const grid::limits &newSize);
161  // Snake connectivity operations
162  void OrderEdges();
163  void SetSnaxSurfs()
164  {
165  }
166  void OrientFaces();
167  int FindBlockSnakeMeshVerts(std::vector<int> &vertBlock) const;
168  void AssignInternalVerts();
169  void CheckConnectivity() const;
170  void TakeSpawnStep(int minIndex, double stepLength);
171  void TakeSmoothSpawnStep(int minIndex, double stepLength, std::string smoothStep = "none");
172  void VertIsIn(int vertInd, bool isIn = true);
173  void VertIsIn(std::vector<int> vertInd, bool isIn = true);
174  bool ReturnFlip() const
175  {
176  return (isFlipped);
177  }
178  // io of snake
179  void read(FILE *fid);
180  void write(FILE *fid) const;
181  int read(const char *str);
182  int write(const char *str) const;
183  std::vector<double> MoveDirections() const;
184 
185  void SetSnaxDistanceLimit_conserveShape(bool in)
186  {
187  this->snaxDistanceLimit_conserveShape = in;
188  }
189 };
190 
191 class snax : public meshpart, public snakpart
192 {
193  public:
194  double d = 0.0;
195  double v = 0.0;
196  int fromvert = 0; // root vertex of *snakemesh
197  int tovert = 0; // destination vertex of *snakemesh
198  int edgeind = 0; // edge of snakemesh()
199  int isfreeze = 0; // freeze status
200  int orderedge = 0; // order on the edge
201 
202  // interface functions
203  void disp() const;
204  void disptree(const mesh &meshin, int n) const;
205  void disptree(const snake &snakein, int n) const;
206  double value(const mesh &meshin) const
207  {
208  return meshin.verts.isearch(this->index)->value(meshin);
209  }
210  int Key() const
211  {
212  return (index);
213  };
214  int KeyParent() const
215  {
216  return (edgeind);
217  };
218  void ChangeIndices(int nVert, int nEdge, int nSurf, int nVolu);
219  void ChangeIndicesSnakeMesh(int nVert, int nEdge, int nSurf, int nVolu);
220  void PrepareForUse(){};
221 #pragma GCC diagnostic push
222 #pragma GCC diagnostic ignored "-Wunused-parameter"
223  bool isready(bool isInMesh) const
224  {
225  return (true);
226  }
227 #pragma GCC diagnostic pop
228  void read(FILE *fid);
229  void write(FILE *fid) const;
230  inline void set(int index, double d, double v, int fromvert, int tovert, int edgeind, int isfreeze, int orderedge);
231  void SwitchIndex(int typeInd, int oldInd, int newInd);
232  void TightenConnectivity()
233  {
234  }
235  void TakeSpawnStep(snake &snakein, double stepLength);
236  int CloseToVertex(bool far = false) const
237  {
238  return ((d < 0.5) ^ far) ? fromvert : tovert;
239  }
240  void ValidateDistance(snake &snakein);
241  void Direction(const snake &snakein, coordvec &dir) const;
242 };
243 
244 class snaxedge : public meshpart, public snakpart
245 {
246  public:
247  int surfind = 0;
248  coordvec normvector;
249 
250  void PrepareForUse();
251  void disp() const;
252  void disptree(const mesh &meshin, int n) const;
253  void disptree(const snake &snakein, int n) const;
254  double value(const mesh &meshin) const
255  {
256  return meshin.edges.isearch(this->index)->value(meshin);
257  }
258  int Key() const
259  {
260  return (index);
261  };
262  int KeyParent() const
263  {
264  return (surfind);
265  };
266  void ChangeIndices(int nVert, int nEdge, int nSurf, int nVolu);
267  void ChangeIndicesSnakeMesh(int nVert, int nEdge, int nSurf, int nVolu);
268 #pragma GCC diagnostic push
269 #pragma GCC diagnostic ignored "-Wunused-parameter"
270  bool isready(bool isInMesh) const
271  {
272  return (normvector.isready());
273  }
274 #pragma GCC diagnostic pop
275  void read(FILE *fid);
276  void write(FILE *fid) const;
277  void SwitchIndex(int typeInd, int oldInd, int newInd);
278  void TightenConnectivity()
279  {
280  }
281 };
282 
283 class snaxsurf : public meshpart, public snakpart
284 {
285  public:
286  int voluind = 0;
287  coordvec normvector;
288  void PrepareForUse();
289  void disp() const;
290  void disptree(const mesh &meshin, int n) const;
291  void disptree(const snake &snakein, int n) const;
292  double value(const mesh &meshin) const
293  {
294  return meshin.surfs.isearch(this->index)->value(meshin);
295  }
296  int Key() const
297  {
298  return (index);
299  };
300  int KeyParent() const
301  {
302  return (voluind);
303  };
304  void ChangeIndices(int nVert, int nEdge, int nSurf, int nVolu);
305  void ChangeIndicesSnakeMesh(int nVert, int nEdge, int nSurf, int nVolu);
306 #pragma GCC diagnostic push
307 #pragma GCC diagnostic ignored "-Wunused-parameter"
308  bool isready(bool isInMesh) const
309  {
310  return (normvector.isready());
311  }
312 #pragma GCC diagnostic pop
313  void read(FILE *fid);
314  void write(FILE *fid) const;
315  void SwitchIndex(int typeInd, int oldInd, int newInd);
316  void TightenConnectivity()
317  {
318  }
319 };
320 
321 // Function prototypes
322 double SnaxImpactDt(const snax &snax1, const snax &snax2);
323 int CompareSnakeInternalStatus(const std::vector<bool> &thisVec, bool thisFlipped, const std::vector<bool> &otherVec,
324  bool otherFlipped);
325 // Test Function prototypes
326 int Test_SnakeStructures();
327 int Test_coordvec();
328 int Test_snax();
329 int Test_snaxedge();
330 int Test_snake();
331 int Test_snakeinit_random();
332 int Test_snakeinit_unit();
333 int Test_snakeinit_unitnoreflect();
334 int Test_snakeinit_random_short();
335 int Test_snakeinit_unit_short();
336 int Test_snakeinit_unitnoreflect_short();
337 int Test_snakeinit_MC();
338 int Test_snakeOrderEdges();
339 int Test_snakeinitflat();
340 void Test_stepalgo(snake &testSnake, std::vector<int> &isImpact);
341 void Test_stepalgo_mergeclean(snake &testSnake, std::vector<int> &isImpact);
342 // Functions needed at Compile time
343 
344 // set constructors (used to avoid a variable being unknowingly forgotten)
345 
346 inline void snax::set(int indexin, double din, double vin, int fromvertin, int tovertin, int edgeindin, int isfreezein,
347  int orderedgein)
348 {
349  index = indexin;
350  d = din;
351  v = vin;
352  fromvert = fromvertin; // root vertex of *snakemesh
353  tovert = tovertin; // destination vertex of *snakemesh
354  edgeind = edgeindin; // edge of snakemesh()
355  isfreeze = isfreezein; // freeze status
356  orderedge = orderedgein;
357 }
358 
359 #endif // SNAKSTRUCT_H_INCLUDED
Provide std::vector container with hashed index mapping.
Handles the use and norm of a vector for which the norm and the unit value might be needed.
Definition: mesh.hpp:114
Class for mesh handling.
Definition: mesh.hpp:592
/Abstract class to ensure mesh interfaces are correct.
Definition: mesh.hpp:187
Definition: snake.hpp:83
void SetEdgeStepLimits()
Sets the relative edge step limits.
Definition: snake.cpp:902
Definition: snake.hpp:192
Provides all the mesh tools used for the generation of 3D grids and geometries.