00001 #ifndef _CUT_PLANE_H_
00002 #define _CUT_PLANE_H_
00003
00004 #include "Enums.h"
00005 #include "Vec3D.h"
00006 #include "BBox3D.h"
00007 #include "Plane.h"
00008 #include "fv_txt_utls.h"
00009
00010 #include "Point3D.h"
00011 #include "GraphicElem.hpp"
00012 #include "MathHelper.h"
00013 #include "Log.h"
00014 #include <set>
00015 #include <vector>
00016 #include <ostream>
00017 #include <cmath>
00018
00019
00020 namespace FemViewer {
00021
00022
00023 class BBox3D;
00024
00025 class CutPlane : public Plane
00026 {
00027 public:
00028
00029 static int Defaults(const BBox3D& bbox,std::vector<CutPlane>& out_planes);
00030 static CutPlane SetPlane(fvmath::CVec3d normal,fvmath::CVec3d point);
00031
00032 public:
00033
00034 typedef std::pair<int,int> elem_idx;
00035
00036 struct comp {
00037 bool operator()(const elem_idx& lhs,const elem_idx rhs) const {
00038 if (lhs.first < rhs.first) return lhs.second < rhs.second;
00039 return lhs.second < rhs.second;
00040 }
00041 };
00042
00043 typedef std::set<elem_idx,comp> elem_indices;
00044 typedef elem_indices::iterator elem_indices_itr;
00045
00046
00047 CutPlane(double nx=0.0,double ny=0.0, double nz=1.0, double d=-0.05, bool normalize = true)
00048 {
00049 Set(nx,ny,nz,d,normalize);
00050 _active = false;
00051 _display = false;
00052 _isPlaneChanged = false;
00053 _isNormalized = normalize;
00054 }
00055
00056 CutPlane(double p[],bool normalize = true)
00057 {
00058 Set(p[0],p[1],p[2],p[3],normalize);
00059 }
00060
00061 CutPlane(const CutPlane& rhs) : Plane(rhs)
00062 {
00063 if (this != &rhs) {
00064 _active = rhs._active;
00065 _display = rhs._display;
00066 _isPlaneChanged = rhs._isPlaneChanged;
00067 _isNormalized = rhs._isNormalized;
00068 }
00069 }
00070
00071 CutPlane& operator=(const CutPlane& rhs)
00072 {
00073 if (this != &rhs) {
00074 for (int i(0); i<4; ++i) p.n[i] = rhs.p.n[i];
00075 _active = rhs._active;
00076 _display = rhs._display;
00077 _isPlaneChanged = rhs._isPlaneChanged;
00078 _isNormalized = rhs._isNormalized;
00079 _vplaneCorrners = rhs._vplaneCorrners;
00080 _scale = rhs._scale;
00081 _elementIndices = rhs._elementIndices;
00082 }
00083 return *this;
00084 }
00085
00086 virtual ~CutPlane(){}
00087
00088
00089
00090
00091 void Enable(bool status = true) { _active = status; }
00092 bool IsActive() const { return _active; }
00093 void Show(bool status = true) { _display = status; }
00094 void Hide() { _display = false; }
00095 bool IsVisible() const { return _display; }
00096 void SetChanged(bool state = true) { _isPlaneChanged = state; }
00097 bool IsPlaneChanged() const { return _isPlaneChanged; }
00098 bool IsNormalized() const { return _isNormalized; }
00099
00100 elem_indices& GetElementIndices() { return _elementIndices; }
00101 const elem_indices& GetElementIndices() const { return _elementIndices; }
00102
00103 void Set(double a, double b, double c, double d, bool normalize = true)
00104 {
00105 fvmath::CVec3d v(a,b,c);
00106 double l = normalize ? Normalize(v) : 1.0;
00107 p.a = v.x; p.b = v.y; p.c = v.z;
00108 p.d = d / l;
00109 }
00110
00111
00112
00113
00114
00115
00116
00117 bool operator () (const Plane& rhPl)
00118 {
00119 bool res = false;
00120 if(p.n[0] != rhPl.GetParams()[0] ||
00121 p.n[1] != rhPl.GetParams()[1] ||
00122 p.n[2] != rhPl.GetParams()[2] ||
00123 p.n[3] != rhPl.GetParams()[3] ) res = true;
00124
00125 if(res) {
00126 p.a = GetParams()[0];
00127 p.b = GetParams()[1];
00128 p.c = GetParams()[2];
00129 p.d = GetParams()[3];
00130 }
00131
00132 return res;
00133 }
00134
00135 bool operator==(const CutPlane& rhs);
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166 inline int IntersectWithLine(double* x2,double* x1,double& u) const {
00167 return Plane::IntersectWithLine(this->p.n,x2,x1,u);
00168 }
00169
00170
00171
00172
00173
00174
00175 int CheckOrientation(const double v[]);
00176
00177 int InversPlane(const double v[]);
00178
00179 bool InitGeometryOutlines(const BBox3D& bbox);
00180
00181 bool IsValid(const AAbbf& bbox) const {
00182 return IntersectBBox3D(bbox) == 0 ? true : false;
00183 }
00184
00185 template<typename T>
00186 int IntersectBBox3D(const AAbb<T>& bbox) const;
00187
00188 bool InitOutlines(const BBox3D& bbox);
00189 inline void Draw() const {
00190 if (_vplaneCorrners.empty() || !_display) return;
00191 drawPlane(_vplaneCorrners[0].v,_scale.v,_vplaneCorrners.size());
00192 }
00193
00194 void AddIndex(const elem_idx&& idx);
00195 bool IsElement(const elem_idx&& idx) const;
00196
00197 unsigned GetMaxNUmVertices(int max_div);
00198 unsigned GetMaxNumIndices(int max_div);
00199
00200 static unsigned CutElement(const CutPlane* pl,const double vts[18],const int nodes[7],
00201 const int index, int div, std::vector<Node_t>& vertices,std::vector<unsigned>& triagles);
00202 private:
00203
00204 inline Vec3D ToVec3D(const double& a_,
00205 const double& b_,
00206 const double& c_) const;
00207 friend std::ostream& operator << (std::ostream& os, const CutPlane& rhs);
00208
00209 bool _active;
00210 bool _display;
00211 bool _isPlaneChanged;
00212 bool _isNormalized;
00213
00214 std::vector<CVec3f> _vplaneCorrners;
00215 CVec3f _scale;
00216
00217 elem_indices _elementIndices;
00218
00219 };
00220
00221
00222
00223 inline Vec3D CutPlane::ToVec3D(const double& a,
00224 const double& b,
00225 const double& c) const
00226 {
00227 float _a = static_cast<float>(a);
00228 float _b = static_cast<float>(b);
00229 float _c = static_cast<float>(c);
00230 return Vec3D(_a, _b, _c);
00231 }
00232
00233
00234
00235
00236
00237 template<typename T>
00238 inline int CutPlane::IntersectBBox3D(const AAbb<T>& bbox) const
00239 {
00240 using namespace fvmath;
00241 CVec3<T> c = (bbox.mx + bbox.mn) * T(0.5);
00242 CVec3<T> h = (bbox.mx - bbox.mn) * T(0.5);
00243 T nx = std::fabs(p.n[0]);
00244 T ny = std::fabs(p.n[1]);
00245 T nz = std::fabs(p.n[2]);
00246 T e = h.x*nx+ h.y*ny + h.z*nz;
00247 T s = c.x*p.a + c.y*p.b + c.z*p.c + p.d;
00248 if (s - e > T(0.0)) return 1;
00249 if (s + e < T(0.0)) return -1;
00250 return 0;
00251 }
00252
00253
00254
00255
00256 }
00257 #endif
00258