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