00001
00002
00003
00004
00005 #ifndef SPS_H_IS_INCLUDED
00006 #define SPS_H_IS_INCLUDED
00007 #include "mesh/bmesh.H"
00008
00009
00010 class OctreeNode : public BBOX {
00011 public:
00012
00013
00014 OctreeNode(Wpt min, Wpt max, int height, OctreeNode* p) :
00015 _height(height), _parent(p) {
00016 _max = max;
00017 _min = min;
00018 double a = max[0]-min[0], b = max[1]-min[1],
00019 c = max[2]-min[2];
00020 _area = 2 * (a * b + b * c + c * a);
00021 _valid = true;
00022 _leaf = false;
00023 _display = false;
00024 }
00025
00026 ~OctreeNode() {
00027 _terms.clear();
00028 _neibors.clear();
00029 _intersects.clear();
00030 if (!_leaf) {
00031 for (int i = 0; i < 8; i++) {
00032 delete _children[i];
00033 }
00034 }
00035 }
00036
00037
00038 void build_octree(int height);
00039 void set_leaf(bool leaf) {_leaf = leaf; }
00040 bool get_leaf() { return _leaf; }
00041 void set_disp(bool disp) { _display = disp; }
00042 bool get_disp() { return _display; }
00043 int get_height() { return _height; }
00044 double get_area() { return _area; }
00045 OctreeNode** get_children() { return _children; }
00046 OctreeNode* parent() { return _parent; }
00047 ARRAY<OctreeNode*>& neibors() { return _neibors; }
00048 ARRAY<OctreeNode*>& terms() { return _terms; };
00049 void set_neibors();
00050 void set_terms();
00051 int get_term_index() { return _term_index; }
00052 Bface_list& intersects() { return _intersects; }
00053
00054 protected:
00055 void set_terms(ARRAY<OctreeNode*>& terms, int& count);
00056
00057
00058
00059 int _height, _term_index;
00060 double _area;
00061 bool _leaf;
00062 bool _display;
00063 OctreeNode* _parent;
00064 ARRAY<OctreeNode*> _neibors;
00065 ARRAY<OctreeNode*> _terms;
00066 OctreeNode* _children[8];
00067 Bface_list _intersects;
00068 };
00069
00070 class QuadtreeNode {
00071 public:
00072
00073
00074 QuadtreeNode(Wpt p1, Wpt p2, Wpt p3)
00075 {
00076 _v1 = p1;
00077 _v2 = p2;
00078 _v3 = p3;
00079 _leaf = false;
00080 _in_cell = true;
00081 _weight = 0;
00082 }
00083
00084 ~QuadtreeNode() {
00085 _terms.clear();
00086 if (!_leaf) {
00087 for (int i = 0; i < 4; i++) {
00088 delete _children[i];
00089 }
00090 }
00091 }
00092
00093 Wpt centroid()
00094 {
00095 return (_v1 + _v2 + _v3) / 3;
00096 }
00097
00098 double area()
00099 {
00100 double a = _v1.dist(_v2);
00101 double b = _v1.dist(_v3);
00102 double c = _v2.dist(_v3);
00103 double cosv = (a * a + b * b - c * c) / (2 * a * b);
00104 double sinv = sqrt(1-cosv);
00105 return a * b * sinv / 2;
00106 }
00107
00108 Wpt v1() { return _v1; }
00109 Wpt v2() { return _v2; }
00110 Wpt v3() { return _v3; }
00111
00112 bool
00113 contains(CWpt& pt,double threshold)
00114 {
00115
00116
00117 const double dist_threshold=0.00001;
00118 if (Wplane(_v1, _v2, _v3).dist(pt) > dist_threshold)
00119 return false;
00120
00121 Wvec vec1 = (pt-v1()).normalized();
00122 Wvec vec2 = (pt-v2()).normalized();
00123 Wvec vec3 = (pt-v3()).normalized();
00124 Wvec ab = (v2()-v1()).normalized();
00125 Wvec bc = (v3()-v2()).normalized();
00126 Wvec ca = (v1()-v3()).normalized();
00127
00128 Wvec c1 = cross(ab,vec1).normalized();
00129 Wvec c2 = cross(bc,vec2).normalized();
00130 Wvec c3 = cross(ca,vec3).normalized();
00131
00132 Wvec n = cross(ab,bc).normalized();
00133
00134 if(c1*n<-threshold) return false;
00135 if(c2*n<-threshold) return false;
00136 if(c3*n<-threshold) return false;
00137
00138 return true;
00139 }
00140
00141
00142 void build_quadtree(OctreeNode* o, double regularity);
00143 void set_leaf(bool leaf) {_leaf = leaf; }
00144 bool get_leaf() { return _leaf; }
00145 bool is_in_cell() { return _in_cell; }
00146 QuadtreeNode** get_children() { return _children; }
00147 Wpt farthest_pt(Wpt& p);
00148 Wpt nearest_pt(Wpt& p);
00149 void set_terms();
00150 ARRAY<QuadtreeNode*>& terms() { return _terms; }
00151 double get_weight() { return _weight; };
00152 void set_weight(double weight) { _weight = weight; }
00153 Wpt urand_pick();
00154
00155 protected:
00156 void subdivide(OctreeNode* o, double regularity);
00157 void set_terms(ARRAY<QuadtreeNode*>& terms);
00158
00159
00160
00161 bool _leaf;
00162 bool _in_cell;
00163 double _weight;
00164 Wpt _v1, _v2, _v3;
00165 QuadtreeNode* _children[4];
00166 ARRAY<QuadtreeNode*> _terms;
00167 };
00168
00169 void
00170 generate_samples(BMESHptr mesh,
00171 Bface_list& flist,
00172 ARRAY<Wvec>& blist,
00173 int height = 6, double min_dist = 0.35, double regularity = 20);
00174
00175 void
00176 generate_samples(BMESHptr mesh, double min_spacing,
00177 Bface_list& flist,
00178 ARRAY<Wvec>& blist
00179 );
00180
00181 OctreeNode*
00182 sps(BMESHptr mesh, int height, double regularity, double min_dist,
00183 Bface_list& flist,
00184 ARRAY<Wvec>& blist
00185 );
00186
00187 void
00188 visit(OctreeNode* node,
00189 double regularity, Bface_list& flist, ARRAY<Wvec>& blist);
00190
00191 void
00192 remove_nodes(Bface_list& flist, ARRAY<Wvec>& blist, double min_dist, ARRAY<OctreeNode*>& t);
00193
00194 void
00195 assign_weights(ARRAY<QuadtreeNode*>& fs, double regularity, Wpt& pt);
00196
00197 int
00198 pick_triangle(ARRAY<QuadtreeNode*>& fs);
00199
00200 #endif // SPS_H_IS_INCLUDED
00201