00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifndef synaps_topology_cell3d_H
00022 #define synaps_topology_cell3d_H
00023
00024 #include <vector>
00025 #include <iostream>
00026 #include <assert.h>
00027 #include <vector>
00028
00029 #include <synaps/mpol/MPol.h>
00030 #include <synaps/mpol/MPolDse.h>
00031 #include <synaps/topology/box3d.h>
00032 #include <synaps/topology/inter_points.h>
00033
00034
00035
00036 #define VARIDX(poly, idx) (idx)
00037
00038
00039
00040 #define TRUE true
00041 #define FALSE false
00042
00043 #ifdef SYNAPS_SBD3D_USEGMP
00044 #ifdef SYNAPS_WITH_GMP
00045 #define _is_singular(x) ((x) == QQ("0"))
00046 #define _is_verysmall(x) (abs(x)<QQ("0.001"))
00047 #else
00048 #define _is_singular(x) ((x) < 1e-6 && (x) > -1e-6)
00049 #define _is_verysmall(x) (std::abs(x)<1e-3)
00050 #endif //end: SYNAPS_WITH_GMP
00051 #else
00052 #define _is_singular(x) ((x) < 1e-6 && (x) > -1e-6)
00053 #define _is_verysmall(x) (std::abs(x)<1e-3)
00054 #endif //end: SYNAPS_SBD3D_USEGMP
00055
00056 #ifdef SYNAPS_SBD3D_RNDFACTORWHENSUBDIVISION
00057
00058 #include <stdlib.h>
00059 #endif
00060
00061
00062
00063 __BEGIN_NAMESPACE_SYNAPS
00064
00065
00066
00067 template < class C = double,
00068 class MP = MPolDse<C, mpoldse::bernstein<C> > >
00069 struct Cell3d
00070 {
00071 typedef C coeff_t;
00072 typedef topology::box3d<coeff_t> box_t;
00073 typedef MP MPOL_T;
00074
00075 typedef Cell3d<C,MP> cell_t;
00076 typedef Cell3d<C,MP> self_t;
00077
00078 typedef intersection3d<C> intersection_t;
00079 typedef Seq<intersection3d<C>*> intersectionlist_t;
00080 typedef shared_object<intersection_t*> intersection_ptr;
00081 typedef Seq<intersection_ptr> intersection_ptr_list;
00082 typedef topology::point_graph<C, intersection_ptr_list> pointgraph_int_t;
00083
00085
00087
00088 box_t m_cBox;
00089 std::vector<MPOL_T> m_F;
00090 unsigned m_nT;
00091
00092 bool m_FaceComputed[6];
00093 intersectionlist_t m_FaceLstPtIdx[6];
00094
00095 intersectionlist_t m_EdgeLstPtIdx[12];
00096
00097
00098 int m_nDepth;
00099 int m_nRegularIdx;
00100 intersectionlist_t m_aInterList;
00101
00103
00105
00106
00107 Cell3d(unsigned N);
00108 Cell3d(unsigned N, const coeff_t& a0, const coeff_t& b0, const coeff_t& a1, const coeff_t& b1, const coeff_t& a2, const coeff_t& b2);
00109 Cell3d(const MPOL_T& p, const coeff_t& a0, const coeff_t& b0, const coeff_t& a1, const coeff_t& b1, const coeff_t& a2, const coeff_t& b2);
00110
00111 Cell3d(const cell_t& c);
00112
00114
00116
00117
00118 self_t& operator = (const cell_t& c);
00119
00121
00123
00124 int nbpol() const {return m_F.size();}
00125 void push_back(const MPOL_T& p) { m_F.push_back(p); }
00126
00127 void assign(const cell_t&);
00128
00129
00130 void mergelist(intersectionlist_t& dstlist, const intersectionlist_t& srclist);
00131
00132
00133 void merge_inside(intersectionlist_t& dstlist, const intersectionlist_t& srclist);
00134
00136
00138
00139
00140 virtual void setBox(const C& a0, const C& b0,
00141 const C& a1, const C& b1,
00142 const C& a2, const C& b2);
00143
00144 inline virtual bool testsize(coeff_t epsilon)
00145 {
00146 if (m_cBox.x1-m_cBox.x0 > epsilon || m_cBox.z1-m_cBox.z0 > epsilon || m_cBox.z1-m_cBox.z0 > epsilon)
00147 {
00148 return FALSE;
00149 }
00150 return TRUE;
00151 }
00152
00153 bool containsVariety(unsigned i) const;
00154 template<class POINT>
00155 bool contains_point(const POINT& pt) const;
00156 };
00157
00159
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171 template <class C, class MP >
00172 Cell3d<C, MP>::Cell3d(unsigned N) :
00173 m_F(N), m_nT(1), m_nDepth(0), m_nRegularIdx(-2)
00174 {
00175 setBox(0,0,0,0,0,0);
00176 memset(m_FaceComputed, false, sizeof(bool)*6);
00177 }
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191 template <class C, class MP >
00192 Cell3d<C, MP>::Cell3d(const MP & p,
00193 const coeff_t& a0, const coeff_t& b0,
00194 const coeff_t& a1, const coeff_t& b1,
00195 const coeff_t& a2, const coeff_t& b2) :
00196 m_nT(1), m_nDepth(0), m_nRegularIdx(-2)
00197 {
00198
00199 setBox(a0,b0,a1,b1,a2,b2);
00200 memset(m_FaceComputed, false, sizeof(bool)*6);
00201 m_F.push_back(p);
00202 }
00203
00204 template <class C, class MP >
00205 Cell3d<C, MP>::Cell3d(unsigned N,
00206 const coeff_t& a0, const coeff_t& b0,
00207 const coeff_t& a1, const coeff_t& b1,
00208 const coeff_t& a2, const coeff_t& b2) :
00209 m_F(N), m_nT(1), m_nDepth(0), m_nRegularIdx(-2)
00210 {
00211
00212 setBox(a0,b0,a1,b1,a2,b2);
00213 memset(m_FaceComputed, false, sizeof(bool)*6);
00214 }
00215
00216 template <class C, class MP >
00217 Cell3d<C, MP>::Cell3d(const cell_t& c) :
00218 m_F(c.nbpol()), m_nT(1), m_nDepth(c.m_nDepth), m_nRegularIdx(c.m_nRegularIdx)
00219 {
00220 assign(c);
00221 }
00222
00223
00225
00227
00228 template <class C, class MP >
00229 inline Cell3d<C, MP>& Cell3d<C, MP>::operator = (const cell_t& c)
00230 {
00231 assign(c); return *this;
00232 }
00233
00235
00237
00238 template < class C, class MP >
00239 void Cell3d<C, MP>::assign(const cell_t& c)
00240 {
00241 m_cBox = c.m_cBox;
00242 m_F = c.m_F;
00243 m_nT = c.m_nT;
00244 m_nDepth = c.m_nDepth;
00245 m_nRegularIdx = c.m_nRegularIdx;
00246 memcpy(m_FaceComputed, c.m_FaceComputed, sizeof(bool)*6);
00247 m_aInterList = c.m_aInterList;
00248 }
00249
00250 template <class C, class MP >
00251 void Cell3d<C, MP>::mergelist(intersectionlist_t& dstlist,
00252 const intersectionlist_t& srclist)
00253 {
00254 for (int v = 0; v < (int)srclist.size(); v++)
00255 dstlist.push_back(srclist[v]);
00256 }
00257
00258
00259 template <class C, class MP >
00260 void Cell3d<C, MP>::merge_inside(intersectionlist_t& dstlist,
00261 const intersectionlist_t& srclist)
00262 {
00263 PRINT_DEBUG("box "<<m_cBox);
00264 for (int v = 0; v < (int)srclist.size(); v++)
00265 if(contains_point(srclist[v]->pnt))
00266 {
00267 PRINT_DEBUG(" "<<srclist[v]->pnt);
00268 dstlist.push_back(srclist[v]);
00269 }
00270 }
00271
00272 template <class C, class MP>
00273 void Cell3d<C, MP>::setBox(const coeff_t& a0, const coeff_t& b0, const coeff_t& a1, const coeff_t& b1, const coeff_t& a2, const coeff_t& b2)
00274 {
00275 m_cBox = box_t(a0,b0,a1,b1,a2,b2);
00276 }
00277
00278
00279 template <class C, class MP>
00280 bool Cell3d<C,MP>::containsVariety(unsigned i) const
00281 {
00282 assert(i<nbpol());
00283 return has_sign_change(this->m_F[i]);
00284 }
00285
00286
00287 template <class C, class MP>
00288 template <class POINT>
00289 bool Cell3d<C,MP>::contains_point(const POINT& pt) const
00290 {
00291 return ( pt[0] >= m_cBox.x0 && pt[0] <= m_cBox.x1 &&
00292 pt[1] >= m_cBox.y0 && pt[1] <= m_cBox.y1 &&
00293 pt[2] >= m_cBox.z0 && pt[2] <= m_cBox.z1);
00294 }
00295
00297
00299
00300 template <class C, class MP >
00301 std::ostream & operator<<( std::ostream & os, const Cell3d<C, MP>& c )
00302 {
00303 os << "Coord: " << c.m_cBox << std::endl;
00304 for(unsigned i=0;i<c.nbpol();i++)
00305 os << " " <<c.m_F[i] << std::endl;
00306
00307 return os;
00308 }
00309
00310 template <class MP>
00311 bool has_sign_change(const MP& pol)
00312 {
00313 typedef typename MP::coeff_t C;
00314 bool hasroot;
00315
00316 const C* coeff = pol.begin();
00317 C lastC = coeff[0];
00318 hasroot = FALSE;
00319
00320 for (int j = 1; j < pol.rep().env.sz(); j++)
00321 {
00322 C cirC = coeff[j];
00323 if (_is_singular(cirC))
00324 {
00325 continue;
00326 }
00327 else
00328 {
00329 if (lastC*cirC < 0)
00330 {
00331 hasroot = TRUE;
00332 break;
00333 }
00334 lastC = cirC;
00335 }
00336 }
00337
00338 return hasroot;
00339 }
00340
00341 template<class PT, class C, class MP>
00342 bool is_on_face(const PT& pt, Cell3d<C,MP>* c, unsigned i, unsigned j)
00343 {
00344 if(i==0)
00345 if (j==0)
00346 return( pt[0]== c->m_cBox.x0);
00347 else
00348 return( pt[0]== c->m_cBox.x1);
00349 else if(i==1)
00350 if(j==0)
00351 return( pt[1]== c->m_cBox.y0);
00352 else
00353 return( pt[1]== c->m_cBox.y1);
00354 else if(i==2)
00355 if(j==0)
00356 return( pt[2]== c->m_cBox.z0);
00357 else
00358 return( pt[2]== c->m_cBox.z1);
00359 return false;
00360 }
00361
00362 template<class PT, class C, class MP>
00363 bool is_on_border(const PT& pt, Cell3d<C,MP>* c, unsigned i)
00364 {
00365 switch(i)
00366 {
00367 case 0:
00368 return((pt[1]== c->m_cBox.y0) || (pt[1]== c->m_cBox.y1) || (pt[2]== c->m_cBox.z0) || (pt[2]== c->m_cBox.z1));
00369 case 1:
00370 return((pt[0]== c->m_cBox.x0) || (pt[0]== c->m_cBox.x1) || (pt[2]== c->m_cBox.z0) || (pt[2]== c->m_cBox.z1));
00371 case 2:
00372 return((pt[0]== c->m_cBox.x0) || (pt[0]== c->m_cBox.x1) || (pt[1]== c->m_cBox.y0) || (pt[1]== c->m_cBox.y1));
00373 }
00374 }
00375 template<class PT, class C, class MP>
00376 bool is_edge(const PT& pt, Cell3d<C,MP>* c, unsigned i)
00377 {
00378 switch(i)
00379 {
00380 case 0:
00381 return((pt[1]== c->m_cBox.y0) || (pt[1]== c->m_cBox.y1) || (pt[2]== c->m_cBox.z0) || (pt[2]== c->m_cBox.z1));
00382 case 1:
00383 return((pt[0]== c->m_cBox.x0) || (pt[0]== c->m_cBox.x1) || (pt[2]== c->m_cBox.z0) || (pt[2]== c->m_cBox.z1));
00384 case 2:
00385 return((pt[0]== c->m_cBox.x0) || (pt[0]== c->m_cBox.x1) || (pt[1]== c->m_cBox.y0) || (pt[1]== c->m_cBox.y1));
00386 }
00387 }
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408 __END_NAMESPACE_SYNAPS
00409
00410 #endif //synaps_topology_cell3d_H