synaps/topology/TopSbdSurf.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_TopSbdSurf_h
00022 #define synaps_topology_TopSbdSurf_h
00023 #include <synaps/linalg/MatrDse.h>
00024 #include <synaps/topology/Cell3d.h>
00025 #include <synaps/topology/TopSbdCurve3d.h>
00026 __BEGIN_NAMESPACE_SYNAPS 
00027 //====================================================================
00028 // cell3d_curve: the structure of the cell that is tailored for building topological graph of
00029 //               the curve defined by two intersection implicit surfaces
00030 template < class C,
00031            class CELL= Cell3d<C> ,
00032            class MSLV = SbdSolver<typename CELL::coeff_t,SBDSLV_RDL> >
00033 
00034 struct TopSbdSurf3d : public TopSbdCurve3d<C,CELL,MSLV> 
00035 {
00036 
00038   // type definitions //
00040   
00041   typedef TopSbdSurf3d<C, CELL,MSLV>          self_t;
00042   typedef TopSbdCurve3d<C,CELL,MSLV>   base_t;
00043   
00044   typedef typename CELL::coeff_t         coeff_t;
00045   typedef typename CELL::MPOL_T          MPOL_T;
00046   typedef topology::box3d<coeff_t>       box_t;
00047 
00048   typedef CELL                           cell_t;
00049   typedef OCTREE::Node<cell_t*>           node_t;
00050   typedef OCTREE::Octree<cell_t*>         octree_t;
00051   
00052   typedef topology::point<C>             point_t;
00053   typedef topology::point_graph<C>       pointgraph_t;
00054  
00055   typedef intersection3d<coeff_t>        intersection_t;
00056   typedef Seq<intersection3d<coeff_t>*>  intersectionlist_t;
00057   typedef shared_object<intersection_t*> intersection_ptr;
00058   typedef Seq<intersection_ptr>          intersection_ptr_list;
00059   typedef topology::point_graph<coeff_t, intersection_ptr_list> pointgraph_int_t;
00060 
00061   //  typedef topology::point<coeff_t>        point_t;
00062   //  typedef topology::point_graph<coeff_t>  pointgraph_t;
00063 
00064   typedef MPolDse< coeff_t, mpoldse::bernstein<coeff_t> > mpolb_t;
00065 
00066   static OCTREE::EDGE_TYPE EdgesOfFace[6][4];
00067 
00068   unsigned m_min_dp, m_max_dp;
00069   MatrDse< Seq<OCTREE::NODE_TYPE> > insert_matr;
00070 
00071   TopSbdSurf3d():base_t (), m_min_dp(0), m_max_dp(6) {} //init_insert_matr();}
00072   TopSbdSurf3d(unsigned mn, unsigned mx=6):base_t (), m_min_dp(mn), m_max_dp(mx) {} //init_insert_matr();}
00073   TopSbdSurf3d(coeff_t e):base_t(e), m_min_dp(0), m_max_dp(6) {} //init_insert_matr(); }
00074   TopSbdSurf3d(coeff_t e, int d): base_t(e,d), m_min_dp(0), m_max_dp(6) {} //init_insert_matr(); }
00075   //  ~TopSbdSurf3d();
00076 
00077 
00078 
00080   // member functions //
00082 
00083   bool     compute_point_inside(point_t& p, cell_t* c);
00084 
00085   void     computeintersections(intersectionlist_t& inters, cell_t& c);
00086 
00087   // compute intersection on the dedicated face for the given polynomial
00088   void     computeinter_face(intersectionlist_t& inters, cell_t& c, int nAxis, int nFace);
00089 
00090   // compute intersection on the edge corresponding to the two faces
00091   void     computeinter_face(intersectionlist_t& inters, cell_t& c, 
00092                              int n1Axis, int n1Face, int n2Axis, int n2Face);
00093 
00094   void     computeinter_edge(intersectionlist_t& inters, cell_t& c, 
00095                              OCTREE::EDGE_TYPE edge);
00096 
00097   void     computeinter_edges(intersectionlist_t& inters, cell_t& c);
00098   // compute the intersection of  the first polynomial with the edges
00099   //  void     computeinter_edges(Seq<point_t>& inters, cell_t& c);
00100 
00101   bool     regularity(CELL& c);
00102 
00103   template<class POINTGRAPH>
00104   void build_mesh(POINTGRAPH& g, node_t* n);
00105   
00106   
00107   void compute_points(node_t* n);
00108 
00109   template<class POINTGRAPH>
00110   void run(POINTGRAPH& g, CELL* rc);
00111 
00112 protected:
00113 
00114 
00115   // this function subdivide a given node
00116   void subdivide(node_t*  n, std::vector<node_t*>& aNodeList);
00117   // this function subdivide a cell
00118   void subdivide(CELL* cell, std::vector<CELL*>& subCells);
00119 
00120 };
00121 //====================================================================
00122 template< class C, class CELL, class MSLV>
00123 OCTREE::EDGE_TYPE TopSbdSurf3d<C, CELL, MSLV>::EdgesOfFace[6][4]= 
00124   {{OCTREE::B_E,OCTREE::B_W,OCTREE::B_S,OCTREE::B_N},
00125    {OCTREE::F_E,OCTREE::F_W,OCTREE::F_S,OCTREE::F_N},
00126    {OCTREE::B_W,OCTREE::F_W,OCTREE::S_W,OCTREE::N_W},
00127    {OCTREE::B_E,OCTREE::F_E,OCTREE::S_E,OCTREE::N_E},
00128    {OCTREE::B_S,OCTREE::F_S,OCTREE::S_W,OCTREE::S_E},
00129    {OCTREE::B_N,OCTREE::F_N,OCTREE::N_W,OCTREE::N_E}};
00130 //====================================================================
00131 // template< class C, class CELL, class MSLV>
00132 // void TopSbdSurf3d<C, CELL, MSLV>::init_insert_matr()
00133 // {
00134 //   using  namespace OCTREE;
00135 //   insert_matr = MatrDse< Seq<OCTREE::NODE_TYPE> >(8,12);
00136 //   //BS_W
00137 //   insert_matr(B_SW,B_E).push_back(B_SE);
00138 //   insert_matr(B_SW,B_N).push_back(B_SW);
00139 //   insert_matr(B_SW,N_W).push_back(F_NW);
00140 //   insert_matr(B_SW,N_E).push_back(B_SE).push_back(B_NW).push_back(B_NE);
00141 //   insert_matr(B_SW,S_E).push_back(B_SE);
00142 //   insert_matr(B_SW,F_N).push_back(B_NW).push_back(F_SW).push_back(F_NW);
00143 //   insert_matr(B_SW,F_S).push_back(F_SW);
00144 //   insert_matr(B_SW,F_E).push_back(F_SW).push_back(B_SE).push_back(F_SE);
00145 //   insert_matr(B_SW,F_W).push_back(F_SW);
00146 
00147 //   //B_SE
00148 //   insert_matr(B_SE,B_N).push_back(B_NE);
00149 //   insert_matr(B_SE,N_E).push_back(B_NE);
00150 //   insert_matr(B_SE,F_N).push_back(B_NE).push_back(F_SE).push_back(F_NE);
00151 //   insert_matr(B_SE,F_S).push_back(F_SE);
00152 //   insert_matr(B_SE,F_E).push_back(F_SE);
00153 
00154 //   //F_SW
00155 //   insert_matr(F_SW,N_W).push_back(F_NW);
00156 //   insert_matr(F_SW,N_E).push_back(F_SE).push_back(F_NW).push_back(F_NE);
00157 //   insert_matr(F_SW,S_E).push_back(F_SE);
00158 //   insert_matr(F_SW,F_N).push_back(F_NW);
00159 //   insert_matr(F_SW,F_E).push_back(F_SE);
00160   
00161 //   //F_SE
00162 //   insert_matr(F_SE,N_E).push_back(F_NE);
00163 //   insert_matr(F_SE,F_N).push_back(F_NE);
00164 
00165 //   //B_NW
00166 //   insert_matr(B_NW,B_E).push_back(B_NE);
00167 //   insert_matr(B_NW,N_E).push_back(B_NE);
00168 //   insert_matr(B_NW,F_N).push_back(F_NW);
00169 //   insert_matr(B_NW,F_W).push_back(F_NW);
00170 //   insert_matr(B_NW,F_E).push_back(F_NW).push_back(B_NE).push_back(F_NE);
00171 
00172 //   //B_NE
00173 //   insert_matr(B_NE,F_N).push_back(F_NE);
00174 //   insert_matr(B_NE,F_E).push_back(F_NE);
00175 
00176 //   //F_NW
00177 //   insert_matr(F_NW,N_E).push_back(F_NE);
00178 //   insert_matr(F_NW,F_E).push_back(F_NE);
00179 
00180 // }
00181 
00183 // member function definitions  //
00185 
00186 //====================================================================
00187 
00189 /***************************************/
00190 /*               Z^                    */
00191 /*                |_____               */
00192 /*               /|    /|              */
00193 /*     N  ^     /_|_B_/ |              */
00194 /*        |    |  |___|_|___> Y        */
00195 /*        |    | /F   | /              */
00196 /*             |/_____|/               */
00197 /*            |/_                      */
00198 /*           X                         */
00199 /*                                     */
00200 /*    Fig.1  The coordinate system     */
00201 /***************************************/
00203 
00204 template< class C, class CELL, class MSLV>
00205 void TopSbdSurf3d<C, CELL, MSLV>::subdivide(node_t* n, std::vector<node_t*>& aNodeList)
00206 {
00207   using namespace OCTREE;
00208 
00209   std::vector<node_t*> aNodeNeigbrs;
00210 
00211     
00212   cell_t* cell = n->GetCell();
00213   std::vector<cell_t*> subCells;
00214 
00215   // subdivide a cell into 8 subcells
00216   subdivide(cell,subCells);
00217   
00218 
00219     // compute the intersections on the cell borders (Dynamic Programming applied here
00220     // to avoid repetitive computation, see arrangements of _cellidx/_faceidx/_shareidx)
00221 //     for (int i = 0; i < 8*MAX_FACEIDX; i++)
00222 //     {
00223 //         intersectionlist_t aInters;
00224 //         int nCellIdx=_cellidx[i], nFaceIdx = _faceidx[i], nShareIdx = _shareidx[i];
00225 
00226 //         if(nFaceIdx >= 0)
00227 //         {
00228 //             //       computeinter_face(aInters, *subCells[nCellIdx], nFaceIdx>>1, nFaceIdx%2);
00229 //             // the cell shares a face with this cell (i.e. subcells[_cellidx[i]]) should also
00230 //             // share the some intersections (on a particular face) with this cell
00231 //             // cell->mergelist(subCells[nCellIdx]->m_aInterList, aInters);
00232 //             // cell->mergelist(subCells[nShareIdx]->m_aInterList, aInters);
00233 //             // mark the this face (i.e. face nFaceIdx of cell nCellIdx) as 'computed'
00234 //          //            subCells[nCellIdx]->m_FaceComputed[nFaceIdx] = true;
00235 //             // for two subcells that shares a face, the shared face should of coz be parallel,
00236 //             // so their face indices should have same rounded value when devided by 3 (since
00237 //             // the face indices are (YZ_Plane_0, YZ_Plane_1, XZ_Plane0, XZ_Plane1, XY_Plane0,
00238 //             // XY_Plane1)). And of coz, they have different mod against 2.
00239 //             // by a simple deduction, f(x)=x+(x%2==1?-1:1) gives the correct face index for face x;
00240 //             // now we mark the shared face also as 'computed'
00241 //          // assert(subCells[nShareIdx]->m_FaceComputed[nFaceIdx+(nFaceIdx%2?-1:1)] == false);
00242 //             // if (subCells[nShareIdx]->m_FaceComputed[nFaceIdx+(nFaceIdx%2?-1:1)])
00243 //             //    std::cout << "assertion failed at depth " << cell->m_nDepth << " nCell " << nCellIdx << " nFace " << nFaceIdx << " nShare " << nShareIdx << " i"  << i << ", cell " << nShareIdx << " face " << (nFaceIdx+(nFaceIdx%2?-1:1)) << " has already been computed." << std::endl;
00244 //          // subCells[nShareIdx]->m_FaceComputed[nFaceIdx+(nFaceIdx%2?-1:1)] = true;
00245 //         }
00246 //     }
00247 
00248 
00249   // encapsulate the cells with the node of the octree
00250   aNodeList.push_back(new node_t(B_SW, n, subCells[B_SW]));
00251   aNodeList.push_back(new node_t(F_SW, n, subCells[F_SW]));
00252   aNodeList.push_back(new node_t(B_SE, n, subCells[B_SE]));
00253   aNodeList.push_back(new node_t(F_SE, n, subCells[F_SE]));
00254   aNodeList.push_back(new node_t(B_NW, n, subCells[B_NW]));
00255   aNodeList.push_back(new node_t(F_NW, n, subCells[F_NW]));
00256   aNodeList.push_back(new node_t(B_NE, n, subCells[B_NE]));
00257   aNodeList.push_back(new node_t(F_NE, n, subCells[F_NE]));
00258 
00259 //   for(unsigned i=0;i<8;i++)
00260 //     {
00261 //       intersectionlist_t aInters;
00262 //       computeinter_edges(aInters, *subCells[i]);
00263 //       cell->mergelist(subCells[i]->m_aInterList, aInters);
00264 //     }
00265 
00266 
00267 //   node_t* Nbg[6];
00268 //   Nbg[B]=n->getBackNeighborNode();
00269 //   Nbg[F]=n->getFrontNeighborNode();
00270 //   Nbg[N]=n->getNorthNeighborNode();
00271 //   Nbg[S]=n->getSouthNeighborNode();
00272 //   Nbg[E]=n->getEastNeighborNode();
00273 //   Nbg[W]=n->getWestNeighborNode();
00274 
00275 
00276 //   MatrDse<node_t*> ngbrs(8,12);
00277 //   ngbrs(B_SW,B_N)=Nbg[B];
00278 //   ngbrs(B_SW,B_E)=Nbg[B];
00279 //   ngbrs(B_SW,N_W)=Nbg[W];
00280 //   ngbrs(B_SW,F_W)=Nbg[W];
00281 //   ngbrs(B_SW,F_S)=Nbg[S];
00282 //   ngbrs(B_SW,S_E)=Nbg[S];
00283 
00284 //   ngbrs(B_SE,B_N)=Nbg[B];
00285 //   ngbrs(B_SE,N_E)=Nbg[E];
00286 //   ngbrs(B_SE,F_E)=Nbg[E];
00287 //   ngbrs(B_SE,F_S)=Nbg[S];
00288 
00289 //   ngbrs(F_SW,N_W)=Nbg[W];
00290 //   ngbrs(F_SW,F_N)=Nbg[F];
00291 //   ngbrs(F_SW,F_E)=Nbg[F];
00292 //   ngbrs(F_SW,S_E)=Nbg[S];
00293 
00294 //   ngbrs(F_SE,N_E)=Nbg[E];
00295 //   ngbrs(F_SE,F_N)=Nbg[F];
00296 
00297 //   ngbrs(B_NW,F_W)=Nbg[W];
00298 //   ngbrs(B_NW,B_E)=Nbg[B];
00299 //   ngbrs(B_NW,N_E)=Nbg[N];
00300 //   ngbrs(B_NW,F_N)=Nbg[N];
00301 
00302 //   ngbrs(F_NE,B_E)=Nbg[E];
00303 //   ngbrs(F_NE,F_W)=Nbg[F];
00304 //   ngbrs(F_NE,N_W)=Nbg[N];
00305 //   ngbrs(F_NE,B_N)=Nbg[N];
00306 
00307 //   cell_t* clnbr;
00308 
00309 //   for(unsigned i=0;i<8;i++)
00310 //     for(unsigned j=0;j<12;j++)
00311 //       {
00312 //      intersectionlist_t L;
00313 //      computeinter_edge(L,*subCells[i],(EDGE_TYPE)j);
00314 //      //      PRINT_DEBUG(" L sz "<<L.size());
00315 //      if(ngbrs(i,j) != NULL && L.size())
00316 //        {
00317 //          clnbr = ngbrs(i,j)->GetCell();
00318 //          clnbr->mergelist(clnbr->m_aInterList,L);
00319 //        }
00320 //       }
00321 }
00322 //--------------------------------------------------------------------
00324 /***************************************/
00325 /*          ^ Z                        */
00326 /*          |                          */
00327 /*          |                          */
00328 /*          |                          */
00329 /*          |4----6                    */
00330 /*         /||___/|_______> Y          */
00331 /*        5/-0--7 2                    */
00332 /*        /|/   |/                     */
00333 /*       / 1----3                      */
00334 /*     \/_                             */
00335 /*     X                               */
00336 /*                                     */
00337 /*    Fig.2  The layout of the         */
00338 /*        subdivided cells             */
00339 /***************************************/
00341 
00343 /***************************************/
00344 /*          ^ Z                        */
00345 /*          |   5     0                */
00346 /*          |  |     /                 */
00347 /*          |  v   |/_                 */
00348 /*          |------                    */
00349 /*         /||___/|_______> Y          */
00350 /*  2-->  -/ ---- | <--3               */
00351 /*        /|/ 1 |/                     */
00352 /*       / ------                      */
00353 /*     \/_    ^                        */
00354 /*     X      |                        */
00355 /*             4                       */
00356 /*    Fig.3  Faces index of a cell     */
00357 /***************************************/
00359 // this function spawns 8 evenly subdivided child cell of this call
00360 template < class C, class CELL, class MSLV >
00361 void TopSbdSurf3d<C, CELL, MSLV>::subdivide(CELL* cell,
00362                                             std::vector<CELL*>& subCells)
00363 {
00364   typedef typename CELL::intersection_t intersection_t;
00365   typedef typename CELL::intersectionlist_t intersectionlist_t;
00366   typedef typename CELL::MPOL_T MPOL_T;
00367     // define the subdivision points
00368 #ifdef SYNAPS_SBD3D_RNDFACTORWHENSUBDIVISION
00369     // a perturbation ranged from 0.005-0.1
00370     C t[] = {(C(rand())/C(RAND_MAX)-C(0.5))*C(0.095)+C(0.5),
00371              (C(rand())/C(RAND_MAX)-C(0.5))*C(0.095)+C(0.5),
00372              (C(rand())/C(RAND_MAX)-C(0.5))*C(0.095)+C(0.5)};
00373     t[0]+= (t[0]>0.5?0.005:-0.005);
00374     t[1]+= (t[1]>0.5?0.005:-0.005);
00375     t[2]+= (t[2]>0.5?0.005:-0.005);
00376     C mid[] = {cell->m_cBox.x0*(C(1)-t[0])+cell->m_cBox.x1*t[0], cell->m_cBox.y0*(C(1)-t[1])+cell->m_cBox.y1*t[1], cell->m_cBox.z0*(C(1)-t[2])+cell->m_cBox.z1*t[2]};
00377 #else
00378     C mid[] = {(cell->m_cBox.x0+cell->m_cBox.x1)/C(2), (cell->m_cBox.y0+cell->m_cBox.y1)/C(2), (cell->m_cBox.z0+cell->m_cBox.z1)/C(2)};
00379 #endif
00380     C box[] = {cell->m_cBox.x0, cell->m_cBox.x1, cell->m_cBox.y0, cell->m_cBox.y1, cell->m_cBox.z0, cell->m_cBox.z1};
00381 
00382     // create new cells
00383     subCells.push_back(new CELL(cell->nbpol(), box[0], mid[0], box[2], mid[1], box[4], mid[2]));
00384     subCells.push_back(new CELL(cell->nbpol(), mid[0], box[1], box[2], mid[1], box[4], mid[2]));
00385     subCells.push_back(new CELL(cell->nbpol(), box[0], mid[0], mid[1], box[3], box[4], mid[2]));
00386     subCells.push_back(new CELL(cell->nbpol(), mid[0], box[1], mid[1], box[3], box[4], mid[2]));
00387     subCells.push_back(new CELL(cell->nbpol(), box[0], mid[0], box[2], mid[1], mid[2], box[5]));
00388     subCells.push_back(new CELL(cell->nbpol(), mid[0], box[1], box[2], mid[1], mid[2], box[5]));
00389     subCells.push_back(new CELL(cell->nbpol(), box[0], mid[0], mid[1], box[3], mid[2], box[5]));
00390     subCells.push_back(new CELL(cell->nbpol(), mid[0], box[1], mid[1], box[3], mid[2], box[5]));
00391 
00392     // update the depth count for each subdivided cells
00393     for (int i = 0; i < 8; i++)
00394     {
00395         subCells[i]->m_nDepth = cell->m_nDepth+1;
00396     }
00397 
00398   //   // the subcells inherits the previous computed intersections on its parent cell
00399 //     for (int i = 0; i < cell->m_aInterList.size(); i++)
00400 //     {
00401 //         intersection_t* inter = cell->m_aInterList[i];
00402 
00403 //         // assign the intersections on the parent cell to subdivided cells, according to the plane
00404 //         // they are on and the planar coordinates
00405 //      int nidx = inter->nPlane; // testing the plane YZ (nidx=0) or XZ (nidx=1) or XZ (nidx=2)
00406 //         int *cidx=subcellidx+(nidx<<3); // the right set of subcell indices to be assigned each intersection
00407 //      int axisidx0 = plane_axisidx[nidx<<1], axisidx1 = plane_axisidx[(nidx<<1)+1]; // the first and the second axis indices, {1, 2} for YZ plane, {0, 2} for XZ plane and {0, 1} for XY plane
00408 
00409 //         // assert(_is_verysmall(inter->pnt[nidx]-box[nidx<<1]) || _is_verysmall(box[(nidx<<1)+1]-inter->pnt[nidx]));
00410 //      // assert(inter->pnt[axisidx0] >= box[axisidx0<<1] && inter->pnt[axisidx0] <= box[(axisidx0<<1)+1] &&
00411 //         //        inter->pnt[axisidx1] >= box[axisidx1<<1] && inter->pnt[axisidx1] <= box[(axisidx1<<1)+1]);
00412 
00413 //         if (inter->pnt[axisidx0] <= mid[axisidx0]) // if smaller than the first mid-point
00414 //         {
00415 //             if (inter->pnt[axisidx1] <= mid[axisidx1]) // if smaller than the second mid-point
00416 //             {
00417 //                 if (inter->pnt[nidx]-box[nidx<<1] <= box[(nidx<<1)+1]-inter->pnt[nidx]) // if the plane corresponds to x (or y, or z) = a, where x (or y, or z) is in [a, b]
00418 //                     subCells[cidx[0]]->m_aInterList.push_back(inter);
00419 //                 else // if the plane corresponds to x (or y, or z) = b, where x (or y, or z) is in [a, b]
00420 //                     subCells[cidx[1]]->m_aInterList.push_back(inter);
00421 //             }
00422 //             if (inter->pnt[axisidx1] >= mid[axisidx1]) // if larger than the first mid-point
00423 //             {
00424 //                 if (inter->pnt[nidx]-box[nidx<<1] <= box[(nidx<<1)+1]-inter->pnt[nidx]) // if the plane corresponds to x (or y, or z) = a, where x (or y, or z) is in [a, b]
00425 //                     subCells[cidx[2]]->m_aInterList.push_back(inter);
00426 //                 else
00427 //                     subCells[cidx[3]]->m_aInterList.push_back(inter);
00428 //             }
00429 //         }
00430 //         if (inter->pnt[axisidx0] >= mid[axisidx0]) 
00431 //        // if lager than the first mid-point
00432 //         {
00433 //             if (inter->pnt[axisidx1] <= mid[axisidx1]) 
00434 //            // if smaller than the second  mid-point
00435 //             {
00436 //                 if (inter->pnt[nidx]-box[nidx<<1] <= box[(nidx<<1)+1]-inter->pnt[nidx]) // if the plane corresponds to x (or y, or z) = a, where x (or y, or z) is in [a, b]
00437 //                     subCells[cidx[4]]->m_aInterList.push_back(inter);
00438 //                 else // if the plane corresponds to x (or y, or z) = b, where x (or y, or z) is in [a, b]
00439 //                     subCells[cidx[5]]->m_aInterList.push_back(inter);
00440 //             }
00441 //             if (inter->pnt[axisidx1] >= mid[axisidx1])  
00442 //            // if larger than the second mid-point
00443 //             {
00444 //                 if (inter->pnt[nidx]-box[nidx<<1] <= box[(nidx<<1)+1]-inter->pnt[nidx])
00445 //                     subCells[cidx[6]]->m_aInterList.push_back(inter);
00446 //                 else // if the plane corresponds to x (or y, or z) = b, where x (or y, or z) is in [a, b]
00447 //                     subCells[cidx[7]]->m_aInterList.push_back(inter);
00448 //             }
00449 //         }
00450 //     }
00451 
00452   //   // update the 'computed faces' flag for all subcells
00453 //     for (int i = 0; i < 8*MAX_FACEIDX; i++)
00454 //     {
00455 //         int nCellIdx=_cellidx[i], nInheritIdx = _inheritidx[i];
00456 //         // assert that a face never inherit from more than one parent cell's face
00457 //         assert((subCells[nCellIdx]->m_FaceComputed[nInheritIdx]) == false);
00458 //         /*if ((subCells[nCellIdx]->m_FaceComputed[nInheritIdx]))
00459 //             std::cout << "assertion failed at depth " << cell->m_nDepth << std::endl;*/
00460 //      //        if (cell->m_FaceComputed[nInheritIdx]) // if the parent cell's face this cell inherited from has 'computed' flag
00461 //      //            subCells[nCellIdx]->m_FaceComputed[nInheritIdx] = true;
00462 //     }
00463 
00464     // split the representations for each surface
00465     for (int i = 0; i < cell->nbpol(); i++)
00466     {
00467         MPOL_T splited[8];
00468         int vr_idx[3] = {VARIDX(cell->m_F[i], 0), VARIDX(cell->m_F[i], 1), VARIDX(cell->m_F[i], 2)};
00469 
00470         subCells[7]->m_F[i] = cell->m_F[i];
00471 #ifdef SYNAPS_SBD3D_RNDFACTORWHENSUBDIVISION
00472         // subdivide along z direction with a perturbation
00473         mpoldse::split(subCells[3]->m_F[i].rep(), subCells[7]->m_F[i].rep(), vr_idx[2], t[2]);
00474 
00475         // subdivide along y direction with a perturbation
00476         mpoldse::split(subCells[1]->m_F[i].rep(), subCells[3]->m_F[i].rep(), vr_idx[1], t[1]);
00477         mpoldse::split(subCells[5]->m_F[i].rep(), subCells[7]->m_F[i].rep(), vr_idx[1], t[1]);
00478 
00479         // subdivide along x direction with a perturbation
00480         mpoldse::split(subCells[0]->m_F[i].rep(), subCells[1]->m_F[i].rep(), vr_idx[0], t[0]);
00481         mpoldse::split(subCells[2]->m_F[i].rep(), subCells[3]->m_F[i].rep(), vr_idx[0], t[0]);
00482         mpoldse::split(subCells[4]->m_F[i].rep(), subCells[5]->m_F[i].rep(), vr_idx[0], t[0]);
00483         mpoldse::split(subCells[6]->m_F[i].rep(), subCells[7]->m_F[i].rep(), vr_idx[0], t[0]);
00484 #else
00485         // subdivide along z direction
00486         mpoldse::split(subCells[3]->m_F[i].rep(), subCells[7]->m_F[i].rep(), vr_idx[2]);
00487 
00488         // subdivide along y direction
00489         mpoldse::split(subCells[1]->m_F[i].rep(), subCells[3]->m_F[i].rep(), vr_idx[1]);
00490         mpoldse::split(subCells[5]->m_F[i].rep(), subCells[7]->m_F[i].rep(), vr_idx[1]);
00491 
00492         // subdivide along x direction
00493         mpoldse::split(subCells[0]->m_F[i].rep(), subCells[1]->m_F[i].rep(), vr_idx[0]);
00494         mpoldse::split(subCells[2]->m_F[i].rep(), subCells[3]->m_F[i].rep(), vr_idx[0]);
00495         mpoldse::split(subCells[4]->m_F[i].rep(), subCells[5]->m_F[i].rep(), vr_idx[0]);
00496         mpoldse::split(subCells[6]->m_F[i].rep(), subCells[7]->m_F[i].rep(), vr_idx[0]);
00497 #endif
00498     }
00499         
00500 }
00501 //====================================================================
00502 template< class C, class CELL, class MSLV>
00503 template< class POINTGRAPH>
00504 void TopSbdSurf3d<C, CELL, MSLV>::run(POINTGRAPH& g, CELL* rc)
00505 {
00506   typedef CELL cell_t;
00507     node_t* root = this->m_cOcTree.GetRoot();
00508 
00509     //    computeintersections(rc->m_aInterList, *rc);
00510     //    std::cout << "no. of roots at root: " << rc->m_aInterList.size() << std::endl;
00511 
00512     root->SetCell(rc);
00513 
00514     // step3:
00515     // subdivision
00516     //    PRINT_DEBUG("Subdivision");
00517     std::list<node_t*> aNodeQueue;
00518     std::list<node_t*> aNodeKept;
00519     std::vector<node_t*> aSingular;
00520     pointgraph_int_t g_tmp;
00521     int nCellProc = 0;
00522 
00523     aNodeQueue.push_front(root);
00524 
00525     while(aNodeQueue.size())
00526     {
00527         // process the first node in the queue
00528         node_t* n = *aNodeQueue.begin();
00529         aNodeQueue.pop_front();
00530 
00531         bool bSubdivide = false;
00532         bool bBuildGraph = false;
00533 
00534         // if the cell is regular, i.e. the topology of the surface within the cell is certified
00535         if (regularity(*n->GetCell()))
00536         {
00537             if (is_variety_in(*n->GetCell())) // it may contains the variety
00538             {
00539                 if (n->GetCell()->m_nDepth < this->m_nMinSbd) // if we did less than the minimum number of subdivision
00540                 {
00541                     // subdivide further
00542                     bSubdivide = true;
00543                 }
00544                 else // build the graph
00545                 {
00546                     bBuildGraph = true;
00547                 }
00548             }
00549             else // if regular yet does not contain the surface, of no interest for further subdivision
00550             {
00551                 // its safe to say that not any facet of this cell should contain a intersection point
00552                 memset(n->GetCell()->m_FaceComputed, true, sizeof(bool)*6);
00553             }
00554         }
00555         else // if the cell is not regular
00556         {
00557             if (n->GetCell()->m_nDepth> m_max_dp) // if the cell size is smaller than epsilon
00558             {
00559                 // keep a count of singular cells
00560                 if (is_variety_in(*n->GetCell()))
00561                 {
00562                     bBuildGraph = true;
00563                     aSingular.push_back(n);
00564                 }
00565                 else
00566                   memset(n->GetCell()->m_FaceComputed, true, sizeof(bool)*6);
00567             }
00568             else // if the cell size is still larger than the set threshold
00569             {
00570                 // further subdivision if it may contains the intersection
00571                 if (is_variety_in(*n->GetCell()))
00572                     bSubdivide = true;
00573                 else
00574                   memset(n->GetCell()->m_FaceComputed, true, sizeof(bool)*6);
00575             }
00576         }
00577 
00578         // in fact, bSubdivide and bBuildGraph cannot be both true (but can be both false)
00579         // assert(!(bSubdivide && bBuildGraph))
00580         if (bSubdivide)
00581         {
00582             // append the subdivided node at the back of the queue
00583             // in doing this, we can guarantee that larger nodes are processed first
00584             std::vector<node_t*> aNodeList;
00585             subdivide(n, aNodeList);
00586             for (int i = 0; i < (int)aNodeList.size(); i++)
00587                 aNodeQueue.push_back(aNodeList[i]);
00588         }
00589         else if (bBuildGraph)
00590         {
00591           aNodeKept.push_front(n);
00592         }
00593 
00594         // a counter
00595         nCellProc++;
00596     }
00597     PRINT_DEBUG("Computing points");
00598     typedef typename std::list<node_t*>::const_iterator node_iterator_t;
00599     for(node_iterator_t it=aNodeKept.begin(); it != aNodeKept.end(); it++)
00600       {
00601         compute_points(*it);
00602       }
00603     //Once all cells are computed, we build the mesh.
00604     PRINT_DEBUG("Building mesh");
00605     for(node_iterator_t it=aNodeKept.begin(); it != aNodeKept.end(); it++)
00606       {
00607         build_mesh(g,(*it));
00608       }
00609 
00610     std::cout << "Number of Cells     : " << nCellProc << std::endl;
00611     std::cout << "Number of Sing Cells: " << aSingular.size() << std::endl;
00612 }
00613 
00614 //====================================================================
00615 template <class C, class CELL, class MSLV >
00616 bool TopSbdSurf3d<C, CELL, MSLV>::compute_point_inside(point_t& p, cell_t* cell)
00617 {
00618   using namespace OCTREE;
00619   std::vector<cell_t*> subCells;
00620   subdivide(cell,subCells);
00621   
00622   intersectionlist_t L;
00623   computeinter_edge(L,*subCells[B_SW],N_E);
00624   if(L.size())
00625     {
00626       for(unsigned j=0;j<3;j++) p[j]=L[0]->pnt[j]; return true; 
00627     }
00628 
00629   computeinter_edge(L,*subCells[B_SW],F_N);
00630   if(L.size())
00631     {
00632       for(unsigned j=0;j<3;j++) p[j]=L[0]->pnt[j]; return true; 
00633     }
00634 
00635   computeinter_edge(L,*subCells[B_SW],F_E);
00636   if(L.size())
00637     {
00638       for(unsigned j=0;j<3;j++) p[j]=L[0]->pnt[j]; return true; 
00639     }
00640 
00641   computeinter_edge(L,*subCells[F_NE],B_W);
00642   if(L.size())
00643     {
00644       for(unsigned j=0;j<3;j++) p[j]=L[0]->pnt[j]; return true; 
00645     }
00646 
00647   computeinter_edge(L,*subCells[F_NE],B_S);
00648   if(L.size())
00649     {
00650       for(unsigned j=0;j<3;j++) p[j]=L[0]->pnt[j]; return true; 
00651     }
00652 
00653   computeinter_edge(L,*subCells[F_NE],S_W);
00654   if(L.size())
00655     {
00656       for(unsigned j=0;j<3;j++) p[j]=L[0]->pnt[j]; return true; 
00657     }
00658 
00659   return false;
00660 }
00661 //--------------------------------------------------------------------
00662 template <class C, class CELL, class MSLV >
00663 void TopSbdSurf3d<C, CELL, MSLV>::computeintersections(intersectionlist_t& inters, CELL& c)
00664 {
00665 
00666   // for each facet of the cell, compute its intersections with the curve
00667   for (int v = 0; v < 3; v++) // for each axis
00668     {
00669       for (int f = 0; f < 2; f++) // for each facet perpendicular to that axis
00670         {         // compute the intersections on this facet if it has not yet been computed
00671           if (!c.m_FaceComputed[v*2+f])
00672             {
00673               computeinter_face(inters, c, v, f);
00674               //c.m_FaceComputed[v*2+f] = true;
00675             }
00676         }
00677     }
00678 }
00679 //--------------------------------------------------------------------
00680 template < class C, class CELL, class MSLV >
00681 void TopSbdSurf3d<C, CELL, MSLV>::computeinter_face(intersectionlist_t& inters, 
00682                                                     CELL& c, 
00683                                                     int nAxis, int nFace)
00684 {
00685     PRINT_DEBUG("Points on face "<< nAxis<<" "<<nFace);
00686     unsigned N=c.m_nT;
00687     if (N==1)      return;
00688 
00689     // build a system of equations
00690     std::vector<MPOL_T> facepol(N+3); // = {m_F[0], m_F[1]};
00691     std::list<MPOL_T> eqnList;
00692     unsigned sz=0;
00693     for(unsigned i=0;i<N;i++)
00694       {
00695         // obtain the polynomial representing the face
00696         face(facepol[i].rep(), c.m_F[i].rep(), nAxis, nFace);
00697         eqnList.push_back(facepol[i]);
00698         sz++;
00699       }
00700     MPOL_T dp[3];
00701     for (unsigned i = 0; i < 3; i++)
00702       {
00703         diff(dp[i],c.m_F[0],VARIDX(c.m_F[0], i));
00704         face(facepol[N+i].rep(), dp[i].rep(), nAxis, nFace);
00705         sz++;
00706       }
00707     PRINT_DEBUG("Solving "<<sz<<" equations");
00708     // solve the equation using a 2-variate solver
00709     MSLV solver(&facepol[0], &facepol[0]+sz, 1e-4);
00710     PRINT_DEBUG("Solving "<<sz<<" equations");
00711     std::vector<C> results;
00712     int nSol, nVar;
00713     solver.solve(results, nSol, nVar, eqnList.begin(), eqnList.end());
00714     PRINT_DEBUG("Nb of sol: "<<nSol<<" Nb of var: "<<nVar);
00715     //    assert(nVar==2);
00716     // rescale the solution to the coordinates of the cell
00717     // also update the multiplicity accordingly
00718     for (int s = 0; s < nSol; s++)
00719     {
00720         C x[3] = {(C)nFace,(C)nFace,(C)nFace}; // the 3D coord of the point
00721 
00722         switch(nAxis)
00723         {
00724         case PLANEYZ: // yz-planes
00725             x[1] = (C)(results[nVar*s]);
00726             x[2] = (C)(results[nVar*s+1]);
00727             break;
00728         case PLANEXZ: // xz-planes
00729             x[0] = (C)(results[nVar*s]);
00730             x[2] = (C)(results[nVar*s+1]);
00731             break;
00732         case PLANEXY: // xy-planes
00733             x[0] = (C)(results[nVar*s]);
00734             x[1] = (C)(results[nVar*s+1]);
00735             break;
00736         }
00737         // determine the multiplicity
00738         //int nMaxDeg = c.m_T[nAxis].rep().env.sz(VARIDX(c.m_T[nAxis], nAxis)); // the degree of nAxis_th variable of nAxis_th component of t = {t1, t2, t3} = gradF cross gradG
00739         int nMulti =  2;
00740 
00741         // currently, only account for multiplicity 1 or 2...
00742         //for (int v = 0; v< nMaxDeg; v++)
00743         if(false)
00744           {
00745             C val[3] = {-1,-1,-1};
00746             eval(val[0], c.m_F[c.m_nT], x); // evaluate the t_nAxis(x0, y0, z0) at the intersection (x0, y0, z0)
00747             eval(val[1], c.m_F[c.m_nT+1], x); // evaluate the t_nAxis(x0, y0, z0) at the intersection (x0, y0, z0)
00748             eval(val[2], c.m_F[c.m_nT+2], x); // evaluate the t_nAxis(x0, y0, z0) at the intersection (x0, y0, z0)
00749 
00750             /*if (abs(val[nAxis]) < 0.1)
00751             {
00752                 std::cout << "sin val: " << val[nAxis];
00753                 val[nAxis] /= sqrt(val[0]*val[0]+val[1]*val[1]+val[2]*val[2]); // normalize the vector
00754                 std::cout << " nor: " << val[nAxis] << std::endl;
00755             }
00756             else
00757             {
00758                 val[nAxis] /= sqrt(val[0]*val[0]+val[1]*val[1]+val[2]*val[2]); // normalize the vector
00759             }*/
00760 
00761             val[nAxis] /= sqrt(val[0]*val[0]+val[1]*val[1]+val[2]*val[2]); // normalize the vector
00762 
00763             if (_is_verysmall(std::abs(val[nAxis])))
00764             {
00765                 nMulti = 2;
00766                 //std::cout << "multiple point: val =" << val << ",  f(" << nAxis << ")=" << c.m_T[nAxis] << std::endl;
00767             }
00768           }
00769 
00770 
00771         // scale to the cell's coordinate
00772         point_t l(3u);
00773         l[0] = c.m_cBox.x0*((C)1-x[0]) + c.m_cBox.x1*x[0];
00774         l[1] = c.m_cBox.y0*((C)1-x[1]) + c.m_cBox.y1*x[1];
00775         l[2] = c.m_cBox.z0*((C)1-x[2]) + c.m_cBox.z1*x[2];
00776 
00777 
00778         intersection_t *ni = new intersection_t(l, nAxis, nMulti);
00779         inters.push_back(ni);
00780         ni->nDepth = c.m_nDepth;
00781         // PRINT_DEBUG("new point");
00782     }
00783     PRINT_DEBUG("End point on face");
00784 }
00785 //--------------------------------------------------------------------
00786 template < class C, class CELL, class MSLV >
00787 void TopSbdSurf3d<C, CELL, MSLV>::computeinter_face(intersectionlist_t& inters, 
00788                                                 CELL& c, 
00789                                                 int n1Axis, int n1Face,
00790                                                 int n2Axis, int n2Face)
00791 {
00792   assert(n1Axis<n2Axis);
00793   MPOL_T pf,p[1];
00794   //PRINT_DEBUG(" ");
00795   //PRINT_DEBUG("FaceFace "<<n1Axis<<" "<<n1Face<<" "<<n2Axis<<" "<<n2Face);
00796 
00797   face(pf.rep(), c.m_F[0].rep(),n1Axis,n1Face); 
00798   face(p[0].rep(), pf.rep(),n2Axis-1,n2Face); 
00799 
00800   //  PRINT_DEBUG(p[0]);
00801 
00802   MSLV slv(p, p+1, 1e-4);
00803 
00804   std::vector<coeff_t> sol;
00805   std::list<MPOL_T> eqnList; eqnList.push_back(p[0]);
00806   int nSol, nVar;
00807   slv.solve(sol, nSol, nVar, eqnList.begin(), eqnList.end());
00808   assert(nVar==1);
00809   //  if(sol.size()) { VECTOR::print(std::cout,sol)<<std::endl;}
00810   point_t pt(3u);
00811   for(unsigned j=0;j<sol.size();j++)
00812     {
00813       for(unsigned i=0;i<3;i++)
00814         {
00815           if(i==n1Axis)
00816             switch(i)
00817               {
00818               case 0:
00819                 pt[0]=(n1Face?c.m_cBox.x1:c.m_cBox.x0);
00820               case 1:
00821                 pt[1]=(n1Face?c.m_cBox.y1:c.m_cBox.y0);
00822               case 2:
00823                 pt[2]=(n1Face?c.m_cBox.z1:c.m_cBox.z0);
00824               }
00825           else if(i==n2Axis)
00826             switch(i)
00827               {
00828               case 0:
00829                 pt[0]=(n2Face?c.m_cBox.x1:c.m_cBox.x0);
00830               case 1:
00831                 pt[1]=(n2Face?c.m_cBox.y1:c.m_cBox.y0);
00832               case 2:
00833                 pt[2]=(n2Face?c.m_cBox.z1:c.m_cBox.z0);
00834               }
00835           else
00836             switch(i)
00837               {
00838               case 0:
00839                 pt[0]=c.m_cBox.x0*((coeff_t)1-sol[j]) + c.m_cBox.x1*sol[j];
00840               case 1:
00841                 pt[1]=c.m_cBox.y0*((coeff_t)1-sol[j]) + c.m_cBox.y1*sol[j];
00842               case 2:
00843                 pt[2]=c.m_cBox.z0*((coeff_t)1-sol[j]) + c.m_cBox.z1*sol[j];
00844               }
00845         }
00846       int nMulti = 1;
00847       C val;
00848       unsigned sz=p[0].rep().size()-1;
00849       if(sz>1)
00850         {
00851           C dp[sz];
00852           for(unsigned u=0;u<sz;u++) dp[u]=p[0][u+1]-p[0][u];
00853           mpoldse::decasteljau(dp,sz,sol[j]);
00854           if(_is_singular(dp[0]))
00855             {
00856               //              PRINT_DEBUG(p[0]);
00857               PRINT_DEBUG("Multiple point: "<<pt<<" "<<dp[0]<<
00858                           " ["<<c.m_cBox.x0<<" "<<c.m_cBox.x1<<" "<<c.m_cBox.y0<<" "<<c.m_cBox.y1<<" "<<c.m_cBox.z0<<" "<<c.m_cBox.z1<<"]");
00859 
00860               nMulti=2;
00861             }
00862         }
00863       intersection_t *ni = new intersection_t(pt, n1Axis , nMulti);
00864       inters.push_back(ni);
00865       ni->nDepth = c.m_nDepth;
00866       //      nbpt++;
00867     }
00868 
00869 
00870 }
00871 //====================================================================
00872 template < class C, class CELL, class MSLV >
00873 void TopSbdSurf3d<C, CELL, MSLV>::computeinter_edge(intersectionlist_t& inters, 
00874                                                      CELL& c,
00875                                                      OCTREE::EDGE_TYPE edge)
00876 {
00877   using namespace OCTREE;
00878   switch(edge)
00879     {
00880     case B_W:
00881       computeinter_face(inters,c,0,0,1,0);
00882       break;
00883     case B_E:
00884       computeinter_face(inters,c,0,0,1,1);
00885       break;
00886     case B_S:
00887       computeinter_face(inters,c,0,0,2,0);
00888       break;
00889     case B_N:
00890       computeinter_face(inters,c,0,0,2,1);
00891       break;
00892     case F_W:
00893       computeinter_face(inters,c,0,1,1,0);
00894       break;
00895     case F_E:
00896       computeinter_face(inters,c,0,1,1,1);
00897       break;
00898     case F_S:
00899       computeinter_face(inters,c,0,1,2,0);
00900       break;
00901     case F_N:
00902       computeinter_face(inters,c,0,1,2,1);
00903       break;
00904     case S_W:
00905       computeinter_face(inters,c,1,0,2,0);
00906       break;
00907     case N_W:
00908       computeinter_face(inters,c,1,0,2,1);
00909       break;
00910     case S_E:
00911       computeinter_face(inters,c,1,1,2,0);
00912       break;
00913     case N_E:
00914       computeinter_face(inters,c,1,1,2,1);
00915       break;
00916     }
00917 }
00918 //====================================================================
00919 template < class C, class CELL, class MSLV >
00920 void TopSbdSurf3d<C, CELL, MSLV>::computeinter_edges(intersectionlist_t& inters, 
00921                                                  CELL& c)
00922 {
00923   //  PRINT_DEBUG("-------------------------------");
00924   //  PRINT_DEBUG(c.m_cBox.x0<<" "<<c.m_cBox.x1<<" "<<c.m_cBox.y0<<" "<<c.m_cBox.y1<<" "<<c.m_cBox.z0<<" "<<c.m_cBox.z1);
00925 //   for(unsigned i0=0;i0<3;i0++)
00926 //     for(unsigned i1=i0+1;i1<3;i1++)
00927 //       for(unsigned j0=0;j0<2;j0++)
00928 //      for(unsigned j1=0;j1<2;j1++)
00929 //        computeinter_face(inters,c,i0,j0,i1,j1);
00930   using namespace OCTREE;
00931   for(unsigned i=0;i<12;i++)
00932     computeinter_edge(inters,c,(EDGE_TYPE)i);
00933 }
00934 //--------------------------------------------------------------------
00935 template < class POINT, class CELL>
00936 unsigned Computeinter_edges(VectDse<Seq<POINT> >& inters, 
00937                             const CELL& c)
00938 {
00939 
00940   typedef typename CELL::coeff_t         coeff_t;
00941   typedef typename CELL::MPOL_T          MPOL_T;
00942   typedef POINT                          point_t;
00943 
00944   unsigned nbpt=0;
00945   MPOL_T lp[3],px0,px1,pz0,pz1;
00946   int nSol, nVar;
00947   point_t pt(3u);
00948 
00949   PRINT_DEBUG("================================");
00950   //  PRINT_DEBUG(c.m_cBox.x0<<" "<<c.m_cBox.x1<<" "<<c.m_cBox.y0<<" "<<c.m_cBox.y1<<" "<<c.m_cBox.z0<<" "<<c.m_cBox.z1);
00951   face(px0.rep(), c.m_F[0].rep(),0,0); 
00952   face(px1.rep(), c.m_F[0].rep(),0,1); 
00953 
00954 
00955   face(lp[2].rep(), px0.rep(),0,0); 
00956   //  PRINT_DEBUG(" ");
00957   //  PRINT_DEBUG("X0Y0 "<<lp[2]);
00958 
00959   SbdSolver<coeff_t,SBDSLV_RDL> slv2(lp+2, lp+3, 1e-4);
00960   std::vector<coeff_t> sol;
00961   std::list<MPOL_T> eqnList; eqnList.push_back(lp[2]);
00962   slv2.solve(sol, nSol, nVar, eqnList.begin(), eqnList.end());
00963 
00964   assert(nVar==1);
00965   //  if(sol.size()) { VECTOR::print(std::cout,sol)<<std::endl;}
00966 
00967   pt[0]=c.m_cBox.x0;
00968   pt[1]=c.m_cBox.y0;
00969   for(unsigned j=0;j<sol.size();j++)
00970     {
00971        pt[2]= c.m_cBox.z0*((coeff_t)1-sol[j]) + c.m_cBox.z1*sol[j];
00972        inters[0].push_back(pt);
00973        //  PRINT_DEBUG(pt<<" |"<<sol[j]<<"|  "<<c.m_cBox.x0<<" "<<c.m_cBox.x1<<" "<<c.m_cBox.y0<<" "<<c.m_cBox.y1<<" "<<c.m_cBox.z0<<" "<<c.m_cBox.z1);
00974        //  PRINT_DEBUG(pt);
00975        nbpt++;
00976     }
00977 
00978   face(lp[2].rep(), px0.rep(),0,1); 
00979   //  PRINT_DEBUG(" ");
00980   //  PRINT_DEBUG("X0Y1 "<<lp[2]);
00981   (*eqnList.begin())=lp[2];
00982   slv2.solve(sol, nSol, nVar, eqnList.begin(), eqnList.end());
00983   //  if(sol.size()) { VECTOR::print(std::cout,sol)<<std::endl;}
00984   pt[1]=c.m_cBox.y1;
00985   for(unsigned j=0;j<sol.size();j++)
00986     {
00987       pt[2]= c.m_cBox.z0*((coeff_t)1-sol[j]) + c.m_cBox.z1*sol[j];
00988       inters[1].push_back(pt);
00989       //      PRINT_DEBUG(pt<<" |"<<sol[j]<<"|  "<<c.m_cBox.x0<<" "<<c.m_cBox.x1<<" "<<c.m_cBox.y0<<" "<<c.m_cBox.y1<<" "<<c.m_cBox.z0<<" "<<c.m_cBox.z1);
00990       //      PRINT_DEBUG(pt);
00991       nbpt++;
00992     }
00993 
00994   face(lp[2].rep(), px1.rep(),0,0); 
00995   //  PRINT_DEBUG(" ");
00996   //  PRINT_DEBUG("X1Y0 "<<lp[2]);
00997   (*eqnList.begin())=lp[2];
00998   slv2.solve(sol, nSol, nVar, eqnList.begin(), eqnList.end());
00999   //  if(sol.size()) { VECTOR::print(std::cout,sol)<<std::endl;}
01000 
01001   pt[0]=c.m_cBox.x1;
01002   pt[1]=c.m_cBox.y0;
01003   for(unsigned j=0;j<sol.size();j++)
01004     {
01005       pt[2]= c.m_cBox.z0*((coeff_t)1-sol[j]) + c.m_cBox.z1*sol[j];
01006       inters[2].push_back(pt);
01007       //      PRINT_DEBUG(pt);
01008       nbpt++;
01009     }
01010 
01011   face(lp[2].rep(), px1.rep(),0,1); 
01012   //  PRINT_DEBUG(" ");
01013   //  PRINT_DEBUG("X1Y1 "<<lp[2]);
01014   (*eqnList.begin())=lp[2];
01015   slv2.solve(sol, nSol, nVar, eqnList.begin(), eqnList.end());
01016   //  if(sol.size()) { VECTOR::print(std::cout,sol)<<std::endl;}
01017   pt[1]=c.m_cBox.y1;
01018   for(unsigned j=0;j<sol.size();j++)
01019     {
01020       pt[2]= c.m_cBox.z0*((coeff_t)1-sol[j]) + c.m_cBox.z1*sol[j];
01021       inters[3].push_back(pt);
01022       //      PRINT_DEBUG(pt<<" |"<<sol[j]<<"|  "<<c.m_cBox.x0<<" "<<c.m_cBox.x1<<" "<<c.m_cBox.y0<<" "<<c.m_cBox.y1<<" "<<c.m_cBox.z0<<" "<<c.m_cBox.z1);
01023       //      PRINT_DEBUG(pt);
01024       nbpt++;
01025     }
01026 
01027   face(lp[1].rep(), px0.rep(),1,0); 
01028   SbdSolver<coeff_t,SBDSLV_RDL> slv1(lp+1, lp+2, 1e-4);
01029 
01030   //  PRINT_DEBUG(" ");
01031   //  PRINT_DEBUG("X0Z0 "<<lp[1]);
01032   (*eqnList.begin())=lp[1];
01033   slv1.solve(sol, nSol, nVar, eqnList.begin(), eqnList.end());
01034   //  if(sol.size()) { VECTOR::print(std::cout,sol)<<std::endl;}
01035   pt[0]=c.m_cBox.x0;
01036   pt[2]=c.m_cBox.z0;
01037   for(unsigned j=0;j<sol.size();j++)
01038     {
01039       pt[1]= c.m_cBox.y0*((coeff_t)1-sol[j]) + c.m_cBox.y1*sol[j];
01040       inters[4].push_back(pt);
01041       //      PRINT_DEBUG(pt<<" |"<<sol[j]<<"|  "<<c.m_cBox.x0<<" "<<c.m_cBox.x1<<" "<<c.m_cBox.y0<<" "<<c.m_cBox.y1<<" "<<c.m_cBox.z0<<" "<<c.m_cBox.z1);
01042       //      PRINT_DEBUG(pt);
01043       nbpt++;
01044     }
01045   
01046   face(lp[1].rep(), px0.rep(),1,1); 
01047   //  PRINT_DEBUG(" ");
01048   //  PRINT_DEBUG("X0Z1 "<<lp[1]);
01049   (*eqnList.begin())=lp[1];
01050   slv1.solve(sol, nSol, nVar, eqnList.begin(), eqnList.end());
01051   //  if(sol.size()) { VECTOR::print(std::cout,sol)<<std::endl;}
01052   pt[0]=c.m_cBox.x0;
01053   pt[2]=c.m_cBox.z1;
01054   for(unsigned j=0;j<sol.size();j++)
01055     {
01056       pt[1]= c.m_cBox.y0*((coeff_t)1-sol[j]) + c.m_cBox.y1*sol[j];
01057       inters[5].push_back(pt);
01058       //      PRINT_DEBUG(pt<<" |"<<sol[j]<<"|  "<<c.m_cBox.x0<<" "<<c.m_cBox.x1<<" "<<c.m_cBox.y0<<" "<<c.m_cBox.y1<<" "<<c.m_cBox.z0<<" "<<c.m_cBox.z1);
01059       //      PRINT_DEBUG(pt);
01060       nbpt++;
01061     }
01062   
01063   face(lp[1].rep(), px1.rep(),1,0); 
01064   //  PRINT_DEBUG(" ");
01065   //  PRINT_DEBUG("X1Z0 "<<lp[1]);
01066   (*eqnList.begin())=lp[1];
01067   slv1.solve(sol, nSol, nVar, eqnList.begin(), eqnList.end());
01068   //  if(sol.size()) { VECTOR::print(std::cout,sol)<<std::endl;}
01069   pt[0]=c.m_cBox.x1;
01070   pt[2]=c.m_cBox.z0;
01071   for(unsigned j=0;j<sol.size();j++)
01072     {
01073       pt[1]= c.m_cBox.y0*((coeff_t)1-sol[j]) + c.m_cBox.y1*sol[j];
01074       inters[6].push_back(pt);
01075       //      PRINT_DEBUG(pt<<" |"<<sol[j]<<"|  "<<c.m_cBox.x0<<" "<<c.m_cBox.x1<<" "<<c.m_cBox.y0<<" "<<c.m_cBox.y1<<" "<<c.m_cBox.z0<<" "<<c.m_cBox.z1);
01076       //      PRINT_DEBUG(pt);
01077       nbpt++;
01078     }
01079   
01080   face(lp[1].rep(), px1.rep(),1,1); 
01081   //  PRINT_DEBUG(" ");
01082   //  PRINT_DEBUG("X1Z1 "<<lp[1]);
01083   (*eqnList.begin())=lp[1];
01084   slv1.solve(sol, nSol, nVar, eqnList.begin(), eqnList.end());
01085   //  if(sol.size()) { VECTOR::print(std::cout,sol)<<std::endl;}
01086   pt[0]=c.m_cBox.x1;
01087   pt[2]=c.m_cBox.z1;
01088   for(unsigned j=0;j<sol.size();j++)
01089     {
01090       pt[1]= c.m_cBox.y0*((coeff_t)1-sol[j]) + c.m_cBox.y1*sol[j];
01091       inters[7].push_back(pt);
01092       //      PRINT_DEBUG(pt<<" |"<<sol[j]<<"|  "<<c.m_cBox.x0<<" "<<c.m_cBox.x1<<" "<<c.m_cBox.y0<<" "<<c.m_cBox.y1<<" "<<c.m_cBox.z0<<" "<<c.m_cBox.z1);
01093       //      PRINT_DEBUG(pt);
01094       nbpt++;
01095     }
01096 
01097   face(pz0.rep(), c.m_F[0].rep(),2,0); 
01098   face(pz1.rep(), c.m_F[0].rep(),2,1); 
01099 
01100   face(lp[0].rep(), pz0.rep(),1,0); 
01101   SbdSolver<coeff_t,SBDSLV_RDL> slv0(lp, lp+1, 1e-4);
01102 
01103   //  PRINT_DEBUG(" ");
01104   //  PRINT_DEBUG("Y0Z0 "<<lp[0]);
01105   (*eqnList.begin())=lp[0];
01106   slv0.solve(sol, nSol, nVar, eqnList.begin(), eqnList.end());
01107   //  if(sol.size()) { VECTOR::print(std::cout,sol)<<std::endl;}
01108   pt[1]=c.m_cBox.y0;
01109   pt[2]=c.m_cBox.z0;
01110   for(unsigned j=0;j<sol.size();j++)
01111     {
01112       pt[0]= c.m_cBox.x0*((coeff_t)1-sol[j]) + c.m_cBox.x1*sol[j];
01113       inters[8].push_back(pt);
01114       //      PRINT_DEBUG(pt<<" |"<<sol[j]<<"|  "<<c.m_cBox.x0<<" "<<c.m_cBox.x1<<" "<<c.m_cBox.y0<<" "<<c.m_cBox.y1<<" "<<c.m_cBox.z0<<" "<<c.m_cBox.z1);
01115       //      PRINT_DEBUG(pt);
01116       nbpt++;
01117     }
01118   
01119   face(lp[0].rep(), pz0.rep(),1,1); 
01120   //  PRINT_DEBUG(" ");
01121   //  PRINT_DEBUG("Y1Z0 "<<lp[0]);
01122    (*eqnList.begin())=lp[0];
01123   slv0.solve(sol, nSol, nVar, eqnList.begin(), eqnList.end());
01124   //  if(sol.size()) { VECTOR::print(std::cout,sol)<<std::endl;}
01125   pt[1]=c.m_cBox.y1;
01126   pt[2]=c.m_cBox.z0;
01127   for(unsigned j=0;j<sol.size();j++)
01128     {
01129       pt[0]= c.m_cBox.x0*((coeff_t)1-sol[j]) + c.m_cBox.x1*sol[j];
01130       inters[9].push_back(pt);
01131       //      PRINT_DEBUG(pt<<" |"<<sol[j]<<"|  "<<c.m_cBox.x0<<" "<<c.m_cBox.x1<<" "<<c.m_cBox.y0<<" "<<c.m_cBox.y1<<" "<<c.m_cBox.z0<<" "<<c.m_cBox.z1);
01132       //      PRINT_DEBUG(pt);
01133       nbpt++;
01134     }
01135 
01136   face(lp[0].rep(), pz1.rep(),1,0); 
01137   //  PRINT_DEBUG(" ");
01138   //  PRINT_DEBUG("Y0Z1 "<<lp[0]);
01139   (*eqnList.begin())=lp[0];
01140   slv0.solve(sol, nSol, nVar, eqnList.begin(), eqnList.end());
01141   //  if(sol.size()) { VECTOR::print(std::cout,sol)<<std::endl;}
01142   pt[1]=c.m_cBox.y0;
01143   pt[2]=c.m_cBox.z1;
01144   for(unsigned j=0;j<sol.size();j++)
01145     {
01146       pt[0]= c.m_cBox.x0*((coeff_t)1-sol[j]) + c.m_cBox.x1*sol[j];
01147       inters[10].push_back(pt);
01148       //      PRINT_DEBUG(pt<<" |"<<sol[j]<<"|  "<<c.m_cBox.x0<<" "<<c.m_cBox.x1<<" "<<c.m_cBox.y0<<" "<<c.m_cBox.y1<<" "<<c.m_cBox.z0<<" "<<c.m_cBox.z1);
01149       //      PRINT_DEBUG(pt);
01150       nbpt++;
01151     }
01152 
01153   face(lp[0].rep(), pz1.rep(),1,1); 
01154   //  PRINT_DEBUG(" ");
01155   //  PRINT_DEBUG("Y1Z1 "<<lp[0]);
01156   (*eqnList.begin())=lp[0];
01157   slv0.solve(sol, nSol, nVar, eqnList.begin(), eqnList.end());
01158   //  if(sol.size()) {VECTOR::print(std::cout,sol)<<std::endl;}
01159   pt[1]=c.m_cBox.y1;
01160   pt[2]=c.m_cBox.z1;
01161   for(unsigned j=0;j<sol.size();j++)
01162     {
01163       pt[0]= c.m_cBox.x0*((coeff_t)1-sol[j]) + c.m_cBox.x1*sol[j];
01164       inters[11].push_back(pt);
01165       //      PRINT_DEBUG(pt<<" |"<<sol[j]<<"|  "<<c.m_cBox.x0<<" "<<c.m_cBox.x1<<" "<<c.m_cBox.y0<<" "<<c.m_cBox.y1<<" "<<c.m_cBox.z0<<" "<<c.m_cBox.z1);
01166       //      PRINT_DEBUG(pt);
01167       nbpt++;
01168     }
01169 
01170   return nbpt;
01171 
01172 }
01173 //--------------------------------------------------------------------
01174 template <class C, class CELL, class MSLV >
01175 void TopSbdSurf3d<C, CELL, MSLV>::compute_points(node_t* n)
01176 {
01177  
01178 
01179 
01180   std::vector<node_t*> Nbg[6];
01181   n->getAllBackNeighbors(Nbg[OCTREE::B]);
01182   n->getAllFrontNeighbors(Nbg[OCTREE::F]);
01183   n->getAllSouthNeighbors(Nbg[OCTREE::S]);
01184   n->getAllNorthNeighbors(Nbg[OCTREE::N]);
01185   n->getAllEastNeighbors(Nbg[OCTREE::E]);
01186   n->getAllWestNeighbors(Nbg[OCTREE::W]);
01187   cell_t* c=n->GetCell();
01188   //  PRINT_DEBUG(">>>>>["<<c->m_cBox.x0<<" "<<c->m_cBox.x1<<" "<<c->m_cBox.y0<<" "<<c->m_cBox.y1<<" "<<c->m_cBox.z0<<" "<<c->m_cBox.z1<<"]");
01189   //  PRINT_DEBUG(">>>>>|"<<c->m_cBox.x1-c->m_cBox.x0<<" "<<c->m_cBox.y1-c->m_cBox.y0<<" "<<c->m_cBox.z1-c->m_cBox.z0<<"|");
01190   unsigned f;
01191   for(unsigned i=0;i<6;i++)
01192     {
01193       f=i+(i%2?-1:1);
01194       //      PRINT_DEBUG(i<<" "<<f<<" sz "<<Nbg[i].size());
01195       c->m_FaceComputed[i]=false;
01196       for(unsigned j=0;j<Nbg[i].size();j++)
01197         {
01198           if(Nbg[i][j]->GetCell()->m_FaceComputed[f])
01199             {
01200               //            PRINT_DEBUG(i<<" "<<j<<" merge");
01201               c->mergelist(c->m_FaceLstPtIdx[i], Nbg[i][j]->GetCell()->m_FaceLstPtIdx[f]);
01202               c->m_FaceComputed[i]=true;
01203             }
01204           else
01205             {
01206               // There can be only one neightbor (of the same size), which faces are not computed
01207               // since the size of the cells is increasing in the list aNodeKept.
01208               assert(Nbg[i].size()==1);
01209               //                  cell_t* cf=Nbg[i][j]->GetCell();
01210               //                  PRINT_DEBUG("Face "<< f<<" of box "<<j<<" not computed");
01211               //                  PRINT_DEBUG("Contains variety? "<<is_variety_in(*Nbg[i][j]->GetCell()));
01212               //                  PRINT_DEBUG("["<<cf->m_cBox.x0<<" "<<cf->m_cBox.x1<<" "<<cf->m_cBox.y0<<" "<<cf->m_cBox.y1<<" "<<cf->m_cBox.z0<<" "<<cf->m_cBox.z1<<"]");
01213             }
01214           for(unsigned e=0;e<4;e++)
01215             if(is_edge_in_face(Nbg[i][j]->GetCell(),EdgesOfFace[f][e],c,i))
01216               c->mergelist(c->m_FaceLstPtIdx[i], Nbg[i][j]->GetCell()->m_EdgeLstPtIdx[EdgesOfFace[f][e]]);
01217         }
01218       if(!c->m_FaceComputed[i])
01219         {
01220           //  PRINT_DEBUG(i<<" compute points");
01221           if (c->m_nRegularIdx ==-1) 
01222             {
01223               computeinter_face(c->m_FaceLstPtIdx[i],*c,i/2,i%2);
01224               PRINT_DEBUG("End of face comp.");
01225             }
01226           c->m_FaceComputed[i]=true;
01227         }
01228     }
01229   for(unsigned j=0;j<12;j++)
01230     computeinter_edge(c->m_EdgeLstPtIdx[j],*c,OCTREE::EDGE_TYPE(j));
01231 
01232 }
01233 //--------------------------------------------------------------------
01234 template <class C, class CELL, class MSLV >
01235 template < class POINTGRAPH>
01236 void TopSbdSurf3d<C, CELL, MSLV>::build_mesh(POINTGRAPH& g, node_t* n)
01237 {
01238   typedef typename CELL::coeff_t         coeff_t;
01239   typedef typename CELL::MPOL_T          MPOL_T;
01240   typedef intersection3d<coeff_t>        intersection_t;
01241   typedef topology::point<coeff_t>       point_t;
01242   typedef shared_object<intersection_t*> intersection_ptr;
01243 
01244   cell_t* c= n->GetCell();
01245 
01246   // determine the regularity if it is not known
01247   if (c->m_nRegularIdx == -2)
01248     regularity(*c);
01249   
01250   if (c->m_nRegularIdx == -1) // a singular cell
01251     {
01252       build_box(g,c);
01253     }
01254   else // a regular cell
01255     {
01256       unsigned nbp=0;
01257       point_t m(3u);
01258       m[0]=0;m[1]=0;m[2]=0;
01259       for(unsigned i=0;i<6;i++)
01260         {
01261           nbp+=c->m_FaceLstPtIdx[i].size();
01262           for(unsigned j=0;j<c->m_FaceLstPtIdx[i].size();j++)
01263             {
01264               m[0]+=c->m_FaceLstPtIdx[i][j]->pnt[0];
01265               m[1]+=c->m_FaceLstPtIdx[i][j]->pnt[1];
01266               m[2]+=c->m_FaceLstPtIdx[i][j]->pnt[2];
01267             }
01268         }
01269       for(unsigned i=0;i<12;i++)
01270         {
01271           nbp+=c->m_EdgeLstPtIdx[i].size();
01272           for(unsigned j=0;j<c->m_EdgeLstPtIdx[i].size();j++)
01273             {
01274               m[0]+=c->m_EdgeLstPtIdx[i][j]->pnt[0];
01275               m[1]+=c->m_EdgeLstPtIdx[i][j]->pnt[1];
01276               m[2]+=c->m_EdgeLstPtIdx[i][j]->pnt[2];
01277             }
01278         }
01279       if(nbp)
01280         {
01281           m[0]/= nbp;
01282           m[1]/= nbp;
01283           m[2]/= nbp;
01284           //      Seq<intersection_t*> inters = c->m_aInterList;
01285           // intersections of the polar curve and the cell facets
01286           
01287           // Computeinter_edges(boundary,c);
01288           //      unsigned nbp = inters.size();
01289           // intersection of the surface with the edges of the box.
01290           //    PRINT_DEBUG(nbp);
01291 
01292           //        PRINT_DEBUG("Treating cell of reg "<<c->m_nRegularIdx<<" sz = "<<inters.size());
01293           //      for(unsigned i=0;i<inters.size();i++) PRINT_DEBUG(inters[i]->pnt);
01294           // build_box(g,c);
01295           
01296           //        PRINT_DEBUG("Ordering points on the border");
01297           std::vector<point_t> lf[6];
01298           unsigned nbp=0;
01299           for(unsigned i=0;i<6;i++)
01300             {
01301               for(unsigned j=0;j< c->m_FaceLstPtIdx[i].size();j++)
01302                 lf[i].push_back(c->m_FaceLstPtIdx[i][j]->pnt);
01303               for(unsigned e=0;e<4;e++)
01304                 for(unsigned j=0;j< c->m_EdgeLstPtIdx[EdgesOfFace[i][e]].size();j++)
01305                   {
01306                     lf[i].push_back(c->m_EdgeLstPtIdx[EdgesOfFace[i][e]][j]->pnt);
01307                     if(c->m_EdgeLstPtIdx[EdgesOfFace[i][e]][j]->nMulti==2)
01308                       lf[i].push_back(c->m_EdgeLstPtIdx[EdgesOfFace[i][e]][j]->pnt);
01309                   }
01310             }
01311 //        PRINT_DEBUG(">>>>>["<<c->m_cBox.x0<<" "<<c->m_cBox.x1<<" "<<c->m_cBox.y0<<" "<<c->m_cBox.y1<<" "<<c->m_cBox.z0<<" "<<c->m_cBox.z1<<"]");
01312 //        PRINT_DEBUG(">>>>>|"<<c->m_cBox.x1-c->m_cBox.x0<<" "<<c->m_cBox.y1-c->m_cBox.y0<<" "<<c->m_cBox.z1-c->m_cBox.z0<<"|");
01313 //        PRINT_DEBUG("=======================");
01314 //        for(unsigned i=0;i<6;i++) 
01315 //          for(unsigned j=0;j< c->m_FaceLstPtIdx[i].size();j++)
01316 //            PRINT_DEBUG("Face "<<i<<" "<<c->m_FaceLstPtIdx[i][j]->pnt);
01317 //        PRINT_DEBUG(".......................");
01318 //        for(unsigned i=0;i<12;i++) 
01319 //          for(unsigned j=0;j< c->m_EdgeLstPtIdx[i].size();j++)
01320 //            PRINT_DEBUG("Edge "<<i<<" "<<c->m_EdgeLstPtIdx[i][j]->pnt);
01321           
01322           //      PRINT_DEBUG("----------------------");
01323           //      PRINT_DEBUG("Computing point inside");
01324           compute_point_inside(m,c);
01325 
01326             //  VECTOR::print(std::cout,m)<<std::endl;
01327             //  int im=g.push_back(intersection_ptr(new intersection_t(m,0,1))),
01328             // sort according to the regular direction
01329 
01330 
01331           //        PRINT_DEBUG("Connecting the points by triangles");
01332           int i0, i1,
01333             im=g.push_back(m);
01334           //        PRINT_DEBUG(im<<" "<<m);
01335           // g.insert(im,iv);
01336           for(unsigned i=0;i<6;i++) 
01337             {
01338               if(lf[i].size()==2)
01339                 {
01340                   i0=g.push_back(lf[i][0]);
01341                   i1=g.push_back(lf[i][1]);
01342                   g.insert_face(im,i0,i1);
01343                   g.insert(im,i0);
01344                   g.insert(im,i1);
01345 //                PRINT_DEBUG("f "<<i<<" sz "<<lf[i].size());
01346 //                for(unsigned l=0;l<lf[i].size();l++) PRINT_DEBUG(lf[i][l]);
01347                 }
01348               else if(lf[i].size()>0)
01349                 {
01350                   int reg= c->m_nRegularIdx %3;
01351                   int rf =reg;
01352                   //              if(rf>3) rf/=3;
01353                   if((i/2)==reg)
01354                     if(i%2)
01355                       rf+=c->m_nRegularIdx/9;
01356                     else
01357                       rf+=(c->m_nRegularIdx/3)%3;
01358                   else
01359                     rf+=(i/2);
01360                   //PRINT_DEBUG("face "<<i<<" sz "<<lf[i].size()<<" RIDX "<<c->m_nRegularIdx<<" reg "<<reg<<" rf "<<rf);
01361                   //for(unsigned l=0;l<lf[i].size();l++) PRINT_DEBUG(lf[i][l]);
01362                   switch(rf)
01363                     {
01364                     case 3:
01365                       //                      PRINT_DEBUG("Sort X");
01366                       sort(lf[i].begin(), lf[i].end(), XPT());
01367                       break;
01368                     case 2:
01369                       //                      PRINT_DEBUG("Sort Y");
01370                       sort(lf[i].begin(), lf[i].end(), YPT());
01371                       break;
01372                     case 1:
01373                       //                      PRINT_DEBUG("Sort Z");
01374                       sort(lf[i].begin(), lf[i].end(), ZPT());
01375                       break;
01376                     }
01377 //                PRINT_DEBUG("f "<<i<<" sz "<<lf[i].size());
01378 //                for(unsigned l=0;l<lf[i].size();l++) PRINT_DEBUG(lf[i][l]);
01379                   
01380                   int j=0, f=i/2;
01381 
01382                   i0=g.push_back(lf[i][0]);
01383                   g.insert(im,i0);
01384                   while(j<lf[i].size()-1)
01385                     {
01386                       if(same_point(lf[i][j],lf[i][j+1]))
01387                         j++;
01388                       else
01389                         {
01390                           i0=g.push_back(lf[i][j+1]);
01391                           g.insert(im,i0);
01392                           g.insert_face(im,i0-1,i0);
01393                           if(is_on_border(lf[i][j+1],c,f)) 
01394                             {
01395                               j+=2;
01396                               if(j<lf[i].size()) i0=g.push_back(lf[i][j]);
01397                               g.insert(im,i0);
01398                             }
01399                           else
01400                             j++;
01401                         }
01402                     }
01403                 }
01404             }
01405         }
01406       
01407       //         // construct the graph
01408       //         bool bConnectWithLast = false;
01409       //         int nMulti = 1;
01410       //         int nLastIdx = -1;
01411       //        point_t ipt(3u);
01412       //         for (int v = 0; v < (int)inters.size(); v++)
01413       //         {
01414       //          // int nBIdx = g.push_back(intersection_ptr(inters[v]));
01415       //          ipt[0]=inters[v]->pnt[0];
01416       //          ipt[1]=inters[v]->pnt[1];
01417       //          ipt[2]=inters[v]->pnt[2];
01418       //          int nBIdx = g.push_back(ipt);
01419       
01420       //             if (bConnectWithLast)
01421       //                 g.insert(nLastIdx, nBIdx);
01422       
01423       //             if (!bConnectWithLast && nMulti < inters[v]->nMulti)
01424       //                 bConnectWithLast = false;
01425       //             else
01426       //                 bConnectWithLast = !bConnectWithLast;
01427       
01428       //             if (nMulti < inters[v]->nMulti)
01429       //             {
01430       //                 nMulti++;
01431       //                 v--;
01432       //             }
01433       //             else
01434       //             {
01435       //                 nMulti = 1;
01436       //             }
01437       
01438       //             nLastIdx = nBIdx;
01439       //         }
01440 
01441     }
01442 }
01443 //====================================================================
01444 template<class C, class MP>
01445 bool is_edge_in_face(Cell3d<C,MP>* c0, unsigned e, Cell3d<C,MP>* c, unsigned f)
01446 {
01447   typedef topology::point<C>             point_t;
01448   using namespace OCTREE;
01449   point_t m(3u);
01450   switch(OCTREE::EDGE_TYPE(e))
01451     {
01452     case B_E:
01453       m[0]= c0->m_cBox.x0; m[1]= c0->m_cBox.y1; m[2]= (c0->m_cBox.z0 + c0->m_cBox.z1)/2; break;
01454     case B_W:
01455       m[0]= c0->m_cBox.x0; m[1]= c0->m_cBox.y0; m[2]= (c0->m_cBox.z0 + c0->m_cBox.z1)/2; break;
01456     case B_S:
01457       m[0]= c0->m_cBox.x0; m[1]= (c0->m_cBox.y0 + c0->m_cBox.y1)/2; m[2]= c0->m_cBox.z0; break;
01458     case B_N:
01459       m[0]= c0->m_cBox.x0; m[1]= (c0->m_cBox.y0 + c0->m_cBox.y1)/2; m[2]= c0->m_cBox.z1; break;
01460 
01461     case F_E:
01462       m[0]= c0->m_cBox.x1; m[1]= c0->m_cBox.y1; m[2]= (c0->m_cBox.z0 + c0->m_cBox.z1)/2; break;
01463     case F_W:
01464       m[0]= c0->m_cBox.x1; m[1]= c0->m_cBox.y0; m[2]= (c0->m_cBox.z0 + c0->m_cBox.z1)/2; break;
01465     case F_S:
01466       m[0]= c0->m_cBox.x1; m[1]= (c0->m_cBox.y0 + c0->m_cBox.y1)/2; m[2]= c0->m_cBox.z0; break;
01467     case F_N:
01468       m[0]= c0->m_cBox.x1; m[1]= (c0->m_cBox.y0 + c0->m_cBox.y1)/2; m[2]= c0->m_cBox.z1; break;
01469 
01470     case S_E:
01471       m[0]= (c0->m_cBox.x0 + c0->m_cBox.x1)/2; m[1]= c0->m_cBox.y1; m[2]= c0->m_cBox.z0; break;
01472     case S_W:
01473       m[0]= (c0->m_cBox.x0 + c0->m_cBox.x1)/2; m[1]= c0->m_cBox.y0; m[2]= c0->m_cBox.z0; break;
01474     case N_E:
01475       m[0]= (c0->m_cBox.x0 + c0->m_cBox.x1)/2; m[1]= c0->m_cBox.y1; m[2]= c0->m_cBox.z1; break;
01476     case N_W:
01477       m[0]= (c0->m_cBox.x0 + c0->m_cBox.x1)/2; m[1]= c0->m_cBox.y0; m[2]= c0->m_cBox.z1; break;
01478     }
01479   switch(f)
01480     {
01481     case 0:
01482       return (m[0]== c->m_cBox.x0 && m[1]>c->m_cBox.y0 && m[1]<c->m_cBox.y1 && m[2]>c->m_cBox.z0 && m[2]<c->m_cBox.z1);
01483     case 1:
01484       return (m[0]== c->m_cBox.x1 && m[1]>c->m_cBox.y0 && m[1]<c->m_cBox.y1 && m[2]>c->m_cBox.z0 && m[2]<c->m_cBox.z1);
01485     case 2:
01486       return (m[1]== c->m_cBox.y0 && m[0]>c->m_cBox.x0 && m[0]<c->m_cBox.x1 && m[2]>c->m_cBox.z0 && m[2]<c->m_cBox.z1);
01487     case 3:
01488       return (m[1]== c->m_cBox.y1 && m[0]>c->m_cBox.x0 && m[0]<c->m_cBox.x1 && m[2]>c->m_cBox.z0 && m[2]<c->m_cBox.z1);
01489     case 4:
01490       return (m[2]== c->m_cBox.z0 && m[0]>c->m_cBox.x0 && m[0]<c->m_cBox.x1 && m[1]>c->m_cBox.y0 && m[1]<c->m_cBox.y1);
01491     case 5:
01492       return (m[2]== c->m_cBox.z1 && m[0]>c->m_cBox.x0 && m[0]<c->m_cBox.x1 && m[1]>c->m_cBox.y0 && m[1]<c->m_cBox.y1);
01493     }
01494   return false;
01495 }
01496 
01497 //====================================================================
01498 template < class C >
01499 bool is_variety_in(Cell3d<C>& c)
01500 {
01501   return c.containsVariety(0);
01502 }
01503 //--------------------------------------------------------------------
01504 template <class C, class CELL, class MSLV >
01505 bool TopSbdSurf3d<C, CELL, MSLV>::regularity(CELL& c)
01506 {
01507   typedef typename CELL::MPOL_T mpol_t;
01508   if(c.m_nDepth<m_min_dp)
01509      return false;
01510   else if(c.m_nDepth>m_max_dp)
01511     {
01512       c.m_nRegularIdx=-1;
01513       return false;
01514     }
01515   mpol_t dp[3];
01516   mpol_t f0,f1,df0,df1;
01517   for (int i = 0; i < 3; i++)
01518     {
01519       diff(dp[i],c.m_F[0],VARIDX(c.m_F[0], i));
01520       //      PRINT_DEBUG(i);
01521       if(!has_sign_change(dp[i]))
01522         {
01523           //      PRINT_DEBUG("df/dx"<<i<<" no sign change");
01524           bool b0= true, b1=true;
01525           c.m_nRegularIdx = i;
01526           for(int j=0;j <3 && (b0 ||b1) ;j++)
01527             if(j!=i)
01528               {
01529                 int v=j;
01530                 if(j>i) v--;
01531                 if(b0)
01532                   {
01533                     face(f0.rep(),c.m_F[0].rep(),i,0);
01534                     //              PRINT_DEBUG("f0 "<<v<<" "<<df0);
01535                     if(!has_sign_change(f0))
01536                       {
01537                         c.m_nRegularIdx += 3*j;
01538                         //PRINT_DEBUG("f0 "<<j<<" "<<c.m_nRegularIdx);
01539                         b0=false;
01540                         //                  return true;
01541                       }
01542                     else 
01543                       {
01544                         diff(df0, f0,  v);
01545                         if(!has_sign_change(df0))
01546                           {
01547                             c.m_nRegularIdx += 3*j;
01548                             //PRINT_DEBUG("f0 "<<j<<" "<<c.m_nRegularIdx);
01549                             b0=false;
01550                             //              return true;
01551                           }
01552                       }
01553                   }
01554                 if(b1)
01555                   {
01556                     face(f1.rep(),c.m_F[0].rep(),i,1);
01557                     //              PRINT_DEBUG("f1 "<<v<<" "<<df1);
01558                     if (!has_sign_change(f1))
01559                       {
01560                         c.m_nRegularIdx += 9*j;
01561                         b1=false;
01562                         //PRINT_DEBUG("f1 "<<j<<" "<<c.m_nRegularIdx);
01563                       }
01564                     else
01565                       {
01566                         diff(df1, f1, v);
01567                         if (!has_sign_change(df1))
01568                           {
01569                             c.m_nRegularIdx += 9*j;
01570                             b1=false;
01571                             //PRINT_DEBUG("f1 "<<j<<" "<<c.m_nRegularIdx);
01572                           }
01573                       }
01574                   }
01575               }
01576           if(!(b0 || b1))
01577             {
01578               //PRINT_DEBUG("reg "<<  c.m_nRegularIdx);
01579               //PRINT_DEBUG("reg for x"<<i);
01580               return true;
01581             }
01582 //        else
01583 //          PRINT_DEBUG("reg not for x"<<i);
01584         }
01585     }
01586   c.m_nRegularIdx =-1;
01587   //  PRINT_DEBUG("reg "<<  c.m_nRegularIdx);
01588   return false;
01589 
01590   // check if the curve tangent, i.e. t = (t0, t1, t2) = grad F cross grad G
01591   // has no sign change for at least one of its component (or say, along one axis)
01592   for (unsigned i = c.m_nT; i < c.nbpol(); i++)
01593     {
01594       C* coeff = c.m_F[i].begin();
01595       C lastC = coeff[0];
01596       bool bSignChange = false;
01597       
01598       for (int j = 1; j < c.m_F[i].rep().env.sz() && !bSignChange; j++)
01599         {
01600           C cirC = coeff[j];
01601           if (_is_singular(cirC)) // if cirC is a zero value
01602             {
01603               continue;
01604             }
01605           else
01606             {
01607               if (lastC*cirC < 0) // a sign change is detected
01608                 {
01609                   bSignChange = true;
01610                   lastC = cirC;
01611                   break;
01612                 }
01613               
01614               lastC = cirC; // always remember the last non-singular coefficient
01615             }
01616         }
01617       
01618       if (_is_singular(lastC))  //all coefficients are singular (or 0)
01619         continue;
01620       else if (!bSignChange) // no sign changes
01621         {
01622             c.m_nRegularIdx = i;
01623             PRINT_DEBUG("REG "<<  c.m_nRegularIdx);
01624             return TRUE;
01625         }
01626     }
01627   c.m_nRegularIdx = -1;
01628   PRINT_DEBUG("reg "<<  c.m_nRegularIdx);
01629   return FALSE;
01630 }
01631 //====================================================================
01632 namespace topology 
01633 {
01634   template<class C, class POINTGRAPH, class MPOL, class MTH>
01635   void assign(POINTGRAPH& g, 
01636               const MPOL & p0,
01637               MTH mth,
01638               const C& x0, const C& x1, 
01639               const C& y0, const C& y1, 
01640               const C& z0, const C& z1)
01641   {
01642     typedef typename MTH::cell_t  cell_t;
01643     typedef typename MTH::mpolb_t mpolb_t;
01644 
01645     std::cout<<p0<<std::endl;
01646     
01647     // step1:
01648     // computing grad F1 cross grad F2
01649     MPOL p1 = diff(p0,0u);
01650     MPOL p2 = diff(p0,1u);
01651 
01652     MPOL d0 = diff(p1,1u)*diff(p2,2u)-diff(p1,2u)*diff(p2,1u);
01653     MPOL d1 = diff(p1,0u)*diff(p2,2u)-diff(p1,2u)*diff(p2,0u);
01654     MPOL d2 = diff(p1,0u)*diff(p2,1u)-diff(p1,1u)*diff(p2,0u);
01655     std::cout<<"Tangent field:"<<std::endl;
01656 
01657     std::cout<<d0<<"\n"<<d1<<"\n"<<d2<<std::endl;
01658     mpolb_t p0dse;
01659 
01660     toBernstein(p0, p0dse, x0,x1,y0,y1,z0,z1);
01661 //     mpolb_t  p1dse, p2dse;
01662 //     toBernstein(p1, p1dse, x0,x1,y0,y1,z0,z1);
01663 //     toBernstein(p2, p2dse, x0,x1,y0,y1,z0,z1);
01664 
01665 //     // debug only
01666 //     std::cout << "F("
01667 //               << degree(p1,0) << ", "
01668 //               << degree(p1,1) << ", "
01669 //               << degree(p1,2) << "): "
01670 //               << p1 << std::endl;
01671 
01672 //     std::cout << "G("
01673 //               << degree(p2,0) << ", "
01674 //               << degree(p2,1) << ", "
01675 //               << degree(p2,2) << "): "
01676 //               << p2 << std::endl;
01677 
01678 //     std::cout << "Fb("
01679 //               << p1dse.rep().env.sz(VARIDX(pd1dse, 0)) << ", "
01680 //               << p1dse.rep().env.sz(VARIDX(pd1dse, 1)) << ", "
01681 //               << p1dse.rep().env.sz(VARIDX(pd1dse, 2)) << "): "
01682 //               << p1dse << std::endl;
01683 
01684 //     std::cout << "Gb("
01685 //               << p2dse.rep().env.sz(VARIDX(pd2dse, 0)) << ", "
01686 //               << p2dse.rep().env.sz(VARIDX(pd2dse, 1)) << ", "
01687 //               << p2dse.rep().env.sz(VARIDX(pd2dse, 2)) << "): "
01688 //               << p2dse << std::endl;
01689 
01690 
01691 //     diff(p1_dy, p1dse, VARIDX(pd1dse, 1));
01692 //     diff(p1_dz, p1dse, VARIDX(pd1dse, 2));
01693 //     diff(p2_dx, p2dse, VARIDX(pd2dse, 0));
01694 //     diff(p2_dy, p2dse, VARIDX(pd2dse, 1));
01695 //     diff(p2_dz, p2dse, VARIDX(pd2dse, 2));
01696 
01697 //     std::cout << "grad Fb = {" << p1_dx << ", " <<  std::endl
01698 //               << "           " << p1_dy << ", " <<  std::endl
01699 //               << "           " << p1_dz << "} " <<  std::endl;
01700 //     std::cout << "grad Gb = {" << p2_dx << ", " <<  std::endl
01701 //               << "           " << p2_dy << ", " <<  std::endl
01702 //               << "           " << p2_dz << "} " <<  std::endl;
01703 
01704 
01705 /*   
01706      mpolb_t c0,c1,c2;
01707      toBernstein(d0, c0, x0,x1,y0,y1,z0,z1);
01708      toBernstein(d1, c1, x0,x1,y0,y1,z0,z1);
01709      toBernstein(d2, c2, x0,x1,y0,y1,z0,z1);
01710      std::cout<<c0<<"\n"<<c1<<"\n"<<c2<<std::endl;
01711 */
01712 //     mpolb_t c1, c2, c3; // grad F1 cross grad F2
01713 //     using arithm::operator*;
01714 //     c1 = p1_dy * p2_dz - p1_dz * p2_dy;
01715 //     c2 = p2_dx * p1_dz - p2_dz * p1_dx;
01716 //     c3 = p1_dx * p2_dy - p1_dy * p2_dx;
01717 
01718 //     // debug only
01719 //     std::cout << "grad(F) X grad(G) = {" << std::endl
01720 //               << "                     " << c1 << "," << std::endl
01721 //               << "                     " << c2 << "," << std::endl
01722 //               << "                     " << c3 << "}" << std::endl;
01723 
01724     // step2:
01725     // assign to the octree
01726     cell_t* rc = new cell_t(p0dse,x0,x1,y0,y1,z0,z1);
01727 
01728     //    rc->m_F =std::vector<mpolb_t>(7);
01729     //    rc->m_F[0] = p0dse;
01730     //    rc->m_F[1] = p0_dx;
01731     //    rc->m_F[2] = p0_dy;
01732     //    rc->m_F[3] = p0_dz;
01733     //    rc->m_F[4] = c1;
01734     //    rc->m_F[5] = c2;
01735     //    rc->m_F[6] = c3;
01736     //    rc->m_F[1] = c1;
01737     //    rc->m_F[2] = c2;
01738     //    rc->m_F[3] = c3;
01739     mth.run(g,rc);
01740   }
01741 }// namespace topology
01742 __END_NAMESPACE_SYNAPS
01743 /********************************************************************/
01744 #endif //CELL3DCURVE_H

SYNAPS DOCUMENTATION
logo