void
GenericOCIO::describeInContextContext(OFX::ImageEffectDescriptor &desc, OFX::ContextEnum /*context*/, OFX::PageParamDescriptor *page)
{
#ifdef OFX_IO_USING_OCIO
    OFX::GroupParamDescriptor* group = desc.defineGroupParam(kOCIOParamContext);
    group->setHint(kOCIOParamContextHint);
    group->setOpen(false);

    {
        OFX::StringParamDescriptor* param = desc.defineStringParam(kOCIOParamContextKey1);
        param->setHint(kOCIOParamContextHint);
        param->setAnimates(true);
        param->setParent(*group);
        param->setLayoutHint(OFX::eLayoutHintNoNewLine);
        page->addChild(*param);
    }
    {
        OFX::StringParamDescriptor* param = desc.defineStringParam(kOCIOParamContextValue1);
        param->setHint(kOCIOParamContextHint);
        param->setAnimates(true);
        param->setParent(*group);
        page->addChild(*param);
    }
    {
        OFX::StringParamDescriptor* param = desc.defineStringParam(kOCIOParamContextKey2);
        param->setHint(kOCIOParamContextHint);
        param->setAnimates(true);
        param->setParent(*group);
        param->setLayoutHint(OFX::eLayoutHintNoNewLine);
        page->addChild(*param);
    }
    {
        OFX::StringParamDescriptor* param = desc.defineStringParam(kOCIOParamContextValue2);
        param->setHint(kOCIOParamContextHint);
        param->setAnimates(true);
        param->setParent(*group);
        page->addChild(*param);
    }
    {
        OFX::StringParamDescriptor* param = desc.defineStringParam(kOCIOParamContextKey3);
        param->setHint(kOCIOParamContextHint);
        param->setAnimates(true);
        param->setParent(*group);
        param->setLayoutHint(OFX::eLayoutHintNoNewLine);
        page->addChild(*param);
    }
    {
        OFX::StringParamDescriptor* param = desc.defineStringParam(kOCIOParamContextValue3);
        param->setHint(kOCIOParamContextHint);
        param->setAnimates(true);
        param->setParent(*group);
        page->addChild(*param);
    }
    {
        OFX::StringParamDescriptor* param = desc.defineStringParam(kOCIOParamContextKey4);
        param->setHint(kOCIOParamContextHint);
        param->setAnimates(true);
        param->setParent(*group);
        param->setLayoutHint(OFX::eLayoutHintNoNewLine);
        page->addChild(*param);
    }
    {
        OFX::StringParamDescriptor* param = desc.defineStringParam(kOCIOParamContextValue4);
        param->setHint(kOCIOParamContextHint);
        param->setAnimates(true);
        param->setParent(*group);
        page->addChild(*param);
    }
    page->addChild(*group);
#endif
}
/**
 * @brief Function called to describe the plugin controls and features.
 * @param[in, out]   desc       Effect descriptor
 * @param[in]        context    Application context
 */
void LensDistortPluginFactory::describeInContext( OFX::ImageEffectDescriptor& desc, OFX::EContext context )
{
	// Create the mandated output clip
	OFX::ClipDescriptor* dstClip = desc.defineClip( kOfxImageEffectOutputClipName );

	dstClip->addSupportedComponent( OFX::ePixelComponentRGBA );
	dstClip->addSupportedComponent( OFX::ePixelComponentAlpha );
	dstClip->setSupportsTiles( true );

	// create the mandated source clip
	OFX::ClipDescriptor* srcClip = desc.defineClip( kOfxImageEffectSimpleSourceClipName );
	srcClip->addSupportedComponent( OFX::ePixelComponentRGBA );
	srcClip->addSupportedComponent( OFX::ePixelComponentAlpha );
	srcClip->setSupportsTiles( true );

	// declare an optional clip reference for RoD
	OFX::ClipDescriptor* srcRefClip = desc.defineClip( kClipOptionalSourceRef );
	srcRefClip->addSupportedComponent( OFX::ePixelComponentRGBA );
	srcRefClip->addSupportedComponent( OFX::ePixelComponentAlpha );
	srcRefClip->setSupportsTiles( true );
	srcRefClip->setOptional( true );
	srcRefClip->setLabel( "ref" );

	OFX::BooleanParamDescriptor* reverse = desc.defineBooleanParam( kParamReverse );
	reverse->setLabel( "Reverse" );
	reverse->setDefault( false );
	reverse->setHint( "Invert the effect.\n"
	                  "Distort becomes undistort, and vice versa." );

	// Controls
	OFX::BooleanParamDescriptor* displaySource = desc.defineBooleanParam( kParamDisplaySource );
	displaySource->setLabel( "displaySource" );
	displaySource->setDefault( false );
	displaySource->setHint( "Display the image source (usefull to parameter the distortion with lines overlays on the source image)." );

	OFX::ChoiceParamDescriptor* lensType = desc.defineChoiceParam( kParamLensType );
	lensType->setLabel( "Lens type" );
	lensType->appendOption( kParamLensTypeStandard );
	#ifndef TUTTLE_PRODUCTION
	lensType->appendOption( kParamLensTypeFishEye ); // not implemented yet...
	lensType->appendOption( kParamLensTypeAdvanced ); // not implemented yet...
	lensType->setIsSecret( true );
	#endif
	lensType->setDefault( 0 );

	OFX::DoubleParamDescriptor* coef1 = desc.defineDoubleParam( kParamCoef1 );
	coef1->setScriptName( "Main" );
	coef1->setDefault( 0.1 );
	coef1->setDisplayRange( -1.0, 1.0 );
	coef1->setHint( "Main distortion coeffecient\n"
	                ">0 : Barrel distortion\n"
	                "<0 : Pincushion distortion\n"
	                );

	OFX::DoubleParamDescriptor* coef2 = desc.defineDoubleParam( kParamCoef2 );
	coef2->setLabel( "Secondary" );
	coef2->setDefault( 0.0 );
	coef2->setDisplayRange( -1.0, 1.0 );
	coef2->setHint( "Secondary distortion coeffecient (usefull for fisheyes only)\n"
	                ">0 : Barrel distortion\n"
	                "<0 : Pincushion distortion\n"
	                );
	#ifdef TUTTLE_PRODUCTION
	coef2->setIsSecret( true );
	#endif

	OFX::DoubleParamDescriptor* squeeze = desc.defineDoubleParam( kParamSqueeze );
	squeeze->setLabel( "Squeeze" );
	#ifdef TUTTLE_PRODUCTION
	squeeze->setIsSecret( true );
	#endif
	//    squeeze->setDoubleType( eDoubleTypeNormalisedX );
	squeeze->setDefault( 1.0 );
	squeeze->setRange( 0.00001, 1.0 );
	squeeze->setDisplayRange( 0.01, 1.0 );
	squeeze->setHint( "Squeeze distortion coeffecient (usefull for bad quality lens...)" );

	OFX::Double2DParamDescriptor* asymmetric = desc.defineDouble2DParam( kParamAsymmetric );
	asymmetric->setLabel( "Asymmetric" );
	#ifdef TUTTLE_PRODUCTION
	asymmetric->setIsSecret( true );
	#endif
	//    asymmetric->setDoubleType( eDoubleTypeNormalisedXY );
	asymmetric->setDefault( 0.0, 0.0 );
	asymmetric->setRange( 0.0, 0.0, 1.0, 1.0 );
	asymmetric->setDisplayRange( 0.0, 0.0, 1.0, 1.0 );
	asymmetric->setHint( "asymmetric distortion coeffecient (usefull for bad quality lens...)" );

	OFX::Double2DParamDescriptor* center = desc.defineDouble2DParam( kParamCenter );
	center->setLabel( "Center" );
	center->setDoubleType( OFX::eDoubleTypePlain );
	center->setDefault( 0.0, 0.0 );
	center->setDisplayRange( -1.0, -1.0, 1.0, 1.0 );
	center->setHint( "Center parameter allows you to shift the center of distortion." );

	OFX::BooleanParamDescriptor* centerOverlay = desc.defineBooleanParam( kParamCenterOverlay );
	centerOverlay->setLabel( "Display distortion center" );
	centerOverlay->setDefault( false );
	centerOverlay->setEvaluateOnChange( false );
	centerOverlay->setHint( "Active distortion center point overlay." );

	OFX::ChoiceParamDescriptor* centerType = desc.defineChoiceParam( kParamCenterType );
	centerType->setLabel( "Center type" );
	#ifdef TUTTLE_PRODUCTION
	centerType->setIsSecret( true );
	#endif
	centerType->appendOption( kParamCenterTypeSource );
	centerType->appendOption( kParamCenterTypeRoW );
	centerType->setDefault( 0 );
	centerType->setHint( "Centered on source or output image." );

	OFX::DoubleParamDescriptor* preScale = desc.defineDoubleParam( kParamPreScale );
	preScale->setLabel( "Pre-scale" );
	//    preScale->setDoubleType( eDoubleTypeNormalisedXY );
	preScale->setDefault( 1.0 );
	preScale->setRange( 0.00001, std::numeric_limits<double>::max() );
	preScale->setDisplayRange( 0.0, 2.5 );
	preScale->setHint( "If the transformation of optics is high, you may need to change the scale of the result to be globally closer to the source image or preserve a good resolution." );

	OFX::DoubleParamDescriptor* postScale = desc.defineDoubleParam( kParamPostScale );
	postScale->setLabel( "Post-scale" );
	//    scale->setDoubleType( eDoubleTypeNormalisedXY );
	postScale->setDefault( 1.0 );
	postScale->setRange( 0.00001, std::numeric_limits<double>::max() );
	postScale->setDisplayRange( 0.0, 2.5 );
	postScale->setHint( "If the transformation of optics is high, you may need to change the scale of the result to be globally closer to the source image or preserve a good resolution." );

	OFX::ChoiceParamDescriptor* interpolation = desc.defineChoiceParam( kParamInterpolation );
	interpolation->setLabel( "Interpolation" );
	interpolation->appendOption( kParamInterpolationNearest );
	interpolation->appendOption( kParamInterpolationBilinear );
	interpolation->setDefault( 1 );
	interpolation->setHint( "Interpolation method" );

	OFX::ChoiceParamDescriptor* resizeRod = desc.defineChoiceParam( kParamResizeRod );
	resizeRod->setLabel( "Resize RoD" );
	resizeRod->appendOption( kParamResizeRodNo );
	resizeRod->appendOption( kParamResizeRodSourceRef );
	resizeRod->appendOption( kParamResizeRodMin );
	resizeRod->appendOption( kParamResizeRodMax );
	resizeRod->appendOption( kParamResizeRodManual );
	resizeRod->setDefault( 0 );
	resizeRod->setHint( "Resize output RoD" );

	OFX::DoubleParamDescriptor* scaleRod = desc.defineDoubleParam( kParamResizeRodManualScale );
	scaleRod->setLabel( "Scale RoD" );
	//    scaleRod->setDoubleType( eDoubleTypeNormalisedXY );
	//    scaleRod->setIsSecret( true );
	//    scaleRod->setEnabled( false );
	scaleRod->setDefault( 1.0 );
	scaleRod->setRange( 0.0, std::numeric_limits<double>::max() );
	scaleRod->setDisplayRange( 0, 2.5 );
	scaleRod->setHint( "Adjust the output RoD." );

	OFX::GroupParamDescriptor* displayOptions = desc.defineGroupParam( kParamDisplayOptions );
	displayOptions->setLabel( "Display options" );
	displayOptions->setHint( "Display options (change nothing on the image)" );

	OFX::BooleanParamDescriptor* displayGrid = desc.defineBooleanParam( kParamGridOverlay );
	displayGrid->setLabel( "Display grid" );
	displayGrid->setParent( *displayOptions );
	displayGrid->setDefault( false );
	displayGrid->setEvaluateOnChange( false );
	displayGrid->setHint( "Display the grid" );

	OFX::Double2DParamDescriptor* gridCenter = desc.defineDouble2DParam( kParamGridCenter );
	gridCenter->setLabel( "Grid center" );
	gridCenter->setDoubleType( OFX::eDoubleTypePlain );
	gridCenter->setParent( *displayOptions );
	gridCenter->setDefault( 0.0, 0.0 );
	gridCenter->setDisplayRange( -1.0, -1.0, 1.0, 1.0 );
	gridCenter->setEvaluateOnChange( false );
	gridCenter->setHint( "Allows you to shift the center of the  display grid." );

	OFX::BooleanParamDescriptor* gridCenterOverlay = desc.defineBooleanParam( kParamGridCenterOverlay );
	gridCenterOverlay->setLabel( "Display grid center" );
	gridCenterOverlay->setParent( *displayOptions );
	gridCenterOverlay->setDefault( false );
	gridCenterOverlay->setEvaluateOnChange( false );
	gridCenterOverlay->setHint( "Active grid center point overlay." );

	OFX::Double2DParamDescriptor* gridScale = desc.defineDouble2DParam( kParamGridScale );
	gridScale->setLabel( "Grid scale" );
	gridScale->setDoubleType( OFX::eDoubleTypePlain );
	gridScale->setParent( *displayOptions );
	gridScale->setDefault( 1.0, 1.0 );
	gridScale->setDisplayRange( -10.0, -10.0, 10.0, 10.0 );
	gridScale->setEvaluateOnChange( false );
	gridScale->setHint( "Allows you to scale the display grid." );

	OFX::GroupParamDescriptor* debugOptions = desc.defineGroupParam( kParamDebugOptions );
	debugOptions->setLabel( "Debug options" );
	debugOptions->setHint( "Debug options" );
	debugOptions->setParent( *displayOptions );
	#ifdef TUTTLE_PRODUCTION
	debugOptions->setIsSecret( true );
	#endif

	OFX::BooleanParamDescriptor* debugDisplayRoi = desc.defineBooleanParam( kParamDebugDisplayRoi );
	debugDisplayRoi->setLabel( "Display RoI" );
	#ifdef TUTTLE_PRODUCTION
	debugDisplayRoi->setIsSecret( true );
	#endif
	debugDisplayRoi->setParent( *debugOptions );
	debugDisplayRoi->setDefault( false );
	debugDisplayRoi->setEvaluateOnChange( false );
	debugDisplayRoi->setHint( "Display RoI" );

	OFX::PushButtonParamDescriptor* helpButton = desc.definePushButtonParam( kParamHelp );
	helpButton->setLabel( "Help" );
}
/**
 * @brief Function called to describe the plugin controls and features.
 * @param[in, out]   desc       Effect descriptor
 * @param[in]        context    Application context
 */
void PinningPluginFactory::describeInContext( OFX::ImageEffectDescriptor& desc,
                                              OFX::EContext context )
{
	OFX::ClipDescriptor* srcClip = desc.defineClip( kOfxImageEffectSimpleSourceClipName );
	srcClip->addSupportedComponent( OFX::ePixelComponentRGBA );
	srcClip->addSupportedComponent( OFX::ePixelComponentAlpha );
	srcClip->setSupportsTiles( kSupportTiles );

	// Create the mandated output clip
	OFX::ClipDescriptor* dstClip = desc.defineClip( kOfxImageEffectOutputClipName );
	dstClip->addSupportedComponent( OFX::ePixelComponentRGBA );
	dstClip->addSupportedComponent( OFX::ePixelComponentAlpha );
	dstClip->setSupportsTiles( kSupportTiles );

	//////////////////// Options ////////////////////
	OFX::ChoiceParamDescriptor* method = desc.defineChoiceParam( kParamMethod );
	method->setLabel( "Method" );
	method->appendOption( kParamMethodAffine );
	method->appendOption( kParamMethodPerspective );
	method->appendOption( kParamMethodBilinear );
	method->setDefault( 1 );
	method->setHint( "Interpolation method" );

	OFX::ChoiceParamDescriptor* interpolation = desc.defineChoiceParam( kParamInterpolation );
	interpolation->setLabel( "Interpolation" );
	interpolation->appendOption( kParamInterpolationNearest );
	interpolation->appendOption( kParamInterpolationBilinear );
	interpolation->setDefault( 1 );
	interpolation->setHint( "Interpolation method" );

        OFX::PushButtonParamDescriptor* setToCornersIn = desc.definePushButtonParam( kParamSetToCornersIn);
        setToCornersIn->setLabel( "Set In" );
        setToCornersIn->setHint("Set to corners in points");

        OFX::PushButtonParamDescriptor* setToCornersOut = desc.definePushButtonParam( kParamSetToCornersOut);
        setToCornersOut->setLabel( "Set Out" );
        setToCornersOut->setHint("Set to corners out points");

	OFX::BooleanParamDescriptor* overlay = desc.defineBooleanParam( kParamOverlay );
	overlay->setLabel( "Overlay" );
	overlay->setDefault( true );

        OFX::BooleanParamDescriptor* inverse = desc.defineBooleanParam( kParamInverse );
        inverse->setLabel( "Inverse" );
        inverse->setDefault( false );
/*
        //TODO-vince///////////
        //////////////////// Transform Centre Point ////////////////////
        OFX::GroupParamDescriptor* groupCentre = desc.defineGroupParam( kParamGroupCentre );
        groupCentre->setLabel( "Centre point" );
        groupCentre->setOpen(false);

        OFX::ChoiceParamDescriptor* manipulatorMode = desc.defineChoiceParam( kParamManipulatorMode );
        manipulatorMode->appendOption( kParamManipulatorModeTranslate );
        manipulatorMode->appendOption( kParamManipulatorModeRotate );
        manipulatorMode->appendOption( kParamManipulatorModeScale );

        OFX::Double2DParamDescriptor* pCentre = desc.defineDouble2DParam( kParamPointCentre);
        pCentre->setLabel( "Centre point" );
        pCentre->setHint( "Transform Centre point" );
        pCentre->setDefault( 0.0, 0.0 );
        pCentre->setParent( groupCentre );

        OFX::BooleanParamDescriptor* overlayCentre = desc.defineBooleanParam( kParamOverlayCentre );
        overlayCentre->setLabel( "Overlay" );
        overlayCentre->setDefault( true );
        overlayCentre->setParent( groupCentre );

        OFX::RGBParamDescriptor* ouverlayCentreColor = desc.defineRGBParam( kParamOverlayCentreColor );
        ouverlayCentreColor->setLabel( "Color" );
        ouverlayCentreColor->setHint( "Centre point overlay color" );
        ouverlayCentreColor->setDefault( 0.0, 1.0, 0.0 );
        ouverlayCentreColor->setParent( groupCentre );
*/
	//////////////////// IN Points ////////////////////
	OFX::GroupParamDescriptor* groupIn = desc.defineGroupParam( kParamGroupIn );
	groupIn->setLabel( "Input points" );
        groupIn->setOpen(false);

	OFX::Double2DParamDescriptor* pIn0 = desc.defineDouble2DParam( kParamPointIn + "0" );
	pIn0->setLabel( "In 0" );
	pIn0->setHint( "Input point 0" );
        pIn0->setDefault( -0.5, -0.5 );
        pIn0->setParent( groupIn );

	OFX::Double2DParamDescriptor* pIn1 = desc.defineDouble2DParam( kParamPointIn + "1" );
	pIn1->setLabel( "In 1" );
	pIn1->setHint( "Input point 1" );
	pIn1->setDefault( 0.5, -0.5 );
	pIn1->setParent( groupIn );

	OFX::Double2DParamDescriptor* pIn2 = desc.defineDouble2DParam( kParamPointIn + "2" );
	pIn2->setLabel( "In 2" );
	pIn2->setHint( "Input point 2" );
	pIn2->setDefault( -0.5, 0.5 );
	pIn2->setParent( groupIn );

	OFX::Double2DParamDescriptor* pIn3 = desc.defineDouble2DParam( kParamPointIn + "3" );
	pIn3->setLabel( "In 3" );
	pIn3->setHint( "Input point 3" );
	pIn3->setDefault( 0.5, 0.5 );
	pIn3->setParent( groupIn );

	OFX::BooleanParamDescriptor* overlayIn = desc.defineBooleanParam( kParamOverlayIn );
	overlayIn->setLabel( "Overlay" );
	overlayIn->setDefault( true );
	overlayIn->setParent( groupIn );

	OFX::RGBParamDescriptor* ouverlayInColor = desc.defineRGBParam( kParamOverlayInColor );
	ouverlayInColor->setLabel( "Color" );
	ouverlayInColor->setHint( "Input point overlay color" );
	ouverlayInColor->setDefault( 1.0, 0.0, 0.0 );
	ouverlayInColor->setParent( groupIn );

	//////////////////// OUT Points ////////////////////
	OFX::GroupParamDescriptor* groupOut = desc.defineGroupParam( kParamGroupOut );
	groupOut->setLabel( "Output points" );
        groupOut->setOpen(false);

	OFX::Double2DParamDescriptor* pOut0 = desc.defineDouble2DParam( kParamPointOut + "0" );
	pOut0->setLabel( "Out 0" );
	pOut0->setHint( "Output point 0" );
	pOut0->setDefault( -0.5, -0.5 );
	pOut0->setParent( groupOut );

	OFX::Double2DParamDescriptor* pOut1 = desc.defineDouble2DParam( kParamPointOut + "1" );
	pOut1->setLabel( "Out 1" );
	pOut1->setHint( "Output point 1" );
	pOut1->setDefault( 0.5, -0.5 );
	pOut1->setParent( groupOut );

	OFX::Double2DParamDescriptor* pOut2 = desc.defineDouble2DParam( kParamPointOut + "2" );
	pOut2->setLabel( "Out 2" );
	pOut2->setHint( "Output point 2" );
	pOut2->setDefault( -0.5, 0.5 );
	pOut2->setParent( groupOut );

	OFX::Double2DParamDescriptor* pOut3 = desc.defineDouble2DParam( kParamPointOut + "3" );
	pOut3->setLabel( "Out 3" );
	pOut3->setHint( "Output point 3" );
	pOut3->setDefault( 0.5, 0.5 );
	pOut3->setParent( groupOut );

	OFX::BooleanParamDescriptor* overlayOut = desc.defineBooleanParam( kParamOverlayOut );
	overlayOut->setLabel( "Overlay" );
	overlayOut->setDefault( true );
	overlayOut->setParent( groupOut );

	OFX::RGBParamDescriptor* ouverlayOutColor = desc.defineRGBParam( kParamOverlayOutColor );
	ouverlayOutColor->setLabel( "Color" );
	ouverlayOutColor->setHint( "Output point overlay color" );
	ouverlayOutColor->setDefault( 0.0, 0.0, 1.0 );
	ouverlayOutColor->setParent( groupOut );

	//////////////////// Persp Matrix ////////////////////
	OFX::GroupParamDescriptor* groupPerspMatrix = desc.defineGroupParam( kParamGroupPerspMatrix );
	groupPerspMatrix->setLabel( "Perspective matrix" );
	groupPerspMatrix->setHint( "Transformation matrix" );

	OFX::Double3DParamDescriptor* perspMatrixRow0 = desc.defineDouble3DParam( kParamPerspMatrixRow + "0" );
	perspMatrixRow0->setLabel( "row 0" );
	perspMatrixRow0->setDefault( 1.0, 0.0, 0.0 );
	perspMatrixRow0->setParent( groupPerspMatrix );

	OFX::Double3DParamDescriptor* perspMatrixRow1 = desc.defineDouble3DParam( kParamPerspMatrixRow + "1" );
	perspMatrixRow1->setLabel( "row 1" );
	perspMatrixRow1->setDefault( 0.0, 1.0, 0.0 );
	perspMatrixRow1->setParent( groupPerspMatrix );

	OFX::Double3DParamDescriptor* perspMatrixRow2 = desc.defineDouble3DParam( kParamPerspMatrixRow + "2" );
	perspMatrixRow2->setLabel( "row 2" );
	perspMatrixRow2->setDefault( 0.0, 0.0, 1.0 );
	perspMatrixRow2->setParent( groupPerspMatrix );

	////////////////// Bilinear Matrix ////////////////////
	OFX::GroupParamDescriptor* groupBilMatrix = desc.defineGroupParam( kParamGroupBilinearMatrix );
	groupBilMatrix->setLabel( "Bilinear matrix" );
	groupBilMatrix->setHint( "Billinear transformation matrix" );

	OFX::Double2DParamDescriptor* bilMatrixRow0 = desc.defineDouble2DParam( kParamBilinearMatrixRow + "0" );
	bilMatrixRow0->setLabel( "row 0" );
	bilMatrixRow0->setDefault( 1.0, 0.0 );
	bilMatrixRow0->setParent( groupBilMatrix );

	OFX::Double2DParamDescriptor* bilMatrixRow1 = desc.defineDouble2DParam( kParamBilinearMatrixRow + "1" );
	bilMatrixRow1->setLabel( "row 1" );
	bilMatrixRow1->setDefault( 0.0, 1.0 );
	bilMatrixRow1->setParent( groupBilMatrix );

	OFX::Double2DParamDescriptor* bilMatrixRow2 = desc.defineDouble2DParam( kParamBilinearMatrixRow + "2" );
	bilMatrixRow2->setLabel( "row 2" );
	bilMatrixRow2->setDefault( 0.0, 0.0 );
	bilMatrixRow2->setParent( groupBilMatrix );

	OFX::Double2DParamDescriptor* bilMatrixRow3 = desc.defineDouble2DParam( kParamBilinearMatrixRow + "3" );
	bilMatrixRow3->setLabel( "row 3" );
	bilMatrixRow3->setDefault( 0.0, 0.0 );
	bilMatrixRow3->setParent( groupBilMatrix );

}
/**
 * @brief Function called to describe the plugin controls and features.
 * @param[in, out]   desc       Effect descriptor
 * @param[in]        context    Application context
 */
void PinningPluginFactory::describeInContext( OFX::ImageEffectDescriptor& desc,
                                                  OFX::EContext context )
{

	OFX::ClipDescriptor* srcClip = desc.defineClip( kOfxImageEffectSimpleSourceClipName ); // clip de source nomme source
	//OFX::ClipDescriptor* toto = desc.defineClip( "toto" );
	srcClip->addSupportedComponent( OFX::ePixelComponentRGBA );	//proprietes de la source
	srcClip->addSupportedComponent( OFX::ePixelComponentAlpha );
	srcClip->setSupportsTiles( kSupportTiles );

	// Create the mandated output clip
	OFX::ClipDescriptor* dstClip = desc.defineClip( kOfxImageEffectOutputClipName ); 	//sortie, laisser comme ca et pi c'est tout
	dstClip->addSupportedComponent( OFX::ePixelComponentRGBA );
	dstClip->addSupportedComponent( OFX::ePixelComponentAlpha );
	dstClip->setSupportsTiles( kSupportTiles );

	OFX::GroupParamDescriptor* grpSrc = desc.defineGroupParam( kParamGroupSource );	//groupe source
	grpSrc->setLabel( "Points de départ" );
	grpSrc->setHint( "Selectionnez 4 points de départ" );

	OFX::Double2DParamDescriptor* src0 = desc.defineDouble2DParam( kParamPointSource + "0" );	//kpa... nom utilisé par le plug
	src0->setLabel( "src0" );	//nom que voit l'utilisateur	
	src0->setDefault( 0, 0 );
	src0->setParent(grpSrc);
	OFX::Double2DParamDescriptor* src1 = desc.defineDouble2DParam( kParamPointSource + "1" );
	src1->setLabel( "src1" );
	src1->setDefault( 0, 1 );
	src1->setParent(grpSrc);
	OFX::Double2DParamDescriptor* src2 = desc.defineDouble2DParam( kParamPointSource + "2" );
	src2->setLabel( "src2" );
	src2->setDefault( 1, 1 );
	src2->setParent(grpSrc);
	OFX::Double2DParamDescriptor* src3 = desc.defineDouble2DParam( kParamPointSource + "3" );
	src3->setLabel( "src3" );
	src3->setDefault( 1, 0 );
	src3->setParent(grpSrc);
	
	OFX::GroupParamDescriptor* grpDst = desc.defineGroupParam( kParamGroupDestination );	//groupe destination
	grpDst->setLabel( "Points d'arrivée" );
	grpDst->setHint( "Selectionnez 4 points d'arrivée" );

	OFX::Double2DParamDescriptor* dest0 = desc.defineDouble2DParam( kParamPointDestination + "0" );	//kpa... nom utilisé par le plug
	dest0->setLabel( "dst0" );	//nom que voit l'utilisateur	
	dest0->setDefault( 0, 0 );
	dest0->setParent(grpDst);
	OFX::Double2DParamDescriptor* dest1 = desc.defineDouble2DParam( kParamPointDestination + "1" );
	dest1->setLabel( "dst1" );
	dest1->setDefault( 0, 1 );
	dest1->setParent(grpDst);
	OFX::Double2DParamDescriptor* dest2 = desc.defineDouble2DParam( kParamPointDestination + "2" );
	dest2->setLabel( "dst2" );
	dest2->setDefault( 1, 1 );
	dest2->setParent(grpDst);
	OFX::Double2DParamDescriptor* dest3 = desc.defineDouble2DParam( kParamPointDestination + "3" );
	dest3->setLabel( "dst3" );
	dest3->setDefault( 1, 0 );
	dest3->setParent(grpDst);
	
	OFX::PushButtonParamDescriptor* helpButton = desc.definePushButtonParam( kParamHelpButton );	//cree un bouton help
	//helpButton->setHint( "bla bla" );
	helpButton->setLabel( "Help" );

	OFX::GroupParamDescriptor* displayOptions = desc.defineGroupParam( kParamDisplayOptions );
	displayOptions->setLabel( "Options d'affichage" );
	displayOptions->setHint( "Options d'affichage (Ne change rien sur l'image)" );

	OFX::BooleanParamDescriptor* displayGrid = desc.defineBooleanParam( kParamGridOverlay );
	displayGrid->setLabel( "Afficher la grille" );
	displayGrid->setParent( *displayOptions );
	displayGrid->setDefault( false );
	displayGrid->setEvaluateOnChange( false );
	displayGrid->setHint( "Afficher la grille" );

	OFX::Double2DParamDescriptor* gridCenter = desc.defineDouble2DParam( kParamGridCenter );
	gridCenter->setLabel( "Centre de la grille" );
	gridCenter->setDoubleType( OFX::eDoubleTypePlain );
	gridCenter->setParent( *displayOptions );
	gridCenter->setDefault( 0.0, 0.0 );
	gridCenter->setDisplayRange( -1.0, -1.0, 1.0, 1.0 );
	gridCenter->setEvaluateOnChange( false );
	gridCenter->setHint( "Allows you to shift the center of the  display grid." );

	OFX::Double2DParamDescriptor* center = desc.defineDouble2DParam( kParamCenter );
	center->setLabel( "Center" );
	center->setDoubleType( OFX::eDoubleTypePlain );
	center->setDefault( 0.0, 0.0 );
	center->setDisplayRange( -1.0, -1.0, 1.0, 1.0 );
	center->setHint( "Center parameter allows you to shift the center of distortion." );


	OFX::Double2DParamDescriptor* gridScale = desc.defineDouble2DParam( kParamGridScale );
	gridScale->setLabel( "Echelle de la grille" );
	gridScale->setDoubleType( OFX::eDoubleTypePlain );
	gridScale->setParent( *displayOptions );
	gridScale->setDefault( 1.0, 1.0 );
	gridScale->setDisplayRange( -10.0, -10.0, 10.0, 10.0 );
	gridScale->setEvaluateOnChange( false );
	gridScale->setHint( "Allows you to scale the display grid." );

																				//kParamhelpButton : appelle un pluging
	//OFX::PushButtonParamDescriptor* poussoir = desc.definePushButtonParam( kParamPoussoir );	//cree un bouton help
	//poussoir->setLabel( "poussoir" );
}