void LowStretchSphereParametrization::WrapComponents(const GfxTL::AABox< GfxTL::Vector2Df > &bbox, float epsilon, size_t uextent, size_t vextent, MiscLib::Vector< int > *componentImg, MiscLib::Vector< std::pair< int, size_t > > *labels) const { // wraps are necessary only in v direction // relabel the components MiscLib::Vector< std::pair< int, size_t > > tempLabels(*labels); // wrap along v float vstartPrev, vendPrev, vstart = 0, vend = 0, vstartNext = 0, vendNext = 0; size_t vsPrev, vePrev, vs = 0, ve = 0, vsNext = 0, veNext = 0; float uangle = (bbox.Min()[0] + .5f * epsilon) / m_sphere->Radius(); float radius = std::sin(uangle) * m_sphere->Radius(); vstartNext = float(-M_PI) * radius; vendNext = float(M_PI) * radius; vsNext = std::min(vextent - 1, (size_t)std::max((intptr_t)0, (intptr_t)((vstartNext - bbox.Min()[1]) / epsilon))); veNext = (size_t)std::max((intptr_t)0, std::min((intptr_t)vextent - 1, (intptr_t)((vendNext - bbox.Min()[1]) / epsilon))); for(size_t u = 0; u < uextent; ++u) { vstartPrev = vstart; vstart = vstartNext; vendPrev = vend; vend = vendNext; vsPrev = vs; vs = vsNext; vePrev = ve; ve = veNext; // determine starting position in the next column if(u < uextent - 1) { float uangleNext = ((u + 1.5f) * epsilon + bbox.Min()[0]) / m_sphere->Radius(); float radiusNext = std::sin(uangle) * m_sphere->Radius(); vstartNext = float(-M_PI) * radius; vendNext = float(M_PI) * radius; vsNext = std::min(vextent - 1, (size_t)std::max((intptr_t)0, (intptr_t)((vstartNext - bbox.Min()[1]) / epsilon))); veNext = (size_t)std::max((intptr_t)0, std::min((intptr_t)vextent - 1, (intptr_t)((vendNext - bbox.Min()[1]) / epsilon))); } if(vstart <= bbox.Min()[1] - epsilon || vend >= bbox.Max()[1] + epsilon || !(*componentImg)[vs * uextent + u]) continue; // check the three neighbors on the other side if((*componentImg)[ve * uextent + u]) AssociateLabel((*componentImg)[vs * uextent + u], (*componentImg)[ve * uextent + u], &tempLabels); if(u > 0 && vstartPrev > bbox.Min()[1] - epsilon && vendPrev < bbox.Min()[1] + epsilon && (*componentImg)[vePrev * uextent + u - 1]) AssociateLabel((*componentImg)[vs * uextent + u], (*componentImg)[vePrev * uextent + u - 1], &tempLabels); if(u < uextent - 1 && vstartNext > bbox.Min()[1] - epsilon && vendNext < bbox.Min()[1] + epsilon && (*componentImg)[veNext * uextent + u + 1]) AssociateLabel((*componentImg)[vs * uextent + u], (*componentImg)[veNext * uextent + u + 1], &tempLabels); } // condense labels for(size_t i = tempLabels.size() - 1; i > 0; --i) tempLabels[i].first = ReduceLabel(i, tempLabels); MiscLib::Vector< int > condensed(tempLabels.size()); labels->clear(); labels->reserve(condensed.size()); int count = 0; for(size_t i = 0; i < tempLabels.size(); ++i) if(i == tempLabels[i].first) { labels->push_back(std::make_pair(count, tempLabels[i].second)); condensed[i] = count; ++count; } else (*labels)[condensed[tempLabels[i].first]].second += tempLabels[i].second; // set new component ids for(size_t i = 0; i < componentImg->size(); ++i) (*componentImg)[i] = condensed[tempLabels[(*componentImg)[i]].first]; }
void ConePrimitiveShape::WrapComponents( const GfxTL::AABox< GfxTL::Vector2Df > &bbox, float epsilon, size_t uextent, size_t vextent, MiscLib::Vector< int > *componentImg, MiscLib::Vector< std::pair< int, size_t > > *labels) const { if(m_cone.Angle() >= float(M_PI / 4)) return; // for wrapping we copy the first pixel to the last one in each v column for(size_t u = 0; u < uextent; ++u) { // determine the coordinates of the last pixel in the column // get the radius of the column float r = m_cone.RadiusAtLength(u * epsilon + bbox.Min()[0]); size_t v = std::floor((2 * float(M_PI) * r - bbox.Min()[1]) / epsilon) + 1; if(v >= vextent) continue; if((*componentImg)[u]) (*componentImg)[v * uextent + u] = (*componentImg)[u]; // do the wrap } // relabel the components MiscLib::Vector< std::pair< int, size_t > > tempLabels(*labels); int curLabel = tempLabels.size() - 1; for(size_t u = 0; u < uextent; ++u) { float r = m_cone.RadiusAtLength(u * epsilon + bbox.Min()[0]); size_t v = std::floor((2 * float(M_PI) * r - bbox.Min()[1]) / epsilon) + 1; if(v >= vextent) continue; if(!(*componentImg)[v * uextent + u]) continue; // get the neighbors int n[8]; size_t i = 0; if(v >= 1) { size_t prevRow = (v - 1) * uextent; if(u >= 1) n[i++] = (*componentImg)[prevRow + u - 1]; n[i++] = (*componentImg)[prevRow + u]; if(u < uextent - 1) n[i++] = (*componentImg)[prevRow + u + 1]; } size_t row = v * uextent; if(u >= 1) n[i++] = (*componentImg)[row + u - 1]; if(u < uextent - 1) n[i++] = (*componentImg)[row + u + 1]; if(v < vextent - 1) { size_t nextRow = (v + 1) * uextent; if(u >= 1) n[i++] = (*componentImg)[nextRow + u - 1]; n[i++] = (*componentImg)[nextRow + u]; if(u < uextent - 1) n[i++] = (*componentImg)[nextRow + u + 1]; } // associate labels int l = (*componentImg)[v * uextent + u]; for(size_t j = 0; j < i; ++j) if(n[j]) AssociateLabel(l, n[j], &tempLabels); } // condense labels for(size_t i = tempLabels.size() - 1; i > 0; --i) tempLabels[i].first = ReduceLabel(i, tempLabels); MiscLib::Vector< int > condensed(tempLabels.size()); labels->clear(); labels->reserve(condensed.size()); int count = 0; for(size_t i = 0; i < tempLabels.size(); ++i) if(i == tempLabels[i].first) { labels->push_back(std::make_pair(count, tempLabels[i].second)); condensed[i] = count; ++count; } else (*labels)[condensed[tempLabels[i].first]].second += tempLabels[i].second; // set new component ids for(size_t i = 0; i < componentImg->size(); ++i) (*componentImg)[i] = condensed[tempLabels[(*componentImg)[i]].first]; }