1 // Gmsh - Copyright (C) 1997-2021 C. Geuzaine, J.-F. Remacle
2 //
3 // See the LICENSE.txt file in the Gmsh root directory for license information.
4 // Please report all issues on https://gitlab.onelab.info/gmsh/gmsh/issues.
5 
6 #ifndef SMOOTH_DATA_H
7 #define SMOOTH_DATA_H
8 
9 #include <set>
10 #include <vector>
11 #include <string>
12 
13 // Basic coordinate-based floating point data averager
14 
15 struct xyzv {
16   double x, y, z, *vals;
17   int nbvals;
18   int nboccurrences;
19   // Added by Trevor Strickler for scaling last element layer in quadtri
20   // boundary layer to make better quality interfaces
21   double scaleValue;
22   int scale_numvals;
23   static double eps;
xyzvxyzv24   xyzv(double xx, double yy, double zz)
25     : x(xx), y(yy), z(zz), vals(nullptr), nbvals(0), nboccurrences(0),
26       scaleValue(1.0), scale_numvals(0)
27   {
28   }
~xyzvxyzv29   ~xyzv()
30   {
31     if(vals) delete[] vals;
32   }
33   // these are needed for set<> operations since the default copy constructor
34   // won't allocate *vals
35   xyzv(const xyzv &other);
36   xyzv &operator=(const xyzv &other);
37   void update(int n, double *v);
38   void scale_update(double scale_val);
39 };
40 
41 struct lessthanxyzv {
operatorlessthanxyzv42   bool operator()(const xyzv &p2, const xyzv &p1) const
43   {
44     if(p1.x - p2.x > xyzv::eps) return true;
45     if(p1.x - p2.x < -xyzv::eps) return false;
46     if(p1.y - p2.y > xyzv::eps) return true;
47     if(p1.y - p2.y < -xyzv::eps) return false;
48     if(p1.z - p2.z > xyzv::eps) return true;
49     return false;
50   }
51 };
52 
53 class smooth_data {
54 private:
55   std::set<xyzv, lessthanxyzv> c;
56 
57 public:
58   typedef std::set<xyzv, lessthanxyzv>::iterator iter;
begin()59   iter begin() { return c.begin(); }
end()60   iter end() { return c.end(); }
smooth_data()61   smooth_data() {}
62   void add(double x, double y, double z, int n, double *vals);
63   bool get(double x, double y, double z, int n, double *vals) const;
64   void add_scale(double x, double y, double z, double scale_val);
65   bool get_scale(double x, double y, double z, double *scale_val) const;
66   void normalize();
67   bool exportview(const std::string &filename) const;
68 };
69 
70 // Normal smoother with threshold (saves memory by storing normals as
71 // chars and coordinates as floats)
72 
73 struct nnb {
74   char nx, ny, nz;
75   unsigned char nb;
76 };
77 
78 struct xyzn {
79   float x, y, z;
80   std::vector<nnb> n;
81   static float eps;
xyznxyzn82   xyzn(float xx, float yy, float zz) : x(xx), y(yy), z(zz) {}
~xyznxyzn83   ~xyzn() {}
84   float angle(int i, char n0, char n1, char n2);
85   void update(char n0, char n1, char n2, float tol);
86 };
87 
88 struct lessthanxyzn {
operatorlessthanxyzn89   bool operator()(const xyzn &p2, const xyzn &p1) const
90   {
91     if(p1.x - p2.x > xyzn::eps) return true;
92     if(p1.x - p2.x < -xyzn::eps) return false;
93     if(p1.y - p2.y > xyzn::eps) return true;
94     if(p1.y - p2.y < -xyzn::eps) return false;
95     if(p1.z - p2.z > xyzn::eps) return true;
96     return false;
97   }
98 };
99 
100 class smooth_normals {
101 private:
102   float tol;
103   std::set<xyzn, lessthanxyzn> c;
104 
105 public:
smooth_normals(double angle)106   smooth_normals(double angle) : tol((float)angle) {}
107   void add(double x, double y, double z, double nx, double ny, double nz);
108   bool get(double x, double y, double z, double &nx, double &ny, double &nz) const;
109 };
110 
111 #endif
112