rsvs3D  0.0.0
Codes for the c++ implementation of the 3D RSVS
mesh.hpp
Go to the documentation of this file.
1 
11 //===============================================
12 // Include Guards
13 #ifndef MESH_H_INCLUDED
14 #define MESH_H_INCLUDED
15 
16 //===============================================
17 // Levels of debuging Guards
18 #ifdef DEBUGLVL2 // All Debugging calls
19 #define DEBUGLVL1
20 #define TEST_RANGE // deprecated
21 #define TEST_ARRAYSTRUCT
22 
23 #endif
24 
25 #ifdef DEBUGLVL1 // Debugging of new features.
26 #ifndef SAFE_ACCESS
27 #define SAFE_ACCESS
28 #endif
29 #endif
30 
31 //------------------------------------------------------------------------------
32 // forward declared dependencies class foo; //when you only need a pointer not
33 // the actual object and to avoid circular dependencies
34 
35 //------------------------------------------------------------------------------
36 // included dependencies
37 #ifdef DBG_MEMLEAK
38 #define _CRTDBG_MAP_ALLOC
39 #include <crtdbg.h>
40 #include <stdlib.h>
41 #endif // DBG_MEMLEAK
42 
43 #include <algorithm>
44 #include <array>
45 #include <cfloat>
46 #include <cmath>
47 #include <cstdlib>
48 #include <functional>
49 #include <iostream>
50 #include <sstream>
51 #include <stdexcept>
52 #include <string>
53 #include <unordered_map>
54 #include <vector>
55 
56 #include "arraystructures.hpp"
57 #include "warning.hpp"
58 
59 //------------------------------------------------------------------------------
60 // Code NOTE: function in a class definition are IMPLICITELY INLINED ie replaced
61 // by their code at compile time
62 
63 class meshpart;
64 class mesh;
65 class meshdependence;
66 class ConnecRemv;
67 
68 class volu;
69 class surf;
70 class vert;
71 class edge;
72 class coordvec;
73 
74 // typedef ArrayStruct<surf> surfarray;
79 namespace grid
80 {
81 
82 typedef std::array<std::array<double, 2>, 3> limits;
85 typedef std::array<std::array<double, 3>, 3> transformation;
87 typedef std::vector<const std::vector<double> *> coordlist;
88 } // namespace grid
89 
90 namespace rsvs3d
91 {
92 namespace constants
93 {
94 static const auto __issetlength = [](double l) -> bool { return l >= -0.0; };
95 static const double __unsetlength = -1.0;
96 namespace ordering
97 {
98 static const int ordered = 0;
99 static const int truncated = 1;
100 static const int open = -1;
101 static const int error = 2;
102 static const auto __isordered = [](int l) -> bool { return l == ordered; };
103 } // namespace ordering
104 } // namespace constants
105 } // namespace rsvs3d
106 
113 class coordvec
114 {
115  protected:
116  std::vector<double> elems;
117  double norm;
118  int isuptodate;
119 
120  public:
121  double CalcNorm();
122  double GetNorm();
123  double GetNorm() const;
124  void PrepareForUse();
125  coordvec Unit() const;
126  double Unit(const int a) const;
127  double Normalize();
128  void assign(double a, double b, double c);
129  double &operator[](int a);
130  double operator()(int a) const;
131  void disp() const;
132  bool isready() const
133  {
134  return (bool(isuptodate));
135  };
136  const std::vector<double> &usedata() const
137  {
138  return (elems);
139  }
140  const std::vector<double> *retPtr() const
141  {
142  return (&elems);
143  }
144  // Math and logical operations (element wise)
145  void flipsign();
146  void max(const std::vector<double> &vecin);
147  void min(const std::vector<double> &vecin);
148  void add(const std::vector<double> &vecin);
149  void substract(const std::vector<double> &vecin);
150  void substractfrom(const std::vector<double> &vecin);
151  void div(const std::vector<double> &vecin);
152  void div(double scalin);
153  void mult(const std::vector<double> &vecin);
154  void mult(double scalin);
155  void swap(std::vector<double> &vecin);
156  void swap(coordvec &coordin);
157  std::vector<double> cross(const std::vector<double> &vecin) const;
158  double dot(const std::vector<double> &vecin) const;
159  double angle(const coordvec &coordin) const;
160 
161  coordvec()
162  {
163  elems.reserve(3); // reserves 3 as this is the size of the array
164  elems.assign(3, 0);
165  norm = 0;
166  isuptodate = 0;
167 #ifdef TEST_SNAKSTRUCT
168  std::cout << "constructor called for coordvec" << std::endl;
169 #endif
170  }
171  void operator=(const std::vector<double> &a)
172  {
173  if (int(a.size()) != 3)
174  {
175  RSVS3D_ERROR_NOTHROW("Warning : Coordinate std::vector is being a "
176  "std::vector other than 3 long");
177  }
178  elems = a;
179  isuptodate = 0;
180  }
181 };
182 
186 class meshpart : public ArrayStructpart
187 {
188  public:
189  virtual void disptree(const mesh &meshin, int n) const = 0;
190  virtual double value(const mesh &meshin) const = 0;
191 };
192 
196 class volu : public meshpart
197 {
198  public:
199  double fill, target, error, volume;
200  std::vector<int> surfind;
201 
202  std::vector<int> vertind(const mesh &meshin) const;
203  void ChangeIndices(int nVert, int nEdge, int nSurf, int nVolu);
204  void disp() const;
205  void disptree(const mesh &meshin, int n) const;
206  double value(const mesh &meshin) const;
207  void PrepareForUse(){};
208 #pragma GCC diagnostic push
209 #pragma GCC diagnostic ignored "-Wunused-parameter"
210  bool isready(bool isInMesh) const
211  {
212  return (true);
213  }
214 #pragma GCC diagnostic pop
215  void read(FILE *fid);
216  void write(FILE *fid) const;
217  void TightenConnectivity()
218  {
219  sort(surfind);
220  unique(surfind);
221  };
222  coordvec PseudoCentroid(const mesh &meshin) const;
223 
224  volu()
225  { // Constructor
226  this->index = 0;
227  this->fill = 0;
228  this->target = 1;
229  this->error = 1;
230 
231 #ifdef TEST_ARRAYSTRUCT
232  std::cout << "volu #" << index << " Was created " << surfind.size() << std::endl;
233 #endif
234  }
235  ~volu()
236  { // Destructor
237  surfind.clear();
238 
239 #ifdef TEST_ARRAYSTRUCT
240  std::cout << "volu #" << index << " Was deleted " << surfind.size() << std::endl;
241 #endif
242  }
243  void operator=(const volu *other)
244  {
245  index = other->index;
246  fill = other->fill;
247  target = other->target;
248  error = other->error;
249  surfind = other->surfind;
250 
251 #ifdef TEST_ARRAYSTRUCT
252  std::cout << "OTHER: ";
253  other->disp();
254 #endif
255  }
256 
257  int Key() const
258  {
259  return (index);
260  }
261 };
262 
266 class surf : public meshpart, public modiftrackpart
267 {
268  protected:
269  bool isordered;
270  // bool isModif=true;
271  public:
272  friend class mesh;
273  friend surfarray;
274  // friend void mesh::SwitchIndex(int typeInd, int oldInd, int newInd,
275  // vector<int> scopeInd); friend void mesh::RemoveIndex(int typeInd, int
276  // oldInd);
277 
278  double fill, target, error, area;
279  std::vector<int> edgeind;
280  std::vector<int> voluind;
281  // reserves 2 as this is the size of the array
282 
283  std::vector<int> vertind(const mesh &meshin) const;
284  void disp() const;
285  double value(const mesh &meshin) const;
286  void disptree(const mesh &meshin, int n) const;
287  void ChangeIndices(int nVert, int nEdge, int nSurf, int nVolu);
288  void PrepareForUse(){};
289  bool isready(bool isInMesh) const
290  {
291  return (isInMesh ? isordered : true);
292  }
293  bool IsOrdered() const
294  {
295  return (isordered);
296  }
297  void read(FILE *fid);
298  void write(FILE *fid) const;
299  int OrderEdges(mesh *meshin);
300  int SplitSurface(mesh &meshin, const std::vector<int> &fullEdgeInd);
301  void OrderedVerts(const mesh *meshin, std::vector<int> &vertList) const;
302  std::vector<int> OrderedVerts(const mesh *meshin) const;
303  void TightenConnectivity()
304  {
305  sort(voluind);
306  unique(voluind);
307  sort(edgeind);
308  unique(edgeind);
309  isordered = false;
310  };
311  void FlipVolus();
312  bool edgeconneq(const surf &other, bool recurse = true) const;
313  coordvec PseudoCentroid(const mesh &meshin) const;
314  int PseudoCentroid(const mesh &meshin, coordvec &coord) const;
315 
316  surf()
317  { // Constructor
318  index = 0;
319  fill = 1;
320  target = 1;
321  error = 1;
322  voluind.reserve(2); // reserves 2 as this is the size of the array
323  voluind.assign(2, 0);
324  isordered = false;
325  }
326  ~surf()
327  { // Destructor
328 
329  edgeind.clear();
330  voluind.clear();
331  }
332  void operator=(const surf *other)
333  {
334  index = other->index;
335  fill = other->fill;
336  error = other->error;
337  target = other->target;
338  edgeind = other->edgeind;
339  voluind = other->voluind;
340  isordered = other->isordered;
341  }
342 
343  int Key() const
344  {
345  return (index);
346  }
347 };
348 
352 class edge : public meshpart, public modiftrackpart
353 {
354  protected:
355  double length = rsvs3d::constants::__unsetlength;
356 
357  public:
358  friend class mesh;
359  friend edgearray;
360 
361  std::vector<int> vertind;
362  std::vector<int> surfind;
363  // reserves 2 as this is the size of the array
364 
365  void ChangeIndices(int nVert, int nEdge, int nSurf, int nVolu);
366  void disp() const;
367  void disptree(const mesh &meshin, int n) const;
368  double value(const mesh &meshin) const;
369  void PrepareForUse(){};
370 #pragma GCC diagnostic push
371 #pragma GCC diagnostic ignored "-Wunused-parameter"
372  bool isready(bool isInMesh) const
373  {
374  return (true);
375  }
376 #pragma GCC diagnostic pop
377  void read(FILE *fid);
378  void write(FILE *fid) const;
379  void TightenConnectivity()
380  {
381  if (vertind.size() > 2)
382  {
383  RSVS3D_ERROR_ARGUMENT("vertind should be size 2");
384  }
385  sort(surfind);
386  unique(surfind);
387  };
388  void GeometricProperties(const mesh *meshin, coordvec &centre, double &length) const;
389  double Length(const mesh &meshin) const;
390  double SetLength(const mesh &meshin)
391  {
392  this->length = this->Length(meshin);
393  return this->length;
394  };
395  double GetLength(bool warn = true) const
396  {
397  if (!rsvs3d::constants::__issetlength(this->length) && warn)
398  {
399  RSVS3D_ERROR_NOTHROW("Length is accessed but not set. "
400  "Run SetEdgeLengths before call.");
401  }
402  return this->length;
403  }
404  void InvalidateLength()
405  {
406  this->length = rsvs3d::constants::__unsetlength;
407  }
408  double LengthSquared(const mesh &meshin) const;
409  bool IsLength0(const mesh &meshin, double eps = __DBL_EPSILON__) const;
410  bool vertconneq(const edge &other) const;
411  edge()
412  { // Constructor
413  index = 0;
414  vertind.reserve(2);
415  vertind.assign(2, 0); // reserves 2 as this is the size of the array
416  }
417  edge(const edge &oldEdge)
418  { // Copy-Constructor
419  index = oldEdge.index;
420  vertind = oldEdge.vertind;
421  surfind = oldEdge.surfind;
422  }
423  edge &operator=(const edge &other) = default;
424  ~edge()
425  { // Destructor
426 
427  vertind.clear();
428  surfind.clear();
429  }
430  void operator=(const edge *other)
431  {
432  index = other->index;
433 
434  vertind = other->vertind;
435  surfind = other->surfind;
436  }
437 
438  int Key() const
439  {
440  return (index);
441  }
442 };
443 
447 class vert : public meshpart
448 {
449  public:
450  std::vector<int> edgeind;
451  std::vector<double> coord;
452  // reserves 2 as this is the size of the array
453  std::vector<int> elmind(const mesh &meshin, int dimOveride = -1) const;
454 
455  void disp() const;
456  void disptree(const mesh &meshin, int n) const;
457  double value(const mesh &meshin) const;
458  void ChangeIndices(int nVert, int nEdge, int nSurf, int nVolu);
459  void PrepareForUse(){};
460 #pragma GCC diagnostic push
461 #pragma GCC diagnostic ignored "-Wunused-parameter"
462  bool isready(bool isInMesh) const
463  {
464  return (true);
465  }
466 #pragma GCC diagnostic pop
467  void read(FILE *fid);
468  void write(FILE *fid) const;
469  void TightenConnectivity()
470  {
471  sort(edgeind);
472  unique(edgeind);
473  };
474  int OrderEdges(const mesh *meshin);
475  std::pair<std::vector<int>, int> OrderEdges(const mesh *meshin) const;
476  int OrderEdges(const mesh *meshin, std::vector<int> &edgeIndOut) const;
477  int SurroundingCoords(const mesh *meshin, grid::coordlist &coordout, bool isOrdered = false,
478  std::vector<int> *edgeIndOutPtr = NULL) const;
479 
480  int Normal(const mesh *meshin, grid::coordlist &neighCoord, coordvec &normalVec, bool isOrdered = false) const;
481  coordvec Normal(const mesh *meshin) const;
482 
483  vert()
484  { // Constructor
485  index = 0;
486  coord.reserve(3); // reserves 2 as this is the size of the array
487  coord.assign(3, 0);
488  }
489  ~vert()
490  { // Destructor
491 
492  edgeind.clear();
493  coord.clear();
494  }
495  void operator=(const vert *other)
496  {
497  index = other->index;
498 
499  edgeind = other->edgeind;
500  coord = other->coord;
501  }
502 
503  int Key() const
504  {
505  return (index);
506  }
507 };
508 
514 {
515  public:
516  int keepind;
517  int typeobj;
518  std::vector<int> rmvind;
519  std::vector<int> scopeind;
520  void disp();
521 };
522 
530 {
531  protected:
532  friend class mesh;
534  int nParents = 0;
536  std::vector<int> elemind;
538  std::vector<mesh *> parentmesh;
540  std::vector<mesh *> childmesh;
544  std::vector<HashedVectorSafe<int, int>> parentconn;
545  // These methods are protected to avoid broken/uni-directional
546  // connectivities being generated
547 
548  int AddParent(mesh *meshin);
549  int AddChild(mesh *meshin);
550  void AddParent(mesh *meshin, std::vector<int> &parentind);
551  void RemoveChild(mesh *meshin);
552  void RemoveParent(mesh *meshin);
553 
554  public:
555  int NumberOfParents() const
556  {
557  return this->nParents;
558  }
559  const mesh *ParentPointer(int a) const
560  {
561  return this->parentmesh.at(a);
562  }
563  std::vector<int> ChildIndices(int parent, int parentVoluIndex) const
564  {
565  return this->parentconn.at(parent).findall(parentVoluIndex);
566  }
567  void clear()
568  {
569  this->elemind.clear();
570  this->parentconn.clear();
571  for (auto parent : this->parentmesh)
572  {
573  this->RemoveParent(parent);
574  }
575  for (auto child : this->childmesh)
576  {
577  this->RemoveChild(child);
578  }
579  }
580 };
581 
591 class mesh
592 {
593  private:
594  bool borderIsSet = false;
595  bool meshDepIsSet = false;
596  bool facesAreOriented = false;
597  bool edgesLengthsAreSet = false;
598  int meshDim = 0;
599  void SetLastIndex();
600 
601  void OrientSurfaceVolume();
602  void OrientEdgeSurface();
603  int OrientRelativeSurfaceVolume(std::vector<int> &surfOrient);
604  void ArraysAreHashed();
605  void _LinearTransformGeneration(const grid::transformation &transform, std::vector<mesh *> meshdependence::*mp);
606  friend class snake;
607 
608  public:
609  vertarray verts;
610  edgearray edges;
611  surfarray surfs;
612  voluarray volus;
613 
614  meshdependence meshtree;
615 
616  void clear()
617  {
618  this->verts.clear();
619  this->edges.clear();
620  this->surfs.clear();
621  this->volus.clear();
622  this->meshtree.clear();
623  this->borderIsSet = false;
624  this->meshDepIsSet = false;
625  this->facesAreOriented = false;
626  this->edgesLengthsAreSet = false;
627  }
628  // Mesh Lineage
629  void RemoveFromFamily();
630  void AddChild(mesh *meshin);
631  void AddParent(mesh *meshin);
632  void AddParent(mesh *meshin, std::vector<int> &parentind);
633  void AddChild(mesh *meshin, std::vector<int> &parentind);
634  void SetMeshDepElm();
635  // Method needed to robustly maintain lineage through the family.
636  void MaintainLineage();
637  int CountParents() const;
638  int SurfInParent(int surfind) const;
639  void SurfInParent(std::vector<int> &listInParent) const;
640  void ElmOnParentBound(std::vector<int> &listInParent, std::vector<int> &voluInd, bool isBorderBound = true,
641  bool outerVolume = true) const;
642  void SurfOnParentBound(std::vector<int> &listInParent, std::vector<int> &voluInd, bool isBorderBound,
643  bool outerVolume) const;
644  void EdgeOnParentBound(std::vector<int> &listInParent, std::vector<int> &voluInd, bool isBorderBound,
645  bool outerVolume) const;
646  int CountVoluParent() const;
647  void ReturnParentMap(std::vector<int> &currind, std::vector<int> &parentpos,
648  std::vector<std::pair<int, int>> &parentcases, std::vector<double> &voluVals) const;
649  void MapVolu2Parent(const std::vector<double> &fillIn, const std::vector<std::pair<int, int>> &parentcases,
650  double volu::*mp = &volu::fill);
651  void MapVolu2Self(const std::vector<double> &fillIn, const std::vector<int> &elms, double volu::*mp = &volu::fill);
652  void VoluValuesofParents(int elmInd, std::vector<double> &vals, int volType = 0) const;
653  void VoluValuesofParents(int elmInd, std::vector<double> &vals, double volu::*mp) const;
654  void SurfValuesofParents(int elmInd, std::vector<double> &vals, int volType = 0) const;
655  void SurfValuesofParents(int elmInd, std::vector<double> &vals, double surf::*mp) const;
656  int ParentElementIndex(int childElmInd, int parentInd = 0) const;
657  // Mesh property
658  int WhatDim() const
659  {
660  return (meshDim);
661  }
662  // basic operations grouped from each field
663  void HashArray();
664  void SetMaxIndex();
665  void GetMaxIndex(int *nVert, int *nEdge, int *nSurf, int *nVolu) const;
666  void Init(int nVe, int nE, int nS, int nVo);
667  void size(int &nVe, int &nE, int &nS, int &nVo) const;
668  void reserve(int nVe, int nE, int nS, int nVo);
669  void PrepareForUse(bool needOrder = true);
670  void SetEdgeLengths();
671  void InvalidateEdgeLength(int iEdge);
672  void disp() const;
673  void displight() const;
674  void Concatenate(const mesh &other);
675  bool isready() const;
676  void PopulateIndices();
677  void TightenConnectivity();
678  int TestConnectivity(const char *strRoot = "") const;
679  int TestConnectivityBiDir(const char *strRoot = "", bool emptyIsErr = true) const;
680  // File I/o
681  void write(FILE *fid) const;
682  void read(FILE *fid);
683  int write(const char *str) const;
684  int read(const char *str);
685  // Mesh merging
686  void MakeCompatible_inplace(mesh &other) const;
687  mesh MakeCompatible(mesh other) const;
688  void ChangeIndices(int nVert, int nEdge, int nSurf, int nVolu);
689  void SwitchIndex(int typeInd, int oldInd, int newInd, const std::vector<int> &scopeInd = {0});
690  void RemoveIndex(int typeInd, int oldInd);
691  int ConnectedVertex(std::vector<int> &vertBlock) const;
692  int ConnectedVolumes(std::vector<int> &volBlock, const std::vector<bool> &boundaryFaces = {}) const;
693  void ForceCloseContainers();
694  void RemoveSingularConnectors(const std::vector<int> &rmvVertInds = {}, bool voidError = true);
695  std::vector<int> MergeGroupedVertices(HashedVector<int, int> &closeVert, bool delVerts = true);
696  // Mesh Quality
697  std::vector<int> OrderEdges();
698  void SetBorders();
699  void OrientFaces();
700  int OrderVertexEdges(int vertIndex);
701  // Mesh Ordering
702  void ReOrder();
703  bool CompareVerts(const vert &in1, const vert &in2) const;
704  bool CompareEdges(const edge &in1, const edge &in2) const;
705  bool CompareSurfs(const surf &in1, const surf &in2) const;
706  bool CompareVolus(const volu &in1, const volu &in2) const;
707  // Mesh component comparison
708  void GetOffBorderVert(std::vector<int> &vertList, std::vector<int> &voluInd, int outerVolume = -1);
709  void GetOffBorderVert(std::vector<int> &vertList, std::vector<int> &voluInd, int outerVolume = -1) const;
710  void GetOffBorderVert3D(std::vector<int> &vertList, std::vector<int> &voluInd, int outerVolume = -1) const;
711  void GetOffBorderVert2D(std::vector<int> &vertInd, std::vector<int> &surfind, int outerVolume = -1) const;
712  // Mesh calculations
713  coordvec CalcCentreVolu(int ind) const;
714  coordvec CalcPseudoNormalSurf(int ind) const;
715  std::vector<int> VertexInVolume(const std::vector<double> testVertices, int sizeVert = 3) const;
716  // Mesh size and position
717  grid::transformation Scale();
718  grid::transformation Scale(const grid::limits &domain);
719  void LinearTransform(const grid::transformation &transform);
720  void LinearTransformFamily(const grid::transformation &transform);
721  void LoadTargetFill(const std::string &fileName);
722  grid::limits BoundingBox() const;
723  void ReturnBoundingBox(std::array<double, 3> &lowerB, std::array<double, 3> &upperB) const;
724  // Mesh Splitting and cropping
725  void Crop(std::vector<int> indList, int indType = 1);
726  std::vector<int> AddBoundary(const std::vector<double> &lb, const std::vector<double> &ub);
727  void CropAtBoundary(const std::vector<double> &lb, const std::vector<double> &ub);
728  // Mesh traversal convenience functions
729  int EdgeFromVerts(int v1, int v2) const;
730  int SurfFromEdges(int e1, int e2, int repetitionBehaviour = -1) const;
731  int VertFromVertEdge(int v, int e) const;
732  void VerticesVector(int v1, int v2, coordvec &vec) const;
733  void EdgeVector(int e, coordvec &vec) const;
734  // Destructor
735  ~mesh()
736  {
737  RemoveFromFamily();
738  }
739 };
740 
741 // Function declarations
742 
743 void ConnVertFromConnEdge(const mesh &meshin, const std::vector<int> &edgeind, std::vector<int> &vertind);
744 std::pair<int, int> OrderMatchLists(const std::vector<int> &vec1, int p1, int p2);
745 int OrderMatchLists(const std::vector<int> &vec1, const std::vector<int> &vec2, int p1, int p2);
746 void CropMeshGreedy(mesh &meshin, const std::vector<double> &lb, const std::vector<double> &ub);
747 int OrderEdgeList(std::vector<int> &edgeind, const mesh &meshin, bool warn = true, bool errout = true,
748  const std::vector<int> *edgeIndOrigPtr = NULL, const surf *surfin = NULL);
749 int OrderList(std::vector<int> &edgeind, const std::vector<int> &edge2Vert, bool warn = true, bool errout = true,
750  const std::vector<int> *edgeIndOrigPtr = NULL);
751 void DiffPointsFromCentre(const std::vector<double> &centre, const std::vector<double> &planeVert2,
752  const std::vector<double> &planeVert3, coordvec &normal, coordvec &temp1);
753 void DiffPoints(const std::vector<double> &vert1, const std::vector<double> &vert2, coordvec &diffVerts);
754 double Angle3Points(const std::vector<double> &centre, const std::vector<double> &planeVert2,
755  const std::vector<double> &planeVert3, coordvec &vec1, coordvec &vec2);
756 double VertexDistanceToPlane(const std::vector<double> &planeVert1, const std::vector<double> &planeVert2,
757  const std::vector<double> &planeVert3, const std::vector<double> &testVertex,
758  coordvec &temp1, coordvec &temp2);
759 std::vector<double> VerticesDistanceToPlane(const std::vector<double> &planeVert1,
760  const std::vector<double> &planeVert2,
761  const std::vector<double> &planeVert3,
762  const std::vector<double> &testVertices, coordvec &temp1, coordvec &temp2);
763 double VertexDistanceToPlane(const std::vector<double> &planeVert1, const std::vector<double> &planeVert2,
764  const std::vector<double> &planeVert3, const std::vector<double> &testVertex);
765 std::vector<double> VerticesDistanceToPlane(const std::vector<double> &planeVert1,
766  const std::vector<double> &planeVert2,
767  const std::vector<double> &planeVert3,
768  const std::vector<double> &testVertices);
769 mesh Points2Mesh(const std::vector<double> &vecPts, int nProp = 3);
770 double PlanesDotProduct(const std::vector<double> &planeVert1, const std::vector<double> &planeVert2,
771  const std::vector<double> &planeVert3, const std::vector<double> &planeVert4,
772  const std::vector<double> &planeVert5, const std::vector<double> &planeVert6,
773  bool normalize = true);
774 void PlaneNormal(const std::vector<double> &planeVert1, const std::vector<double> &planeVert2,
775  const std::vector<double> &planeVert3, coordvec &normal, coordvec &temp1);
776 double PlaneNormalAndAngle(const std::vector<double> &planeVert1, const std::vector<double> &planeVert2,
777  const std::vector<double> &planeVert3, coordvec &normal, coordvec &temp1);
778 std::tuple<coordvec, double> VertexNormal(const std::vector<double> &centre, const grid::coordlist &vecPts);
779 
780 namespace meshhelp
781 {
782 template <class T, class V, class W>
783 double ProjectRay(int count, const W &&boundBox, const T &dir, const V &orig, double minDist = 0.0);
784 
785 void PlaceBorderVertex(const std::vector<double> &coordIn, const std::vector<double> &coordOut,
786  const std::vector<double> &lb, const std::vector<double> &ub, std::vector<double> &coordTarg);
787 
788 void SplitBorderSurfaceEdgeind(const mesh &meshin, const std::vector<bool> &edgeOut, std::vector<int> &vecconnIn,
789  std::vector<int> &vecconnOut);
790 void SplitBorderVolumeSurfind(const mesh &meshin, const std::vector<bool> &edgeOut, std::vector<int> &vecconnIn,
791  std::vector<int> &vecconnOut);
792 void HandleMultiSurfaceSplit(mesh &meshin, std::vector<int> &edgeindOld, std::vector<int> &edgeindNew,
793  std::vector<int> &vertindNew);
794 std::vector<int> FindVertInFromEdgeOut(const mesh &meshin, const std::vector<bool> &vertOut,
795  const std::vector<int> &edgeList, const std::vector<int> &edgeListCheck);
796 std::vector<int> FindEdgeInFromSurfOut(const mesh &meshin, const std::vector<bool> &edgeOut, std::vector<int> surfList);
797 double VerticesDistanceSquared(const mesh &meshin, const std::vector<int> &vertind);
798 double VerticesDistance(const mesh &meshin, const std::vector<int> &vertind);
799 bool IsVerticesDistance0(const mesh &meshin, const std::vector<int> &vertind, double eps = __DBL_EPSILON__);
800 int VertexInVolume(const mesh &meshin, const std::vector<double> testCoord, bool needFlip = false);
801 int Get3PointsInSurface(const mesh &meshin, int surfCurr, std::array<int, 3> &surfacePoints);
802 int NormalShouldFlip(const std::vector<int> orderedList, int elm1, int elm2, const std::vector<int> &voluind,
803  bool innerComparison);
804 } // namespace meshhelp
805 // test functions
806 int Test_ArrayStructures();
807 int Test_Volu();
808 int Test_Surf();
809 int Test_Vert();
810 int Test_Edge();
811 int Test_Mesh();
812 int Test_Crop();
813 
814 template <class T, class V, class W>
815 double meshhelp::ProjectRay(int count, const W &&boundBox, const T &dir, const V &orig, double minDist)
816 {
817  /*
818  Calculates the distance to project a single ray to reach the bounding box
819 
820  It is templated to accept any types of containers with `count` elements,
821  accessible by operator[];
822 
823  W is an object of size [2][count] accessible by operators [][]
824  */
825 
826  double l = -INFINITY;
827 
828  for (int i = 0; i < count; ++i)
829  {
830  l = std::max(l, std::min((boundBox[0][i] - orig[i]) / dir[i], (boundBox[1][i] - orig[i]) / dir[i]));
831  }
832  return std::min(l, minDist);
833 }
834 
835 #endif // MESH_H_INCLUDED
Provide std::vector container with hashed index mapping.
Class containing the information needed to trim objects from a mesh.
Definition: mesh.hpp:514
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 an edge object in a mesh.
Definition: mesh.hpp:353
double Length(const mesh &meshin) const
Calculate the edge length.
Definition: mesh.cpp:1496
double LengthSquared(const mesh &meshin) const
Calculate squared edge length.
Definition: mesh.cpp:1477
bool IsLength0(const mesh &meshin, double eps=__DBL_EPSILON__) const
Returns.
Definition: mesh.cpp:1514
void GeometricProperties(const mesh *meshin, coordvec &centre, double &length) const
Math operations in mesh.
Definition: mesh.cpp:1456
Class for mesh handling.
Definition: mesh.hpp:592
std::vector< int > AddBoundary(const std::vector< double > &lb, const std::vector< double > &ub)
Adds boundaries alond max and min xyz planes.
Definition: mesh.cpp:5357
void LinearTransform(const grid::transformation &transform)
Applies a linear transformation to the points on a grid.
Definition: mesh.cpp:5207
void LinearTransformFamily(const grid::transformation &transform)
Applies a linear transform to child and parent meshes.
Definition: mesh.cpp:5225
void _LinearTransformGeneration(const grid::transformation &transform, std::vector< mesh * > meshdependence::*mp)
Applies reccursively linear transforms to a tree of meshes.
Definition: mesh.cpp:5238
std::vector< int > VertexInVolume(const std::vector< double > testVertices, int sizeVert=3) const
Finds for each vertex, the volume object containing it.
Definition: mesh.cpp:492
int VertFromVertEdge(int v, int e) const
Returns the vertex in edges.isearch(e)->vertind which does not match v.
Definition: mesh.cpp:5926
int ConnectedVertex(std::vector< int > &vertBlock) const
Return in a vector for each vertex a block number which it is part of.
Definition: mesh.cpp:4633
int SurfFromEdges(int e1, int e2, int repetitionBehaviour=-1) const
Returns the index of the surface connecting two edges.
Definition: mesh.cpp:5872
void OrientFaces()
Orients either surfaces or edges depending on the dimensionality of the object.
Definition: mesh.cpp:4948
Class for connecting meshes.
Definition: mesh.hpp:530
std::vector< HashedVectorSafe< int, int > > parentconn
parent/to self connectivity, 1 vector element per parent.
Definition: mesh.hpp:544
std::vector< int > elemind
Indices of the active elements of the owning mesh.
Definition: mesh.hpp:536
std::vector< mesh * > parentmesh
Vector of pointers to the mesh which are coarser (parents).
Definition: mesh.hpp:538
std::vector< mesh * > childmesh
Vector of pointers to the mesh which are finer (children).
Definition: mesh.hpp:540
int nParents
Number of parent meshes.
Definition: mesh.hpp:534
/Abstract class to ensure mesh interfaces are correct.
Definition: mesh.hpp:187
Definition: snake.hpp:83
Class for surface object in a mesh.
Definition: mesh.hpp:267
coordvec PseudoCentroid(const mesh &meshin) const
Calculates the length weighted pseudo-centroid of a surface.
Definition: mesh.cpp:556
Class for a vertex in a mesh.
Definition: mesh.hpp:448
Class for volume cell objects in a mesh.
Definition: mesh.hpp:197
std::vector< int > vertind(const mesh &meshin) const
Get all the vertices a volume is connected to.
Definition: mesh.cpp:1919
coordvec PseudoCentroid(const mesh &meshin) const
Calculates the length weighted pseudo-centroid of a volume.
Definition: mesh.cpp:610
std::vector< const std::vector< double > * > coordlist
Defines a list of coordinates.
Definition: mesh.hpp:87
std::tuple< coordvec, double > VertexNormal(const std::vector< double > &centre, const grid::coordlist &vecPts)
Calculates the vertex normal weighted by surface angle partitions.
Definition: mesh.cpp:747
mesh Points2Mesh(const std::vector< double > &vecPts, int nProp=3)
Takes in a set of points and returns a mesh of points ready for voronisation.
Definition: mesh.cpp:6293
double PlaneNormalAndAngle(const std::vector< double > &planeVert1, const std::vector< double > &planeVert2, const std::vector< double > &planeVert3, coordvec &normal, coordvec &temp1)
Calculates a plane's normal vector.
Definition: mesh.cpp:352
void PlaneNormal(const std::vector< double > &planeVert1, const std::vector< double > &planeVert2, const std::vector< double > &planeVert3, coordvec &normal, coordvec &temp1)
Calculates a plane's normal vector.
Definition: mesh.cpp:333
double Angle3Points(const std::vector< double > &centre, const std::vector< double > &planeVert2, const std::vector< double > &planeVert3, coordvec &vec1, coordvec &vec2)
Calculates a plane's normal vector.
Definition: mesh.cpp:373
void DiffPoints(const std::vector< double > &vert1, const std::vector< double > &vert2, coordvec &diffVerts)
Computes vector between vertices to then compute angles and plane normals.
Definition: mesh.cpp:296
std::array< std::array< double, 3 >, 3 > transformation
Defines a linear transformation to the mesh where for each dimension: {new minimum,...
Definition: mesh.hpp:85
std::vector< double > VerticesDistanceToPlane(const std::vector< double > &planeVert1, const std::vector< double > &planeVert2, const std::vector< double > &planeVert3, const std::vector< double > &testVertices, coordvec &temp1, coordvec &temp2)
Calculates the distance from a set of vertices to a plane.
Definition: mesh.cpp:438
int OrderEdgeList(std::vector< int > &edgeind, const mesh &meshin, bool warn=true, bool errout=true, const std::vector< int > *edgeIndOrigPtr=NULL, const surf *surfin=NULL)
Orders a list of edge to be connected.
Definition: mesh.cpp:3287
int OrderList(std::vector< int > &edgeind, const std::vector< int > &edge2Vert, bool warn=true, bool errout=true, const std::vector< int > *edgeIndOrigPtr=NULL)
Orders a list of elements defined by pairs of indices.
Definition: mesh.cpp:3449
void CropMeshGreedy(mesh &meshin, const std::vector< double > &lb, const std::vector< double > &ub)
Crops a mesh to only the elements inside the cropBox.
Definition: mesh.cpp:6264
void DiffPointsFromCentre(const std::vector< double > &centre, const std::vector< double > &planeVert2, const std::vector< double > &planeVert3, coordvec &normal, coordvec &temp1)
Computes vector between vertices to then compute angles and plane normals.
Definition: mesh.cpp:313
double VertexDistanceToPlane(const std::vector< double > &planeVert1, const std::vector< double > &planeVert2, const std::vector< double > &planeVert3, const std::vector< double > &testVertex, coordvec &temp1, coordvec &temp2)
Calculates the distance from a vertex to a plane.
Definition: mesh.cpp:400
Namespace for general purpose tools of the RSVS project.
Definition: snake.cpp:1464
void error(const char *message="", const char *caller="", const char *file="", int line=0, bool throwError=true)
Custom error function.
Definition: warning.hpp:203
Provides the error and warning system used by the RSVS3D project.
#define RSVS3D_ERROR_NOTHROW(M)
Generic rsvs warning.
Definition: warning.hpp:120
#define RSVS3D_ERROR_ARGUMENT(M)
Throw a invalid_argument.
Definition: warning.hpp:148