void CylinderPrimitiveShape::WrapBitmap(
	const GfxTL::AABox< GfxTL::Vector2Df > &bbox, float epsilon, bool *uwrap,
	bool *vwrap) const
{
	*uwrap = false;
	if(bbox.Max()[1] - bbox.Min()[1]
		>= 2 * M_PI * m_cylinder.Radius() - 2 * epsilon)
		*vwrap = true; // wrap around angular component
	else
		*vwrap = false;
}
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];
}
Beispiel #3
0
bool BitmapPrimitiveShape::Init(bool binary, std::istream *i)
{
	if(binary)
	{
		GfxTL::AABox< GfxTL::Vector2Df > bbox;
		size_t uextent, vextent;
		// read number of components
		size_t size;
		i->read((char *)&size, sizeof(size));
		if(size)
		{
			// read bbox
			i->read((char *)&bbox, sizeof(bbox));
			// read uextent and vextent
			i->read((char *)&uextent, sizeof(uextent));
			i->read((char *)&vextent, sizeof(vextent));
			// read every component
			for(size_t j = 0; j < size; ++j)
			{
				// read number of polys in component
				size_t numPolys;
				i->read((char *)&numPolys, sizeof(numPolys));
				for(size_t k = 0; k < numPolys; ++k)
				{
					// read number of points in poly
					size_t numPoints;
					i->read((char *)&numPoints, sizeof(numPoints));
					GfxTL::VectorXD< 2, size_t > pp;
					for(size_t l = 0; l < numPoints; ++l)
						i->read((char *)&pp, sizeof(pp));
				}
			}
		}
	}
	else
	{
		GfxTL::AABox< GfxTL::Vector2Df > bbox;
		size_t uextent, vextent;
		// read number of components
		size_t size;
		(*i) >> size;
		if(size)
		{
			// read bbox
			(*i) >> bbox.Min()[0] >> bbox.Max()[0]
				>> bbox.Min()[1] >> bbox.Max()[1];
			// read uextent and vextent
			(*i) >> uextent >> vextent;
			// read every component
			for(size_t j = 0; j < size; ++j)
			{
				// read number of polys in component
				size_t numPolys;
				(*i) >> numPolys;
				for(size_t k = 0; k < numPolys; ++k)
				{
					// read number of points in poly
					size_t numPoints;
					(*i) >> numPoints;
					GfxTL::VectorXD< 2, size_t > pp;
					for(size_t l = 0; l < numPoints; ++l)
						(*i) >> pp[0] >> pp[1];
				}
			}
		}
	}
	return true;
}
Beispiel #4
0
size_t BitmapPrimitiveShape::ConnectedComponent(
	const PointCloud &pc, float epsilon,
	std::shared_ptr<MiscLib::Vector< size_t > >indices, bool doFiltering, float* borderRatio )
{
	MiscLib::Vector< int > componentsImg;
	MiscLib::Vector< std::pair< int, size_t > > labels;

	BitmapInfo bitmapInfo;
	if( AllConnectedComponents( pc, epsilon, bitmapInfo, indices, componentsImg, labels, doFiltering ) <= 1 )
		return 0;

	size_t size = indices->size();
	MiscLib::Vector< size_t >::iterator begin = indices->begin();

	// find the largest component
	size_t maxComp = 1;
	for(size_t i = 2; i < labels.size(); ++i)
		if(labels[maxComp].second < labels[i].second)
			maxComp = i;

	GfxTL::AABox< GfxTL::Vector2Df > bbox;
	bbox.Min() = GfxTL::Vector2Df(
			std::numeric_limits< float >::infinity(),
			std::numeric_limits< float >::infinity());
	bbox.Max() = -bbox.Min();
	// compute bbox and update indices
	size_t offset = 0;
	for(size_t i = 0; i < size; ++i)
	{
		if(componentsImg[bitmapInfo.bmpIdx[i]] == labels[maxComp].first)
		{
			std::swap(begin[offset], begin[i]);
			offset++;
			// update bounding box
			if(bbox.Min()[0] > bitmapInfo.params[i].first)
				bbox.Min()[0] = bitmapInfo.params[i].first;
			if(bbox.Max()[0] < bitmapInfo.params[i].first)
				bbox.Max()[0] = bitmapInfo.params[i].first;
			if(bbox.Min()[1] > bitmapInfo.params[i].second)
				bbox.Min()[1] = bitmapInfo.params[i].second;
			if(bbox.Max()[1] < bitmapInfo.params[i].second)
				bbox.Max()[1] = bitmapInfo.params[i].second;
		}
	}

	// ratio between border and connected-comp size should be calculated if borderRatio is a valid pointer
	if( borderRatio )
	{
		int borderPixels = 0;
		int maxLabel = labels[maxComp].first;
		int row = bitmapInfo.uextent;
		int pos = 0;
		char numNeighbours = 0;
		int ccSize = 0;

		// test neightbourhood for all bitmappixels that are not marginal
		for( size_t v = 1; v < bitmapInfo.vextent-1; ++v )
		{
			for( size_t u = 1; u < bitmapInfo.uextent-1; ++u )
			{
				pos = row + u;

				if( componentsImg[pos] == maxLabel )
				{
					ccSize++;
					numNeighbours = bitmapInfo.bitmap[pos-1] + bitmapInfo.bitmap[pos+1] + 
								bitmapInfo.bitmap[pos-bitmapInfo.uextent-1] + bitmapInfo.bitmap[pos-bitmapInfo.uextent+1] +
								bitmapInfo.bitmap[pos+bitmapInfo.uextent-1] + bitmapInfo.bitmap[pos+bitmapInfo.uextent+1] +
								bitmapInfo.bitmap[pos-bitmapInfo.uextent] + bitmapInfo.bitmap[pos+bitmapInfo.uextent];

					if( (int)numNeighbours != 8 )
						++borderPixels;
				}
			}
			row += bitmapInfo.uextent;
		}

		// check left/right margins
		row = bitmapInfo.uextent;
		for( size_t v = 1; v < bitmapInfo.vextent-1; ++v )
		{
			ccSize++;
			if( componentsImg[row] == maxLabel )
				++borderPixels;

			ccSize++;
			if( componentsImg[row+bitmapInfo.uextent-1] == maxLabel )
				++borderPixels;

			row += bitmapInfo.uextent;
		}

		// check top/bottom margins
		row = ( bitmapInfo.vextent-1 ) * bitmapInfo.uextent;
		for( size_t u = 0; u < bitmapInfo.uextent; ++u )
		{
			ccSize++;
			if( componentsImg[u] == maxLabel )
				++borderPixels;

			ccSize++;
			if( componentsImg[row + u] == maxLabel )
				++borderPixels;
		}
		
		*borderRatio = static_cast<float>( borderPixels ) / static_cast<float>( ccSize );
	}

	m_extBbox = bbox;
	return offset;
}
void CylinderPrimitiveShape::SetExtent(
	const GfxTL::AABox< GfxTL::Vector2Df > &extBbox,
	const MiscLib::Vector< int > &componentsImg, size_t uextent,
	size_t vextent, float epsilon, int label)
{
	if(extBbox.Min()[1] * m_cylinder.Radius() <= epsilon
		&& extBbox.Max()[1] * m_cylinder.Radius()
			>= 2 * M_PI * m_cylinder.Radius() - epsilon)
	{
		// component has been cut along angular direction
		// run from both sides to find both ends
		size_t row = 0, j = 0;
		for(; j < vextent; ++j)
		{
			bool found = false;
			for(size_t i = 0; i < uextent; ++i)
			{
				if(componentsImg[row + i] == label)
				{
					found = true;
					break;
				}
			}
			if(!found)
				break;
			row += uextent;
		}
		size_t maxj = j;
		if(maxj == vextent) // cylinder is complete
		{
			m_clip = false;
			return;
		}
		row = (vextent - 1) * uextent, j = 0;
		for(; j < vextent; ++j)
		{
			bool found = false;
			for(size_t i = 0; i < uextent; ++i)
			{
				if(componentsImg[row + i] == label)
				{
					found = true;
					break;
				}
			}
			if(!found)
				break;
			row -= uextent;
		}
		size_t minj = j;
		// convert min and max to angular parameters
		m_minPhi = minj * epsilon / m_cylinder.Radius() + extBbox.Min()[1];
		m_maxPhi = maxj * epsilon / m_cylinder.Radius() + extBbox.Min()[1];
	}
	else
	{
		m_minPhi = extBbox.Min()[1];
		m_maxPhi = extBbox.Max()[1];
	}
	m_clip = true;
}