///////////////////////////////////// // Destructor ///////////////////////////////////// UVMapping::~UVMapping() { UVdata* uvd; size_t k, i, cnt=0; //We should be unreferenced if we get here... assert(!_use_cnt); //Remove ourself from the uvdata of binned faces for (k=0; k<_mapping.size(); k++) { for (i=0; i<_mapping[k]->size(); i++) { uvd = UVdata::lookup((*_mapping[k])[i]); assert(uvd); if (uvd->mapping()) { assert(uvd->mapping()==this); uvd->set_mapping(nullptr); cnt++; } } } err_mesg(ERR_LEV_WARN, "UVMapping::~UVMapping() - Removed from %d faces (should have been %d).", cnt, _face_cnt); for (k=0;k<_mapping.size();k++) delete _mapping[k]; _mapping.clear(); if (_virgin_debug_image) delete[] _virgin_debug_image; if (_marked_debug_image) delete[] _marked_debug_image; }
///////////////////////////////////// // 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; }