Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "stdfx.h"
Toshihiro Shimizu 890ddd
#include "tfxparam.h"
Toshihiro Shimizu 890ddd
#include "trop.h"
Toshihiro Shimizu 890ddd
#include "warp.h"
Toshihiro Shimizu 890ddd
#include "trasterfx.h"
Toshihiro Shimizu 890ddd
//#include "timage_io.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
class WarpFx : public TStandardRasterFx
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	FX_PLUGIN_DECLARATION(WarpFx)
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
protected:
Toshihiro Shimizu 890ddd
	TRasterFxPort m_warped, m_warper;
Toshihiro Shimizu 890ddd
	TDoubleParamP m_intensity;
Toshihiro Shimizu 890ddd
	TDoubleParamP m_gridStep;
Toshihiro Shimizu 890ddd
	TBoolParamP m_sharpen;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Toshihiro Shimizu 890ddd
	WarpFx()
Toshihiro Shimizu 890ddd
		: m_intensity(20), m_gridStep(2), m_sharpen(true)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		addInputPort("Source", m_warped);
Toshihiro Shimizu 890ddd
		addInputPort("warper", m_warper);
Toshihiro Shimizu 890ddd
		bindParam(this, "intensity", m_intensity);
Toshihiro Shimizu 890ddd
		bindParam(this, "sensitivity", m_gridStep);
Toshihiro Shimizu 890ddd
		bindParam(this, "sharpen", m_sharpen);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		m_intensity->setValueRange(-1000, 1000);
Toshihiro Shimizu 890ddd
		m_gridStep->setValueRange(2, 20);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	virtual ~WarpFx() {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	bool canHandle(const TRenderSettings &info, double frame)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		return isAlmostIsotropic(info.m_affine);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	bool doGetBBox(double frame, TRectD &bBox, const TRenderSettings &info)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		if (m_warped.isConnected()) {
Toshihiro Shimizu 890ddd
			int ret = m_warped->doGetBBox(frame, bBox, info);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			if (ret && !bBox.isEmpty()) {
Toshihiro Shimizu 890ddd
				if (bBox != TConsts::infiniteRectD) {
Toshihiro Shimizu 890ddd
					WarpParams params;
Toshihiro Shimizu 890ddd
					params.m_intensity = m_intensity->getValue(frame);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
					bBox = bBox.enlarge(getWarpRadius(params));
Toshihiro Shimizu 890ddd
				}
Toshihiro Shimizu 890ddd
				return true;
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		bBox = TRectD();
Toshihiro Shimizu 890ddd
		return false;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void doDryCompute(TRectD &rect,
Toshihiro Shimizu 890ddd
					  double frame,
Toshihiro Shimizu 890ddd
					  const TRenderSettings &info)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		bool isWarped = m_warped.isConnected();
Toshihiro Shimizu 890ddd
		bool isWarper = m_warper.isConnected();
Toshihiro Shimizu 890ddd
		if (!isWarped)
Toshihiro Shimizu 890ddd
			return;
Toshihiro Shimizu 890ddd
		if (!isWarper || fabs(m_intensity->getValue(frame)) < 0.01) {
Toshihiro Shimizu 890ddd
			m_warped->dryCompute(rect, frame, info);
Toshihiro Shimizu 890ddd
			return;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		int shrink = (info.m_shrinkX + info.m_shrinkY) / 2;
Toshihiro Shimizu 890ddd
		double scale = sqrt(fabs(info.m_affine.det()));
Toshihiro Shimizu 890ddd
		double gridStep = 1.5 * m_gridStep->getValue(frame);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		WarpParams params;
Toshihiro Shimizu 890ddd
		params.m_intensity = m_intensity->getValue(frame) / gridStep;
Toshihiro Shimizu 890ddd
		params.m_warperScale = scale * gridStep;
Toshihiro Shimizu 890ddd
		params.m_sharpen = m_sharpen->getValue();
Toshihiro Shimizu 890ddd
		params.m_shrink = shrink;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		TRenderSettings warperInfo(info);
Toshihiro Shimizu 890ddd
		double warperScaleFactor = 1.0 / params.m_warperScale;
Toshihiro Shimizu 890ddd
		warperInfo.m_affine = TScale(warperScaleFactor) * info.m_affine;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		TRectD warpedBox, warpedComputeRect, tileComputeRect;
Toshihiro Shimizu 890ddd
		m_warped->getBBox(frame, warpedBox, info);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		getWarpComputeRects(tileComputeRect, warpedComputeRect, warpedBox, rect, params);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		if (tileComputeRect.getLx() <= 0 || tileComputeRect.getLy() <= 0)
Toshihiro Shimizu 890ddd
			return;
Toshihiro Shimizu 890ddd
		if (warpedComputeRect.getLx() <= 0 || warpedComputeRect.getLy() <= 0)
Toshihiro Shimizu 890ddd
			return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		TPointD db;
Toshihiro Shimizu 890ddd
		TRectD warperComputeRect(TScale(warperScaleFactor) * tileComputeRect);
Toshihiro Shimizu 890ddd
		double warperEnlargement = getWarperEnlargement(params);
Toshihiro Shimizu 890ddd
		warperComputeRect = warperComputeRect.enlarge(warperEnlargement);
Toshihiro Shimizu 890ddd
		warperComputeRect.x0 = tfloor(warperComputeRect.x0);
Toshihiro Shimizu 890ddd
		warperComputeRect.y0 = tfloor(warperComputeRect.y0);
Toshihiro Shimizu 890ddd
		warperComputeRect.x1 = tceil(warperComputeRect.x1);
Toshihiro Shimizu 890ddd
		warperComputeRect.y1 = tceil(warperComputeRect.y1);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		m_warped->dryCompute(warpedComputeRect, frame, info);
Toshihiro Shimizu 890ddd
		m_warper->dryCompute(warperComputeRect, frame, warperInfo);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void doCompute(TTile &tile, double frame, const TRenderSettings &info)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		bool isWarped = m_warped.isConnected();
Toshihiro Shimizu 890ddd
		bool isWarper = m_warper.isConnected();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		if (!isWarped)
Toshihiro Shimizu 890ddd
			return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		if (!isWarper) {
Toshihiro Shimizu 890ddd
			m_warped->compute(tile, frame, info);
Toshihiro Shimizu 890ddd
			return;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
		if (fabs(m_intensity->getValue(frame)) < 0.01) {
Toshihiro Shimizu 890ddd
			m_warped->compute(tile, frame, info);
Toshihiro Shimizu 890ddd
			return;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		int shrink = (info.m_shrinkX + info.m_shrinkY) / 2;
Toshihiro Shimizu 890ddd
		double scale = sqrt(fabs(info.m_affine.det()));
Toshihiro Shimizu 890ddd
		double gridStep = 1.5 * m_gridStep->getValue(frame);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		//NOTE: The gridStep is absorbed by the warper scale and the intensity - the former
Toshihiro Shimizu 890ddd
		//balancing the latter.
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		WarpParams params;
Toshihiro Shimizu 890ddd
		params.m_intensity = m_intensity->getValue(frame) / gridStep;
Toshihiro Shimizu 890ddd
		params.m_warperScale = scale * gridStep;
Toshihiro Shimizu 890ddd
		params.m_sharpen = m_sharpen->getValue();
Toshihiro Shimizu 890ddd
		params.m_shrink = shrink;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		//The warper is calculated with a fixed dpi. This makes sure that the lattice
Toshihiro Shimizu 890ddd
		//created for the warp does not depend on camera resolutions / affine scales.
Toshihiro Shimizu 890ddd
		TRenderSettings warperInfo(info);
Toshihiro Shimizu 890ddd
		double warperScaleFactor = 1.0 / params.m_warperScale;
Toshihiro Shimizu 890ddd
		warperInfo.m_affine = TScale(warperScaleFactor) * info.m_affine;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		//Retrieve tile's geometry
Toshihiro Shimizu 890ddd
		TRectD tileRect;
Toshihiro Shimizu 890ddd
		{
Toshihiro Shimizu 890ddd
			TRasterP tileRas = tile.getRaster();
Toshihiro Shimizu 890ddd
			tileRect = TRectD(tile.m_pos, TDimensionD(tileRas->getLx(), tileRas->getLy()));
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		//Build the compute rect
Toshihiro Shimizu 890ddd
		TRectD warpedBox, warpedComputeRect, tileComputeRect;
Toshihiro Shimizu 890ddd
		m_warped->getBBox(frame, warpedBox, info);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		getWarpComputeRects(tileComputeRect, warpedComputeRect, warpedBox, tileRect, params);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		if (tileComputeRect.getLx() <= 0 || tileComputeRect.getLy() <= 0)
Toshihiro Shimizu 890ddd
			return;
Toshihiro Shimizu 890ddd
		if (warpedComputeRect.getLx() <= 0 || warpedComputeRect.getLy() <= 0)
Toshihiro Shimizu 890ddd
			return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		TRectD warperComputeRect(TScale(warperScaleFactor) * tileComputeRect);
Toshihiro Shimizu 890ddd
		double warperEnlargement = getWarperEnlargement(params);
Toshihiro Shimizu 890ddd
		warperComputeRect = warperComputeRect.enlarge(warperEnlargement);
Toshihiro Shimizu 890ddd
		warperComputeRect.x0 = tfloor(warperComputeRect.x0);
Toshihiro Shimizu 890ddd
		warperComputeRect.y0 = tfloor(warperComputeRect.y0);
Toshihiro Shimizu 890ddd
		warperComputeRect.x1 = tceil(warperComputeRect.x1);
Toshihiro Shimizu 890ddd
		warperComputeRect.y1 = tceil(warperComputeRect.y1);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		//Compute the warped tile
Toshihiro Shimizu 890ddd
		TTile tileIn;
Toshihiro Shimizu 890ddd
		m_warped->allocateAndCompute(tileIn, warpedComputeRect.getP00(),
Toshihiro Shimizu 890ddd
									 TDimension(warpedComputeRect.getLx(), warpedComputeRect.getLy()),
Toshihiro Shimizu 890ddd
									 tile.getRaster(), frame, info);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		//Compute the warper tile
Toshihiro Shimizu 890ddd
		TTile tileWarper;
Toshihiro Shimizu 890ddd
		m_warper->allocateAndCompute(tileWarper, warperComputeRect.getP00(),
Toshihiro Shimizu 890ddd
									 TDimension(warperComputeRect.getLx(), warperComputeRect.getLy()),
Toshihiro Shimizu 890ddd
									 tile.getRaster(), frame, warperInfo);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		//Warp
Toshihiro Shimizu 890ddd
		TRasterP rasIn = tileIn.getRaster();
Toshihiro Shimizu 890ddd
		TRasterP rasWarper = tileWarper.getRaster();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		TPointD db;
Toshihiro Shimizu 890ddd
		TRect rasComputeRectI(convert(tileComputeRect - tileRect.getP00(), db));
Toshihiro Shimizu 890ddd
		TRasterP tileRas = tile.getRaster()->extract(rasComputeRectI);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		TPointD rasInPos(warpedComputeRect.getP00() - tileComputeRect.getP00());
Toshihiro Shimizu 890ddd
		TPointD warperPos((TScale(params.m_warperScale) * warperComputeRect.getP00()) - tileComputeRect.getP00());
Toshihiro Shimizu 890ddd
		warp(tileRas, rasIn, rasWarper, rasInPos, warperPos, params);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	int getMemoryRequirement(const TRectD &rect, double frame, const TRenderSettings &info)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		//return 0;   //For debug purpose
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		int shrink = (info.m_shrinkX + info.m_shrinkY) / 2;
Toshihiro Shimizu 890ddd
		double scale = sqrt(fabs(info.m_affine.det()));
Toshihiro Shimizu 890ddd
		double gridStep = 1.5 * m_gridStep->getValue(frame);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		WarpParams params;
Toshihiro Shimizu 890ddd
		params.m_intensity = m_intensity->getValue(frame) / gridStep;
Toshihiro Shimizu 890ddd
		params.m_warperScale = scale * gridStep;
Toshihiro Shimizu 890ddd
		params.m_sharpen = m_sharpen->getValue();
Toshihiro Shimizu 890ddd
		params.m_shrink = shrink;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		double warperScaleFactor = 1.0 / params.m_warperScale;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		TRectD warpedBox, warpedComputeRect, tileComputeRect;
Toshihiro Shimizu 890ddd
		m_warped->getBBox(frame, warpedBox, info);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		getWarpComputeRects(tileComputeRect, warpedComputeRect, warpedBox, rect, params);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		TRectD warperComputeRect(TScale(warperScaleFactor) * tileComputeRect);
Toshihiro Shimizu 890ddd
		double warperEnlargement = getWarperEnlargement(params);
Toshihiro Shimizu 890ddd
		warperComputeRect = warperComputeRect.enlarge(warperEnlargement);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 12c444
		return std::max(
Toshihiro Shimizu 890ddd
			TRasterFx::memorySize(warpedComputeRect, info.m_bpp),
Toshihiro Shimizu 890ddd
			TRasterFx::memorySize(warperComputeRect, info.m_bpp));
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
FX_PLUGIN_IDENTIFIER(WarpFx, "warpFx")