shape_doc 0.1
/Users/mourrain/Devel/mmx/shape/src/ssi_lsegment.cpp
Go to the documentation of this file.
00001 #include <shape/ssi_lsegment.hpp>
00002 
00003 #define ParametricSurface shape::surface_parametric<double>
00004 
00005 namespace mmx {
00006 
00007 namespace shape_ssi {
00008 
00009   void lsegment::pushm(vcode_t code, coord_t j)
00010   {
00011     marks[_size].code = code;
00012     marks[_size].j    = j;
00013     marks[_size].head =-1;
00014     marks[_size].next = 0;
00015     _size++;
00016   }
00017   
00018   void lsegment::addneighbors( mark_t * m0, mark_t * m1 )
00019   {
00020     if ( coherent_code( m0->code, m1->code )  )
00021       {
00022         grp->add_link(m0->head,m1->head);
00023         grp->add_link(m1->head,m0->head);
00024       };
00025   };
00026   
00027   void lsegment::pushr( coord_t i, mark_t * p )
00028   {
00029     p->head =  regions.size();
00030     regions.push_back( region_t() );
00031     region_t * r =&(regions.back());
00032     r->_umin = i;
00033     r->_umax = 1;
00034     r->data = (void*)p;
00035     r->_code = p->code;
00036     grp->add_node();
00037   };
00038   
00039   void lsegment::lines_changes()
00040   {
00041     int i,j;
00042     lines = (unsigned*)(malloc(sizeof(unsigned)*nrows()));
00043     unsigned max_marks = nrows()*ncols();
00044     while ( !(marks = (mark_t*)(malloc(sizeof(mark_t)*max_marks))) ) max_marks >>= 1;
00045     vector3 * ptr  = base();
00046     for ( i = 0; i < this->nrows()-1; i++ )
00047       {
00048         lines[i] = nmarks();
00049         vcode_t code = vcode(*ptr,*(ptr+ncols()),*(ptr+1));
00050         pushm(code,0);
00051         for (  j = 0; j < ncols()-1; j++, ptr++ )
00052           {
00053             vcode_t tmp = vcode(*ptr,*(ptr+ncols()),*(ptr+1));
00054             if ( tmp != code )
00055               { code = tmp; pushm(code,j); };
00056           };
00057         pushm(code,ncols()-1);
00058         ptr++;
00059       };
00060     lines[nrows()-1] = nmarks();
00061     marks = (mark_t*)realloc(marks,sizeof(mark_t)*nmarks());
00062   };
00063 
00064   
00065   void lsegment::find_regions()
00066   {
00067     mark_t * p;
00068     for ( p = begin(0); p != end(0); p++ )
00069       pushr(0,p);
00070     for ( p = begin(0)+1; p != end(0); p++ )
00071       addneighbors(p,p-1);
00072     
00073     mark_t * neighbors[ncols()];
00074     unsigned n_neigh;
00075     coord_t i;
00076 #define INTERVALTEST ( std::abs(std::min(down->b(),up->b())-std::max(down->a(),up->a())) > 1 )
00077     for ( i = 0; i < nrows()-2; i++ )
00078       {
00079         mark_t * startup = begin(i);
00080         for ( mark_t * down = begin(i+1); down != end(i+1); down++ )
00081           {
00082             while ( startup->b() <= down->a() ) startup++;
00083             mark_t * up = startup;
00084             n_neigh = 0;
00085             while( down->b() > up->a() )
00086               if ( (up->next == 0) && ( up->code == down->code ) && INTERVALTEST)
00087                 { 
00088                   regions[up->head]._umax++;
00089                   up->next = down;
00090                   down->head = up->head, up++; 
00091                   break; 
00092                 }
00093               else 
00094                 neighbors[n_neigh++] = up, up++;
00095             
00096               if ( down->head == -1 ) pushr( i+1, down );
00097             
00098               for ( unsigned k = 0; k < n_neigh; k ++ ) addneighbors(down,neighbors[k]);
00099               while( down->b() > up->a() ) addneighbors(down,up), up++;
00100           };
00101       };
00102   };
00103 
00104   void lsegment::promote( region_t& r )
00105   {
00106     mark_t     * mpointer;
00107     bounds_t * bpointer; 
00108     mpointer = (mark_t*)(r.data);
00109     r.data   = (void*)(malloc(sizeof(bounds_t)*(r._umax)));
00110     bpointer = (bounds_t*)(r.data);
00111     
00112     for ( unsigned i = 0; i < r._umax; i++ )
00113       {
00114         bpointer[i][0] = mpointer->a();
00115         bpointer[i][1] = mpointer->b();
00116         mpointer = mpointer->next;
00117       };
00118     
00119     r._umax += r._umin;
00120     r.data  = (void*)(((bounds_t*)(r.data))-r._umin);
00121   };
00122   
00123   void lsegment::convert_regions()
00124     {
00125       for ( unsigned i = 0; i < regions.size(); i++ )
00126         promote( regions[i] );
00127     };
00128   
00129   double _st;
00130   lsegment::lsegment( const ParametricSurface * s , unsigned _w, unsigned _h ) : sample(s,_w,_h)
00131   {
00132     //_st = time();
00133     _size = 0;
00134     lines_changes  ();
00135     grp = new graph_t();
00136     find_regions   ();
00137     convert_regions();
00138     delete[] marks;
00139     delete[] lines;
00140     //    std::cout << "l = " << (time()-_st) << std::endl;
00141   };
00142   
00143   lsegment::~lsegment()
00144   {
00145     delete grp;
00146     for ( unsigned i = 0; i < regions.size(); i++ )
00147       rfree(regions[i]);
00148   };
00149 };
00150         
00151 } //namespace mmx
00152 
00153 # undef ParametricSurface