/** * @brief Function called to describe the plugin controls and features. * @param[in, out] desc Effect descriptor * @param[in] context Application context */ void OpenImageIOWriterPluginFactory::describeInContext( OFX::ImageEffectDescriptor& desc, OFX::EContext context ) { OFX::ClipDescriptor* srcClip = desc.defineClip( kOfxImageEffectSimpleSourceClipName ); srcClip->addSupportedComponent( OFX::ePixelComponentRGBA ); srcClip->addSupportedComponent( OFX::ePixelComponentRGB ); srcClip->addSupportedComponent( OFX::ePixelComponentAlpha ); srcClip->setSupportsTiles( kSupportTiles ); OFX::ClipDescriptor* dstClip = desc.defineClip( kOfxImageEffectOutputClipName ); dstClip->addSupportedComponent( OFX::ePixelComponentRGBA ); dstClip->addSupportedComponent( OFX::ePixelComponentRGB ); dstClip->addSupportedComponent( OFX::ePixelComponentAlpha ); dstClip->setSupportsTiles( kSupportTiles ); // Controls OFX::StringParamDescriptor* filename = desc.defineStringParam( kParamWriterFilename ); filename->setLabel( "Filename" ); filename->setStringType( OFX::eStringTypeFilePath ); filename->setCacheInvalidation( OFX::eCacheInvalidateValueAll ); desc.addClipPreferencesSlaveParam( *filename ); OFX::ChoiceParamDescriptor* components = desc.defineChoiceParam( kParamOutputComponents ); components->setLabel( "Components" ); components->appendOption( kParamOutputComponentsRGBA ); components->appendOption( kParamOutputComponentsRGB ); components->setCacheInvalidation( OFX::eCacheInvalidateValueAll ); components->setDefault( 0 ); OFX::ChoiceParamDescriptor* bitDepth = desc.defineChoiceParam( kParamWriterBitDepth ); bitDepth->setLabel( "Bit depth" ); bitDepth->appendOption( kTuttlePluginBitDepth8 ); bitDepth->appendOption( kTuttlePluginBitDepth16 ); bitDepth->appendOption( kTuttlePluginBitDepth32f ); bitDepth->setCacheInvalidation( OFX::eCacheInvalidateValueAll ); bitDepth->setDefault( 1 ); OFX::PushButtonParamDescriptor* render = desc.definePushButtonParam( kParamWriterRender ); render->setLabels( "Render", "Render", "Render step" ); render->setHint( "Force render (writing)" ); OFX::BooleanParamDescriptor* renderAlways = desc.defineBooleanParam( kParamWriterRenderAlways ); renderAlways->setLabel( "Render always" ); renderAlways->setCacheInvalidation( OFX::eCacheInvalidateValueAll ); renderAlways->setDefault( false ); OFX::IntParamDescriptor* forceNewRender = desc.defineIntParam( kParamWriterForceNewRender ); forceNewRender->setLabel( "Force new render" ); forceNewRender->setIsSecret( true ); forceNewRender->setIsPersistant( false ); forceNewRender->setAnimates( false ); forceNewRender->setCacheInvalidation( OFX::eCacheInvalidateValueAll ); forceNewRender->setEvaluateOnChange( true ); forceNewRender->setDefault( 0 ); }
void describeWriterParamsInContext( OFX::ImageEffectDescriptor& desc, OFX::EContext context ) { OFX::StringParamDescriptor* filename = desc.defineStringParam( kTuttlePluginFilename ); filename->setLabel( kTuttlePluginFilenameLabel ); filename->setStringType( OFX::eStringTypeFilePath ); filename->setCacheInvalidation( OFX::eCacheInvalidateValueAll ); desc.addClipPreferencesSlaveParam( *filename ); OFX::ChoiceParamDescriptor* channel = desc.defineChoiceParam( kTuttlePluginChannel ); channel->setLabel( kTuttlePluginChannelLabel ); channel->appendOption( kTuttlePluginChannelAuto ); channel->appendOption( kTuttlePluginChannelGray ); channel->appendOption( kTuttlePluginChannelRGB ); channel->appendOption( kTuttlePluginChannelRGBA ); channel->setDefault( 0 ); OFX::ChoiceParamDescriptor* bitDepth = desc.defineChoiceParam( kTuttlePluginBitDepth ); bitDepth->setLabel( kTuttlePluginBitDepthLabel ); bitDepth->appendOption( kTuttlePluginBitDepth8 ); bitDepth->appendOption( kTuttlePluginBitDepth16 ); bitDepth->setDefault( 0 ); OFX::BooleanParamDescriptor* premult = desc.defineBooleanParam( kParamPremultiplied ); premult->setLabel( kParamPremultipliedLabel ); premult->setDefault( false ); OFX::PushButtonParamDescriptor* render = desc.definePushButtonParam( kParamWriterRender ); render->setLabels( "Render", "Render", "Render step" ); render->setHint("Force render (writing)"); OFX::BooleanParamDescriptor* renderAlways = desc.defineBooleanParam( kParamWriterRenderAlways ); renderAlways->setLabel( "Render always" ); // renderAlways->setDefault( false ); renderAlways->setDefault( true ); // because tuttle is not declared as a background renderer OFX::IntParamDescriptor* forceNewRender = desc.defineIntParam( kParamWriterForceNewRender ); forceNewRender->setLabel( "Force new render" ); forceNewRender->setEnabled( false ); forceNewRender->setIsSecret( true ); forceNewRender->setIsPersistant( false ); forceNewRender->setAnimates( false ); forceNewRender->setCacheInvalidation( OFX::eCacheInvalidateValueAll ); forceNewRender->setEvaluateOnChange( true ); forceNewRender->setDefault( 0 ); }
void describeWriterParamsInContext( OFX::ImageEffectDescriptor& desc, OFX::EContext context ) { OFX::StringParamDescriptor* filename = desc.defineStringParam( kTuttlePluginFilename ); filename->setLabel( kTuttlePluginFilenameLabel ); filename->setStringType( OFX::eStringTypeFilePath ); filename->setCacheInvalidation( OFX::eCacheInvalidateValueAll ); // the file doesn't need to exist, the writer will create it! filename->setFilePathExists(false); desc.addClipPreferencesSlaveParam( *filename ); OFX::ChoiceParamDescriptor* channel = desc.defineChoiceParam( kTuttlePluginChannel ); channel->setLabel( kTuttlePluginChannelLabel ); channel->appendOption( kTuttlePluginChannelAuto ); channel->appendOption( kTuttlePluginChannelGray ); channel->appendOption( kTuttlePluginChannelRGB ); channel->appendOption( kTuttlePluginChannelRGBA ); channel->setDefault( 0 ); OFX::ChoiceParamDescriptor* bitDepth = desc.defineChoiceParam( kTuttlePluginBitDepth ); bitDepth->setLabel( kTuttlePluginBitDepthLabel ); bitDepth->appendOption( kTuttlePluginBitDepth8 ); bitDepth->appendOption( kTuttlePluginBitDepth16 ); bitDepth->setDefault( 0 ); OFX::BooleanParamDescriptor* premult = desc.defineBooleanParam( kParamPremultiplied ); premult->setLabel( "Premultiplied" ); premult->setDefault( false ); OFX::ChoiceParamDescriptor* existingFile = desc.defineChoiceParam( kParamWriterExistingFile ); existingFile->setLabel( "Existing File" ); existingFile->appendOption( kParamWriterExistingFile_overwrite ); existingFile->appendOption( kParamWriterExistingFile_error ); if( OFX::getImageEffectHostDescription()->hostName == "TuttleOfx" ) { // Only Tuttle is able to do that, because we disable the computation // using the IsIdentity Action. This is not in the OpenFX standard. existingFile->appendOption( kParamWriterExistingFile_skip ); } //existingFile->appendOption( kParamWriterExistingFile_reader ); // TODO: not implemented yet. existingFile->setDefault( eParamWriterExistingFile_overwrite ); OFX::BooleanParamDescriptor* copyToOutput = desc.defineBooleanParam( kParamWriterCopyToOutput ); copyToOutput->setLabel( "Copy buffer to output" ); copyToOutput->setHint( "This is only useful if you connect nodes to the output clip of the writer." ); copyToOutput->setDefault( false ); OFX::PushButtonParamDescriptor* render = desc.definePushButtonParam( kParamWriterRender ); render->setLabels( "Render", "Render", "Render step" ); render->setHint("Force render (writing)"); OFX::BooleanParamDescriptor* renderAlways = desc.defineBooleanParam( kParamWriterRenderAlways ); renderAlways->setLabel( "Render always" ); renderAlways->setHint( "This is only useful as a workaround for GUI applications." ); renderAlways->setDefault( true ); // because tuttle is not declared as a background renderer OFX::IntParamDescriptor* forceNewRender = desc.defineIntParam( kParamWriterForceNewRender ); forceNewRender->setLabel( "Force new render" ); forceNewRender->setHint( "This is only useful as a workaround for GUI applications." ); forceNewRender->setEnabled( false ); forceNewRender->setIsSecret( true ); forceNewRender->setIsPersistant( false ); forceNewRender->setAnimates( false ); forceNewRender->setCacheInvalidation( OFX::eCacheInvalidateValueAll ); forceNewRender->setEvaluateOnChange( true ); forceNewRender->setDefault( 0 ); }
void LensCalibrationPluginFactory::describeInContext(OFX::ImageEffectDescriptor& desc, OFX::ContextEnum context) { //Input Clip OFX::ClipDescriptor *srcClip = desc.defineClip(kOfxImageEffectSimpleSourceClipName); srcClip->addSupportedComponent(OFX::ePixelComponentRGBA); srcClip->setTemporalClipAccess(false); srcClip->setSupportsTiles(false); srcClip->setIsMask(false); srcClip->setOptional(false); //Output clip OFX::ClipDescriptor *dstClip = desc.defineClip(kOfxImageEffectOutputClipName); dstClip->addSupportedComponent(OFX::ePixelComponentRGBA); dstClip->setSupportsTiles(false); //Calibration Group { OFX::GroupParamDescriptor *groupCalibration = desc.defineGroupParam(kParamGroupCalibration); groupCalibration->setLabel("Calibration"); groupCalibration->setAsTab(); { OFX::Int2DParamDescriptor *param = desc.defineInt2DParam(kParamImageSize); param->setLabel("Image Size"); param->setHint("Input image size used to calibrate the optics. Obviously, all images should have the same size."); param->setDefault(0, 0); param->setDisplayRange(0, 0, 10000, 10000); param->setAnimates(false); param->setParent(*groupCalibration); param->setEnabled(false); // should not be edited by the user } { OFX::BooleanParamDescriptor *param = desc.defineBooleanParam(kParamInputImageIsGray); param->setLabel("Input image is gray"); param->setHint("Input image is gray"); param->setParent(*groupCalibration); } { OFX::ChoiceParamDescriptor *param = desc.defineChoiceParam(kParamPatternType); param->setLabel("Pattern Type"); param->setHint("Type of pattern to detect"); param->appendOptions(kStringParamPatternType); param->setDefault(eParamPatternTypeChessboard); param->setAnimates(false); param->setParent(*groupCalibration); } { OFX::Int2DParamDescriptor *param = desc.defineInt2DParam(kParamPatternSize); param->setLabel("Pattern Size"); param->setHint("Number of inner corners per one of board dimension Width Height"); param->setDefault(10, 7); param->setRange(2, 2, kOfxFlagInfiniteMax, kOfxFlagInfiniteMax); param->setDisplayRange(2, 2, 15, 15); param->setAnimates(false); param->setParent(*groupCalibration); } { OFX::DoubleParamDescriptor *param = desc.defineDoubleParam(kParamSquareSize); param->setLabel("Square Size"); param->setHint("Define the size of the grid's square cells (mm)"); param->setDisplayRange(0, 100); param->setDefault(1); param->setAnimates(false); param->setParent(*groupCalibration); param->setLayoutHint(OFX::eLayoutHintDivider); } { OFX::IntParamDescriptor *param = desc.defineIntParam(kParamNbRadialCoef); param->setLabel("Nb Radial Coef"); param->setHint("Number of radial coefficient."); param->setRange(0, 6); param->setDisplayRange(0, 6); param->setDefault(3); param->setAnimates(false); param->setParent(*groupCalibration); } { OFX::IntParamDescriptor *param = desc.defineIntParam(kParamMaxFrames); param->setLabel("Max Frames"); param->setHint("Maximal number of frames to extract from the video file."); param->setRange(0, kOfxFlagInfiniteMax); param->setDisplayRange(0, 1000); param->setDefault(0); param->setAnimates(false); param->setParent(*groupCalibration); } { OFX::IntParamDescriptor *param = desc.defineIntParam(kParamMaxCalibFrames); param->setLabel("Max Calibration Frames"); param->setHint("Maximal number of frames to use to calibrate from the selected frames."); param->setRange(0, kOfxFlagInfiniteMax); param->setDisplayRange(0, 1000); param->setDefault(100); param->setAnimates(false); param->setParent(*groupCalibration); } { OFX::IntParamDescriptor *param = desc.defineIntParam(kParamCalibGridSize); param->setLabel("Max Calibration Grid Size"); param->setHint("Define the number of cells per edge."); param->setRange(0, kOfxFlagInfiniteMax); param->setDisplayRange(0, 100); param->setDefault(10); param->setAnimates(false); param->setParent(*groupCalibration); } { OFX::IntParamDescriptor *param = desc.defineIntParam(kParamMinInputFrames); param->setLabel("Min Input Frames"); param->setHint("Minimal number of frames to limit the calibration refinement loop."); param->setRange(0, kOfxFlagInfiniteMax); param->setDisplayRange(0, 1000); param->setDefault(10); param->setAnimates(false); param->setParent(*groupCalibration); } { OFX::DoubleParamDescriptor *param = desc.defineDoubleParam(kParamMaxTotalAvgErr); param->setLabel("Max Total Average Error"); param->setHint("Maximal limit of the total average error"); param->setRange(0, 1); param->setDisplayRange(0, 1); param->setDefault(0.1); param->setAnimates(false); param->setParent(*groupCalibration); } { OFX::PushButtonParamDescriptor *param = desc.definePushButtonParam(kParamCalibrate); param->setLabel("Calibrate"); param->setHint("calibrate"); param->setParent(*groupCalibration); } } //Output Group { OFX::GroupParamDescriptor *groupOutput = desc.defineGroupParam(kParamGroupOutput); groupOutput->setLabel("Output"); groupOutput->setAsTab(); { OFX::BooleanParamDescriptor *param = desc.defineBooleanParam(kParamOutputIsCalibrated); param->setLabel("Is calibrated"); param->setHint("Is calibrated"); param->setParent(*groupOutput); } { OFX::DoubleParamDescriptor *param = desc.defineDoubleParam(kParamOutputAvgReprojErr); param->setLabel("Average Reprojection Error"); param->setDisplayRange(0, 10); param->setEvaluateOnChange(false); param->setEnabled(false); param->setAnimates(true); param->setParent(*groupOutput); param->setLayoutHint(OFX::eLayoutHintDivider); } { OFX::GroupParamDescriptor *groupCamera = desc.defineGroupParam(kParamOutputCameraGroup); groupCamera->setLabel("Intrinsics Camera Parameters"); groupCamera->setParent(*groupOutput); groupCamera->setOpen(true); { OFX::DoubleParamDescriptor *param = desc.defineDoubleParam(kParamOutputFocalLenght); param->setLabel("Focal Length"); param->setDisplayRange(1, 100); param->setAnimates(true); param->setEvaluateOnChange(false); param->setEnabled(false); param->setAnimates(false); param->setParent(*groupCamera); } { OFX::Double2DParamDescriptor *param = desc.defineDouble2DParam(kParamOutputPrincipalPointOffset); param->setLabel("Principal Point"); param->setAnimates(true); param->setEvaluateOnChange(false); param->setEnabled(false); param->setAnimates(false); param->setParent(*groupCamera); } } { OFX::GroupParamDescriptor *groupLensDistortion = desc.defineGroupParam(kParamOutputLensDistortionGroup); groupLensDistortion->setLabel("Lens Distortion Coefficients"); groupLensDistortion->setParent(*groupOutput); groupLensDistortion->setOpen(true); { OFX::DoubleParamDescriptor *param = desc.defineDoubleParam(kParamOutputRadialCoef1); param->setLabel("Radial Coef1"); param->setDisplayRange(0, 10); param->setAnimates(true); param->setEvaluateOnChange(false); param->setEnabled(false); param->setAnimates(false); param->setParent(*groupLensDistortion); } { OFX::DoubleParamDescriptor *param = desc.defineDoubleParam(kParamOutputRadialCoef2); param->setLabel("Radial Coef2"); param->setDisplayRange(0, 10); param->setAnimates(true); param->setEvaluateOnChange(false); param->setEnabled(false); param->setAnimates(false); param->setParent(*groupLensDistortion); } { OFX::DoubleParamDescriptor *param = desc.defineDoubleParam(kParamOutputRadialCoef3); param->setLabel("Radial Coef3"); param->setDisplayRange(0, 10); param->setAnimates(true); param->setEvaluateOnChange(false); param->setEnabled(false); param->setAnimates(false); param->setParent(*groupLensDistortion); } { OFX::DoubleParamDescriptor *param = desc.defineDoubleParam(kParamOutputTangentialCoef1); param->setLabel("Tangential Coef1"); param->setDisplayRange(0, 10); param->setAnimates(true); param->setEvaluateOnChange(false); param->setEnabled(false); param->setAnimates(false); param->setParent(*groupLensDistortion); } { OFX::DoubleParamDescriptor *param = desc.defineDoubleParam(kParamOutputTangentialCoef2); param->setLabel("Tangential Coef2"); param->setDisplayRange(0, 10); param->setAnimates(true); param->setEvaluateOnChange(false); param->setEnabled(false); param->setAnimates(false); param->setParent(*groupLensDistortion); param->setLayoutHint(OFX::eLayoutHintDivider); } } { OFX::PushButtonParamDescriptor *param = desc.definePushButtonParam(kParamOutputClear); param->setLabel("Clear"); param->setHint("clear"); param->setEnabled(false); param->setParent(*groupOutput); } } //Debug Group { OFX::GroupParamDescriptor *groupDebug = desc.defineGroupParam(kParamGroupDebug); groupDebug->setLabel("Debug"); groupDebug->setAsTab(); { OFX::BooleanParamDescriptor *param = desc.defineBooleanParam(kParamDebugEnable); param->setLabel("Enable Debug"); param->setHint("Would you want to export undistorted images?"); param->setParent(*groupDebug); } { OFX::StringParamDescriptor *param = desc.defineStringParam(kParamDebugRejectedImgFolder); param->setLabel("Rejected Frames"); param->setHint("Folder to export delete images during the calibration refinement loop."); param->setStringType(OFX::eStringTypeDirectoryPath); param->setFilePathExists(true); param->setParent(*groupDebug); } { OFX::StringParamDescriptor *param = desc.defineStringParam(kParamDebugSelectedImgFolder); param->setLabel("Selected Frames"); param->setHint("Folder to export debug images."); param->setStringType(OFX::eStringTypeDirectoryPath); param->setFilePathExists(true); param->setParent(*groupDebug); } } }
/** * @brief Override this to describe in context the writer. * You should call the base-class version at the end like this: * GenericWriterPluginFactory<YOUR_FACTORY>::describeInContext(desc,context); **/ PageParamDescriptor* GenericWriterDescribeInContextBegin(OFX::ImageEffectDescriptor &desc, OFX::ContextEnum context, bool isVideoStreamPlugin, bool supportsRGBA, bool supportsRGB, bool supportsAlpha, const char* inputSpaceNameDefault, const char* outputSpaceNameDefault) { // create the mandated source clip ClipDescriptor *srcClip = desc.defineClip(kOfxImageEffectSimpleSourceClipName); if (supportsRGBA) { srcClip->addSupportedComponent(ePixelComponentRGBA); } if (supportsRGB) { srcClip->addSupportedComponent(ePixelComponentRGB); } if (supportsAlpha) { srcClip->addSupportedComponent(ePixelComponentAlpha); } srcClip->setSupportsTiles(false); // create the mandated output clip ClipDescriptor *dstClip = desc.defineClip(kOfxImageEffectOutputClipName); if (supportsRGBA) { dstClip->addSupportedComponent(ePixelComponentRGBA); } if (supportsRGB) { dstClip->addSupportedComponent(ePixelComponentRGB); } if (supportsAlpha) { dstClip->addSupportedComponent(ePixelComponentAlpha); } dstClip->setSupportsTiles(false);//< we don't support tiles in output! // make some pages and to things in PageParamDescriptor *page = desc.definePageParam("Controls"); //////////Output file OFX::StringParamDescriptor* fileParam = desc.defineStringParam(kWriterFileParamName); fileParam->setLabels(kWriterFileParamLabel, kWriterFileParamLabel, kWriterFileParamLabel); fileParam->setStringType(OFX::eStringTypeFilePath); fileParam->setFilePathExists(false); fileParam->setHint(kWriterFileParamHint); // in the Writer context, the script name should be "filename", for consistency with the reader nodes @see kOfxImageEffectContextReader fileParam->setScriptName(kWriterFileParamName); fileParam->setAnimates(!isVideoStreamPlugin); desc.addClipPreferencesSlaveParam(*fileParam); page->addChild(*fileParam); // insert OCIO parameters GenericOCIO::describeInContext(desc, context, page, inputSpaceNameDefault, outputSpaceNameDefault); ///////////Frame range choosal OFX::ChoiceParamDescriptor* frameRangeChoiceParam = desc.defineChoiceParam(kWriterFrameRangeChoiceParamName); frameRangeChoiceParam->setLabels(kWriterFrameRangeChoiceParamLabel, kWriterFrameRangeChoiceParamLabel, kWriterFrameRangeChoiceParamLabel); frameRangeChoiceParam->setHint(kWriterFrameRangeChoiceParamHint); frameRangeChoiceParam->appendOption(kWriterFrameRangeChoiceParamOptionUnion, kWriterFrameRangeChoiceParamOptionUnionHint); frameRangeChoiceParam->appendOption(kWriterFrameRangeChoiceParamOptionBounds, kWriterFrameRangeChoiceParamOptionBoundsHint); frameRangeChoiceParam->appendOption(kWriterFrameRangeChoiceParamOptionManual, kWriterFrameRangeChoiceParamOptionManualHint); frameRangeChoiceParam->setAnimates(true); frameRangeChoiceParam->setDefault(0); page->addChild(*frameRangeChoiceParam); /////////////First frame OFX::IntParamDescriptor* firstFrameParam = desc.defineIntParam(kWriterFirstFrameParamName); firstFrameParam->setLabels(kWriterFirstFrameParamLabel, kWriterFirstFrameParamLabel, kWriterFirstFrameParamLabel); firstFrameParam->setIsSecret(true); firstFrameParam->setAnimates(true); page->addChild(*firstFrameParam); ////////////Last frame OFX::IntParamDescriptor* lastFrameParam = desc.defineIntParam(kWriterLastFrameParamName); lastFrameParam->setLabels(kWriterLastFrameParamLabel, kWriterLastFrameParamLabel, kWriterLastFrameParamLabel); lastFrameParam->setIsSecret(true); lastFrameParam->setAnimates(true); page->addChild(*lastFrameParam); return page; }