///////////////////////////////////// // find_face(); ///////////////////////////////////// Bface* UVMapping::find_face(CUVpt &uv, Wvec &bc) { static bool debug = Config::get_var_bool("HATCHING_DEBUG_MAPPING",false); int k,i; // double bc1,bc2,bc3; UVdata* uvdata; Bface *f; int u = int(floor( ( uv[0] - _min_u ) / _du )); if (u==MAPPING_SIZE) u--; int v = int(floor( ( uv[1] - _min_v ) / _dv )); if (v==MAPPING_SIZE) v--; i = u+MAPPING_SIZE*v; for (k=0; k<_mapping[i]->num(); k++) { f = (*_mapping[i])[k]; uvdata = UVdata::lookup(f); assert(uvdata); CUVpt& uv1 = uvdata->uv1(); CUVpt& uv2 = uvdata->uv2(); CUVpt& uv3 = uvdata->uv3(); UVvec uv3_1 = uv3 - uv1; double A = det(uv2 - uv1, uv3_1 ); double bc1 = det(uv2 - uv , uv3 - uv ) / A; if ((bc1<0)||(bc1>1)) continue; double bc2 = det(uv - uv1, uv3_1 ) / A; if ((bc2<0)||(bc2>1)) continue; double bc3 = 1.0 - bc1 - bc2; if (bc3>=0) { bc = Wvec(bc1,bc2,bc3); if (debug) { _marked_debug_image[3*i ] = 0xFF; _marked_debug_image[3*i+1] = 0x77; _marked_debug_image[3*i+2] = 0x77; } return f; } /* double A = 0.5 * det(uvdata->uv2() - uvdata->uv1(), uvdata->uv3() - uvdata->uv1()); double bc1 = 0.5 * det(uvdata->uv2() - uv, uvdata->uv3() - uv ) / A; double bc2 = 0.5 * det(uv - uvdata->uv1(), uvdata->uv3() - uvdata->uv1()) / A; double bc3 = 1.0 - bc1 - bc2; if ( ((bc1>=0)&&(bc1<=1)) && ((bc2>=0)&&(bc2<=1)) && ((bc3)>=0) ) { bc = Wvec(bc1,bc2,bc3); if (debug) { _marked_debug_image[3*i ] = 0xFF; _marked_debug_image[3*i+1] = 0x77; _marked_debug_image[3*i+2] = 0x77; } return f; } */ } return 0; }
///////////////////////////////////// // add_face() ///////////////////////////////////// void UVMapping::add_face(Bface *f) { int k, u, v; int umax=0, vmax=0; int umin=MAPPING_SIZE-1, vmin=MAPPING_SIZE-1; int entry_count = 0; int bin_count = 0; assert(f); UVdata* uvdata = UVdata::lookup(f); assert(uvdata); assert(uvdata->mapping()==0); //Sanity check for (k=1; k<=3; k++) { assert( uvdata->uv(k)[0] <= _max_u ); assert( uvdata->uv(k)[1] <= _max_v ); assert( uvdata->uv(k)[0] >= _min_u ); assert( uvdata->uv(k)[1] >= _min_v ); } //Find the square set of u,v bins holding face for (k=1; k<=3; k++) { u = int(floor( (uvdata->uv(k)[0] - _min_u) / _du )); if (u==MAPPING_SIZE) u--; v = int(floor( (uvdata->uv(k)[1] - _min_v ) /_dv )); if (v==MAPPING_SIZE) v--; if (u<umin) umin=u; if (u>umax) umax=u; if (v<vmin) vmin=v; if (v>vmax) vmax=v; } //So escape rounding error that would //exclude bins that we genuinely intersect //we puff out the set of bins by 1 on each side if (umin>0) umin--; if (vmin>0) vmin--; if (umax<MAPPING_SIZE-1) umax++; if (vmax<MAPPING_SIZE-1) vmax++; //Sanity checks assert(umin>=0); assert(vmin>=0); assert(umax<MAPPING_SIZE); assert(vmax<MAPPING_SIZE); assert(umax>=umin); assert(vmax>=vmin); UVpt_list box; UVpt_list tri; bool isect; for (v=vmin; v<=vmax; v++) { for (u=umin; u<=umax; u++) { isect = false; box.clear(); tri.clear(); box += UVpt( _min_u + u *_du , _min_v + v * _dv ); box += UVpt( _min_u + (u+1) *_du , _min_v + v * _dv ); box += UVpt( _min_u + (u+1) *_du , _min_v + (v+1) * _dv ); box += UVpt( _min_u + u *_du , _min_v + (v+1) * _dv ); tri += uvdata->uv1(); tri += uvdata->uv2(); tri += uvdata->uv3(); //isect if box holds tri or vice versa if (box.contains(tri)) isect = true; else if (tri.contains(box)) isect = true; //or if any edges intersect else { for (k=0; k<3; k++) { if (!isect) { if (intersect(box[0],box[1],tri[k],tri[(k+1)%3])) isect=true; else if (intersect(box[1],box[2],tri[k],tri[(k+1)%3])) isect=true; else if (intersect(box[2],box[3],tri[k],tri[(k+1)%3])) isect=true; else if (intersect(box[3],box[0],tri[k],tri[(k+1)%3])) isect=true; } } } if (isect) { entry_count++; _mapping[u+MAPPING_SIZE*v]->add(f); if ( _mapping[u+MAPPING_SIZE*v]->num() == 1 ) bin_count++; } } } //By definition , a face imust fall somewhere //within the mapping's bin assert(entry_count>0); uvdata->set_mapping(this); //Increment mapped face count _face_cnt++; //Increment map face entry count _entry_cnt += entry_count; //Increment unique bin usage count _bin_cnt += bin_count; }