00001
00002
00003
00004
00005
00006 #include "bmesh.H"
00007 #include "stripcb.H"
00008
00009
00010
00011
00012 void
00013 ZcrossPath::get_g(Bface * f , double g[], int& ex1, int& ex2)
00014 {
00015 int i;
00016 Wvec v1;
00017 for ( i=0; i < 3; i++ ) {
00018 g[i] = (_eye - f->v(i+1)->loc()).normalized() * f->vert_normal(f->v(i+1), v1);
00019 if ( g[i] == 0 ) {
00020
00021 g[i] = -1e-8;
00022 }
00023 }
00024
00025 if ( g[0] > 0 ) {
00026 if( g[1] > 0 ){
00027 ex1 = 1; ex2 = 2;
00028 } else if( g[2] > 0 ){
00029 ex1 = 0; ex2 = 1;
00030 } else {
00031 ex1 = 0; ex2 = 2;
00032 }
00033 } else {
00034 if( g[1] < 0 ){
00035 ex1 = 1; ex2 = 2;
00036 } else if( g[2] < 0 ){
00037 ex1 = 0; ex2 = 1;
00038 } else {
00039 ex1 = 0; ex2 = 2;
00040 }
00041 }
00042 }
00043
00044 bool
00045 ZcrossPath::has_sil(Bface * f)
00046 {
00047
00048 if ( f->zx_query() )
00049 return false;
00050 f->zx_mark();
00051
00052 int i;
00053 double g[3];
00054 Wvec v1;
00055 for ( i=0; i < 3; i++ ) {
00056 g[i] = ( _eye - f->v(i+1)->loc() ).normalized() * f->vert_normal(f->v(i+1), v1);
00057 if ( g[i] == 0 ) {
00058
00059 g[i] = -1e-8;
00060 }
00061
00062 }
00063
00064
00065
00066
00067
00068 if ( ( g[0] > 0 && ( g[1] < 0 || g[2] < 0 ) ) ||
00069 ( g[0] < 0 && ( g[1] > 0 || g[2] > 0 ) ) )
00070 return true;
00071
00072 return false;
00073 }
00074
00075 void
00076 ZcrossPath::build(CBface_list& list )
00077 {
00078 int k;
00079 for (k = 0 ; k < list.num(); k++)
00080 if ( has_sil(list[k]))
00081 start_sil(list[k]);
00082 }
00083
00084 void
00085 ZcrossPath::start_sil(Bface *f )
00086 {
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105 if (!has_sil(f))
00106 return;
00107
00108
00109 double g[3];
00110 int ex1, ex2 , nex1, nex2;
00111
00112
00113 bool bgrad;
00114
00115 get_g(f, g, ex1, ex2 );
00116
00117 Bface *f1;
00118 Bface *f2;
00119
00120 Bface *iter_f;
00121 nex1 = (ex1+1)%3;
00122 nex2 = (ex2+1)%3;
00123
00124
00125 Bvert * svrt[3];
00126 double sg[3];
00127
00128
00129
00130
00131 f1 = ( f->e(ex1+1)->is_crease()) ? NULL : f->nbr(ex1+1);
00132 f2 = ( f->e(ex2+1)->is_crease()) ? NULL : f->nbr(ex2+1);
00133
00134
00135
00136
00137
00138 double alph1 = -g[ex1] / (g[nex1] - g[ex1]);
00139 Wpt pt1 = interp ( f->v(ex1+1)->loc(), f->v(nex1+1)->loc(), alph1);
00140
00141 double alph2 = -g[ex2] / (g[nex2] - g[ex2]);
00142 Wpt pt2 = interp ( f->v(ex2+1)->loc(), f->v(nex2+1)->loc(), alph2);
00143
00144
00145
00146 int gmax = ( g[0] > g[1] ) ? 0 : 1;
00147 gmax = ( g[2] > g[gmax] ) ? 2 : gmax;
00148
00149 Wvec v_iso = pt1 - pt2;
00150 Wvec v_max = f->v(gmax+1)->loc() - pt2;
00151 Wvec v_grad = v_max.orthogonalized(v_iso);
00152 bgrad = ( ( _eye - pt2 ) * v_grad > 0 ) ;
00153
00154
00155
00156
00157
00158
00159
00160 if ( cross( v_grad , f->norm()) * v_iso > 0 ) {
00161 swap ( pt1, pt2);
00162 swap ( alph1, alph2);
00163 swap ( f1, f2);
00164 swap ( ex1, ex2 );
00165 swap ( nex1, nex2);
00166 }
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176 Wvec bc;
00177 bc[ex2] = 1.0-alph2;
00178 bc[nex2] = alph2;
00179
00180
00181
00182
00183
00184
00185 int cstart = num();
00186
00187 iter_f = f;
00188 add_seg ( f , pt2, f->v(ex2+1), bgrad, f);
00189
00190 if (f1) {
00191
00192 svrt [0] = f->v(ex2+1) ;
00193 sg [0] = g[ex2];
00194 svrt [1] = f->v(nex2+1);
00195 sg [1] = g[nex2];
00196
00197
00198 while ( iter_f ) {
00199
00200 iter_f = sil_walk_search(iter_f, svrt, sg);
00201
00202 if ( iter_f == f ) {
00203
00204 if ( !( _segs[cstart].p() == _segs.last().p() ) ) {
00205
00206
00207
00208
00209 _segs.last().p() = _segs[cstart].p() ;
00210 }
00211 _segs.last().setf( NULL );
00212 _segs.last().set_end();
00213 _segs.last().set_bary(f2);
00214
00215 return;
00216 }
00217
00218 }
00219 } else {
00220 add_seg ( NULL , pt1, f->v(ex1+1), bgrad, f);
00221 }
00222
00223
00224
00225
00226
00227
00228
00229 int chain2start = num();
00230
00231 if ( !f2 )
00232 return;
00233
00234
00235
00236
00237
00238 iter_f = f2;
00239 add_seg ( f2 , pt2, f->v(ex2+1), bgrad, f2);
00240
00241 svrt[0] = f->v(ex2+1) ;
00242 sg[0] = g[ex2];
00243 svrt[1] = f->v(nex2+1);
00244 sg[1] = g[nex2];
00245
00246 while ( iter_f ) {
00247 iter_f = sil_walk_search ( iter_f, svrt, sg );
00248 }
00249 int chain2end = num();
00250
00251
00252
00253
00254
00255
00256 int chain2num = (chain2end - chain2start) -1 ;
00257 if ( chain2num < 0 )
00258 return;
00259
00260 _segs.insert(cstart, chain2num);
00261 int last_ind = num()-1;
00262
00263 int j=0;
00264 for ( ; j < chain2num ; j++ ) {
00265 _segs[last_ind-j].setf( _segs[last_ind-(j+1)].f() );
00266
00267 _segs[last_ind-j].setg(_segs[last_ind-(j+1)].g());
00268 _segs[last_ind-j].set_bary(_segs[last_ind-j].f());
00269 }
00270 for ( j=0; j < chain2num ; j++) {
00271 _segs[cstart+j] = _segs.pop();
00272 }
00273
00274 _segs.pop();
00275
00276 return;
00277 }
00278
00279 Bface*
00280 ZcrossPath::sil_search(Bface *last, Bface * f)
00281 {
00282 return last;
00283 }
00284
00285 Bface*
00286 ZcrossPath::sil_walk_search ( Bface *f, Bvert * vrt[3], double g[3] )
00287 {
00288
00289
00290
00291
00292
00293
00294 assert ( f == _segs.last().f() );
00295
00296 f->zx_mark();
00297
00298 Wvec dummy_vec;
00299
00300
00301
00302
00303 vrt[2] = f->other_vertex ( vrt[0], vrt[1] );
00304 g[2] = (_eye - vrt[2]->loc()).normalized() * f->vert_normal(vrt[2], dummy_vec);
00305 if ( g[2] == 0 )
00306 g[2] = -1e-8;
00307
00308
00309 Wpt last_pt = last();
00310
00311
00312
00313 int cross_vrt = ( g[2] > 0 ) ? ((g[0] < 0)? 0:1) : ((g[0] > 0)? 0:1);
00314 double alph = -g[2] / ( g[cross_vrt]-g[2] );
00315
00316
00317 Wpt new_pt = interp ( vrt[2]->loc(), vrt[cross_vrt]->loc(), alph );
00318
00319 int gmax = ( g[0] > g[1] ) ? 0 : 1 ;
00320 gmax = ( g[2] > gmax ) ? 2 : gmax;
00321
00322
00323 Wvec v_iso ( last_pt - new_pt ) ;
00324 Wvec v_max = vrt[gmax]->loc() - new_pt;
00325 Wvec v_grad = v_max.orthogonalized(v_iso);
00326 bool bgrad = ( (_eye - new_pt) * v_grad > 0 );
00327
00328
00329
00330
00331 _segs.last().setg(bgrad);
00332
00333
00334
00335 Bface * next_f = f->opposite_face(vrt[1-cross_vrt]);
00336 Wvec bc(0,0,0);
00337
00338 if ( !next_f || f->shared_edge(next_f)->is_crease() ) {
00339 bc[f->vindex(vrt[2])-1] = 1.0-alph;
00340 bc[f->vindex(vrt[cross_vrt])-1] = alph;
00341 add_seg (NULL , new_pt, vrt[2], bgrad, f );
00342 next_f = NULL;
00343 } else {
00344 bc[next_f->vindex(vrt[2])-1] = 1.0-alph;
00345 bc[next_f->vindex(vrt[cross_vrt])-1] = alph;
00346 add_seg (next_f, new_pt, vrt[2], bgrad, next_f);
00347
00348 }
00349
00350
00351 vrt[1-cross_vrt] = vrt[2];
00352 g[1-cross_vrt] = g[2];
00353 vrt[2] = NULL;
00354 g[2] = 0;
00355 return next_f;
00356 }
00357
00358
00359 Bface*
00360 ZcrossPath::sil_finish(Bface *last, Bface * f)
00361 {
00362 return f;
00363 }
00364
00365