shape_doc 0.1
|
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