synaps/topology/Cell3d.h

00001 /***************************************************************************
00002  *   Copyright (C) 2005 by Chen Liang                                      *
00003  *   cliang@cs.hku.hk                                                      *
00004  *                                                                         *
00005  *   This program is free software; you can redistribute it and/or modify  *
00006  *   it under the terms of the GNU General Public License as published by  *
00007  *   the Free Software Foundation; either version 2 of the License, or     *
00008  *   (at your option) any later version.                                   *
00009  *                                                                         *
00010  *   This program is distributed in the hope that it will be useful,       *
00011  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00012  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00013  *   GNU General Public License for more details.                          *
00014  *                                                                         *
00015  *   You should have received a copy of the GNU General Public License     *
00016  *   along with this program; if not, write to the                         *
00017  *   Free Software Foundation, Inc.,                                       *
00018  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
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 // custom macros
00036 #define VARIDX(poly, idx) (idx)
00037 //#define VARIDX(poly, idx) (poly.rep().env.vr(idx))
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 // random factor
00058 #include <stdlib.h> // for rnd
00059 #endif
00060 
00061 
00062 //--------------------------------------------------------------------
00063 __BEGIN_NAMESPACE_SYNAPS
00064 //====================================================================
00065 // Cell3d: the structure of the cell that is tailored for building topological graph of
00066 //               the curve defined by two intersection implicit surfaces
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   //  typedef topology::point<C>         point_t;
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   // data members //
00087 
00088   box_t       m_cBox;
00089   std::vector<MPOL_T>  m_F; // surface functions
00090   unsigned             m_nT; // index of tangent fields
00091   
00092   bool                m_FaceComputed[6]; // flag indicating wether the intersection has been computed for a facet
00093   intersectionlist_t  m_FaceLstPtIdx[6];  // list of points on the corresponding face, including the edges.
00094 
00095   intersectionlist_t  m_EdgeLstPtIdx[12];  // list of points on the corresponding face, including the edges.
00096 
00097 
00098   int                 m_nDepth;      // the depth of this cell in the octree
00099   int                 m_nRegularIdx; // -2 = not computed, -1 = singular, 0-k = regular w.r.t.
00100   intersectionlist_t  m_aInterList; // a list of intersections already computed for this cell
00101   
00103   // constructors //
00105   
00106   //  Cell3d();
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   //  Cell3d(const coeff_t& a0, const coeff_t& b0, const coeff_t& a1, const coeff_t& b1, const coeff_t& a2, const coeff_t& b2);  
00111   Cell3d(const cell_t& c); // copy constructor
00112   
00114   // operator overrides //
00116   
00117   // assign operator
00118   self_t&  operator = (const cell_t& c);
00119   
00121   // helpers  //
00123 
00124   int nbpol() const {return m_F.size();}
00125   void push_back(const MPOL_T& p) { m_F.push_back(p); }
00126   // this function copies the content of cell c to this cell, used by operator = and copy constructor
00127   void     assign(const cell_t&);
00128 
00129   // merge two lists of type intersectionlist_t
00130   void     mergelist(intersectionlist_t& dstlist, const intersectionlist_t& srclist);
00131 
00132   // merge two lists of type intersectionlist_t with points inside the cell
00133   void     merge_inside(intersectionlist_t& dstlist, const intersectionlist_t& srclist);
00134   
00136   // member functions //
00138   
00139   // this function set the bounding box (or coordinate represented by this cell)
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 // constructors //
00161 
00162 // template <class C, class MP >
00163 // Cell3d<C, MP>::Cell3d() :
00164 //   m_nT(1), m_nDepth(0), m_nRegularIdx(-2)
00165 // {
00166 //     setBox(0,0,0,0,0,0);
00167 //     memset(m_FaceComputed, false, sizeof(bool)*6);
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 // template <class C, class MP >
00181 // Cell3d<C, MP>::Cell3d(const coeff_t& a0, const coeff_t& b0, 
00182 //                    const coeff_t& a1, const coeff_t& b1, 
00183 //                    const coeff_t& a2, const coeff_t& b2) :
00184 //   m_nT(1), m_nDepth(0), m_nRegularIdx(-2)
00185 // {
00186 //     // m_cBox = [a0,b0]X[a1,b1]X[a2,b2]
00187 //     setBox(a0,b0,a1,b1,a2,b2);
00188 //     memset(m_FaceComputed, false, sizeof(bool)*6);
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     // m_cBox = [a0,b0]X[a1,b1]X[a2,b2]
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     // m_cBox = [a0,b0]X[a1,b1]X[a2,b2]
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 // operator overrides //
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 // helpers //
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 // test whether its zero-levelset crosses the current cell or not
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 // test whether its zero-levelset crosses the current cell or not
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 // non-member functions //
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)) // treat it as 0
00324         {
00325           continue;
00326         }
00327       else
00328         {
00329           if (lastC*cirC < 0) // a sign change of the coefficient is detected
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  //if(i==2 && j==1)
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 // template<class PT, class C, class MP>
00392 // OCTREE::FACE_TYPE face_of(const PT& pt, const Cell3d<C,MP> & c)
00393 // {
00394 //   if (pt[0]== c.m_cBox.x0)
00395 //     return B;
00396 //   else if (pt[0]== c.m_cBox.x1)
00397 //     return F;
00398 //   else if (pt[1]== c.m_cBox.y0)
00399 //     return W;
00400 //   else if (pt[1]== c.m_cBox.y1)
00401 //     return E;
00402 //   else if (pt[2]== c.m_cBox.z0)
00403 //     return S;
00404 //   else 
00405 //     return N:
00406 // }
00407 //====================================================================
00408 __END_NAMESPACE_SYNAPS
00409 /********************************************************************/
00410 #endif //synaps_topology_cell3d_H

SYNAPS DOCUMENTATION
logo