void Renderer::ApplyFilter() {
	int n = Height();
	int m = Width();
	filter_->SetRange(support_*0.5/std::max(n, m));

	// Preprocessing of the values of the image on the sample points
	if (!precomputed_) {
		sampled_values_.clear();
		for (const auto &p : samples_) {
			sampled_values_.insert({p, ImageToPrint().Value(p)});
		}
		precomputed_ = true;
	}

	// Parallelisation of the computation, pixel per pixel
	std::vector<QRgb> new_image(n*m);
	#ifdef _OPENMP
	#pragma omp parallel for collapse(2)
	#endif
	for (int i=0; i<n; i++) {
		for (int j=0; j<m; j++) {
			PointSet::Point p((i+0.5)/std::max(n, m), (j+0.5)/std::max(n, m));
			int v = 255*ComputePoint(p);
			new_image.at(i*m+j) = qRgb(v, v, v);
		}
	}

	// Setting of the new output image
	memcpy(output_.bits(), new_image.data(), n*m*sizeof(QRgb));
	image_label_->setPixmap(QPixmap::fromImage(output_));
}
//-----------------------------------------------------------------------------
void Region::ComputeDimension( Region &anchor, int set ) {

	int ip = set * 3; // index base for points and anchor_points
	int ir = set * 2; // index base for ?

	if( m_points[ip].set && m_points[ip+2].set ) {
		// left and right set, compute from points
		 
		m_computed_rect[0+set] = 
				ComputePoint( anchor, m_anchor_points[ip], set, m_points[ip] );

		m_computed_rect[2+set] = 
				ComputePoint( anchor, m_anchor_points[ip+2], set, m_points[ip] );

	} else if( m_points[ip+1].set && m_size[set].set ) {
		// center set, compute from size

		int pos = ComputePoint( anchor, m_anchor_points[ip+1], set, m_points[ip+1] );
		int size = ComputeSize( anchor, set );

		m_computed_rect[0+set] = pos - size / 2;
		m_computed_rect[2+set] = m_computed_rect[0+set] + size;
		
	} else if( m_points[ip].set && m_size[set].set ) {

		m_computed_rect[0+set] = 
				ComputePoint( anchor, m_anchor_points[ip], set, m_points[ip] );

		m_computed_rect[2+set] =
				m_computed_rect[0+set] + ComputeSize( anchor, set );

	} else if( m_points[ip+2].set && m_size[set].set ) {

		m_computed_rect[2+set] =
				ComputePoint( anchor, m_anchor_points[ip], set, m_points[ip] );

		m_computed_rect[0+set] = 
				m_computed_rect[2+set] - ComputeSize( anchor, set );

	} else {
		// not enough data to compute.
		return;
	}

	m_computed_size[set] = m_computed_rect[2+set] - m_computed_rect[0+set];
}
//-----------------------------------------------------------------------------
// Compute the shield points using catmull-rom
//-----------------------------------------------------------------------------
void C_Shield::ComputeShieldPoints( Vector* pt, Vector* normal, float* opacity )
{
	int i;
	for ( i = 0; i < m_SubdivisionCount; ++i)
	{
		float t = (Height() - 1) * (float)i * m_InvSubdivisionCount;
		for (int j = 0; j < m_SubdivisionCount; ++j)
		{
			float s = (Width() - 1) * (float)j * m_InvSubdivisionCount;
			int idx = i * m_SubdivisionCount + j;

			ComputePoint( s, t, pt[idx], normal[idx], opacity[idx] );
		}
	}
}
void C_EnergyWave::ComputeEWavePoints( Vector* pt, Vector* normal, float* opacity )
{
	int i;
	for ( i = 0; i < NUM_SUBDIVISIONS; ++i)
	{
		float t = (EWAVE_NUM_VERTICAL_POINTS -1 ) * (float)i / (float)(NUM_SUBDIVISIONS - 1);
		for (int j = 0; j < NUM_SUBDIVISIONS; ++j)
		{
			float s = (EWAVE_NUM_HORIZONTAL_POINTS-1) * (float)j / (float)(NUM_SUBDIVISIONS - 1);
			int idx = i * NUM_SUBDIVISIONS + j;

			ComputePoint( s, t, pt[idx], normal[idx], opacity[idx] );
		}
	}
}