synaps/topology/Cell3dN.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_cell3dN_H
00022 #define synaps_topology_cell3dN_H
00023 
00024 #include <vector>
00025 #include <iostream>
00026 #include <assert.h>
00027 
00028 #include <synaps/mpol/MPol.h>
00029 #include <synaps/mpol/MPolDse.h>
00030 #include <synaps/topology/box3d.h>
00031 #include <synaps/topology/inter_points.h>
00032 #include <synaps/topology/point_graph.h>
00033 
00034 // custom macros
00035 #define VARIDX(poly, idx) (idx)
00036 //#define VARIDX(poly, idx) (poly.rep().env.vr(idx))
00037 
00038 
00039 #define TRUE true
00040 #define FALSE false
00041 
00042 #ifdef SYNAPS_SBD3D_USEGMP
00043 #ifdef SYNAPS_WITH_GMP
00044 #define _is_singular(x) ((x) == QQ("0"))
00045 #define _is_verysmall(x) (abs(x)<QQ("0.001"))
00046 #else
00047 #define _is_singular(x) ((x) < 1e-6 && (x) > -1e-6)
00048 #define _is_verysmall(x) (std::abs(x)<1e-3)
00049 #endif //end: SYNAPS_WITH_GMP
00050 #else
00051 #define _is_singular(x) ((x) < 1e-6 && (x) > -1e-6)
00052 #define _is_verysmall(x) (std::abs(x)<1e-3)
00053 #endif //end: SYNAPS_SBD3D_USEGMP
00054 
00055 #ifdef SYNAPS_SBD3D_RNDFACTORWHENSUBDIVISION
00056 // random factor
00057 #include <stdlib.h> // for rnd
00058 #endif
00059 
00060 
00061 //--------------------------------------------------------------------
00062 __BEGIN_NAMESPACE_SYNAPS
00063 //--------------------------------------------------------------------
00064 
00065 //====================================================================
00066 // Cell3dN: the structure of the cell that is tailored for building topological graph of
00067 //               the curve defined by two intersection implicit surfaces
00068 template < int N, 
00069            class C = double,
00070            class MP = MPolDse<C, mpoldse::bernstein<C> > >
00071 struct Cell3dN
00072 {
00073   typedef C                          coeff_t;
00074   typedef topology::box3d<coeff_t>   box_t;
00075   typedef MP                         MPOL_T;
00076   //  typedef topology::point<C>         point_t;
00077   typedef Cell3dN<N,C,MP>  cell_t;
00078   typedef Cell3dN<N,C,MP>  self_t;
00079   
00080   typedef intersection3d<C>        intersection_t;
00081   typedef Seq<intersection3d<C>*>  intersectionlist_t;
00082   typedef shared_object<intersection_t*>  intersection_ptr;
00083   typedef Seq<intersection_ptr>   intersection_ptr_list;
00084   typedef topology::point_graph<C, intersection_ptr_list> pointgraph_int_t;
00085   
00087   // data members //
00089   
00090   box_t       m_cBox;
00091   MPOL_T      m_F[N]; // surface functions
00092   MPOL_T*     m_T;//=M_F+2; // tangent fields
00093   
00094   bool        m_aFaceComputed[6]; // flag indicating wether the intersection has been computed for a facet
00095   int         m_nDepth;      // the depth of this cell in the octree
00096   int         m_nRegularIdx; // -2 = not computed, -1 = singular, 0-k = regular w.r.t.
00097   intersectionlist_t    m_aInterList; // a list of intersections already computed for this cell
00098   
00100   // constructors //
00102   
00103   Cell3dN();
00104   Cell3dN(const coeff_t& a0, const coeff_t& b0, const coeff_t& a1, const coeff_t& b1, const coeff_t& a2, const coeff_t& b2);
00105   Cell3dN(const cell_t& c); // copy constructor
00106   
00108   // operator overrides //
00110   
00111   // assign operator
00112   self_t&  operator = (const cell_t& c);
00113   
00115   // helpers  //
00117 
00118   int nbpol() const {return N;}
00119   // this function copies the content of cell c to this cell, used by operator = and copy constructor
00120   void     assign(const cell_t&);
00121 
00122   // merge two lists of type intersectionlist_t
00123   void     mergelist(intersectionlist_t& dstlist, const intersectionlist_t& srclist);
00124 
00125   // merge two lists of type intersectionlist_t with points inside the cell
00126   void     merge_inside(intersectionlist_t& dstlist, const intersectionlist_t& srclist);
00127   
00129   // member functions //
00131   
00132   // this function set the bounding box (or coordinate represented by this cell)
00133   virtual void setBox(const C& a0, const C& b0, 
00134                       const C& a1, const C& b1, 
00135                       const C& a2, const C& b2);
00136 
00137   inline virtual bool testsize(coeff_t epsilon)
00138   {
00139     if (m_cBox.x1-m_cBox.x0 > epsilon || m_cBox.z1-m_cBox.z0 > epsilon || m_cBox.z1-m_cBox.z0 > epsilon)
00140       {
00141         return FALSE;
00142       }
00143     return TRUE;
00144   }
00145 
00146   bool containsVariety(unsigned i) const;
00147   template<class POINT>
00148   bool contains_point(const POINT& pt) const;
00149 };
00150 //====================================================================
00152 // constructors //
00154 
00155 template <int N, class C, class MP >
00156 Cell3dN<N, C, MP>::Cell3dN() :
00157   m_T(m_F+2), m_nDepth(0), m_nRegularIdx(-2)
00158 {
00159     setBox(0,0,0,0,0,0);
00160     memset(m_aFaceComputed, false, sizeof(bool)*6);
00161 }
00162 
00163 
00164 template <int N, class C, class MP >
00165 Cell3dN<N, C, MP>::Cell3dN(const coeff_t& a0, const coeff_t& b0, 
00166                          const coeff_t& a1, const coeff_t& b1, 
00167                          const coeff_t& a2, const coeff_t& b2) :
00168   m_T(m_F+2), m_nDepth(0), m_nRegularIdx(-2)
00169 {
00170     // m_cBox = [a0,b0]X[a1,b1]X[a2,b2]
00171     setBox(a0,b0,a1,b1,a2,b2);
00172     memset(m_aFaceComputed, false, sizeof(bool)*6);
00173 }
00174 
00175 template <int N, class C, class MP >
00176 Cell3dN<N, C, MP>::Cell3dN(const cell_t& c) :
00177   m_T(m_F+2), m_nDepth(c.m_nDepth), m_nRegularIdx(c.m_nRegularIdx)
00178 {
00179     assign(c);
00180 }
00181 
00182 
00184 // operator overrides //
00186 
00187 template < int N, class C, class MP >
00188 inline Cell3dN<N, C, MP>& Cell3dN<N, C, MP>::operator = (const cell_t& c)
00189 {
00190     assign(c); return *this;
00191 }
00192 
00194 // helpers //
00196 //--------------------------------------------------------------------
00197 template < int N, class C, class MP >
00198 void Cell3dN<N, C, MP>::assign(const cell_t& c)
00199 {
00200     m_cBox = c.m_cBox;
00201     for (int i = 0; i < N; i++)
00202         m_F[i] = c.m_F[i];
00203     m_T = m_F+2;
00204 //     for (int i = 0; i < 3; i++)
00205 //         m_T[i] = c.m_T[i];
00206 
00207     m_nDepth = c.m_nDepth;
00208     m_nRegularIdx = c.m_nRegularIdx;
00209     memcpy(m_aFaceComputed, c.m_aFaceComputed, sizeof(bool)*6);
00210     m_aInterList = c.m_aInterList;
00211 }
00212 //--------------------------------------------------------------------
00213 template < int N, class C, class MP >
00214 void Cell3dN<N, C, MP>::mergelist(intersectionlist_t& dstlist, 
00215                                  const intersectionlist_t& srclist)
00216 {
00217     for (int v = 0; v < (int)srclist.size(); v++)
00218         dstlist.push_back(srclist[v]);
00219 }
00220 
00221 //--------------------------------------------------------------------
00222 template < int N, class C, class MP >
00223 void Cell3dN<N, C, MP>::merge_inside(intersectionlist_t& dstlist, 
00224                                     const intersectionlist_t& srclist)
00225 {
00226   PRINT_DEBUG("box "<<m_cBox);
00227     for (int v = 0; v < (int)srclist.size(); v++)
00228       if(contains_point(srclist[v]->pnt))
00229         {
00230           PRINT_DEBUG(" "<<srclist[v]->pnt);
00231           dstlist.push_back(srclist[v]);
00232         }
00233 }
00234 //--------------------------------------------------------------------
00235 template < int N, class C, class MP>
00236 void Cell3dN<N, 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)
00237 {
00238     m_cBox = box_t(a0,b0,a1,b1,a2,b2);
00239 }
00240 //--------------------------------------------------------------------
00241 // test whether its zero-levelset crosses the current cell or not
00242 template <int N, class C, class MP>
00243 bool Cell3dN<N,C,MP>::containsVariety(unsigned i) const
00244 {
00245   assert(i<N);
00246   bool hasroot;
00247 
00248   const C* coeff = this->m_F[i].begin();
00249   C lastC = coeff[0];
00250   hasroot = FALSE;
00251   
00252   for (int j = 1; j < this->m_F[i].rep().env.sz(); j++)
00253     {
00254       C cirC = coeff[j];
00255       if (_is_singular(cirC)) // treat it as 0
00256         {
00257           continue;
00258         }
00259       else
00260         {
00261           if (lastC*cirC < 0) // a sign change of the coefficient is detected
00262             {
00263               hasroot = TRUE;
00264               break;
00265             }
00266           lastC = cirC;
00267         }
00268     }
00269   
00270   if (!hasroot) // if either surface (0-levelset) does not cross this cell, returns FALSE
00271     return FALSE;
00272   return TRUE;
00273 }
00274 //--------------------------------------------------------------------
00275 // test whether its zero-levelset crosses the current cell or not
00276 template <int N, class C, class MP>
00277 template <class POINT>
00278 bool Cell3dN<N,C,MP>::contains_point(const POINT& pt) const
00279 {
00280   return ( pt[0] >= m_cBox.x0 && pt[0] <= m_cBox.x1 && 
00281            pt[1] >= m_cBox.y0 && pt[1] <= m_cBox.y1 && 
00282            pt[2] >= m_cBox.z0 && pt[2] <= m_cBox.z1);
00283 }
00284 
00286 // non-member functions //
00288 
00289 template <int N, class C, class MP >
00290 std::ostream & operator<<( std::ostream & os, const Cell3dN<N, C, MP>& c )
00291 {
00292     os  << "Coord: " << c.m_cBox << std::endl
00293         << "F: " << c.m_F[0] << std::endl
00294         << "G: " << c.m_F[1] << std::endl
00295         << "t1: " << c.m_T[0] << std::endl
00296         << "t2: " << c.m_T[1] << std::endl
00297         << "t3: " << c.m_T[2] << std::endl;
00298     return os;
00299 }
00300 //====================================================================
00301 __END_NAMESPACE_SYNAPS
00302 /********************************************************************/
00303 #endif //synaps_topology_cell3dN_H

SYNAPS DOCUMENTATION
logo