///////////////////////////////////// // recurse() ///////////////////////////////////// void UVMapping::recurse(Bface *seed_f, rec_fun_t fun ) { int k; // bool done = false; Bface* f; ARRAY<Bface*> faces; assert(seed_f); faces.push(seed_f); while (faces.num()>0) { //Remove oldest face from end of queue f = faces.pop(); //Skip if already seen if (!f->is_set(1)) { f->set_bit(1); //If we get here, then this face *should* have uvdata //and *should* be unmapped UVdata* uvdata = UVdata::lookup(f); assert(uvdata); assert(uvdata->mapping()==0); //Do the action (add to map, or update limits, etc.) (this->*fun)(f); for (k=1; k<=3; k++) { Bedge *nxt_e = f->e(k); assert(nxt_e); Bface *nxt_f = nxt_e->other_face(f); if (nxt_f) { UVdata *nxt_uvdata = UVdata::lookup(nxt_f); if (nxt_uvdata) { UVpt uva = uvdata->uv(k); UVpt uvb = uvdata->uv((k==3)?(1):(k+1)); int nxt_k = ( (nxt_f->e1()==nxt_e)?(1): ((nxt_f->e2()==nxt_e)?(2): ((nxt_f->e3()==nxt_e)?(3):(0)))); assert(nxt_k); UVpt nxt_uva = nxt_uvdata->uv(nxt_k); UVpt nxt_uvb = nxt_uvdata->uv((nxt_k==3)?(1):(nxt_k+1)); //If neighboring face has uv, and the they match //we recurse into this next face if ((uva==nxt_uvb)&&(uvb==nxt_uva)) { //Add to front of queue faces.push(nxt_f); } else { //Nothing } } } } } } }
///////////////////////////////////// // recurse_wrapping() ///////////////////////////////////// void UVMapping::recurse_wrapping(Bface *seed_f) { int k; Bface *f; ARRAY<Bface*> faces; assert(seed_f); faces.push(seed_f); while (faces.num()>0) { //Remove face from end of queue f = faces.pop(); //Skip if already seen if (!f->is_set(1)) { f->set_bit(1); //If we get here, then this face *should* have uvdata //and *should* be allready be mapped to us! UVdata* uvdata = UVdata::lookup(f); assert(uvdata); assert(uvdata->mapping()==this); for (k=1; k<=3; k++) { Bedge *nxt_e = f->e(k); assert(nxt_e); Bface *nxt_f = nxt_e->other_face(f); if (nxt_f) { UVdata *nxt_uvdata = UVdata::lookup(nxt_f); if (nxt_uvdata) { UVpt uva = uvdata->uv(k); UVpt uvb = uvdata->uv((k==3)?(1):(k+1)); int nxt_k = ( (nxt_f->e1()==nxt_e)?(1): ((nxt_f->e2()==nxt_e)?(2): ((nxt_f->e3()==nxt_e)?(3):(0)))); assert(nxt_k); UVpt nxt_uva = nxt_uvdata->uv(nxt_k); UVpt nxt_uvb = nxt_uvdata->uv((nxt_k==3)?(1):(nxt_k+1)); //If neighboring face has uv, and the they match //we recurse into this next face if ((uva==nxt_uvb)&&(uvb==nxt_uva)) { //Stick face on start of queue faces.push(nxt_f); } //But if not, let's see if the other face is //part of this mapping. If it is, then we found //a seam. Find the direction (u or v) and if //its consistent with the _min_u/_max_u (or v) //Then set the wrap flag for u or v appropriately //or just turn all wrapping off if something's amiss else { //Here's a seam! if (nxt_uvdata->mapping() == this) { //We support 2 kinds of wrapping: //-Wrap on a line of constant u (wrap at _min_u,_max_u) //-Wrap on a line of constant v (wrap at _min_v,_max_v) //If neither is seen, or if the discontinuity isn't //at the extrema, we found something anomolous, abort! //Note - There can be holes at the seam without problems. if ((uva[0]==uvb[0])&&(nxt_uva[0]==nxt_uvb[0])) { //This looks like wrapping on a line of const. u //Let's make sure the discontinuity is at the extrema if ( (uva[0]==_min_u && nxt_uva[0]==_max_u) || (uva[0]==_max_u && nxt_uva[0]==_min_u)) { //It's all good if (!_wrap_u) { err_mesg(ERR_LEV_SPAM, "UVMapping::recurse_wrapping() - Found a valid wrapping seam in u."); _wrap_u = true; } } else { //We aren't at the extrema, so set the bad flag //to avoid further checking _wrap_bad = true; _wrap_u = false; _wrap_v = false; err_mesg(ERR_LEV_WARN, "UVMapping::recurse_wrapping() - Found an INVALID wrapping seam in u: (%f,%f) since u extrema are: (%f,%f)", uva[0], nxt_uva[0], _min_u, _max_u); err_mesg(ERR_LEV_WARN, "UVMapping::recurse_wrapping() - Aborting all wrapping."); } } else if ((uva[1]==uvb[1])&&(nxt_uva[1]==nxt_uvb[1])) { //This looks like wrapping on a line of const. v //Let's make sure the discontinuity is at the extrema if ( (uva[1]==_min_v && nxt_uva[1]==_max_v) || (uva[1]==_max_v && nxt_uva[1]==_min_v)) { //It's all good if (!_wrap_v) { err_mesg(ERR_LEV_INFO, "UVMapping::recurse_wrapping() - Found a valid wrapping seam in v."); _wrap_v = true; } } else { //We aren't at the extrema, so set the bad flag //to avoid further checking _wrap_bad = true; _wrap_u = false; _wrap_v = false; err_mesg(ERR_LEV_WARN, "UVMapping::recurse_wrapping() - Found an INVALID wrapping seam in v: (%f,%f) since v extrema are: (%f,%f)", uva[1], nxt_uva[1], _min_v, _max_v); err_mesg(ERR_LEV_WARN, "UVMapping::recurse_wrapping() - Aborting all wrapping."); } } else { //One or both edges failed to show constant u or v //Abort any further wrapping... _wrap_bad = true; _wrap_u = false; _wrap_v = false; err_mesg(ERR_LEV_WARN, "UVMapping::recurse_wrapping() - Found an INVALID wrapping. The seam wasn't constant in u or v."); err_mesg(ERR_LEV_WARN, "UVMapping::recurse_wrapping() - Edge #1 (%f,%f)-(%f,%f) Edge #2 (%f,%f)-(%f,%f)", uva[0], uva[1], uvb[0], uvb[1], nxt_uvb[0], nxt_uvb[1], nxt_uva[0], nxt_uva[1]); err_mesg(ERR_LEV_WARN, "UVMapping::recurse_wrapping() - Aborting all wrapping."); } } } } } } } } }