00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 # ifndef shape_cell3d_hpp
00013 # define shape_cell3d_hpp
00014
00015 # include <shape/vertex.hpp>
00016 # include <shape/edge.hpp>
00017 # include <shape/face.hpp>
00018 # include <shape/bounding_box.hpp>
00019 # include <shape/cell.hpp>
00020 # include <shape/graph.hpp>
00021 # include <shape/topology.hpp>
00022 # include <shape/mesh3d.hpp>
00023
00024 # include <shape/solver_implicit.hpp>
00025 # define TMPL template<class C, class V>
00026 # define TMPL1 template<class K>
00027 # define SELF cell3d<C,V>
00028
00029 namespace mmx { namespace shape {
00030
00031
00032
00033
00034 TMPL class cell3d;
00035 TMPL class tpl3d;
00036
00037
00038 struct cell3d_def {};
00039 template<> struct use<cell3d_def>
00040 :public use<cell_def>
00041 {
00042 typedef cell3d<double,double> Cell3d;
00043 };
00044
00045
00046 template<class C, class V=default_env>
00047 class cell3d : public bounding_box<C,V>
00048 {
00049 public:
00050 typedef topology<C,V> Topology;
00051 typedef tpl3d<C,V> Topology3d;
00052 typedef typename use<mesh3d_def,C,V>::Point Point;
00053 typedef typename Topology::Edge Edge;
00054
00055 typedef cell3d<C,V> CellBase;
00056 typedef cell<C,V> Cell;
00057 typedef bounding_box<C,V> BoundingBox;
00058
00059 typedef solver_implicit<C,V> Solver;
00060
00061 cell3d(void) {};
00062 cell3d(const BoundingBox& bx): BoundingBox(bx) {} ;
00063 virtual ~cell3d(void) {};
00064
00065 BoundingBox boundingBox() const { return (BoundingBox)*this; }
00066 virtual bool is_regular(void) = 0 ;
00067 virtual bool is_active (void) const = 0 ;
00068
00069 virtual int subdivide(SELF*& left, SELF*& right);
00070 virtual void subdivide(SELF*& left, SELF*& right, int v, double s)=0;
00071 virtual void split_position(int& v, double& t);
00072
00073 virtual bool is_adjacent(SELF* c);
00074
00075 Point center() { return Point((this->xmin()+this->xmax())/2, (this->ymin()+this->ymax())/2,
00076 (this->zmin()+this->zmax())/2); }
00077 };
00078
00079
00080 TMPL int
00081 SELF::subdivide(SELF*& Left, SELF*& Right) {
00082 int v; double s;
00083 this->split_position(v,s);
00084 this->subdivide(Left,Right,v,s);
00085 return v;
00086 }
00087
00088 TMPL void
00089 SELF::split_position(int& v, double& s) {
00090 double sx = (this->xmax()-this->xmin());
00091 double sy = (this->ymax()-this->ymin());
00092 double sz = (this->zmax()-this->zmin());
00093
00094 if(sx<sy)
00095 if(sy<sz) {
00096 v=2;
00097 s=(this->zmax()+this->zmin())/2;
00098 } else {
00099 v=1;
00100 s=(this->ymax()+this->ymin())/2;
00101 }
00102 else
00103 if(sx<sz) {
00104 v=2;
00105 s=(this->zmax()+this->zmin())/2;
00106 } else {
00107 v=0;
00108 s=(this->xmax()+this->xmin())/2;
00109 }
00110 }
00111
00112
00113 TMPL
00114 bool SELF::is_adjacent(SELF* c2){
00115 if(this->xmax()<c2->xmin() || c2->xmax()<this->xmin())
00116 return false;
00117 if(this->ymax()<c2->ymin() || c2->ymax()<this->ymin())
00118 return false;
00119 if(this->zmax()<c2->zmin() || c2->zmax()<this->zmin())
00120 return false;
00121 if((this->xmax()==c2->xmin() || c2->xmax()==this->xmin())) {
00122 if((this->ymax()==c2->ymin() || c2->ymax()==this->ymin()) ||
00123 (this->zmax()==c2->zmin() || c2->zmax()==this->zmin()) )
00124 return false;
00125 } else if((this->ymax()==c2->ymin() || c2->ymax()==this->ymin()) &&
00126 (this->zmax()==c2->zmin() || c2->zmax()==this->zmin()) )
00127 return false;
00128 return true;
00129 }
00130
00131
00132 template<class CELL> bool
00133 is_adjacentpl3d(CELL* c1,CELL* c2){
00134 if(c1->xmax()<c2->xmin() || c2->xmax()<c1->xmin())
00135 return false;
00136 if(c1->ymax()<c2->ymin() || c2->ymax()<c1->ymin())
00137 return false;
00138 if(c1->zmax()<c2->zmin() || c2->zmax()<c1->zmin())
00139 return false;
00140 if((c1->xmax()==c2->xmin() || c2->xmax()==c1->xmin())) {
00141 if((c1->ymax()==c2->ymin() || c2->ymax()==c1->ymin()) ||
00142 (c1->zmax()==c2->zmin() || c2->zmax()==c1->zmin()) )
00143 return false;
00144 } else if((c1->ymax()==c2->ymin() || c2->ymax()==c1->ymin()) &&
00145 (c1->zmax()==c2->zmin() || c2->zmax()==c1->zmin()) )
00146 return false;
00147 return true;
00148 }
00149
00150 #define xMIN (c2->xmin()<c3->xmin()?c3->xmin():c2->xmin())
00151 #define xMAX (c2->xmax()<c3->xmax()?c2->xmax():c3->xmax())
00152 #define yMIN (c2->ymin()<c3->ymin()?c3->ymin():c2->ymin())
00153 #define yMAX (c2->ymax()<c3->ymax()?c2->ymax():c3->ymax())
00154 #define zMIN (c2->zmin()<c3->zmin()?c3->zmin():c2->zmin())
00155 #define zMAX (c2->zmax()<c3->zmax()?c2->zmax():c3->zmax())
00156
00157 template<class CELL> bool
00158 is_adjacentpl3d(CELL* c1,CELL* c2, CELL* c3){
00159
00160 if(c1->xmax()< xMIN || xMAX <c1->xmin())
00161 return false;
00162 if(c1->ymax()<yMIN || yMAX<c1->ymin())
00163 return false;
00164 if(c1->zmax()<zMIN || zMAX<c1->zmin())
00165 return false;
00166
00167 if((c1->xmax()==xMIN || xMAX==c1->xmin())) {
00168 if((c1->ymax()==yMIN || yMAX==c1->ymin()) ||
00169 (c1->zmax()==zMIN || zMAX==c1->zmin()) )
00170 return false;
00171 } else if((c1->ymax()==yMIN || yMAX==c1->ymin()) &&
00172 (c1->zmax()==zMIN || zMAX==c1->zmin()) )
00173 return false;
00174 return true;
00175 }
00176
00177
00178 #undef xMIN
00179 #undef xMAX
00180 #undef yMIN
00181 #undef yMAX
00182 #undef zMIN
00183 #undef zMAX
00184
00185 } ;
00186 } ;
00187 # undef TMPL
00188 # undef TMPL1
00189 # undef SELF
00190 # endif // shape_cell3d_hpp