Пример #1
0
void
KnobGui::setInterpolationForDimensions(QAction* action,
                                       KeyframeTypeEnum interp)
{
    if (!action) {
        return;
    }
    int dimension = action->data().toInt();
    KnobPtr knob = getKnob();


    for (int i = 0; i < knob->getDimension(); ++i) {
        if ( (dimension == -1) || (dimension == i) ) {
            boost::shared_ptr<Curve> c = knob->getCurve(ViewIdx(0), i);
            if (c) {
                int kfCount = c->getKeyFramesCount();
                for (int j = 0; j < kfCount; ++j) {
                    c->setKeyFrameInterpolation(interp, j);
                }
                boost::shared_ptr<Curve> guiCurve = getCurve(ViewIdx(0), i);
                if (guiCurve) {
                    guiCurve->clone(*c);
                }
            }
        }
    }
    if ( knob->getHolder() ) {
        knob->getHolder()->incrHashAndEvaluate(knob->getEvaluateOnChange(), false);
    }
    Q_EMIT keyInterpolationChanged();
}
Пример #2
0
void
KnobGui::setAllKeyframeMarkersOnTimeline(int dimension)
{
    KnobPtr knob = getKnob();
    AppInstPtr app = knob->getHolder()->getApp();

    assert(app);
    std::list<SequenceTime> times;

    if (dimension == -1) {
        int dim = knob->getDimension();
        for (int i = 0; i < dim; ++i) {
            KeyFrameSet kfs = knob->getCurve(ViewIdx(0), i)->getKeyFrames_mt_safe();
            for (KeyFrameSet::iterator it = kfs.begin(); it != kfs.end(); ++it) {
                times.push_back( it->getTime() );
            }
        }
    } else {
        KeyFrameSet kfs = knob->getCurve(ViewIdx(0), dimension)->getKeyFrames_mt_safe();
        for (KeyFrameSet::iterator it = kfs.begin(); it != kfs.end(); ++it) {
            times.push_back( it->getTime() );
        }
    }
    app->addMultipleKeyframeIndicatorsAdded(times, true);
}
Пример #3
0
void
BezierCurve::getFeatherPointPosition(int index, double time, double* x, double *y, double *lx, double *ly, double *rx, double *ry) const
{
    boost::shared_ptr<BezierCP> cp = _bezier->getFeatherPointAtIndex(index);
    cp->getPositionAtTime(true, time, ViewIdx(0), x, y);
    cp->getLeftBezierPointAtTime(true, time, ViewIdx(0), lx, ly);
    cp->getRightBezierPointAtTime(true, time, ViewIdx(0), rx, ry);
}
Пример #4
0
void
ViewerNodePrivate::refreshInputChoices(bool resetChoiceIfNotFound)
{
    // Refresh the A and B input choices
    KnobChoicePtr aInputKnob = aInputNodeChoiceKnob.lock();
    KnobChoicePtr bInputKnob = bInputNodeChoiceKnob.lock();

    ViewerCompositingOperatorEnum operation = (ViewerCompositingOperatorEnum)blendingModeChoiceKnob.lock()->getValue();
    bInputKnob->setEnabled(operation != eViewerCompositingOperatorNone);

    std::vector<ChoiceOption> entries;
    entries.push_back(ChoiceOption("-", "", ""));

    int nInputs = _publicInterface->getMaxInputCount();
    for (int i = 0; i < nInputs; ++i) {
        NodePtr inputNode = _publicInterface->getNode()->getRealInput(i);
        if (!inputNode) {
            continue;
        }

        std::string optionID;
        {
            std::stringstream ss;
            ss << i;
            optionID = ss.str();
        }

        entries.push_back(ChoiceOption(optionID, inputNode->getLabel(), ""));
    }

    ChoiceOption currentAChoice = aInputKnob->getActiveEntry();
    ChoiceOption currentBChoice = bInputKnob->getActiveEntry();

    aInputKnob->populateChoices(entries);
    bInputKnob->populateChoices(entries);

    if (resetChoiceIfNotFound) {
        if (currentAChoice.id == "-" || !aInputKnob->isActiveEntryPresentInEntries(ViewIdx(0))) {
            aInputKnob->setValue(entries.size() > 1 ? 1 : 0);
        }
        if (currentBChoice.id == "-" || !bInputKnob->isActiveEntryPresentInEntries(ViewIdx(0))) {
            bInputKnob->setValue(entries.size() > 1 ? 1 : 0);
        }
    }

    if (uiContext) {
        if ( (operation == eViewerCompositingOperatorNone) || !bInputKnob->isEnabled()  || bInputKnob->getActiveEntry().id.empty() ) {
            uiContext->setInfoBarVisible(1, false);
        } else if (operation != eViewerCompositingOperatorNone) {
            uiContext->setInfoBarVisible(1, true);
        }
    }
    
} // refreshInputChoices
void
AnimationModuleSelectionModel::addAnimatedItemsWithoutKeyframes(const AnimItemBasePtr& item,
                                                        DimSpec dim,
                                                        ViewSetSpec viewSpec,
                                                        AnimItemDimViewKeyFramesMap* result)
{
    if (!result) {
        return;
    }
    std::list<ViewIdx> views = item->getViewsList();
    int nDims = item->getNDimensions();
    if (viewSpec.isAll()) {
        for (std::list<ViewIdx>::const_iterator it3 = views.begin(); it3 != views.end(); ++it3) {

            if (dim.isAll()) {
                for (int i = 0; i < nDims; ++i) {
                    QTreeWidgetItem* treeItem = item->getTreeItem(DimIdx(i), *it3);
                    if (AnimationModuleTreeView::isItemVisibleRecursive(treeItem)) {
                        AnimItemDimViewIndexID key(item, *it3, DimIdx(i));
                        KeyFrameWithStringSet &keysForItem = (*result)[key];
                        (void)keysForItem;
                    }
                }
            } else {
                QTreeWidgetItem* treeItem = item->getTreeItem(DimIdx(dim), *it3);
                if (AnimationModuleTreeView::isItemVisibleRecursive(treeItem)) {
                    AnimItemDimViewIndexID key(item, *it3, DimIdx(dim));
                    KeyFrameWithStringSet &keysForItem = (*result)[key];
                    (void)keysForItem;
                }
            }
        }

    } else {
        if (dim.isAll()) {
            for (int i = 0; i < nDims; ++i) {
                QTreeWidgetItem* treeItem = item->getTreeItem(DimIdx(i), ViewIdx(viewSpec));
                if (AnimationModuleTreeView::isItemVisibleRecursive(treeItem)) {
                    AnimItemDimViewIndexID key(item, ViewIdx(viewSpec), DimIdx(i));
                    KeyFrameWithStringSet &keysForItem = (*result)[key];
                    (void)keysForItem;
                }
            }
        } else {
            QTreeWidgetItem* treeItem = item->getTreeItem(DimIdx(dim), ViewIdx(viewSpec));
            if (AnimationModuleTreeView::isItemVisibleRecursive(treeItem)) {
                AnimItemDimViewIndexID key(item, ViewIdx(viewSpec), DimIdx(dim));
                KeyFrameWithStringSet &keysForItem = (*result)[key];
                (void)keysForItem;
            }
        }
    }
} // addAnimatedItemsWithoutKeyframes
Пример #6
0
void
DSPasteKeysCommand::setKeyValueFromKnob(const KnobIPtr& knob, double keyTime, KeyFrame* key)
{
    KnobDoubleBasePtr isDouble = toKnobDoubleBase(knob);
    KnobBoolBasePtr isBool = toKnobBoolBase(knob);
    KnobIntBasePtr isInt = toKnobIntBase(knob);
    KnobStringBasePtr isString = toKnobStringBase(knob);


    if (isDouble) {
        key->setValue( isDouble->getValueAtTime(keyTime) );
    } else if (isBool) {
        key->setValue( isBool->getValueAtTime(keyTime) );
    } else if (isInt) {
        key->setValue( isInt->getValueAtTime(keyTime) );
    } else if (isString) {
        std::string v = isString->getValueAtTime(keyTime);
        double keyFrameValue = 0.;
        AnimatingKnobStringHelperPtr isStringAnimatedKnob = boost::dynamic_pointer_cast<AnimatingKnobStringHelper>(isString);
        assert(isStringAnimatedKnob);
        if (isStringAnimatedKnob) {
            isStringAnimatedKnob->stringToKeyFrameValue(keyTime, ViewIdx(0), v, &keyFrameValue);
        }
        key->setValue(keyFrameValue);
    }
}
Пример #7
0
void
KnobGui::onRemoveKeyActionTriggered()
{
    QAction* action = qobject_cast<QAction*>( sender() );

    assert(action);
    int dim = action->data().toInt();
    KnobPtr knob = getKnob();

    assert( knob->getHolder()->getApp() );
    //get the current time on the global timeline
    SequenceTime time = knob->getHolder()->getApp()->getTimeLine()->currentFrame();
    std::map<boost::shared_ptr<CurveGui>, std::vector<KeyFrame > > toRemove;
    KnobGuiPtr thisShared = shared_from_this();

    for (int i = 0; i < knob->getDimension(); ++i) {
        if ( (dim == -1) || (i == dim) ) {
            std::list<boost::shared_ptr<CurveGui> > curves = getGui()->getCurveEditor()->findCurve(thisShared, i);
            for (std::list<boost::shared_ptr<CurveGui> >::iterator it = curves.begin(); it != curves.end(); ++it) {
                KeyFrame kf;
                bool foundKey = knob->getCurve(ViewIdx(0), i)->getKeyFrameWithTime(time, &kf);

                if (foundKey) {
                    std::vector<KeyFrame > vect;
                    vect.push_back(kf);
                    toRemove.insert( std::make_pair(*it, vect) );
                }
            }
        }
    }
    pushUndoCommand( new RemoveKeysCommand(getGui()->getCurveEditor()->getCurveWidget(),
                                           toRemove) );
}
Пример #8
0
std::pair<ImagePtr, RectD>
TrackMarker::getMarkerImage(TimeValue time,
                            const RectD& roi) const
{

    assert( !roi.isNull() );

    NodePtr node = getModel()->getNode();
    NodePtr input = node->getInput(0);
    if (!input) {
        return std::make_pair(ImagePtr(), roi);
    }

    TreeRender::CtorArgsPtr args(new TreeRender::CtorArgs);
    {
        args->treeRootEffect = input->getEffectInstance();
        args->time = time;
        args->view = ViewIdx(0);

        // Render default plane
        args->plane = 0;
        args->mipMapLevel = 0;
        args->proxyScale = RenderScale(1.);
        args->canonicalRoI = &roi;
        args->draftMode = false;
        args->playback = false;
        args->byPassCache = false;
    }

    TreeRenderPtr render = TreeRender::create(args);

    FrameViewRequestPtr outputRequest;
    ActionRetCodeEnum stat = render->launchRender(&outputRequest);
    if (isFailureRetCode(stat)) {
        return std::make_pair(ImagePtr(), roi);
    }
    ImagePtr sourceImage = outputRequest->getRequestedScaleImagePlane();

    // Make sure the Natron image rendered is RGBA full rect and on CPU, we don't support other formats
    if (sourceImage->getStorageMode() != eStorageModeRAM) {
        Image::InitStorageArgs initArgs;
        initArgs.bounds = sourceImage->getBounds();
        initArgs.plane = sourceImage->getLayer();
        initArgs.bufferFormat = eImageBufferLayoutRGBAPackedFullRect;
        initArgs.storage = eStorageModeRAM;
        initArgs.bitdepth = sourceImage->getBitDepth();
        ImagePtr tmpImage = Image::create(initArgs);
        if (!tmpImage) {
            return std::make_pair(ImagePtr(), roi);
        }
        Image::CopyPixelsArgs cpyArgs;
        cpyArgs.roi = initArgs.bounds;
        tmpImage->copyPixels(*sourceImage, cpyArgs);
        sourceImage = tmpImage;
        
    }

    return std::make_pair(sourceImage, roi);
} // TrackMarker::getMarkerImage
Пример #9
0
std::string
KnobFile::getFileName(int time,
                      ViewSpec view)
{
    if (!_isInputImage) {
        return getValue(0, view);
    } else {
        ///try to interpret the pattern and generate a filename if indexes are found
        std::vector<std::string> views;
        if ( getHolder() && getHolder()->getApp() ) {
            views = getHolder()->getApp()->getProject()->getProjectViewNames();
        }
        if ( !view.isViewIdx() ) {
            view = ViewIdx(0);
        }

        return SequenceParsing::generateFileNameFromPattern(getValue( 0, ViewIdx(0) ), views, time, view);
    }
}
Пример #10
0
void
ViewerNode::setRefreshButtonDown(bool down)
{
    KnobButtonPtr knob = _imp->refreshButtonKnob.lock();
    // Ignore evaluation

    ScopedChanges_RAII changes(this, true);
    knob->setValue(down, ViewIdx(0), DimIdx(0), eValueChangedReasonTimeChanged);

}
Пример #11
0
void
TrackMarker::getCenterKeyframes(std::set<double>* keyframes) const
{
    CurvePtr curve = _imp->center.lock()->getAnimationCurve(ViewIdx(0), DimIdx(0));

    assert(curve);
    KeyFrameSet keys = curve->getKeyFrames_mt_safe();
    for (KeyFrameSet::iterator it = keys.begin(); it != keys.end(); ++it) {
        keyframes->insert( it->getTime() );
    }
}
Пример #12
0
void
KnobFile::reloadFile()
{
    assert( getHolder() );
    EffectInstance* effect = dynamic_cast<EffectInstance*>( getHolder() );
    if (effect) {
        effect->purgeCaches();
        effect->clearPersistentMessage(false);
    }
    evaluateValueChange(0, getCurrentTime(), ViewIdx(0), eValueChangedReasonNatronInternalEdited);
}
Пример #13
0
SetExpressionCommand::SetExpressionCommand(const KnobIPtr & knob,
                                           bool hasRetVar,
                                           DimSpec dimension,
                                           ViewSetSpec view,
                                           const std::string& expr,
                                           QUndoCommand *parent)
: QUndoCommand(parent)
, _knob(knob)
, _oldExprs()
, _newExpr(expr)
, _hasRetVar(hasRetVar)
, _dimension(dimension)
, _view(view)
{
    int nDims = knob->getNDimensions();
    std::list<ViewIdx> allViews = knob->getViewsList();
    if (dimension.isAll()) {
        for (int i = 0; i < nDims; ++i) {
            if (view.isAll()) {
                for (std::list<ViewIdx>::const_iterator it = allViews.begin(); it!=allViews.end(); ++it) {
                    getOldExprForDimView(knob, DimIdx(i), *it, &_oldExprs);
                }
            } else {
                getOldExprForDimView(knob, DimIdx(i), ViewIdx(view), &_oldExprs);
            }
        }

    } else {
        if (view.isAll()) {
            for (std::list<ViewIdx>::const_iterator it = allViews.begin(); it!=allViews.end(); ++it) {
                getOldExprForDimView(knob, DimIdx(dimension), *it, &_oldExprs);
            }
        } else {
            getOldExprForDimView(knob, DimIdx(dimension), ViewIdx(view), &_oldExprs);
        }
    }

    setText( tr("Set Expression") );


}
Пример #14
0
void
DSTransformKeysCommand::redo()
{
    /*
       The view is going to get MANY update() calls since every knob change will trigger a computeNodeRange() in DopeSheetView
       We explicitly disable update on the dopesheet view and re-enable it afterwards.
     */
    DopeSheetView* view = _model->getDopesheetView();

    view->setUpdatesEnabled(false);

    std::list<KnobHolderPtr> differentKnobs;
    for (TransformKeys::iterator it = _keys.begin(); it != _keys.end(); ++it) {
        KnobHolderPtr holder = it->first->getInternalKnob()->getHolder();
        if (holder) {
            if ( std::find(differentKnobs.begin(), differentKnobs.end(), holder) == differentKnobs.end() ) {
                differentKnobs.push_back(holder);
                holder->beginChanges();
            }
        }
    }

    if (!_firstRedoCalled) {
        for (TransformKeys::iterator it = _keys.begin(); it != _keys.end(); ++it) {
            it->second.oldCurve.reset( new Curve( *it->first->getInternalKnob()->getCurve( ViewIdx(0), it->first->getDimension() ) ) );
        }
        for (TransformKeys::iterator it = _keys.begin(); it != _keys.end(); ++it) {
            for (DSKeyPtrList::iterator it2 = it->second.keys.begin(); it2 != it->second.keys.end(); ++it2) {
                transformKey(*it2);
            }
        }

        for (TransformKeys::iterator it = _keys.begin(); it != _keys.end(); ++it) {
            it->second.newCurve.reset( new Curve( *it->first->getInternalKnob()->getCurve( ViewIdx(0), it->first->getDimension() ) ) );
        }
        _firstRedoCalled = true;
    } else {
        for (TransformKeys::iterator it = _keys.begin(); it != _keys.end(); ++it) {
            it->first->getInternalKnob()->cloneCurve(ViewIdx(0), it->first->getDimension(), *it->second.newCurve);
        }
    }

    for (std::list<KnobHolderPtr>::iterator it = differentKnobs.begin(); it != differentKnobs.end(); ++it) {
        (*it)->endChanges();
    }

    view->setUpdatesEnabled(true);


    _model->refreshSelectionBboxAndRedrawView();
}
Пример #15
0
void
KnobGui::removeAllKeyframeMarkersOnTimeline(int dimension)
{
    KnobPtr knob = getKnob();

    if ( knob->getHolder() && knob->getHolder()->getApp() && !knob->getIsSecret() && ( knob->isDeclaredByPlugin() || knob->isUserKnob() ) ) {
        AppInstPtr app = knob->getHolder()->getApp();
        assert(app);
        std::list<SequenceTime> times;
        std::set<SequenceTime> tmpTimes;
        if (dimension == -1) {
            int dim = knob->getDimension();
            for (int i = 0; i < dim; ++i) {
                boost::shared_ptr<Curve> curve = knob->getCurve(ViewIdx(0), i);
                if (curve) {
                    KeyFrameSet kfs = curve->getKeyFrames_mt_safe();
                    for (KeyFrameSet::iterator it = kfs.begin(); it != kfs.end(); ++it) {
                        tmpTimes.insert( it->getTime() );
                    }
                }
            }
            for (std::set<SequenceTime>::iterator it = tmpTimes.begin(); it != tmpTimes.end(); ++it) {
                times.push_back(*it);
            }
        } else {
            boost::shared_ptr<Curve> curve = knob->getCurve(ViewIdx(0), dimension);
            if (curve) {
                KeyFrameSet kfs = curve->getKeyFrames_mt_safe();
                for (KeyFrameSet::iterator it = kfs.begin(); it != kfs.end(); ++it) {
                    times.push_back( it->getTime() );
                }
            }
        }
        if ( !times.empty() ) {
            app->removeMultipleKeyframeIndicator(times, true);
        }
    }
}
Пример #16
0
void
SetExpressionCommand::undo()
{
    KnobIPtr knob = _knob.lock();

    if (!knob) {
        return;
    }

    knob->beginChanges();
    try {
        int nDims = knob->getNDimensions();
        std::list<ViewIdx> allViews = knob->getViewsList();
        if (_dimension.isAll()) {
            for (int i = 0; i < nDims; ++i) {
                if (_view.isAll()) {
                    for (std::list<ViewIdx>::const_iterator it = allViews.begin(); it!=allViews.end(); ++it) {
                        setOldExprForDimView(knob, DimIdx(i), *it, _oldExprs);
                    }
                } else {
                    setOldExprForDimView(knob, DimIdx(i), ViewIdx(_view), _oldExprs);
                }
            }

        } else {
            if (_view.isAll()) {
                for (std::list<ViewIdx>::const_iterator it = allViews.begin(); it!=allViews.end(); ++it) {
                    setOldExprForDimView(knob, DimIdx(_dimension), *it, _oldExprs);
                }
            } else {
                setOldExprForDimView(knob, DimIdx(_dimension), ViewIdx(_view), _oldExprs);
            }
        }
    } catch (...) {
        Dialogs::errorDialog( tr("Expression").toStdString(), tr("The expression is invalid.").toStdString() );
    }
    knob->endChanges();
}
Пример #17
0
static void
deleteKnobAnimation(const std::set<double>& userKeyframes,
                    const KnobIPtr& knob,
                    DeleteKnobAnimationEnum type,
                    double currentTime)
{
    for (int i = 0; i < knob->getNDimensions(); ++i) {
        CurvePtr curve = knob->getAnimationCurve(ViewIdx(0), DimIdx(i));
        assert(curve);
        KeyFrameSet keys = curve->getKeyFrames_mt_safe();
        std::list<double> toRemove;
        switch (type) {
        case eDeleteKnobAnimationAll: {
            for (KeyFrameSet::iterator it = keys.begin(); it != keys.end(); ++it) {
                std::set<double>::iterator found = userKeyframes.find( it->getTime() );
                if ( found == userKeyframes.end() ) {
                    toRemove.push_back( it->getTime() );
                }
            }
            break;
        }
        case eDeleteKnobAnimationBeforeTime: {
            for (KeyFrameSet::iterator it = keys.begin(); it != keys.end(); ++it) {
                if (it->getTime() >= currentTime) {
                    break;
                }
                std::set<double>::iterator found = userKeyframes.find( it->getTime() );
                if ( found == userKeyframes.end() ) {
                    toRemove.push_back( it->getTime() );
                }
            }
            break;
        }
        case eDeleteKnobAnimationAfterTime: {
            for (KeyFrameSet::reverse_iterator it = keys.rbegin(); it != keys.rend(); ++it) {
                if (it->getTime() <= currentTime) {
                    break;
                }
                std::set<double>::iterator found = userKeyframes.find( it->getTime() );
                if ( found == userKeyframes.end() ) {
                    toRemove.push_back( it->getTime() );
                }
            }
            break;
        }
        }
        knob->deleteValuesAtTime(toRemove, ViewSetSpec::all(), DimIdx(i), eValueChangedReasonUserEdited);
    }
}
Пример #18
0
void
KnobGui::onSetKeyActionTriggered()
{
    QAction* action = qobject_cast<QAction*>( sender() );

    assert(action);
    int dim = action->data().toInt();
    KnobPtr knob = getKnob();

    assert( knob->getHolder()->getApp() );
    //get the current time on the global timeline
    SequenceTime time = knob->getHolder()->getApp()->getTimeLine()->currentFrame();
    AddKeysCommand::KeysToAddList toAdd;
    KnobGuiPtr thisShared = shared_from_this();
    for (int i = 0; i < knob->getDimension(); ++i) {
        if ( (dim == -1) || (i == dim) ) {
            std::list<boost::shared_ptr<CurveGui> > curves = getGui()->getCurveEditor()->findCurve(thisShared, i);
            for (std::list<boost::shared_ptr<CurveGui> >::iterator it = curves.begin(); it != curves.end(); ++it) {
                AddKeysCommand::KeyToAdd keyToAdd;
                KeyFrame kf;
                kf.setTime(time);
                Knob<int>* isInt = dynamic_cast<Knob<int>*>( knob.get() );
                Knob<bool>* isBool = dynamic_cast<Knob<bool>*>( knob.get() );
                AnimatingKnobStringHelper* isString = dynamic_cast<AnimatingKnobStringHelper*>( knob.get() );
                Knob<double>* isDouble = dynamic_cast<Knob<double>*>( knob.get() );

                if (isInt) {
                    kf.setValue( isInt->getValue(i) );
                } else if (isBool) {
                    kf.setValue( isBool->getValue(i) );
                } else if (isDouble) {
                    kf.setValue( isDouble->getValue(i) );
                } else if (isString) {
                    std::string v = isString->getValue(i);
                    double dv;
                    isString->stringToKeyFrameValue(time, ViewIdx(0), v, &dv);
                    kf.setValue(dv);
                }

                keyToAdd.keyframes.push_back(kf);
                keyToAdd.curveUI = *it;
                keyToAdd.knobUI = thisShared;
                keyToAdd.dimension = i;
                toAdd.push_back(keyToAdd);
            }
        }
    }
    pushUndoCommand( new AddKeysCommand(getGui()->getCurveEditor()->getCurveWidget(), toAdd) );
}
Пример #19
0
QString
KnobOutputFile::generateFileNameAtTime(SequenceTime time,
                                       ViewSpec view)
{
    std::vector<std::string> views;

    if ( getHolder() && getHolder()->getApp() ) {
        views = getHolder()->getApp()->getProject()->getProjectViewNames();
    }
    if ( !view.isViewIdx() ) {
        view = ViewIdx(0);
    }

    return QString::fromUtf8( SequenceParsing::generateFileNameFromPattern(getValue( 0, ViewIdx(0) ), views, time, view).c_str() );
}
Пример #20
0
FramesNeededMap
OneViewNode::getFramesNeeded(double time,
                             ViewIdx /*view*/)
{
    FramesNeededMap ret;
    FrameRangesMap& rangeMap = ret[0];
    KnobChoicePtr viewKnob = _imp->viewKnob.lock();
    int view_i = viewKnob->getValue();
    std::vector<RangeD>& ranges = rangeMap[ViewIdx(view_i)];

    ranges.resize(1);
    ranges[0].min = ranges[0].max = time;

    return ret;
}
Пример #21
0
void
RestoreDefaultsCommand::undo()
{
    assert( _clones.size() == _knobs.size() );

    std::list<SequenceTime> times;
    KnobPtr first = _knobs.front().lock();
    AppInstance* app = first->getHolder()->getApp();
    assert(app);
    std::list<KnobWPtr >::const_iterator itClone = _clones.begin();
    for (std::list<KnobWPtr >::const_iterator it = _knobs.begin(); it != _knobs.end(); ++it, ++itClone) {
        KnobPtr itKnob = it->lock();
        if (!itKnob) {
            continue;
        }
        KnobPtr itCloneKnob = itClone->lock();
        if (!itCloneKnob) {
            continue;
        }
        itKnob->cloneAndUpdateGui( itCloneKnob.get() );

        if ( itKnob->getHolder()->getApp() ) {
            int dim = itKnob->getDimension();
            for (int i = 0; i < dim; ++i) {
                if ( (i == _targetDim) || (_targetDim == -1) ) {
                    boost::shared_ptr<Curve> c = itKnob->getCurve(ViewIdx(0), i);
                    if (c) {
                        KeyFrameSet kfs = c->getKeyFrames_mt_safe();
                        for (KeyFrameSet::iterator it = kfs.begin(); it != kfs.end(); ++it) {
                            times.push_back( std::floor(it->getTime() + 0.5) );
                        }
                    }
                }
            }
        }
    }
    app->addMultipleKeyframeIndicatorsAdded(times, true);

    first->getHolder()->incrHashAndEvaluate(true, true);
    if ( first->getHolder()->getApp() ) {
        first->getHolder()->getApp()->redrawAllViewers();
    }

    setText( tr("Restore default value(s)") );
}
Пример #22
0
void
KnobGui::onShowInCurveEditorActionTriggered()
{
    KnobPtr knob = getKnob();

    assert( knob->getHolder()->getApp() );
    getGui()->setCurveEditorOnTop();
    std::vector<boost::shared_ptr<Curve> > curves;
    for (int i = 0; i < knob->getDimension(); ++i) {
        boost::shared_ptr<Curve> c = getCurve(ViewIdx(0), i);
        if ( c->isAnimated() ) {
            curves.push_back(c);
        }
    }
    if ( !curves.empty() ) {
        getGui()->getCurveEditor()->centerOn(curves);
    }
}
Пример #23
0
bool
OneViewNode::isIdentity(double time,
                        const RenderScale & /*scale*/,
                        const RectI & /*roi*/,
                        ViewIdx /*view*/,
                        double* inputTime,
                        ViewIdx* inputView,
                        int* inputNb)
{
    KnobChoicePtr viewKnob = _imp->viewKnob.lock();
    int view_i = viewKnob->getValue();

    *inputView = ViewIdx(view_i);
    *inputNb = 0;
    *inputTime = time;

    return true;
}
Пример #24
0
 bool areToPointsAnimated() const
 {
     bool hasAnimation = true;
     for (int i = 0; i < 4; ++i) {
         KnobDoublePtr knob = to[i].lock();
         for (int d = 0; d < 2; ++d) {
             bool dimHasAnim = knob->isAnimated(DimIdx(d), ViewIdx(0));
             if (!dimHasAnim) {
                 hasAnimation = false;
                 break;
             }
         }
         if (!hasAnimation) {
             break;
         }
     }
     return hasAnimation;
 }
Пример #25
0
void
TrackMarker::clearAnimationAfterTime(TimeValue time)
{
    std::set<double> userKeyframes;

    getMasterKeyFrameTimes(ViewIdx(0), &userKeyframes);

    KnobIPtr offsetKnob = getOffsetKnob();
    assert(offsetKnob);
    deleteKnobAnimation(userKeyframes, offsetKnob, eDeleteKnobAnimationAfterTime, time);

    KnobIPtr centerKnob = getCenterKnob();
    assert(centerKnob);
    deleteKnobAnimation(userKeyframes, centerKnob, eDeleteKnobAnimationAfterTime, time);

    KnobIPtr errorKnob = getErrorKnob();
    assert(errorKnob);
    deleteKnobAnimation(userKeyframes, errorKnob, eDeleteKnobAnimationAfterTime, time);
}
Пример #26
0
int
TrackMarker::getReferenceFrame(TimeValue time,
                               int frameStep) const
{
    QMutexLocker k(&_imp->trackMutex);

    std::set<double> userKeyframes;
    getMasterKeyFrameTimes(ViewIdx(0), &userKeyframes);

    std::set<double>::iterator upper = userKeyframes.upper_bound(time);

    if ( upper == userKeyframes.end() ) {
        //all keys are lower than time, pick the last one
        if ( !userKeyframes.empty() ) {
            return *userKeyframes.rbegin();
        }

        // no keyframe - use the previous/next as reference
        return time - frameStep;
    } else {
        if ( upper == userKeyframes.begin() ) {
            ///all keys are greater than time
            return *upper;
        }

        int upperKeyFrame = *upper;
        ///If we find "time" as a keyframe, then use it
        --upper;

        int lowerKeyFrame = *upper;

        if (lowerKeyFrame == time) {
            return time;
        }

        /// return the nearest from time
        return (time - lowerKeyFrame) < (upperKeyFrame - time) ? lowerKeyFrame : upperKeyFrame;
    }
}
Пример #27
0
void
TrackerHelper::trackMarkers(const std::list<TrackMarkerPtr >& markers,
                             TimeValue start,
                             TimeValue end,
                             TimeValue frameStep,
                            const ViewerNodePtr& viewer)
{
    if ( markers.empty() ) {
        Q_EMIT trackingFinished();
        return;
    }

    TrackerParamsProviderPtr provider = _imp->provider.lock();
    if (!provider) {
        Q_EMIT trackingFinished();
        return;
    }

    NodePtr trackerNode = provider->getTrackerNode();
    if (!trackerNode) {
        Q_EMIT trackingFinished();
        return;
    }

    if (trackerNode->hasMandatoryInputDisconnected()) {
        Q_EMIT trackingFinished();
        return;
    }



    // The channels we are going to use for tracking
    bool enabledChannels[3];
    provider->getTrackChannels(&enabledChannels[0], &enabledChannels[1], &enabledChannels[2]);


    double formatWidth, formatHeight;
    Format f;
    trackerNode->getApp()->getProject()->getProjectDefaultFormat(&f);
    formatWidth = f.width();
    formatHeight = f.height();

    bool autoKeyingOnEnabledParamEnabled = provider->canDisableMarkersAutomatically();

    /// The accessor and its cache is local to a track operation, it is wiped once the whole sequence track is finished.
    boost::shared_ptr<TrackerFrameAccessor> accessor( new TrackerFrameAccessor(trackerNode, enabledChannels, formatHeight) );
    boost::shared_ptr<mv::AutoTrack> trackContext( new mv::AutoTrack( accessor.get() ) );
    std::vector<TrackMarkerAndOptionsPtr > trackAndOptions;
    mv::TrackRegionOptions mvOptions;
    /*
     Get the global parameters for the LivMV track: pre-blur sigma, No iterations, normalized intensities, etc...
     */
    _imp->beginLibMVOptionsForTrack(&mvOptions);

    /*
     For the given markers, do the following:
     - Get the "User" keyframes that have been set and create a LibMV marker for each keyframe as well as for the "start" time
     - Set the "per-track" parameters that were given by the user, that is the mv::TrackRegionOptions
     - t->mvMarker will contain the marker that evolves throughout the tracking
     */
    int trackIndex = 0;
    for (std::list<TrackMarkerPtr >::const_iterator it = markers.begin(); it != markers.end(); ++it, ++trackIndex) {

        if (autoKeyingOnEnabledParamEnabled) {
            (*it)->setEnabledAtTime(start, true);
        }

        TrackMarkerAndOptionsPtr t(new TrackMarkerAndOptions);
        t->natronMarker = *it;

        int mode_i = (*it)->getMotionModelKnob()->getValue();
        mvOptions.mode = motionModelIndexToLivMVMode(mode_i);

        // Set a keyframe on the marker to initialize its position
        {
            KnobDoublePtr centerKnob = (*it)->getCenterKnob();
            std::vector<double> values(2);
            values[0] = centerKnob->getValueAtTime(start, DimIdx(0));
            values[1] = centerKnob->getValueAtTime(start, DimIdx(1));
            centerKnob->setValueAtTimeAcrossDimensions(start, values);
        }

        // For a translation warp, we do not need to add an animation curve for the pattern which stays constant.
        if (mvOptions.mode != libmv::TrackRegionOptions::TRANSLATION) {
            KnobDoublePtr patternCorners[4];
            patternCorners[0] = (*it)->getPatternBtmLeftKnob();
            patternCorners[1] = (*it)->getPatternBtmRightKnob();
            patternCorners[2] = (*it)->getPatternTopRightKnob();
            patternCorners[3] = (*it)->getPatternTopLeftKnob();
            for (int c = 0; c < 4; ++c) {
                KnobDoublePtr k = patternCorners[c];
                std::vector<double> values(2);
                values[0] = k->getValueAtTime(start, DimIdx(0));
                values[1] = k->getValueAtTime(start, DimIdx(1));
                k->setValueAcrossDimensions(values);
            }
        }

        std::set<double> userKeys;
        t->natronMarker->getMasterKeyFrameTimes(ViewIdx(0), &userKeys);

        if ( userKeys.empty() ) {
            // Set a user keyframe on tracking start if the marker does not have any user keys
            t->natronMarker->setKeyFrame(start, ViewSetSpec(0), 0);
        }

        PreviouslyTrackedFrameSet previousFramesOrdered;

        // Make sure to create a marker at the start time
        userKeys.insert(start);


        // Add a libmv marker for all keyframes
        for (std::set<double>::iterator it2 = userKeys.begin(); it2 != userKeys.end(); ++it2) {

            // Add the marker to the markers ordered only if it can contribute to predicting its next position
            if ( ( (frameStep > 0) && (*it2 <= start) ) || ( (frameStep < 0) && (*it2 >= start) ) ) {
                previousFramesOrdered.insert( PreviouslyComputedTrackFrame(TimeValue(*it2), true) );
            }
        }


        //For all already tracked frames which are not keyframes, add them to the AutoTrack too
        std::set<double> centerKeys;
        t->natronMarker->getCenterKeyframes(&centerKeys);

        for (std::set<double>::iterator it2 = centerKeys.begin(); it2 != centerKeys.end(); ++it2) {
            if ( userKeys.find(*it2) != userKeys.end() ) {
                continue;
            }

            // Add the marker to the markers ordered only if it can contribute to predicting its next position
            if ( ( ( (frameStep > 0) && (*it2 < start) ) || ( (frameStep < 0) && (*it2 > start) ) ) ) {
                previousFramesOrdered.insert( PreviouslyComputedTrackFrame(TimeValue(*it2), false) );
            }
        }


        // Taken from libmv, only initialize the filter to this amount of frames (max)
        const int max_frames_to_predict_from = 20;
        std::list<mv::Marker> previouslyComputedMarkersOrdered;

        // Find the first keyframe that's not considered to go before start or end
        PreviouslyTrackedFrameSet::iterator prevFramesIt = previousFramesOrdered.lower_bound(PreviouslyComputedTrackFrame(start, false));
        if (frameStep < 0) {
            if (prevFramesIt != previousFramesOrdered.end()) {
                while (prevFramesIt != previousFramesOrdered.end() && (int)previouslyComputedMarkersOrdered.size() != max_frames_to_predict_from) {

                    mv::Marker mvMarker;

                    TrackerHelperPrivate::natronTrackerToLibMVTracker(true, enabledChannels, *t->natronMarker, trackIndex, TimeValue(prevFramesIt->frame), frameStep, formatHeight, &mvMarker);
                    trackContext->AddMarker(mvMarker);

                    // insert in the front of the list so that the order is reversed
                    previouslyComputedMarkersOrdered.push_front(mvMarker);
                    ++prevFramesIt;
                }
            }
            // previouslyComputedMarkersOrdered is now ordererd by decreasing order
        } else {

            if (prevFramesIt != previousFramesOrdered.end()) {
                while (prevFramesIt != previousFramesOrdered.begin() && (int)previouslyComputedMarkersOrdered.size() != max_frames_to_predict_from) {

                    mv::Marker mvMarker;

                    TrackerHelperPrivate::natronTrackerToLibMVTracker(true, enabledChannels, *t->natronMarker, trackIndex, TimeValue(prevFramesIt->frame), frameStep, formatHeight, &mvMarker);
                    trackContext->AddMarker(mvMarker);

                    // insert in the front of the list so that the order is reversed
                    previouslyComputedMarkersOrdered.push_front(mvMarker);
                    --prevFramesIt;
                }
                if (prevFramesIt == previousFramesOrdered.begin() && (int)previouslyComputedMarkersOrdered.size() != max_frames_to_predict_from) {
                    mv::Marker mvMarker;

                    TrackerHelperPrivate::natronTrackerToLibMVTracker(true, enabledChannels, *t->natronMarker, trackIndex, TimeValue(prevFramesIt->frame), frameStep, formatHeight, &mvMarker);
                    trackContext->AddMarker(mvMarker);

                    // insert in the front of the list so that the order is reversed
                    previouslyComputedMarkersOrdered.push_front(mvMarker);

                }
            }
            // previouslyComputedMarkersOrdered is now ordererd by increasing order
        }


        // There must be at least 1 marker at the start time
        assert( !previouslyComputedMarkersOrdered.empty() );

        // Initialise the kalman state with the marker at the position

        std::list<mv::Marker>::iterator mIt = previouslyComputedMarkersOrdered.begin();
        t->mvState.Init(*mIt, frameStep);
        ++mIt;
        for (; mIt != previouslyComputedMarkersOrdered.end(); ++mIt) {
            mv::Marker predictedMarker;
            if ( !t->mvState.PredictForward(mIt->frame, &predictedMarker) ) {
                break;
            } else {
                t->mvState.Update(*mIt);
            }
        }


        t->mvOptions = mvOptions;
        trackAndOptions.push_back(t);
    }
    
    
    /*
     Launch tracking in the scheduler thread.
     */
    boost::shared_ptr<TrackArgs> args( new TrackArgs(start, end, frameStep, trackerNode->getApp()->getTimeLine(), viewer, trackContext, accessor, trackAndOptions, formatWidth, formatHeight, autoKeyingOnEnabledParamEnabled) );
    _imp->scheduler->track(args);
} // TrackerHelper::trackMarkers
Пример #28
0
bool
TrackMarkerPM::trackMarker(bool forward,
                           int refFrame,
                           int frame)
{
    KnobButtonPtr button;

    if (forward) {
        button = trackNextButton.lock();
    } else {
        button = trackPrevButton.lock();
    }
    KnobIntPtr refFrameK = refFrameKnob.lock();
    refFrameK->setValue(refFrame);

    // Unslave the center knob since the trackerNode will update it, then update the marker center
    KnobDoublePtr center = centerKnob.lock();
    center->unlink(DimSpec::all(), ViewSetSpec::all(), true);

    trackerNode->getEffectInstance()->onKnobValueChanged_public(button, eValueChangedReasonUserEdited, TimeValue(frame), ViewIdx(0));

    KnobDoublePtr markerCenter = getCenterKnob();
    // The TrackerPM plug-in has set a keyframe at the refFrame and frame, copy them
    bool ret = true;
    double centerPoint[2];
    for (int i = 0; i < center->getNDimensions(); ++i) {
        {
            int index = center->getKeyFrameIndex(ViewIdx(0), DimIdx(i), TimeValue(frame));
            if (index != -1) {
                centerPoint[i] = center->getValueAtTime(TimeValue(frame), DimIdx(i));
                markerCenter->setValueAtTime(TimeValue(frame), centerPoint[i], ViewSetSpec::all(), DimIdx(i));
            } else {
                // No keyframe at this time: tracking failed
                ret = false;
                break;
            }
        }
        {
            int index = center->getKeyFrameIndex(ViewIdx(0), DimIdx(i), TimeValue(refFrame));
            if (index != -1) {
                double value = center->getValueAtTime(TimeValue(refFrame), DimIdx(i));
                markerCenter->setValueAtTime(TimeValue(refFrame), value, ViewSetSpec::all(), DimIdx(i));
            }
        }
    }

    // Convert the correlation score of the TrackerPM to the error
    if (ret) {
        KnobDoublePtr markerError = getErrorKnob();
        KnobDoublePtr correlation = correlationScoreKnob.lock();
        {
            int index = correlation->getKeyFrameIndex(ViewIdx(0), DimIdx(0), TimeValue(frame));
            if (index != -1) {
                // The error is estimated as a percentage of the correlation across the number of pixels in the pattern window
                KnobDoublePtr  pBtmLeft = patternBtmLeftKnob.lock();
                KnobDoublePtr  pTopRight = patternTopRightKnob.lock();
                Point btmLeft, topRight;

                btmLeft.x = pBtmLeft->getValueAtTime(TimeValue(frame), DimIdx(0));
                btmLeft.y = pBtmLeft->getValueAtTime(TimeValue(frame), DimIdx(1));

                topRight.x = pTopRight->getValueAtTime(TimeValue(frame), DimIdx(0));
                topRight.y = pTopRight->getValueAtTime(TimeValue(frame), DimIdx(1));


                double areaPixels = (topRight.x - btmLeft.x) * (topRight.y - btmLeft.y);
                NodePtr trackerInput = trackerNode->getInput(0);
                if (trackerInput) {
                    ImagePlaneDesc comps, paireComps;
                    trackerInput->getEffectInstance()->getMetadataComponents(-1, &comps, &paireComps);
                    areaPixels *= comps.getNumComponents();
                }

                double value = correlation->getValueAtTime(TimeValue(frame), DimIdx(0));

                // Convert to a percentage
                if (areaPixels > 0) {
                    value /= areaPixels;
                }

                markerError->setValueAtTime(TimeValue(frame), value, ViewSetSpec::all(), DimIdx(0));
            }
        }
    }

    if ( !center->linkTo(markerCenter) ) {
        throw std::runtime_error("Could not link center");
    }

    return ret;
} // TrackMarkerPM::trackMarker
Пример #29
0
void
TrackMarker::resetCenter()
{
    KnobItemsTablePtr model = getModel();
    if (!model) {
        return;
    }
    RectD rod;
    NodePtr input = model->getNode()->getInput(0);
    if (!input) {
        Format f;
        getApp()->getProject()->getProjectDefaultFormat(&f);
        rod = f.toCanonicalFormat();
    } else {
        TimeValue time(input->getApp()->getTimeLine()->currentFrame());
        RenderScale scale(1.);
        RectD rod;
        {
            GetRegionOfDefinitionResultsPtr results;
            ActionRetCodeEnum stat = input->getEffectInstance()->getRegionOfDefinition_public(time, scale, ViewIdx(0), &results);
            if (!isFailureRetCode(stat)) {
                rod = results->getRoD();
            }
        }
        Point center;
        center.x = 0;
        center.y = 0;
        center.x = (rod.x1 + rod.x2) / 2.;
        center.y = (rod.y1 + rod.y2) / 2.;


        KnobDoublePtr centerKnob = getCenterKnob();
        centerKnob->setValue(center.x, ViewSetSpec::all(), DimIdx(0));
        centerKnob->setValue(center.y, ViewSetSpec::all(), DimIdx(1));
    }
}
Пример #30
0
bool
TrackMarker::isEnabled(TimeValue time) const
{
    return _imp->enabled.lock()->getValueAtTime(time, DimIdx(0), ViewIdx(0), true);
}