diff --git a/ContactSheet/ContactSheet.cpp b/ContactSheet/ContactSheet.cpp index 0d17cc4e9..cf59aa227 100644 --- a/ContactSheet/ContactSheet.cpp +++ b/ContactSheet/ContactSheet.cpp @@ -294,9 +294,8 @@ ContactSheetPlugin::render(const OFX::RenderArguments &args) throwSuiteStatusException(kOfxStatFailed); } BitDepthEnum dstBitDepth = dst->getPixelDepth(); - PixelComponentEnum dstComponents = dst->getPixelComponents(); + //PixelComponentEnum dstComponents = dst->getPixelComponents(); const OfxRectI& dstBounds = dst->getBounds(); - const size_t depth = dst->getPixelComponentCount(); assert(dst->getPixelDepth() == eBitDepthFloat); float* b = (float*)dst->getPixelData(); const size_t bwidth = dstBounds.x2 - dstBounds.x1; @@ -398,8 +397,8 @@ ContactSheetPlugin::render(const OFX::RenderArguments &args) throwSuiteStatusException(kOfxStatFailed); } BitDepthEnum srcBitDepth = src->getPixelDepth(); - PixelComponentEnum srcComponents = src->getPixelComponents(); - if ( (srcBitDepth != dstBitDepth) || (srcComponents != dstComponents) ) { + //PixelComponentEnum srcComponents = src->getPixelComponents(); + if ( (srcBitDepth != dstBitDepth) /*|| (srcComponents != dstComponents)*/ ) { throwSuiteStatusException(kOfxStatErrImageFormat); } @@ -411,6 +410,7 @@ ContactSheetPlugin::render(const OFX::RenderArguments &args) const size_t aheight = srcBounds.y2 - srcBounds.y1; const size_t axstride = src->getPixelComponentCount(); const size_t aystride = awidth * axstride; + const size_t depth = std::min(axstride, bxstride); const OfxRectD from = {0., 0., (double)awidth, (double)aheight}; OfxRectI to; Coords::toPixelEnclosing(imageRoD, args.renderScale, dstPar, &to); @@ -596,13 +596,6 @@ ContactSheetPlugin::getClipPreferences(OFX::ClipPreferencesSetter & clipPreferen { updateGUI(); - // all inputs and outputs should have the same components - OFX::PixelComponentEnum outputComps = _dstClip->getPixelComponents(); - - for (unsigned i = 0; i < _srcClip.size(); ++i) { - clipPreferences.setClipComponents(*_srcClip[i], outputComps); - } - OfxRectI format = {0, 0, 0, 0}; _resolution->getValue(format.x2, format.y2); clipPreferences.setOutputFormat(format); @@ -675,7 +668,7 @@ class ContactSheetInteract : public OverlayInteract { , _selectionFrame(NULL) { _dstClip = effect->fetchClip(kOfxImageEffectOutputClipName); - assert( _dstClip && (!_dstClip->isConnected() || _dstClip->getPixelComponents() == OFX::ePixelComponentAlpha || _dstClip->getPixelComponents() == OFX::ePixelComponentRGB || _dstClip->getPixelComponents() == OFX::ePixelComponentRGBA) ); + assert( _dstClip && (!_dstClip->isConnected() || _dstClip->getPixelComponents() == OFX::ePixelComponentRGBA) ); _resolution = effect->fetchInt2DParam(kParamResolution); _rowsColumns = effect->fetchInt2DParam(kParamRowsColums); assert(_resolution && _rowsColumns); @@ -755,7 +748,7 @@ ContactSheetInteract::draw(const OFX::DrawArgs &args) OfxRGBColourD color = { 0.8, 0.8, 0.8 }; getSuggestedColour(color); - const OfxPointD& pscale = args.pixelScale; + //const OfxPointD& pscale = args.pixelScale; GLdouble projection[16]; glGetDoublev( GL_PROJECTION_MATRIX, projection); GLint viewport[4]; @@ -892,9 +885,9 @@ ContactSheetPluginFactory::describe(OFX::ImageEffectDescriptor &desc) desc.addSupportedBitDepth(eBitDepthFloat); //desc.addSupportedBitDepth(eBitDepthCustom); #ifdef OFX_EXTENSIONS_VEGAS - desc.addSupportedBitDepth(eBitDepthUByteBGRA); - desc.addSupportedBitDepth(eBitDepthUShortBGRA); - desc.addSupportedBitDepth(eBitDepthFloatBGRA); + //desc.addSupportedBitDepth(eBitDepthUByteBGRA); + //desc.addSupportedBitDepth(eBitDepthUShortBGRA); + //desc.addSupportedBitDepth(eBitDepthFloatBGRA); #endif // set a few flags @@ -941,7 +934,9 @@ ContactSheetPluginFactory::describeInContext(OFX::ImageEffectDescriptor &desc, srcClip = desc.defineClip("0"); srcClip->setOptional(true); } - srcClip->addSupportedComponent(ePixelComponentNone); +#ifdef OFX_EXTENSIONS_NATRON + srcClip->addSupportedComponent(ePixelComponentXY); +#endif srcClip->addSupportedComponent(ePixelComponentRGB); srcClip->addSupportedComponent(ePixelComponentRGBA); srcClip->addSupportedComponent(ePixelComponentAlpha); @@ -953,7 +948,9 @@ ContactSheetPluginFactory::describeInContext(OFX::ImageEffectDescriptor &desc, ClipDescriptor *srcClip; srcClip = desc.defineClip("1"); srcClip->setOptional(true); - srcClip->addSupportedComponent(ePixelComponentNone); +#ifdef OFX_EXTENSIONS_NATRON + srcClip->addSupportedComponent(ePixelComponentXY); +#endif srcClip->addSupportedComponent(ePixelComponentRGB); srcClip->addSupportedComponent(ePixelComponentRGBA); srcClip->addSupportedComponent(ePixelComponentAlpha); @@ -966,7 +963,9 @@ ContactSheetPluginFactory::describeInContext(OFX::ImageEffectDescriptor &desc, for (unsigned i = 2; i < clipSourceCount; ++i) { ClipDescriptor *srcClip = desc.defineClip( unsignedToString(i) ); srcClip->setOptional(true); - srcClip->addSupportedComponent(ePixelComponentNone); +#ifdef OFX_EXTENSIONS_NATRON + srcClip->addSupportedComponent(ePixelComponentXY); +#endif srcClip->addSupportedComponent(ePixelComponentRGB); srcClip->addSupportedComponent(ePixelComponentRGBA); srcClip->addSupportedComponent(ePixelComponentAlpha); @@ -978,10 +977,7 @@ ContactSheetPluginFactory::describeInContext(OFX::ImageEffectDescriptor &desc, // create the mandated output clip ClipDescriptor *dstClip = desc.defineClip(kOfxImageEffectOutputClipName); - dstClip->addSupportedComponent(ePixelComponentNone); - dstClip->addSupportedComponent(ePixelComponentRGB); dstClip->addSupportedComponent(ePixelComponentRGBA); - dstClip->addSupportedComponent(ePixelComponentAlpha); dstClip->setSupportsTiles(kSupportsTiles); // make some pages and to things in diff --git a/LayerContactSheet/Info.plist b/LayerContactSheet/Info.plist new file mode 100644 index 000000000..ad9d4344c --- /dev/null +++ b/LayerContactSheet/Info.plist @@ -0,0 +1,20 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleExecutable + LayerContactSheet.ofx + CFBundleInfoDictionaryVersion + 6.0 + CFBundlePackageType + BNDL + CFBundleSignature + ???? + CFBundleVersion + 0.0.1d1 + CSResourcesFileMapped + + + diff --git a/LayerContactSheet/LayerContactSheet.cpp b/LayerContactSheet/LayerContactSheet.cpp new file mode 100644 index 000000000..324c68b4c --- /dev/null +++ b/LayerContactSheet/LayerContactSheet.cpp @@ -0,0 +1,850 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * This file is part of openfx-misc , + * Copyright (C) 2013-2016 INRIA + * + * openfx-misc is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * openfx-misc is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with openfx-misc. If not, see + * ***** END LICENSE BLOCK ***** */ + +/* + * OFX LayerContactSheet plugin. + * LayerContactSheet between inputs. + */ + +#include +#include +#include + +#if defined(_WIN32) || defined(__WIN32__) || defined(WIN32) +#include +#endif + +#ifdef __APPLE__ +#include +#else +#include +#endif + + +#include "ofxsMacros.h" +#include "ofxNatron.h" +#include "ofxsCopier.h" +#include "ofxsCoords.h" +#include "ofxsFilter.h" +#include "ofxsOGLTextRenderer.h" + +#ifdef OFX_EXTENSIONS_NUKE +#include "nuke/fnOfxExtensions.h" +#endif + +using namespace OFX; + + +OFXS_NAMESPACE_ANONYMOUS_ENTER + +#define kPluginName "LayerContactSheetOFX" +#define kPluginGrouping "Merge" +#define kPluginDescription \ + "Make a contact sheet from all layers." +#define kPluginIdentifier "net.sf.openfx.LayerContactSheetOFX" +#define kPluginVersionMajor 1 // Incrementing this number means that you have broken backwards compatibility of the plug-in. +#define kPluginVersionMinor 0 // Increment this when you have fixed a bug or made it faster. + +#define kSupportsTiles 1 +#define kSupportsMultiResolution 1 +#define kSupportsRenderScale 1 +#define kSupportsMultipleClipPARs false +#define kSupportsMultipleClipDepths false +#define kRenderThreadSafety eRenderFullySafe + +#define kParamResolution "resolution" +#define kParamResolutionLabel "Resolution" +#define kParamResolutionHint \ + "Resolution of the output image, in pixels." + +#define kParamRowsColums "rowsColumns" +#define kParamRowsColumsLabel "Rows/Columns" +#define kParamRowsColumsHint \ + "How many rows and columns in the grid where the input images or frames are arranged." + +#define kParamAutoDims "autoDims" +#define kParamAutoDimsLabel "Automatic Rows/Columns" +#define kParamAutoDimsHint \ + "Automatically sets the number of rows/columns to display all layers." + +#define kParamGap "gap" +#define kParamGapLabel "Gap" +#define kParamGapHint \ +"Gap in pixels around each input or frame." + +#define kParamCenter "center" +#define kParamCenterLabel "Center" +#define kParamCenterHint \ +"Center each input/frame within its cell." + +#define kParamRowOrder "rowOrder" +#define kParamRowOrderLabel "Row Order" +#define kParamRowOrderHint \ +"How image rows are populated." +#define kParamRowOrderOptionTopBottom "TopBottom", "From top to bottom row." +#define kParamRowOrderOptionBottomTop "BottomTop", "From bottom to top row." +enum RowOrderEnum { + eRowOrderTopBottom = 0, + eRowOrderBottomTop, +}; + +#define kParamColumnOrder "colOrder" +#define kParamColumnOrderLabel "Column Order" +#define kParamColumnOrderHint \ +"How image columns are populated." +#define kParamColumnOrderOptionLeftRight "LeftRight", "From left to right column." +#define kParamColumnOrderOptionRightLeft "RightLeft", "From right to left column." +enum ColumnOrderEnum { + eColumnOrderLeftRight = 0, + eColumnOrderRightLeft, +}; + +#define kParamShowLayerNames "showLayerNames" +#define kParamShowLayerNamesLabel "Show Layer Names" +#define kParamShowLayerNamesHint \ +"Display the layer name in the bottom left of each frame." + +//////////////////////////////////////////////////////////////////////////////// +/** @brief The plugin that does our work */ +class LayerContactSheetPlugin + : public OFX::ImageEffect +{ +public: + /** @brief ctor */ + LayerContactSheetPlugin(OfxImageEffectHandle handle); + +private: + /* Override the render */ + virtual void render(const OFX::RenderArguments &args) OVERRIDE FINAL; + + // override the roi call + virtual void getRegionsOfInterest(const OFX::RegionsOfInterestArguments &args, OFX::RegionOfInterestSetter &rois) OVERRIDE FINAL; + virtual bool getRegionOfDefinition(const OFX::RegionOfDefinitionArguments &args, OfxRectD &rod) OVERRIDE FINAL; + + /** Override the get frames needed action */ + //virtual void getFramesNeeded(const OFX::FramesNeededArguments &args, OFX::FramesNeededSetter &frames) OVERRIDE FINAL; + + /** @brief get the clip preferences */ + virtual void getClipPreferences(OFX::ClipPreferencesSetter &clipPreferences) OVERRIDE FINAL; +#ifdef OFX_EXTENSIONS_NUKE + virtual void getClipComponents(const ClipComponentsArguments& args, ClipComponentsSetter& clipComponents) OVERRIDE FINAL; +#endif + + /** @brief called when a clip has just been changed in some way (a rewire maybe) */ + virtual void changedClip(const InstanceChangedArgs &args, const std::string &clipName) OVERRIDE FINAL; + virtual void changedParam(const InstanceChangedArgs &args, const std::string ¶mName) OVERRIDE FINAL; + +private: + + void updateGUI(); + + // do not need to delete these, the ImageEffect is managing them for us + Clip* _dstClip; + Clip* _srcClip; + Int2DParam *_resolution; + Int2DParam* _rowsColumns; + BooleanParam* _autoDims; + IntParam* _gap; + BooleanParam* _center; + ChoiceParam* _rowOrder; + ChoiceParam* _colOrder; + BooleanParam* _showLayerNames; +}; + +LayerContactSheetPlugin::LayerContactSheetPlugin(OfxImageEffectHandle handle) + : ImageEffect(handle) + , _dstClip(NULL) + , _srcClip(NULL) + , _resolution(NULL) + , _rowsColumns(NULL) + , _autoDims(NULL) + , _gap(NULL) + , _center(NULL) + , _rowOrder(NULL) + , _colOrder(NULL) + , _showLayerNames(NULL) +{ + _dstClip = fetchClip(kOfxImageEffectOutputClipName); + assert( _dstClip && (!_dstClip->isConnected() || _dstClip->getPixelComponents() == OFX::ePixelComponentAlpha || _dstClip->getPixelComponents() == OFX::ePixelComponentRGB || _dstClip->getPixelComponents() == OFX::ePixelComponentRGBA) ); + _srcClip = fetchClip(kOfxImageEffectSimpleSourceClipName); + assert(_srcClip); + _resolution = fetchInt2DParam(kParamResolution); + _rowsColumns = fetchInt2DParam(kParamRowsColums); + assert(_resolution && _rowsColumns); + _autoDims = fetchBooleanParam(kParamAutoDims); + _gap = fetchIntParam(kParamGap); + _center = fetchBooleanParam(kParamCenter); + _rowOrder = fetchChoiceParam(kParamRowOrder); + _colOrder = fetchChoiceParam(kParamColumnOrder); + _showLayerNames = fetchBooleanParam(kParamShowLayerNames); + + updateGUI(); +} + +static void +fitRod(const OfxRectD& srcFormatCanonical, + const OfxRectD& cellRoD, + int gap, + bool center, + double* f, + OfxRectD* imageRoD) +{ + double sw = srcFormatCanonical.x2 - srcFormatCanonical.x1; + double sh = srcFormatCanonical.y2 - srcFormatCanonical.y1; + OfxRectD cRoD = { cellRoD.x1 + gap / 2, cellRoD.y1 + gap/2, cellRoD.x2 - (gap + 1) / 2, cellRoD.y2 - (gap + 1) / 2}; + double cw = std::max(1., cRoD.x2 - cRoD.x1); + double ch = std::max(1., cRoD.y2 - cRoD.y1); + bool fitwidth = sw * ch > sh * cw; + *f = fitwidth ? (cw/sw) : (ch / sh); + if (center) { + imageRoD->x1 = cRoD.x1 + (cw - *f * sw) / 2; + imageRoD->x2 = cRoD.x2 - (cw - *f * sw) / 2; + imageRoD->y1 = cRoD.y1 + (ch - *f * sh) / 2; + imageRoD->y2 = cRoD.y2 - (ch - *f * sh) / 2; + } else { + imageRoD->x1 = cRoD.x1; + imageRoD->x2 = cRoD.x1 + *f * sw; + imageRoD->y1 = cRoD.y1; + imageRoD->y2 = cRoD.y1 + *f * sh; + } +} + +void +LayerContactSheetPlugin::render(const OFX::RenderArguments &args) +{ + const double time = args.time; + + // do the rendering + std::auto_ptr dst( _dstClip->fetchImage(time) ); + if ( !dst.get() ) { + throwSuiteStatusException(kOfxStatFailed); + } + if ( (dst->getRenderScale().x != args.renderScale.x) || + ( dst->getRenderScale().y != args.renderScale.y) || + ( ( dst->getField() != eFieldNone) /* for DaVinci Resolve */ && ( dst->getField() != args.fieldToRender) ) ) { + setPersistentMessage(Message::eMessageError, "", "OFX Host gave image with wrong scale or field properties"); + throwSuiteStatusException(kOfxStatFailed); + } + BitDepthEnum dstBitDepth = dst->getPixelDepth(); + //PixelComponentEnum dstComponents = dst->getPixelComponents(); + const OfxRectI& dstBounds = dst->getBounds(); + assert(dst->getPixelDepth() == eBitDepthFloat); + float* b = (float*)dst->getPixelData(); + const size_t bwidth = dstBounds.x2 - dstBounds.x1; + const size_t bheight = dstBounds.y2 - dstBounds.y1; + const size_t bxstride = dst->getPixelComponentCount(); + const size_t bystride = bwidth * bxstride; + // clear the renderWindow + fillBlack( *this, args.renderWindow, dst.get() ); + + OfxRectD rod; + { + int w, h; + _resolution->getValue(w, h); + double par = _dstClip->getPixelAspectRatio(); + OfxPointD rs1 = {1., 1.}; + OfxRectI rodpixel = {0, 0, w, h}; + Coords::toCanonical(rodpixel, rs1, par, &rod); + } + bool topbottom = (_rowOrder->getValueAtTime(time) == eRowOrderTopBottom); + bool leftright = (_colOrder->getValueAtTime(time) == eColumnOrderLeftRight); + int gap = _gap->getValueAtTime(time); + bool center = _center->getValueAtTime(time); + double dstPar = _dstClip->getPixelAspectRatio(); + OfxRectD renderWindowCanonical; + Coords::toCanonical(args.renderWindow, args.renderScale, dstPar, &renderWindowCanonical); + + assert( kSupportsMultipleClipPARs || !_srcClip || _srcClip->getPixelAspectRatio() == _dstClip->getPixelAspectRatio() ); + assert( kSupportsMultipleClipDepths || !_srcClip || _srcClip->getPixelDepth() == _dstClip->getPixelDepth() ); + + OfxRectD srcFormatCanonical; + { + OfxRectI srcFormat; + _srcClip->getFormat(srcFormat); + double srcPar = _srcClip->getPixelAspectRatio(); + if ( OFX::Coords::rectIsEmpty(srcFormat) ) { + // no format is available, use the RoD instead + srcFormatCanonical = _srcClip->getRegionOfDefinition(time); + } else { + const OfxPointD rs1 = {1., 1.}; + Coords::toCanonical(srcFormat, rs1, srcPar, &srcFormatCanonical); + } + } + + std::vector components; + _srcClip->getComponentsPresent(&components); + + // now, for each clip, compute the required region of interest, which is the union of the intersection of each cell with the renderWindow + int rows, columns; + if ( !_autoDims->getValueAtTime(time) ) { + _rowsColumns->getValueAtTime(time, rows, columns); + } else { + std::size_t n = components.size(); + double w = rod.x2 - rod.x1; + double h = rod.y2 - rod.y1; + double sw = srcFormatCanonical.x2 - srcFormatCanonical.x1; + double sh = srcFormatCanonical.y2 - srcFormatCanonical.y1; + columns = std::ceil( std::sqrt( (n * w * sh) / (h * sw) ) ); + rows = std::ceil( n / (double) columns); + } + + for (std::size_t layer = 0; layer < components.size(); ++layer) { + int r = layer / columns; + int c = layer % columns; + if (r >= rows) { + continue; + } + if (topbottom) { + r = rows - 1 - r; + } + if (!leftright) { + c = columns - 1 - c; + } + // now compute the four corners of the cell in the rod + OfxRectD cellRoD = { + rod.x1 + c * (rod.x2 - rod.x1) / columns, + rod.y1 + r * (rod.y2 - rod.y1) / rows, + rod.x1 + (c + 1) * (rod.x2 - rod.x1) / columns, + rod.y1 + (r + 1) * (rod.y2 - rod.y1) / rows + }; + + // and the four corners of the image area in the dest rod + double f = 1; + OfxRectD imageRoD = {0., 0., 0., 0.}; + fitRod(srcFormatCanonical, cellRoD, gap, center, &f, &imageRoD); + + //- intersect with the render window + OfxRectD imageRoDClipped; + if (Coords::rectIntersection(renderWindowCanonical, imageRoD, &imageRoDClipped)) { + + //render: + //- get the the src Image + std::auto_ptr src( ( _srcClip && _srcClip->isConnected() ) ? + _srcClip->fetchImagePlane(time, components[layer].c_str()) : 0 ); + if ( src.get() ) { + if ( (src->getRenderScale().x != args.renderScale.x) || + ( src->getRenderScale().y != args.renderScale.y) || + ( ( src->getField() != eFieldNone) /* for DaVinci Resolve */ && ( src->getField() != args.fieldToRender) ) ) { + setPersistentMessage(Message::eMessageError, "", "OFX Host gave image with wrong scale or field properties"); + throwSuiteStatusException(kOfxStatFailed); + } + BitDepthEnum srcBitDepth = src->getPixelDepth(); + //PixelComponentEnum srcComponents = src->getPixelComponents(); + if ( (srcBitDepth != dstBitDepth) /*|| (srcComponents != dstComponents)*/ ) { + throwSuiteStatusException(kOfxStatErrImageFormat); + } + + //- draw it at the right place + const OfxRectI& srcBounds = src->getBounds(); + assert(src->getPixelDepth() == eBitDepthFloat); + const float* a = (const float*)src->getPixelData(); + const size_t awidth = srcBounds.x2 - srcBounds.x1; + const size_t aheight = srcBounds.y2 - srcBounds.y1; + const size_t axstride = src->getPixelComponentCount(); + const size_t aystride = awidth * axstride; + const size_t depth = std::min(axstride, bxstride); + const OfxRectD from = {0., 0., (double)awidth, (double)aheight}; + OfxRectI to; + Coords::toPixelEnclosing(imageRoD, args.renderScale, dstPar, &to); + to.x1 -= dstBounds.x1; + to.y1 -= dstBounds.y1; + to.x2 -= dstBounds.x1; + to.y2 -= dstBounds.y1; + + ofxsFilterResize2d(a, awidth, aheight, axstride, aystride, depth, + from, /*zeroOutside=*/false, + b, bwidth, bheight, bxstride, bystride, + to); + } + } + } +} + + +// override the roi call +// Required if the plugin requires a region from the inputs which is different from the rendered region of the output. +// (this is the case here) +void +LayerContactSheetPlugin::getRegionsOfInterest(const OFX::RegionsOfInterestArguments &args, + OFX::RegionOfInterestSetter &rois) +{ + const double time = args.time; + + // ask for the full format + OfxRectD srcFormatCanonical; + { + OfxRectI srcFormat; + _srcClip->getFormat(srcFormat); + double srcPar = _srcClip->getPixelAspectRatio(); + if ( OFX::Coords::rectIsEmpty(srcFormat) ) { + // no format is available, use the RoD instead + srcFormatCanonical = _srcClip->getRegionOfDefinition(time); + } else { + const OfxPointD rs1 = {1., 1.}; + Coords::toCanonical(srcFormat, rs1, srcPar, &srcFormatCanonical); + } + } + rois.setRegionOfInterest(*_srcClip, srcFormatCanonical); +} + +bool +LayerContactSheetPlugin::getRegionOfDefinition(const OFX::RegionOfDefinitionArguments &args, + OfxRectD &rod) +{ + const double time = args.time; + int w, h; + _resolution->getValueAtTime(time, w, h); + double par = _dstClip->getPixelAspectRatio(); + OfxPointD rs1 = {1., 1.}; + OfxRectI rodpixel = {0, 0, w, h}; + Coords::toCanonical(rodpixel, rs1, par, &rod); + + return true; +} + + + +/* Override the clip preferences */ +void +LayerContactSheetPlugin::getClipPreferences(OFX::ClipPreferencesSetter & clipPreferences) +{ + updateGUI(); + + OfxRectI format = {0, 0, 0, 0}; + _resolution->getValue(format.x2, format.y2); + clipPreferences.setOutputFormat(format); + //clipPreferences.setPixelAspectRatio(*_dstClip, par); +} + +#ifdef OFX_EXTENSIONS_NUKE +void +LayerContactSheetPlugin::getClipComponents(const ClipComponentsArguments& args, + ClipComponentsSetter& clipComponents) +{ + // no pass-through + clipComponents.setPassThroughClip(NULL, args.time, args.view); + + // produces RGBA only + clipComponents.addClipComponents(*_dstClip, ePixelComponentRGBA); + + // ask for the first rows * cols first components from the input + std::vector components; + _srcClip->getComponentsPresent(&components); + +} +#endif + +void +LayerContactSheetPlugin::changedClip(const InstanceChangedArgs & /*args*/, + const std::string & /*clipName*/) +{ +} + +void +LayerContactSheetPlugin::changedParam(const InstanceChangedArgs &/*args*/, + const std::string ¶mName) +{ + if (paramName == kParamAutoDims) { + updateGUI(); + } +} + +void +LayerContactSheetPlugin::updateGUI() +{ + bool autoDims = _autoDims->getValue(); + _rowsColumns->setEnabled(!autoDims); +} + +//////////// INTERACT + +class LayerContactSheetInteract : public OverlayInteract { + +public: + LayerContactSheetInteract(OfxInteractHandle handle, ImageEffect* effect) + : OverlayInteract(handle) + , _srcClip(NULL) + , _dstClip(NULL) + , _resolution(NULL) + , _rowsColumns(NULL) + , _autoDims(NULL) + , _gap(NULL) + , _center(NULL) + , _rowOrder(NULL) + , _colOrder(NULL) + , _showLayerNames(NULL) + { + _srcClip = effect->fetchClip(kOfxImageEffectSimpleSourceClipName); + _dstClip = effect->fetchClip(kOfxImageEffectOutputClipName); + assert( _dstClip && (!_dstClip->isConnected() || _dstClip->getPixelComponents() == OFX::ePixelComponentAlpha || _dstClip->getPixelComponents() == OFX::ePixelComponentRGB || _dstClip->getPixelComponents() == OFX::ePixelComponentRGBA) ); + _resolution = effect->fetchInt2DParam(kParamResolution); + _rowsColumns = effect->fetchInt2DParam(kParamRowsColums); + _autoDims = effect->fetchBooleanParam(kParamAutoDims); + _gap = effect->fetchIntParam(kParamGap); + _center = effect->fetchBooleanParam(kParamCenter); + _rowOrder = effect->fetchChoiceParam(kParamRowOrder); + _colOrder = effect->fetchChoiceParam(kParamColumnOrder); + _showLayerNames = effect->fetchBooleanParam(kParamShowLayerNames); + } + +private: + // overridden functions from OFX::Interact to do things + virtual bool draw(const OFX::DrawArgs &args) OVERRIDE FINAL; + +private: + Clip* _srcClip; + Clip* _dstClip; + Int2DParam *_resolution; + Int2DParam* _rowsColumns; + BooleanParam* _autoDims; + IntParam* _gap; + BooleanParam* _center; + ChoiceParam* _rowOrder; + ChoiceParam* _colOrder; + BooleanParam* _showLayerNames; + +}; + +// draw the interact +bool +LayerContactSheetInteract::draw(const OFX::DrawArgs &args) +{ + const double time = args.time; + + if ( !_showLayerNames->getValueAtTime(time) ) { + return false; + } + + OfxRectD rod; + { + int w, h; + _resolution->getValue(w, h); + double par = _dstClip->getPixelAspectRatio(); + OfxPointD rs1 = {1., 1.}; + OfxRectI rodpixel = {0, 0, w, h}; + Coords::toCanonical(rodpixel, rs1, par, &rod); + } + bool topbottom = (_rowOrder->getValueAtTime(time) == eRowOrderTopBottom); + bool leftright = (_colOrder->getValueAtTime(time) == eColumnOrderLeftRight); + int gap = _gap->getValueAtTime(time); + bool center = _center->getValueAtTime(time); + //double dstPar = _dstClip->getPixelAspectRatio(); + + OfxRectD srcFormatCanonical; + { + OfxRectI srcFormat; + _srcClip->getFormat(srcFormat); + double srcPar = _srcClip->getPixelAspectRatio(); + if ( OFX::Coords::rectIsEmpty(srcFormat) ) { + // no format is available, use the RoD instead + srcFormatCanonical = _srcClip->getRegionOfDefinition(time); + } else { + const OfxPointD rs1 = {1., 1.}; + Coords::toCanonical(srcFormat, rs1, srcPar, &srcFormatCanonical); + } + } + + std::vector components; + _srcClip->getComponentsPresent(&components); + + // now, for each clip, compute the required region of interest, which is the union of the intersection of each cell with the renderWindow + int rows, columns; + if ( !_autoDims->getValueAtTime(time) ) { + _rowsColumns->getValueAtTime(time, rows, columns); + } else { + std::size_t n = components.size(); + double w = rod.x2 - rod.x1; + double h = rod.y2 - rod.y1; + double sw = srcFormatCanonical.x2 - srcFormatCanonical.x1; + double sh = srcFormatCanonical.y2 - srcFormatCanonical.y1; + columns = std::ceil( std::sqrt( (n * w * sh) / (h * sw) ) ); + rows = std::ceil( n / (double) columns); + } + + OfxRGBColourD color = { 0.8, 0.8, 0.8 }; + getSuggestedColour(color); + //const OfxPointD& pscale = args.pixelScale; + GLdouble projection[16]; + glGetDoublev( GL_PROJECTION_MATRIX, projection); + GLint viewport[4]; + glGetIntegerv(GL_VIEWPORT, viewport); + OfxPointD shadow; // how much to translate GL_PROJECTION to get exactly one pixel on screen + shadow.x = 2. / (projection[0] * viewport[2]); + shadow.y = 2. / (projection[5] * viewport[3]); + + for (std::size_t layer = 0; layer < components.size(); ++layer) { + std::string name = components[layer]; + { + std::size_t first_underline = name.find_first_of('_'); + std::size_t second_underline = std::string::npos; + if (first_underline != std::string::npos) { + second_underline = name.find_first_of('_', first_underline + 1); + name = name.substr(first_underline + 1, second_underline - (first_underline + 1)); + } + } + int r = layer / columns; + int c = layer % columns; + if (r >= rows) { + continue; + } + if (topbottom) { + r = rows - 1 - r; + } + if (!leftright) { + c = columns - 1 - c; + } + // now compute the four corners of the cell in the rod + OfxRectD cellRoD = { + rod.x1 + c * (rod.x2 - rod.x1) / columns, + rod.y1 + r * (rod.y2 - rod.y1) / rows, + rod.x1 + (c + 1) * (rod.x2 - rod.x1) / columns, + rod.y1 + (r + 1) * (rod.y2 - rod.y1) / rows + }; + + // and the four corners of the image area in the dest rod + double f = 1; + OfxRectD imageRoD = {0., 0., 0., 0.}; + fitRod(srcFormatCanonical, cellRoD, gap, center, &f, &imageRoD); + + // Draw everything twice + // l = 0: shadow + // l = 1: drawing + for (int l = 0; l < 2; ++l) { + // shadow (uses GL_PROJECTION) + glMatrixMode(GL_PROJECTION); + int direction = (l == 0) ? 1 : -1; + // translate (1,-1) pixels + glTranslated(direction * shadow.x, -direction * shadow.y, 0); + glMatrixMode(GL_MODELVIEW); // Modelview should be used on Nuke + + glColor3f(color.r * l, color.g * l, color.b * l); + + TextRenderer::bitmapString( imageRoD.x1, imageRoD.y1, name.c_str() ); + } + } + + return true; +} + + + +//////////// FACTORY + +mDeclarePluginFactory(LayerContactSheetPluginFactory, {}, {}); + +class LayerContactSheetOverlayDescriptor : public DefaultEffectOverlayDescriptor {}; + +void +LayerContactSheetPluginFactory::describe(OFX::ImageEffectDescriptor &desc) +{ + // basic labels + desc.setLabel(kPluginName); + desc.setPluginGrouping(kPluginGrouping); + desc.setPluginDescription(kPluginDescription); + + // add the supported contexts + desc.addSupportedContext(eContextGeneral); + desc.addSupportedContext(eContextFilter); + + // add supported pixel depths + //desc.addSupportedBitDepth(eBitDepthNone); + //desc.addSupportedBitDepth(eBitDepthUByte); + //desc.addSupportedBitDepth(eBitDepthUShort); + //desc.addSupportedBitDepth(eBitDepthHalf); + desc.addSupportedBitDepth(eBitDepthFloat); + //desc.addSupportedBitDepth(eBitDepthCustom); +#ifdef OFX_EXTENSIONS_VEGAS + //desc.addSupportedBitDepth(eBitDepthUByteBGRA); + //desc.addSupportedBitDepth(eBitDepthUShortBGRA); + //desc.addSupportedBitDepth(eBitDepthFloatBGRA); +#endif + + // set a few flags + desc.setSingleInstance(false); + desc.setHostFrameThreading(false); + desc.setSupportsMultiResolution(kSupportsMultiResolution); + desc.setSupportsTiles(kSupportsTiles); + desc.setTemporalClipAccess(true); + desc.setRenderTwiceAlways(false); + desc.setSupportsMultipleClipPARs(kSupportsMultipleClipPARs); + desc.setSupportsMultipleClipDepths(kSupportsMultipleClipDepths); +#ifdef OFX_EXTENSIONS_NUKE + // Enable transform by the host. + // It is only possible for transforms which can be represented as a 3x3 matrix. + desc.setCanTransform(false); + + desc.setIsMultiPlanar(true); + desc.setPassThroughForNotProcessedPlanes(ePassThroughLevelBlockAllNonRenderedPlanes); +#endif + desc.setRenderThreadSafety(kRenderThreadSafety); +#ifdef OFX_EXTENSIONS_NATRON + desc.setChannelSelector(ePixelComponentNone); +#endif + + desc.setOverlayInteractDescriptor( new LayerContactSheetOverlayDescriptor); +} + +void +LayerContactSheetPluginFactory::describeInContext(OFX::ImageEffectDescriptor &desc, + OFX::ContextEnum /*context*/) +{ + // Source clip only in the filter context + // create the mandated source clip + { + ClipDescriptor *srcClip; + srcClip = desc.defineClip(kOfxImageEffectSimpleSourceClipName); + srcClip->addSupportedComponent(ePixelComponentNone); + srcClip->addSupportedComponent(ePixelComponentXY); + srcClip->addSupportedComponent(ePixelComponentRGB); + srcClip->addSupportedComponent(ePixelComponentRGBA); + srcClip->addSupportedComponent(ePixelComponentAlpha); + srcClip->setTemporalClipAccess(false); + srcClip->setSupportsTiles(kSupportsTiles); + srcClip->setIsMask(false); + } + + // create the mandated output clip + ClipDescriptor *dstClip = desc.defineClip(kOfxImageEffectOutputClipName); + dstClip->addSupportedComponent(ePixelComponentRGBA); + dstClip->setSupportsTiles(kSupportsTiles); + + // make some pages and to things in + PageParamDescriptor *page = desc.definePageParam("Controls"); + + // resolution + { + Int2DParamDescriptor *param = desc.defineInt2DParam(kParamResolution); + param->setLabel(kParamResolutionLabel); + param->setHint(kParamResolutionHint); + param->setDefault(3072, 2048); + param->setRange(1, 1, INT_MAX, INT_MAX); + param->setDisplayRange(256, 256, 4096, 4096); + param->setAnimates(false); + if (page) { + page->addChild(*param); + } + } + + // rowsColumns + { + Int2DParamDescriptor *param = desc.defineInt2DParam(kParamRowsColums); + param->setLabel(kParamRowsColumsLabel); + param->setHint(kParamRowsColumsHint); + param->setDefault(3, 4); + param->setRange(1, 1, INT_MAX, INT_MAX); + param->setDisplayRange(1, 1, 32, 32); + param->setAnimates(false); + param->setLayoutHint(eLayoutHintNoNewLine, 1); + if (page) { + page->addChild(*param); + } + } + + // autoDims + { + BooleanParamDescriptor *param = desc.defineBooleanParam(kParamAutoDims); + param->setLabel(kParamAutoDimsLabel); + param->setHint(kParamAutoDimsHint); + param->setAnimates(false); + param->setDefault(true); + if (page) { + page->addChild(*param); + } + } + + // gap + { + IntParamDescriptor *param = desc.defineIntParam(kParamGap); + param->setLabel(kParamGapLabel); + param->setHint(kParamGapHint); + param->setDefault(0); + param->setRange(0, INT_MAX); + param->setDisplayRange(0, 100); + param->setAnimates(false); + param->setLayoutHint(eLayoutHintNoNewLine, 1); + if (page) { + page->addChild(*param); + } + } + + // center + { + BooleanParamDescriptor *param = desc.defineBooleanParam(kParamCenter); + param->setLabel(kParamCenterLabel); + param->setHint(kParamCenterHint); + param->setAnimates(false); + if (page) { + page->addChild(*param); + } + } + + // rowOrder + { + ChoiceParamDescriptor *param = desc.defineChoiceParam(kParamRowOrder); + param->setLabel(kParamRowOrderLabel); + param->setHint(kParamRowOrderHint); + param->setAnimates(false); + assert(param->getNOptions() == (int)eRowOrderTopBottom); + param->appendOption(kParamRowOrderOptionTopBottom); + assert(param->getNOptions() == (int)eRowOrderBottomTop); + param->appendOption(kParamRowOrderOptionBottomTop); + if (page) { + page->addChild(*param); + } + } + + // colOrder + { + ChoiceParamDescriptor *param = desc.defineChoiceParam(kParamColumnOrder); + param->setLabel(kParamColumnOrderLabel); + param->setHint(kParamColumnOrderHint); + param->setAnimates(false); + assert(param->getNOptions() == (int)eColumnOrderLeftRight); + param->appendOption(kParamColumnOrderOptionLeftRight); + assert(param->getNOptions() == (int)eColumnOrderRightLeft); + param->appendOption(kParamColumnOrderOptionRightLeft); + if (page) { + page->addChild(*param); + } + } + + // showLayerNames + { + BooleanParamDescriptor *param = desc.defineBooleanParam(kParamShowLayerNames); + param->setLabel(kParamShowLayerNamesLabel); + param->setHint(kParamShowLayerNamesHint); + param->setAnimates(false); + param->setEvaluateOnChange(false); + if (page) { + page->addChild(*param); + } + } + +} // LayerContactSheetPluginFactory::describeInContext + +OFX::ImageEffect* +LayerContactSheetPluginFactory::createInstance(OfxImageEffectHandle handle, + OFX::ContextEnum /*context*/) +{ + return new LayerContactSheetPlugin(handle); +} + +static LayerContactSheetPluginFactory p(kPluginIdentifier, kPluginVersionMajor, kPluginVersionMinor); +mRegisterPluginFactoryInstance(p) + +OFXS_NAMESPACE_ANONYMOUS_EXIT diff --git a/LayerContactSheet/Makefile b/LayerContactSheet/Makefile new file mode 100644 index 000000000..f2c59448c --- /dev/null +++ b/LayerContactSheet/Makefile @@ -0,0 +1,7 @@ +PLUGINOBJECTS = LayerContactSheet.o +PLUGINNAME = LayerContactSheet +#RESOURCES = net.sf.openfx.switchPlugin.png net.sf.openfx.switchPlugin.svg + +TOP_SRCDIR = .. +include $(TOP_SRCDIR)/Makefile.master + diff --git a/Makefile b/Makefile index abda1d7f5..2724251e0 100644 --- a/Makefile +++ b/Makefile @@ -42,6 +42,7 @@ Invert \ JoinViews \ Keyer \ KeyMix \ +LayerContactSheet \ Log2Lin \ MatteMonitor \ Merge \ diff --git a/Misc.files b/Misc.files index a7100c267..3fb531430 100644 --- a/Misc.files +++ b/Misc.files @@ -54,6 +54,7 @@ ImageStatistics/ImageStatistics.cpp Invert/Invert.cpp JoinViews/JoinViews.cpp Keyer/Keyer.cpp +LayerContactSheet/LayerContactSheet.cpp MatteMonitor/MatteMonitor.cpp Merge/Merge.cpp Mirror/Mirror.cpp diff --git a/Misc.xcodeproj/project.pbxproj b/Misc.xcodeproj/project.pbxproj index 7741c1658..af5adab39 100644 --- a/Misc.xcodeproj/project.pbxproj +++ b/Misc.xcodeproj/project.pbxproj @@ -830,6 +830,25 @@ 1EB00C771EDEF90E006CA180 /* ContactSheet.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1EB00C741EDEF75D006CA180 /* ContactSheet.cpp */; }; 1EB00C781EDEF91D006CA180 /* ContactSheet.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1EB00C741EDEF75D006CA180 /* ContactSheet.cpp */; }; 1EB00C791EE0418D006CA180 /* ContactSheet.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1EB00C741EDEF75D006CA180 /* ContactSheet.cpp */; }; + 1EB00C7D1EE078D2006CA180 /* ofxsCore.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1E3E3CB517995D5C005F2132 /* ofxsCore.cpp */; }; + 1EB00C7E1EE078D2006CA180 /* tinythread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1EF77B701E4A3878005C4845 /* tinythread.cpp */; }; + 1EB00C7F1EE078D2006CA180 /* ofxsImageEffect.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1E3E3CB617995D5C005F2132 /* ofxsImageEffect.cpp */; }; + 1EB00C801EE078D2006CA180 /* ofxsInteract.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1E3E3CB717995D5C005F2132 /* ofxsInteract.cpp */; }; + 1EB00C811EE078D2006CA180 /* ofxsGenerator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1E75A0311A87BA37005BAA36 /* ofxsGenerator.cpp */; }; + 1EB00C821EE078D2006CA180 /* ofxsLog.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1E3E3CB817995D5C005F2132 /* ofxsLog.cpp */; }; + 1EB00C831EE078D2006CA180 /* ofxsThreadSuite.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1EF77B721E4A3998005C4845 /* ofxsThreadSuite.cpp */; }; + 1EB00C841EE078D2006CA180 /* ofxsMultiThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1E3E3CB917995D5C005F2132 /* ofxsMultiThread.cpp */; }; + 1EB00C851EE078D2006CA180 /* ofxsParams.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1E3E3CBA17995D5C005F2132 /* ofxsParams.cpp */; }; + 1EB00C861EE078D2006CA180 /* ofxsProperty.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1E3E3CBB17995D5C005F2132 /* ofxsProperty.cpp */; }; + 1EB00C871EE078D2006CA180 /* ofxsPropertyValidation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1E3E3CBC17995D5C005F2132 /* ofxsPropertyValidation.cpp */; }; + 1EB00C881EE078D2006CA180 /* ofxsRectangleInteract.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1E9B5F53198A51840095C8AA /* ofxsRectangleInteract.cpp */; }; + 1EB00C8A1EE078D2006CA180 /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1E551F5A179950EC00A4135C /* OpenGL.framework */; }; + 1EB00C8C1EE078D2006CA180 /* net.sf.openfx.CheckerBoardPlugin.png in CopyFiles */ = {isa = PBXBuildFile; fileRef = 1E75A0801A88E260005BAA36 /* net.sf.openfx.CheckerBoardPlugin.png */; }; + 1EB00C8D1EE078D2006CA180 /* net.sf.openfx.CheckerBoardPlugin.svg in CopyFiles */ = {isa = PBXBuildFile; fileRef = 1E75A0811A88E260005BAA36 /* net.sf.openfx.CheckerBoardPlugin.svg */; }; + 1EB00C931EE0792A006CA180 /* ofxsOGLFontData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1E9B5F4D198A51840095C8AA /* ofxsOGLFontData.cpp */; }; + 1EB00C951EE0792A006CA180 /* ofxsOGLTextRenderer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1E9B5F4F198A51840095C8AA /* ofxsOGLTextRenderer.cpp */; }; + 1EB00C9B1EE07A53006CA180 /* LayerContactSheet.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1EB00C991EE07A4A006CA180 /* LayerContactSheet.cpp */; }; + 1EB00C9C1EE07A55006CA180 /* LayerContactSheet.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1EB00C991EE07A4A006CA180 /* LayerContactSheet.cpp */; }; 1EB0A4401AA1EDB100F9C93E /* TestPosition.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1EB0A43E1AA1EDB100F9C93E /* TestPosition.cpp */; }; 1EB0A4431AA1F03C00F9C93E /* TestGroups.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1EB0A4411AA1F03C00F9C93E /* TestGroups.cpp */; }; 1EB0A4441AA2002700F9C93E /* ofxsTransform3x3.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1E9B5F57198A51840095C8AA /* ofxsTransform3x3.cpp */; }; @@ -2579,6 +2598,17 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 1EB00C8B1EE078D2006CA180 /* CopyFiles */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 7; + files = ( + 1EB00C8C1EE078D2006CA180 /* net.sf.openfx.CheckerBoardPlugin.png in CopyFiles */, + 1EB00C8D1EE078D2006CA180 /* net.sf.openfx.CheckerBoardPlugin.svg in CopyFiles */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 1EB0A4701AA202EC00F9C93E /* CopyFiles */ = { isa = PBXCopyFilesBuildPhase; buildActionMask = 2147483647; @@ -3672,6 +3702,10 @@ 1EB00C741EDEF75D006CA180 /* ContactSheet.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ContactSheet.cpp; sourceTree = ""; }; 1EB00C751EDEF75D006CA180 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 1EB00C761EDEF75D006CA180 /* Makefile */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.make; path = Makefile; sourceTree = ""; }; + 1EB00C911EE078D2006CA180 /* LayerContactSheet.ofx.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = LayerContactSheet.ofx.bundle; sourceTree = BUILT_PRODUCTS_DIR; }; + 1EB00C981EE07A4A006CA180 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 1EB00C991EE07A4A006CA180 /* LayerContactSheet.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LayerContactSheet.cpp; sourceTree = ""; }; + 1EB00C9A1EE07A4A006CA180 /* Makefile */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.make; path = Makefile; sourceTree = ""; }; 1EB0A43E1AA1EDB100F9C93E /* TestPosition.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TestPosition.cpp; sourceTree = ""; }; 1EB0A4411AA1F03C00F9C93E /* TestGroups.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TestGroups.cpp; sourceTree = ""; }; 1EB0A45B1AA202DF00F9C93E /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; @@ -4334,6 +4368,14 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 1EB00C891EE078D2006CA180 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 1EB00C8A1EE078D2006CA180 /* OpenGL.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 1EB0A46E1AA202EC00F9C93E /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -5087,6 +5129,7 @@ 1E2212091E535F170069EB8D /* Card3D.ofx.bundle */, 1EE3F3BD1EC9C3CB00B61988 /* Threshold.ofx.bundle */, 1EB00C711EDEF686006CA180 /* ContactSheet.ofx.bundle */, + 1EB00C911EE078D2006CA180 /* LayerContactSheet.ofx.bundle */, ); name = Products; sourceTree = ""; @@ -5150,6 +5193,7 @@ 1EDE1BAF182D39DA002392CB /* JoinViews */, 1ECF2FA019F51D6700E91A38 /* Keyer */, 1EBEC6021D928EBB00127BC7 /* KeyMix */, + 1EB00C971EE07A17006CA180 /* LayerContactSheet */, 1E89B5721D81A77E00F61E6B /* Log2Lin */, 1E2D33D51C3FB21A004E2F03 /* MatteMonitor */, D74121CA18F9C99300A81F8B /* Merge */, @@ -5625,6 +5669,16 @@ path = ContactSheet; sourceTree = ""; }; + 1EB00C971EE07A17006CA180 /* LayerContactSheet */ = { + isa = PBXGroup; + children = ( + 1EB00C981EE07A4A006CA180 /* Info.plist */, + 1EB00C991EE07A4A006CA180 /* LayerContactSheet.cpp */, + 1EB00C9A1EE07A4A006CA180 /* Makefile */, + ); + path = LayerContactSheet; + sourceTree = ""; + }; 1EB0A45A1AA202AE00F9C93E /* Position */ = { isa = PBXGroup; children = ( @@ -6845,6 +6899,23 @@ productReference = 1EB00C711EDEF686006CA180 /* ContactSheet.ofx.bundle */; productType = "com.apple.product-type.bundle"; }; + 1EB00C7A1EE078D2006CA180 /* LayerContactSheet.ofx */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1EB00C8E1EE078D2006CA180 /* Build configuration list for PBXNativeTarget "LayerContactSheet.ofx" */; + buildPhases = ( + 1EB00C7B1EE078D2006CA180 /* Sources */, + 1EB00C891EE078D2006CA180 /* Frameworks */, + 1EB00C8B1EE078D2006CA180 /* CopyFiles */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = LayerContactSheet.ofx; + productName = basic.ofx; + productReference = 1EB00C911EE078D2006CA180 /* LayerContactSheet.ofx.bundle */; + productType = "com.apple.product-type.bundle"; + }; 1EB0A4601AA202EC00F9C93E /* Position.ofx */ = { isa = PBXNativeTarget; buildConfigurationList = 1EB0A4751AA202EC00F9C93E /* Build configuration list for PBXNativeTarget "Position.ofx" */; @@ -7604,6 +7675,7 @@ 1EDE1B9D182D3985002392CB /* JoinViews.ofx */, 1ECF2F8A19F51D3400E91A38 /* Keyer.ofx */, 1EBEC5ED1D928E9E00127BC7 /* KeyMix.ofx */, + 1EB00C7A1EE078D2006CA180 /* LayerContactSheet.ofx */, 1E89B5771D81A7C000F61E6B /* Log2Lin.ofx */, 1E2D33DB1C3FB9A3004E2F03 /* MatteMonitor.ofx */, D74121D418F9CF3D00A81F8B /* Merge.ofx */, @@ -8244,6 +8316,7 @@ 1E8B5D6818B76F8700C31FDC /* ColorLookup.cpp in Sources */, 1EAFE3E71C5D092900F9E4E4 /* ColorSuppress.cpp in Sources */, 1ED537371A234D3C007966D5 /* ColorTransform.cpp in Sources */, + 1EB00C9C1EE07A55006CA180 /* LayerContactSheet.cpp in Sources */, 1EE7A8CB1C74B909001AE4BC /* ColorWheel.cpp in Sources */, D74A80C719405A14007C3E1C /* Crop.cpp in Sources */, 1E92573819EC1E140018F19A /* Clamp.cpp in Sources */, @@ -8476,6 +8549,28 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 1EB00C7B1EE078D2006CA180 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1EB00C931EE0792A006CA180 /* ofxsOGLFontData.cpp in Sources */, + 1EB00C951EE0792A006CA180 /* ofxsOGLTextRenderer.cpp in Sources */, + 1EB00C7D1EE078D2006CA180 /* ofxsCore.cpp in Sources */, + 1EB00C9B1EE07A53006CA180 /* LayerContactSheet.cpp in Sources */, + 1EB00C7E1EE078D2006CA180 /* tinythread.cpp in Sources */, + 1EB00C7F1EE078D2006CA180 /* ofxsImageEffect.cpp in Sources */, + 1EB00C801EE078D2006CA180 /* ofxsInteract.cpp in Sources */, + 1EB00C811EE078D2006CA180 /* ofxsGenerator.cpp in Sources */, + 1EB00C821EE078D2006CA180 /* ofxsLog.cpp in Sources */, + 1EB00C831EE078D2006CA180 /* ofxsThreadSuite.cpp in Sources */, + 1EB00C841EE078D2006CA180 /* ofxsMultiThread.cpp in Sources */, + 1EB00C851EE078D2006CA180 /* ofxsParams.cpp in Sources */, + 1EB00C861EE078D2006CA180 /* ofxsProperty.cpp in Sources */, + 1EB00C871EE078D2006CA180 /* ofxsPropertyValidation.cpp in Sources */, + 1EB00C881EE078D2006CA180 /* ofxsRectangleInteract.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 1EB0A4611AA202EC00F9C93E /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -10578,6 +10673,28 @@ }; name = Release; }; + 1EB00C8F1EE078D2006CA180 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + EXPORTED_SYMBOLS_FILE = "$(OFX_PATH)/Support/include/osxSymbols"; + INFOPLIST_FILE = LayerContactSheet/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/OFX/Plugins/$(PROJECT_NAME)"; + PRODUCT_NAME = "$(TARGET_NAME)"; + WRAPPER_EXTENSION = bundle; + }; + name = Debug; + }; + 1EB00C901EE078D2006CA180 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + EXPORTED_SYMBOLS_FILE = "$(OFX_PATH)/Support/include/osxSymbols"; + INFOPLIST_FILE = LayerContactSheet/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/OFX/Plugins/$(PROJECT_NAME)"; + PRODUCT_NAME = "$(TARGET_NAME)"; + WRAPPER_EXTENSION = bundle; + }; + name = Release; + }; 1EB0A4761AA202EC00F9C93E /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -12082,6 +12199,15 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + 1EB00C8E1EE078D2006CA180 /* Build configuration list for PBXNativeTarget "LayerContactSheet.ofx" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1EB00C8F1EE078D2006CA180 /* Debug */, + 1EB00C901EE078D2006CA180 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; 1EB0A4751AA202EC00F9C93E /* Build configuration list for PBXNativeTarget "Position.ofx" */ = { isa = XCConfigurationList; buildConfigurations = ( diff --git a/Misc/Makefile b/Misc/Makefile index cc631a876..f8c240d7e 100644 --- a/Misc/Makefile +++ b/Misc/Makefile @@ -54,6 +54,7 @@ Invert.o \ JoinViews.o \ Keyer.o \ KeyMix.o \ +LayerContactSheet.o \ Log2Lin.o \ MatteMonitor.o \ Merge.o \ @@ -284,6 +285,7 @@ $(TOP_SRCDIR)/Invert \ $(TOP_SRCDIR)/JoinViews \ $(TOP_SRCDIR)/Keyer \ $(TOP_SRCDIR)/KeyMix \ +$(TOP_SRCDIR)/LayerContactSheet \ $(TOP_SRCDIR)/Log2Lin \ $(TOP_SRCDIR)/MatteMonitor \ $(TOP_SRCDIR)/Merge \ @@ -363,6 +365,7 @@ CXXFLAGS += \ -I$(TOP_SRCDIR)/Keyer \ -I$(TOP_SRCDIR)/KeyMix \ -I$(TOP_SRCDIR)/Log2Lin \ +-I$(TOP_SRCDIR)/LayerContactSheet \ -I$(TOP_SRCDIR)/MatteMonitor \ -I$(TOP_SRCDIR)/Merge \ -I$(TOP_SRCDIR)/Mirror \ diff --git a/Misc/Misc.vcxproj b/Misc/Misc.vcxproj index c291b5b53..10e58d7ff 100644 --- a/Misc/Misc.vcxproj +++ b/Misc/Misc.vcxproj @@ -81,7 +81,7 @@ Level3 Disabled - $(SolutionDir)..\openfx\include;$(SolutionDir)..\openfx\Support\include;$(SolutionDir)..\openfx\Support\Plugins\include;$(SolutionDir)..\Distortion;$(SolutionDir)..\Position;$(SolutionDir)..\FrameBlend;$(SolutionDir)..\FrameHold;$(SolutionDir)..\FrameRange;$(SolutionDir)..\Test;$(SolutionDir)..\AppendClip;$(SolutionDir)..\Mirror;$(SolutionDir)..\CheckerBoard;$(SolutionDir)..\ImageStatistics;$(SolutionDir)..\Radial;$(SolutionDir)..\Rectangle;$(SolutionDir)..\Clamp;$(SolutionDir)..\GodRays;$(SolutionDir)..\Saturation;$(SolutionDir)..\Switch;$(SolutionDir)..\TimeOffset;$(SolutionDir)..\ColorLookup;$(SolutionDir)..\SideBySide;$(SolutionDir)..\SlitScan;$(SolutionDir)..\MatteMonitor;$(SolutionDir)..\MixViews;$(SolutionDir)..\OneView;$(SolutionDir)..\JoinViews;$(SolutionDir)..\Anaglyph;$(SolutionDir)..\ColorCorrect;$(SolutionDir)..\Grade;$(SolutionDir)..\Transform;$(SolutionDir)..\Merge;$(SolutionDir)..\ChromaKeyer;$(SolutionDir)..\Roto;$(SolutionDir)..\CornerPin;$(SolutionDir);$(SolutionDir)..\Crop;$(SolutionDir)..\CopyRectangle;$(SolutionDir)..\Invert;$(SolutionDir)..\ReConverge;$(SolutionDir)..\Shuffle;$(SolutionDir)..\Difference;$(SolutionDir)..\Constant;$(SolutionDir)..\ContactSheet;$(SolutionDir)..\Premult;$(SolutionDir)..\TrackerPM;$(SolutionDir)..\NoOp;$(SolutionDir)..\Noise;$(SolutionDir)..\SupportExt;$(SolutionDir)..\ColorMatrix;$(SolutionDir)..\ColorSuppress;$(SolutionDir)..\Deinterlace;$(SolutionDir)..\Despill;$(SolutionDir)..\Dissolve;$(SolutionDir)..\Retime;$(SolutionDir)..\HSVTool;$(SolutionDir)..\VectorToColor;$(SolutionDir)..\ColorTransform;$(SolutionDir)..\Multiply;$(SolutionDir)..\Gamma;$(SolutionDir)..\ClipTest;$(SolutionDir)..\TimeBuffer;$(SolutionDir)..\Add;$(SolutionDir)..\Keyer;$(SolutionDir)..\TimeBlur;%(AdditionalIncludeDirectories) + $(SolutionDir)..\openfx\include;$(SolutionDir)..\openfx\Support\include;$(SolutionDir)..\openfx\Support\Plugins\include;$(SolutionDir)..\Distortion;$(SolutionDir)..\Position;$(SolutionDir)..\FrameBlend;$(SolutionDir)..\FrameHold;$(SolutionDir)..\FrameRange;$(SolutionDir)..\Test;$(SolutionDir)..\AppendClip;$(SolutionDir)..\Mirror;$(SolutionDir)..\CheckerBoard;$(SolutionDir)..\ImageStatistics;$(SolutionDir)..\Radial;$(SolutionDir)..\Rectangle;$(SolutionDir)..\Clamp;$(SolutionDir)..\GodRays;$(SolutionDir)..\Saturation;$(SolutionDir)..\Switch;$(SolutionDir)..\TimeOffset;$(SolutionDir)..\ColorLookup;$(SolutionDir)..\SideBySide;$(SolutionDir)..\SlitScan;$(SolutionDir)..\MatteMonitor;$(SolutionDir)..\MixViews;$(SolutionDir)..\OneView;$(SolutionDir)..\JoinViews;$(SolutionDir)..\Anaglyph;$(SolutionDir)..\ColorCorrect;$(SolutionDir)..\Grade;$(SolutionDir)..\Transform;$(SolutionDir)..\Merge;$(SolutionDir)..\ChromaKeyer;$(SolutionDir)..\Roto;$(SolutionDir)..\CornerPin;$(SolutionDir);$(SolutionDir)..\Crop;$(SolutionDir)..\CopyRectangle;$(SolutionDir)..\Invert;$(SolutionDir)..\ReConverge;$(SolutionDir)..\Shuffle;$(SolutionDir)..\Difference;$(SolutionDir)..\Constant;$(SolutionDir)..\ContactSheet;$(SolutionDir)..\LayerContactSheet;$(SolutionDir)..\Premult;$(SolutionDir)..\TrackerPM;$(SolutionDir)..\NoOp;$(SolutionDir)..\Noise;$(SolutionDir)..\SupportExt;$(SolutionDir)..\ColorMatrix;$(SolutionDir)..\ColorSuppress;$(SolutionDir)..\Deinterlace;$(SolutionDir)..\Despill;$(SolutionDir)..\Dissolve;$(SolutionDir)..\Retime;$(SolutionDir)..\HSVTool;$(SolutionDir)..\VectorToColor;$(SolutionDir)..\ColorTransform;$(SolutionDir)..\Multiply;$(SolutionDir)..\Gamma;$(SolutionDir)..\ClipTest;$(SolutionDir)..\TimeBuffer;$(SolutionDir)..\Add;$(SolutionDir)..\Keyer;$(SolutionDir)..\TimeBlur;%(AdditionalIncludeDirectories) OFX_EXTENSIONS_VEGAS;OFX_EXTENSIONS_TUTTLE;OFX_EXTENSIONS_NUKE;OFX_EXTENSIONS_NATRON;_WINDOWS;_USRDLL;_CRT_SECURE_NO_WARNINGS;WIN32;NOMINMAX;%(PreprocessorDefinitions) @@ -161,7 +161,7 @@ xcopy $(SolutionDir)..\VectorToColor\net.sf.openfx.VectorToColorPlugin.png $(Out Level3 Disabled - $(SolutionDir)..\openfx\include;$(SolutionDir)..\openfx\Support\include;$(SolutionDir)..\openfx\Support\Plugins\include;$(SolutionDir)..\Distortion;$(SolutionDir)..\Position;$(SolutionDir)..\FrameBlend;$(SolutionDir)..\FrameHold;$(SolutionDir)..\FrameRange;$(SolutionDir)..\Test;$(SolutionDir)..\AppendClip;$(SolutionDir)..\Mirror;$(SolutionDir)..\CheckerBoard;$(SolutionDir)..\ImageStatistics;$(SolutionDir)..\Radial;$(SolutionDir)..\Rectangle;$(SolutionDir)..\Clamp;$(SolutionDir)..\GodRays;$(SolutionDir)..\Saturation;$(SolutionDir)..\Switch;$(SolutionDir)..\TimeOffset;$(SolutionDir)..\ColorLookup;$(SolutionDir)..\SideBySide;$(SolutionDir)..\SlitScan;$(SolutionDir)..\MatteMonitor;$(SolutionDir)..\MixViews;$(SolutionDir)..\OneView;$(SolutionDir)..\JoinViews;$(SolutionDir)..\Anaglyph;$(SolutionDir)..\ColorCorrect;$(SolutionDir)..\Grade;$(SolutionDir)..\Transform;$(SolutionDir)..\Merge;$(SolutionDir)..\ChromaKeyer;$(SolutionDir)..\Roto;$(SolutionDir)..\CornerPin;$(SolutionDir);$(SolutionDir)..\Crop;$(SolutionDir)..\CopyRectangle;$(SolutionDir)..\Invert;$(SolutionDir)..\ReConverge;$(SolutionDir)..\Shuffle;$(SolutionDir)..\Difference;$(SolutionDir)..\Constant;$(SolutionDir)..\ContactSheet;$(SolutionDir)..\Premult;$(SolutionDir)..\TrackerPM;$(SolutionDir)..\NoOp;$(SolutionDir)..\Noise;$(SolutionDir)..\SupportExt;$(SolutionDir)..\ColorMatrix;$(SolutionDir)..\ColorSuppress;$(SolutionDir)..\Deinterlace;$(SolutionDir)..\Despill;$(SolutionDir)..\Dissolve;$(SolutionDir)..\Retime;$(SolutionDir)..\HSVTool;$(SolutionDir)..\VectorToColor;$(SolutionDir)..\ColorTransform;$(SolutionDir)..\Multiply;$(SolutionDir)..\Gamma;$(SolutionDir)..\ClipTest;$(SolutionDir)..\TimeBuffer;$(SolutionDir)..\Add;$(SolutionDir)..\Keyer;$(SolutionDir)..\TimeBlur;$(SolutionDir)..\AdjustRoD;$(SolutionDir)..\Ramp;%(AdditionalIncludeDirectories) + $(SolutionDir)..\openfx\include;$(SolutionDir)..\openfx\Support\include;$(SolutionDir)..\openfx\Support\Plugins\include;$(SolutionDir)..\Distortion;$(SolutionDir)..\Position;$(SolutionDir)..\FrameBlend;$(SolutionDir)..\FrameHold;$(SolutionDir)..\FrameRange;$(SolutionDir)..\Test;$(SolutionDir)..\AppendClip;$(SolutionDir)..\Mirror;$(SolutionDir)..\CheckerBoard;$(SolutionDir)..\ImageStatistics;$(SolutionDir)..\Radial;$(SolutionDir)..\Rectangle;$(SolutionDir)..\Clamp;$(SolutionDir)..\GodRays;$(SolutionDir)..\Saturation;$(SolutionDir)..\Switch;$(SolutionDir)..\TimeOffset;$(SolutionDir)..\ColorLookup;$(SolutionDir)..\SideBySide;$(SolutionDir)..\SlitScan;$(SolutionDir)..\MatteMonitor;$(SolutionDir)..\MixViews;$(SolutionDir)..\OneView;$(SolutionDir)..\JoinViews;$(SolutionDir)..\Anaglyph;$(SolutionDir)..\ColorCorrect;$(SolutionDir)..\Grade;$(SolutionDir)..\Transform;$(SolutionDir)..\Merge;$(SolutionDir)..\ChromaKeyer;$(SolutionDir)..\Roto;$(SolutionDir)..\CornerPin;$(SolutionDir);$(SolutionDir)..\Crop;$(SolutionDir)..\CopyRectangle;$(SolutionDir)..\Invert;$(SolutionDir)..\ReConverge;$(SolutionDir)..\Shuffle;$(SolutionDir)..\Difference;$(SolutionDir)..\Constant;$(SolutionDir)..\ContactSheet;$(SolutionDir)..\LayerContactSheet;$(SolutionDir)..\Premult;$(SolutionDir)..\TrackerPM;$(SolutionDir)..\NoOp;$(SolutionDir)..\Noise;$(SolutionDir)..\SupportExt;$(SolutionDir)..\ColorMatrix;$(SolutionDir)..\ColorSuppress;$(SolutionDir)..\Deinterlace;$(SolutionDir)..\Despill;$(SolutionDir)..\Dissolve;$(SolutionDir)..\Retime;$(SolutionDir)..\HSVTool;$(SolutionDir)..\VectorToColor;$(SolutionDir)..\ColorTransform;$(SolutionDir)..\Multiply;$(SolutionDir)..\Gamma;$(SolutionDir)..\ClipTest;$(SolutionDir)..\TimeBuffer;$(SolutionDir)..\Add;$(SolutionDir)..\Keyer;$(SolutionDir)..\TimeBlur;$(SolutionDir)..\AdjustRoD;$(SolutionDir)..\Ramp;%(AdditionalIncludeDirectories) OFX_EXTENSIONS_VEGAS;OFX_EXTENSIONS_TUTTLE;OFX_EXTENSIONS_NUKE;OFX_EXTENSIONS_NATRON;_WINDOWS;_USRDLL;_CRT_SECURE_NO_WARNINGS;WIN64;NOMINMAX;%(PreprocessorDefinitions) MultiThreaded @@ -245,7 +245,7 @@ xcopy $(SolutionDir)..\VectorToColor\net.sf.openfx.VectorToColorPlugin.png $(Out true true OFX_EXTENSIONS_VEGAS;OFX_EXTENSIONS_TUTTLE;OFX_EXTENSIONS_NUKE;OFX_EXTENSIONS_NATRON;_WINDOWS;_USRDLL;_CRT_SECURE_NO_WARNINGS;WIN32;NOMINMAX;NDEBUG;%(PreprocessorDefinitions) - $(SolutionDir)..\openfx\include;$(SolutionDir)..\openfx\Support\include;$(SolutionDir)..\openfx\Support\Plugins\include;$(SolutionDir)..\Distortion;$(SolutionDir)..\Position;$(SolutionDir)..\FrameBlend;$(SolutionDir)..\FrameHold;$(SolutionDir)..\FrameRange;$(SolutionDir)..\Test;$(SolutionDir)..\AppendClip;$(SolutionDir)..\Mirror;$(SolutionDir)..\CheckerBoard;$(SolutionDir)..\ImageStatistics;$(SolutionDir)..\Radial;$(SolutionDir)..\Rectangle;$(SolutionDir)..\Clamp;$(SolutionDir)..\GodRays;$(SolutionDir)..\Saturation;$(SolutionDir)..\Switch;$(SolutionDir)..\TimeOffset;$(SolutionDir)..\ColorLookup;$(SolutionDir)..\SideBySide;$(SolutionDir)..\SlitScan;$(SolutionDir)..\MatteMonitor;$(SolutionDir)..\MixViews;$(SolutionDir)..\OneView;$(SolutionDir)..\JoinViews;$(SolutionDir)..\Anaglyph;$(SolutionDir)..\ColorCorrect;$(SolutionDir)..\Grade;$(SolutionDir)..\Transform;$(SolutionDir)..\Merge;$(SolutionDir)..\ChromaKeyer;$(SolutionDir)..\Roto;$(SolutionDir)..\CornerPin;$(SolutionDir);$(SolutionDir)..\Crop;$(SolutionDir)..\CopyRectangle;$(SolutionDir)..\Invert;$(SolutionDir)..\ReConverge;$(SolutionDir)..\Shuffle;$(SolutionDir)..\Difference;$(SolutionDir)..\Constant;$(SolutionDir)..\ContactSheet;$(SolutionDir)..\Premult;$(SolutionDir)..\TrackerPM;$(SolutionDir)..\NoOp;$(SolutionDir)..\Noise;$(SolutionDir)..\SupportExt;$(SolutionDir)..\ColorMatrix;$(SolutionDir)..\ColorSuppress;$(SolutionDir)..\Deinterlace;$(SolutionDir)..\Despill;$(SolutionDir)..\Dissolve;$(SolutionDir)..\Retime;$(SolutionDir)..\HSVTool;$(SolutionDir)..\VectorToColor;$(SolutionDir)..\ColorTransform;$(SolutionDir)..\Multiply;$(SolutionDir)..\Gamma;$(SolutionDir)..\ClipTest;$(SolutionDir)..\TimeBuffer;$(SolutionDir)..\Add;$(SolutionDir)..\Keyer;$(SolutionDir)..\TimeBlur;$(SolutionDir)..\AdjustRoD;$(SolutionDir)..\Ramp;%(AdditionalIncludeDirectories) + $(SolutionDir)..\openfx\include;$(SolutionDir)..\openfx\Support\include;$(SolutionDir)..\openfx\Support\Plugins\include;$(SolutionDir)..\Distortion;$(SolutionDir)..\Position;$(SolutionDir)..\FrameBlend;$(SolutionDir)..\FrameHold;$(SolutionDir)..\FrameRange;$(SolutionDir)..\Test;$(SolutionDir)..\AppendClip;$(SolutionDir)..\Mirror;$(SolutionDir)..\CheckerBoard;$(SolutionDir)..\ImageStatistics;$(SolutionDir)..\Radial;$(SolutionDir)..\Rectangle;$(SolutionDir)..\Clamp;$(SolutionDir)..\GodRays;$(SolutionDir)..\Saturation;$(SolutionDir)..\Switch;$(SolutionDir)..\TimeOffset;$(SolutionDir)..\ColorLookup;$(SolutionDir)..\SideBySide;$(SolutionDir)..\SlitScan;$(SolutionDir)..\MatteMonitor;$(SolutionDir)..\MixViews;$(SolutionDir)..\OneView;$(SolutionDir)..\JoinViews;$(SolutionDir)..\Anaglyph;$(SolutionDir)..\ColorCorrect;$(SolutionDir)..\Grade;$(SolutionDir)..\Transform;$(SolutionDir)..\Merge;$(SolutionDir)..\ChromaKeyer;$(SolutionDir)..\Roto;$(SolutionDir)..\CornerPin;$(SolutionDir);$(SolutionDir)..\Crop;$(SolutionDir)..\CopyRectangle;$(SolutionDir)..\Invert;$(SolutionDir)..\ReConverge;$(SolutionDir)..\Shuffle;$(SolutionDir)..\Difference;$(SolutionDir)..\Constant;$(SolutionDir)..\ContactSheet;$(SolutionDir)..\LayerContactSheet;$(SolutionDir)..\Premult;$(SolutionDir)..\TrackerPM;$(SolutionDir)..\NoOp;$(SolutionDir)..\Noise;$(SolutionDir)..\SupportExt;$(SolutionDir)..\ColorMatrix;$(SolutionDir)..\ColorSuppress;$(SolutionDir)..\Deinterlace;$(SolutionDir)..\Despill;$(SolutionDir)..\Dissolve;$(SolutionDir)..\Retime;$(SolutionDir)..\HSVTool;$(SolutionDir)..\VectorToColor;$(SolutionDir)..\ColorTransform;$(SolutionDir)..\Multiply;$(SolutionDir)..\Gamma;$(SolutionDir)..\ClipTest;$(SolutionDir)..\TimeBuffer;$(SolutionDir)..\Add;$(SolutionDir)..\Keyer;$(SolutionDir)..\TimeBlur;$(SolutionDir)..\AdjustRoD;$(SolutionDir)..\Ramp;%(AdditionalIncludeDirectories) MultiThreaded @@ -331,7 +331,7 @@ xcopy $(SolutionDir)..\VectorToColor\net.sf.openfx.VectorToColorPlugin.png $(Out true true OFX_EXTENSIONS_VEGAS;OFX_EXTENSIONS_TUTTLE;OFX_EXTENSIONS_NUKE;OFX_EXTENSIONS_NATRON;_WINDOWS;_USRDLL;_CRT_SECURE_NO_WARNINGS;WIN64;NOMINMAX;NDEBUG;%(PreprocessorDefinitions) - $(SolutionDir)..\openfx\include;$(SolutionDir)..\openfx\Support\include;$(SolutionDir)..\openfx\Support\Plugins\include;$(SolutionDir)..\Distortion;$(SolutionDir)..\Position;$(SolutionDir)..\FrameBlend;$(SolutionDir)..\FrameHold;$(SolutionDir)..\FrameRange;$(SolutionDir)..\Test;$(SolutionDir)..\AppendClip;$(SolutionDir)..\Mirror;$(SolutionDir)..\CheckerBoard;$(SolutionDir)..\ImageStatistics;$(SolutionDir)..\Radial;$(SolutionDir)..\Rectangle;$(SolutionDir)..\Clamp;$(SolutionDir)..\GodRays;$(SolutionDir)..\Saturation;$(SolutionDir)..\Switch;$(SolutionDir)..\TimeOffset;$(SolutionDir)..\ColorLookup;$(SolutionDir)..\SideBySide;$(SolutionDir)..\SlitScan;$(SolutionDir)..\MatteMonitor;$(SolutionDir)..\MixViews;$(SolutionDir)..\OneView;$(SolutionDir)..\JoinViews;$(SolutionDir)..\Anaglyph;$(SolutionDir)..\ColorCorrect;$(SolutionDir)..\Grade;$(SolutionDir)..\Transform;$(SolutionDir)..\Merge;$(SolutionDir)..\ChromaKeyer;$(SolutionDir)..\Roto;$(SolutionDir)..\CornerPin;$(SolutionDir);$(SolutionDir)..\Crop;$(SolutionDir)..\CopyRectangle;$(SolutionDir)..\Invert;$(SolutionDir)..\ReConverge;$(SolutionDir)..\Shuffle;$(SolutionDir)..\Difference;$(SolutionDir)..\Constant;$(SolutionDir)..\ContactSheet;$(SolutionDir)..\Premult;$(SolutionDir)..\TrackerPM;$(SolutionDir)..\NoOp;$(SolutionDir)..\Noise;$(SolutionDir)..\SupportExt;$(SolutionDir)..\ColorMatrix;$(SolutionDir)..\ColorSuppress;$(SolutionDir)..\Deinterlace;$(SolutionDir)..\Despill;$(SolutionDir)..\Dissolve;$(SolutionDir)..\Retime;$(SolutionDir)..\HSVTool;$(SolutionDir)..\VectorToColor;$(SolutionDir)..\ColorTransform;$(SolutionDir)..\Multiply;$(SolutionDir)..\Gamma;$(SolutionDir)..\ClipTest;$(SolutionDir)..\TimeBuffer;$(SolutionDir)..\Add;$(SolutionDir)..\Keyer;$(SolutionDir)..\TimeBlur;$(SolutionDir)..\AdjustRoD;$(SolutionDir)..\Ramp;%(AdditionalIncludeDirectories) + $(SolutionDir)..\openfx\include;$(SolutionDir)..\openfx\Support\include;$(SolutionDir)..\openfx\Support\Plugins\include;$(SolutionDir)..\Distortion;$(SolutionDir)..\Position;$(SolutionDir)..\FrameBlend;$(SolutionDir)..\FrameHold;$(SolutionDir)..\FrameRange;$(SolutionDir)..\Test;$(SolutionDir)..\AppendClip;$(SolutionDir)..\Mirror;$(SolutionDir)..\CheckerBoard;$(SolutionDir)..\ImageStatistics;$(SolutionDir)..\Radial;$(SolutionDir)..\Rectangle;$(SolutionDir)..\Clamp;$(SolutionDir)..\GodRays;$(SolutionDir)..\Saturation;$(SolutionDir)..\Switch;$(SolutionDir)..\TimeOffset;$(SolutionDir)..\ColorLookup;$(SolutionDir)..\SideBySide;$(SolutionDir)..\SlitScan;$(SolutionDir)..\MatteMonitor;$(SolutionDir)..\MixViews;$(SolutionDir)..\OneView;$(SolutionDir)..\JoinViews;$(SolutionDir)..\Anaglyph;$(SolutionDir)..\ColorCorrect;$(SolutionDir)..\Grade;$(SolutionDir)..\Transform;$(SolutionDir)..\Merge;$(SolutionDir)..\ChromaKeyer;$(SolutionDir)..\Roto;$(SolutionDir)..\CornerPin;$(SolutionDir);$(SolutionDir)..\Crop;$(SolutionDir)..\CopyRectangle;$(SolutionDir)..\Invert;$(SolutionDir)..\ReConverge;$(SolutionDir)..\Shuffle;$(SolutionDir)..\Difference;$(SolutionDir)..\Constant;$(SolutionDir)..\ContactSheet;$(SolutionDir)..\LayerContactSheet;$(SolutionDir)..\Premult;$(SolutionDir)..\TrackerPM;$(SolutionDir)..\NoOp;$(SolutionDir)..\Noise;$(SolutionDir)..\SupportExt;$(SolutionDir)..\ColorMatrix;$(SolutionDir)..\ColorSuppress;$(SolutionDir)..\Deinterlace;$(SolutionDir)..\Despill;$(SolutionDir)..\Dissolve;$(SolutionDir)..\Retime;$(SolutionDir)..\HSVTool;$(SolutionDir)..\VectorToColor;$(SolutionDir)..\ColorTransform;$(SolutionDir)..\Multiply;$(SolutionDir)..\Gamma;$(SolutionDir)..\ClipTest;$(SolutionDir)..\TimeBuffer;$(SolutionDir)..\Add;$(SolutionDir)..\Keyer;$(SolutionDir)..\TimeBlur;$(SolutionDir)..\AdjustRoD;$(SolutionDir)..\Ramp;%(AdditionalIncludeDirectories) MultiThreaded @@ -446,6 +446,7 @@ xcopy $(SolutionDir)..\VectorToColor\net.sf.openfx.VectorToColorPlugin.png $(Out + diff --git a/README.md b/README.md index 66bc58365..c70da7b55 100644 --- a/README.md +++ b/README.md @@ -153,6 +153,7 @@ grouping). * CopyRectangleOFX: Copies a rectangle from the input A to the input B in output. * DissolveOFX: Weighted average of two inputs. * KeyMixOFX: Copies A to B only where Mask is non-zero. +* LayerContactSheetOFX: Make a contact sheet from layers. * MergeOFX: Pixel-by-pixel merge operation between the two inputs. * PreMultOFX/UnpremultOFX: Multiply/divide the selected channels by alpha (or another channel). * SwitchOFX: Lets you switch between any number of inputs.