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
void TrackMarkerPM::initializeKnobs() { TrackMarker::initializeKnobs(); NodePtr thisNode = getModel()->getNode(); NodePtr node; { CreateNodeArgsPtr args(CreateNodeArgs::create( PLUGINID_OFX_TRACKERPM, NodeCollectionPtr() )); args->setProperty<bool>(kCreateNodeArgsPropVolatile, true); args->setProperty<bool>(kCreateNodeArgsPropNoNodeGUI, true); args->setProperty<std::string>(kCreateNodeArgsPropNodeInitialName, "TrackerPMNode"); node = getApp()->createNode(args); if (!node) { throw std::runtime_error("Couldn't create plug-in " PLUGINID_OFX_TRACKERPM); } if (thisNode) { NodePtr inputNode = thisNode->getInput(0); if (inputNode) { node->connectInput(inputNode, 0); } } trackerNode = node; } KnobItemsTablePtr model = getModel(); EffectInstancePtr effect; if (model) { effect = model->getNode()->getEffectInstance(); } trackPrevButton = getNodeKnob<KnobButton>(node, kTrackerPMParamTrackingPrevious); trackNextButton = getNodeKnob<KnobButton>(node, kTrackerPMParamTrackingNext); KnobDoublePtr center = getNodeKnob<KnobDouble>(node, kTrackerPMParamTrackingCenterPoint); centerKnob = center; // Slave the center knob and unslave when tracking if ( !center->linkTo(getCenterKnob()) ) { throw std::runtime_error("Could not link center"); } KnobDoublePtr offset = getNodeKnob<KnobDouble>(node, kTrackerPMParamTrackingOffset); // Slave the offset knob if ( !offset->linkTo( getOffsetKnob() ) ) { throw std::runtime_error("Could not link offset"); } offsetKnob = offset; // Ref frame is set for each refFrameKnob = getNodeKnob<KnobInt>(node, kTrackerPMParamTrackingReferenceFrame); // Enable reference frame KnobBoolPtr enableRefFrameKnob = getNodeKnob<KnobBool>(node, kTrackerPMParamTrackingEnableReferenceFrame); enableRefFrameKnob->setValue(true); KnobChoicePtr scoreType = getNodeKnob<KnobChoice>(node, kTrackerPMParamScore); if (effect) { #ifdef kTrackerParamPatternMatchingScoreType KnobIPtr modelKnob = effect->getKnobByName(kTrackerParamPatternMatchingScoreType); if (modelKnob) { if ( !scoreType->linkTo(modelKnob) ) { throw std::runtime_error("Could not link scoreType"); } } #endif } scoreTypeKnob = scoreType; KnobDoublePtr correlationScore = getNodeKnob<KnobDouble>(node, kTrackerPMParamTrackingCorrelationScore); correlationScoreKnob = correlationScore; KnobDoublePtr patternBtmLeft = getNodeKnob<KnobDouble>(node, kTrackerPMParamTrackingPatternBoxBtmLeft); patternBtmLeftKnob = patternBtmLeft; // Slave the search window and pattern of the node to the parameters of the marker (void)patternBtmLeft->linkTo(getPatternBtmLeftKnob()); KnobDoublePtr patternTopRight = getNodeKnob<KnobDouble>(node, kTrackerPMParamTrackingPatternBoxTopRight); patternTopRightKnob = patternTopRight; (void)patternTopRight->linkTo(getPatternTopRightKnob()); KnobDoublePtr searchWindowBtmLeft = getNodeKnob<KnobDouble>(node, kTrackerPMParamTrackingSearchBoxBtmLeft); searchWindowBtmLeftKnob = searchWindowBtmLeft; (void)searchWindowBtmLeft->linkTo(getSearchWindowBottomLeftKnob()); KnobDoublePtr searchWindowTopRight = getNodeKnob<KnobDouble>(node, kTrackerPMParamTrackingSearchBoxTopRight); searchWindowTopRightKnob = searchWindowTopRight; (void)searchWindowTopRight->linkTo(getSearchWindowTopRightKnob()); } // TrackMarkerPM::initializeKnobs
void TrackerNodePrivate::exportTrackDataFromExportOptions() { //bool transformLink = _imp->exportLink.lock()->getValue(); KnobChoicePtr transformTypeKnob = transformType.lock(); assert(transformTypeKnob); int transformType_i = transformTypeKnob->getValue(); TrackerTransformNodeEnum transformType = (TrackerTransformNodeEnum)transformType_i; KnobChoicePtr motionTypeKnob = motionType.lock(); if (!motionTypeKnob) { return; } int motionType_i = motionTypeKnob->getValue(); TrackerMotionTypeEnum mt = (TrackerMotionTypeEnum)motionType_i; if (mt == eTrackerMotionTypeNone) { Dialogs::errorDialog( tr("Tracker Export").toStdString(), tr("Please select the export mode with the Motion Type parameter").toStdString() ); return; } bool linked = exportLink.lock()->getValue(); QString pluginID; switch (transformType) { case eTrackerTransformNodeCornerPin: pluginID = QString::fromUtf8(PLUGINID_OFX_CORNERPIN); break; case eTrackerTransformNodeTransform: pluginID = QString::fromUtf8(PLUGINID_OFX_TRANSFORM); break; } NodePtr thisNode = publicInterface->getNode(); AppInstancePtr app = thisNode->getApp(); CreateNodeArgsPtr args(CreateNodeArgs::create( pluginID.toStdString(), thisNode->getGroup() )); args->setProperty<bool>(kCreateNodeArgsPropAutoConnect, false); args->setProperty<bool>(kCreateNodeArgsPropSettingsOpened, false); NodePtr createdNode = app->createNode(args); if (!createdNode) { return; } // Move the new node double thisNodePos[2]; double thisNodeSize[2]; thisNode->getPosition(&thisNodePos[0], &thisNodePos[1]); thisNode->getSize(&thisNodeSize[0], &thisNodeSize[1]); createdNode->setPosition(thisNodePos[0] + thisNodeSize[0] * 2., thisNodePos[1]); TimeValue timeForFromPoints(referenceFrame.lock()->getValue()); switch (transformType) { case eTrackerTransformNodeCornerPin: { KnobDoublePtr cornerPinToPoints[4]; KnobDoublePtr cornerPinFromPoints[4]; for (unsigned int i = 0; i < 4; ++i) { cornerPinFromPoints[i] = getCornerPinPoint(createdNode, true, i); assert(cornerPinFromPoints[i]); for (int j = 0; j < cornerPinFromPoints[i]->getNDimensions(); ++j) { cornerPinFromPoints[i]->setValue(fromPoints[i].lock()->getValueAtTime(timeForFromPoints, DimIdx(j)), ViewSetSpec::all(), DimIdx(j)); } cornerPinToPoints[i] = getCornerPinPoint(createdNode, false, i); assert(cornerPinToPoints[i]); if (!linked) { cornerPinToPoints[i]->copyKnob( toPoints[i].lock() ); } else { bool ok = cornerPinToPoints[i]->linkTo(toPoints[i].lock()); (void)ok; assert(ok); } } { KnobIPtr knob = createdNode->getKnobByName(kCornerPinParamMatrix); if (knob) { KnobDoublePtr isType = toKnobDouble(knob); if (isType) { isType->copyKnob(cornerPinMatrix.lock() ); } } } break; } case eTrackerTransformNodeTransform: { KnobIPtr translateKnob = createdNode->getKnobByName(kTransformParamTranslate); if (translateKnob) { KnobDoublePtr isDbl = toKnobDouble(translateKnob); if (isDbl) { if (!linked) { isDbl->copyKnob(translate.lock() ); } else { ignore_result(isDbl->linkTo(translate.lock())); } } } KnobIPtr scaleKnob = createdNode->getKnobByName(kTransformParamScale); if (scaleKnob) { KnobDoublePtr isDbl = toKnobDouble(scaleKnob); if (isDbl) { if (!linked) { isDbl->copyKnob(scale.lock() ); } else { ignore_result(isDbl->linkTo(scale.lock())); } } } KnobIPtr rotateKnob = createdNode->getKnobByName(kTransformParamRotate); if (rotateKnob) { KnobDoublePtr isDbl = toKnobDouble(rotateKnob); if (isDbl) { if (!linked) { isDbl->copyKnob(rotate.lock()); } else { ignore_result(isDbl->linkTo(rotate.lock())); } } } KnobIPtr centerKnob = createdNode->getKnobByName(kTransformParamCenter); if (centerKnob) { KnobDoublePtr isDbl = toKnobDouble(centerKnob); if (isDbl) { isDbl->copyKnob( center.lock() ); } } break; } } // switch KnobIPtr cpInvertKnob = createdNode->getKnobByName(kTransformParamInvert); if (cpInvertKnob) { KnobBoolPtr isBool = toKnobBool(cpInvertKnob); if (isBool) { if (!linked) { isBool->copyKnob(invertTransform.lock()); } else { ignore_result(isBool->linkTo(invertTransform.lock())); } } } { KnobIPtr knob = createdNode->getKnobByName(kTransformParamMotionBlur); if (knob) { KnobDoublePtr isType = toKnobDouble(knob); if (isType) { isType->copyKnob(motionBlur.lock()); } } } { KnobIPtr knob = createdNode->getKnobByName(kTransformParamShutter); if (knob) { KnobDoublePtr isType = toKnobDouble(knob); if (isType) { isType->copyKnob(shutter.lock()); } } } { KnobIPtr knob = createdNode->getKnobByName(kTransformParamShutterOffset); if (knob) { KnobChoicePtr isType = toKnobChoice(knob); if (isType) { isType->copyKnob(shutterOffset.lock()); } } } { KnobIPtr knob = createdNode->getKnobByName(kTransformParamCustomShutterOffset); if (knob) { KnobDoublePtr isType = toKnobDouble(knob); if (isType) { isType->copyKnob(customShutterOffset.lock()); } } } } // exportTrackDataFromExportOptions