Beispiel #1
0
ViewerTab::~ViewerTab()
{
    Gui* gui = getGui();
    if (gui) {
        NodeGraph* graph = 0;
        ViewerNodePtr internalNode = getInternalNode();

        ViewerInstancePtr viewerNode = internalNode ? internalNode->getInternalViewerNode() : ViewerInstancePtr();
        if (viewerNode) {
            NodeCollectionPtr collection = viewerNode->getNode()->getGroup();
            if (collection) {
                NodeGroupPtr isGrp = toNodeGroup(collection);
                if (isGrp) {
                    NodeGraphI* graph_i = isGrp->getNodeGraph();
                    if (graph_i) {
                        graph = dynamic_cast<NodeGraph*>(graph_i);
                        assert(graph);
                    }
                } else {
                    graph = gui->getNodeGraph();
                }
            }
            internalNode->invalidateUiContext();
        } else {
            graph = gui->getNodeGraph();
        }
        assert(graph);
        GuiAppInstancePtr app = gui->getApp();
        if ( app && !app->isClosing() && graph && (graph->getLastSelectedViewer() == this) ) {
            graph->setLastSelectedViewer(0);
        }
    }
    _imp->nodesContext.clear();
}
Beispiel #2
0
void
ViewerTab::onTimeLineTimeChanged(SequenceTime time,
                                 int reason)
{
    Gui* gui = getGui();
    if (!gui) {
        return;
    }
    ViewerNodePtr node = _imp->viewerNode.lock();
    ViewerInstancePtr viewerNode = node->getInternalViewerNode();
    if ((TimelineChangeReasonEnum)reason != eTimelineChangeReasonPlaybackSeek) {
        node->getCurrentFrameKnob()->setValue(time, ViewSetSpec::current(), DimIdx(0), eValueChangedReasonPluginEdited);
    }

    GuiAppInstancePtr app = gui->getApp();
    if ( app &&  _imp->timeLineGui->getTimeline() != app->getTimeLine() ) {
        viewerNode->renderCurrentFrame(true);
    }
}
Beispiel #3
0
void
ViewerTab::abortViewersAndRefresh()
{
    Gui* gui = getGui();
    if (!gui) {
        return;
    }
    const std::list<ViewerTab*> & activeNodes = gui->getViewersList();
    for (std::list<ViewerTab*>::const_iterator it = activeNodes.begin(); it != activeNodes.end(); ++it) {
        ViewerNodePtr viewer = (*it)->getInternalNode();
        if (viewer) {
            ViewerInstancePtr instance = viewer->getInternalViewerNode();
            if (instance) {
                RenderEnginePtr engine = instance->getRenderEngine();
                if ( engine ) {
                    engine->abortRenderingAutoRestart();
                    engine->renderCurrentFrame(false, true);
                }
            }
        }
    }
}
Beispiel #4
0
void
ViewerNodePrivate::setAlphaChannelFromLayerIfRGBA()
{

    ImagePlaneDesc selectedLayer, selectedAlphaLayer, selectedDisplayLayer;
    int alphaChannelIndex;
    ViewerInstancePtr internalViewer = internalViewerProcessNode[0].lock()->isEffectViewerInstance();
    internalViewer->getChannelOptions(_publicInterface->getTimelineCurrentTime(), &selectedLayer, &selectedAlphaLayer, &alphaChannelIndex, &selectedDisplayLayer);

    // Set the alpha channel to the selected layer's alpha channel if it is not pointing to anything
    if (selectedLayer.getNumComponents() == 4 && selectedAlphaLayer.getNumComponents() == 0) {

        ChoiceOption newOption = selectedLayer.getChannelOption(3);
        KnobChoicePtr alphaChoice = alphaChannelKnob.lock();
        std::vector<ChoiceOption> options = alphaChoice->getEntries();
        for (std::size_t i = 0; i < options.size(); ++i) {
            if (options[i].id == newOption.id) {
                alphaChoice->setValue(i);
                break;
            }
        }
    }

}
Beispiel #5
0
void
ViewerNode::createViewerProcessNode()
{
    NodePtr internalViewerNode[2];

    for (int i = 0; i < 2; ++ i) {
        ViewerNodePtr thisShared = shared_from_this();

        QString nodeName = QString::fromUtf8("ViewerProcess");
        nodeName += QString::number(i + 1);
        CreateNodeArgsPtr args(CreateNodeArgs::create(PLUGINID_NATRON_VIEWER_INTERNAL, thisShared));
        args->setProperty<bool>(kCreateNodeArgsPropAutoConnect, false);
        args->setProperty<bool>(kCreateNodeArgsPropAddUndoRedoCommand, false);
        args->setProperty<bool>(kCreateNodeArgsPropAllowNonUserCreatablePlugins, true);
        args->setProperty<bool>(kCreateNodeArgsPropSettingsOpened, false);
        args->setProperty<std::string>(kCreateNodeArgsPropNodeInitialName, nodeName.toStdString());
        internalViewerNode[i] = getApp()->createNode(args);
        assert(internalViewerNode[i]);
        if (!internalViewerNode[i]) {
            throw std::invalid_argument("ViewerNode::setupGraph: No internal viewer process!");
        }


        if (i == 1) {
            Point position;
            internalViewerNode[0]->getPosition(&position.x, &position.y);
            double w,h;
            internalViewerNode[0]->getSize(&w, &h);
            internalViewerNode[0]->setPosition(position.x - w /2. - w/2, position.y);

            internalViewerNode[1]->setPosition(position.x + w /2., position.y);

        }

        _imp->internalViewerProcessNode[i] = internalViewerNode[i];

        // Link output layer and alpha channel to the viewer process choices
        KnobIPtr viewerProcessOutputLayerChoice = internalViewerNode[i]->getKnobByName(kViewerInstanceParamOutputLayer);
        viewerProcessOutputLayerChoice->linkTo(_imp->layersKnob.lock());

        KnobIPtr viewerProcessAlphaChannelChoice = internalViewerNode[i]->getKnobByName(kViewerInstanceParamAlphaChannel);
        viewerProcessAlphaChannelChoice->linkTo(_imp->alphaChannelKnob.lock());

        KnobIPtr viewerProcessDisplayChanelsChoice = internalViewerNode[i]->getKnobByName(kViewerInstanceParamDisplayChannels);
        viewerProcessDisplayChanelsChoice->linkTo(_imp->displayChannelsKnob[i].lock());

        KnobIPtr viewerProcessGammaKnob = internalViewerNode[i]->getKnobByName(kViewerInstanceParamGamma);
        viewerProcessGammaKnob->linkTo(_imp->gammaSliderKnob.lock());

        KnobIPtr viewerProcessGainKnob = internalViewerNode[i]->getKnobByName(kViewerInstanceNodeParamGain);
        viewerProcessGainKnob->linkTo(_imp->gainSliderKnob.lock());

        KnobIPtr viewerProcessAutoContrastKnob = internalViewerNode[i]->getKnobByName(kViewerInstanceParamEnableAutoContrast);
        viewerProcessAutoContrastKnob->linkTo(_imp->enableAutoContrastButtonKnob.lock());

        KnobIPtr viewerProcessAutoColorspaceKnob = internalViewerNode[i]->getKnobByName(kViewerInstanceParamColorspace);
        viewerProcessAutoColorspaceKnob->linkTo(_imp->colorspaceKnob.lock());

        KnobIPtr userRoiEnabledKnob = internalViewerNode[i]->getKnobByName(kViewerInstanceParamEnableUserRoI);
        userRoiEnabledKnob->linkTo(_imp->toggleUserRoIButtonKnob.lock());

        KnobIPtr userRoiBtmLeftKnob = internalViewerNode[i]->getKnobByName(kViewerInstanceParamUserRoIBottomLeft);
        userRoiBtmLeftKnob->linkTo(_imp->userRoIBtmLeftKnob.lock());

        KnobIPtr userRoiSizeKnob = internalViewerNode[i]->getKnobByName(kViewerInstanceParamUserRoISize);
        userRoiSizeKnob->linkTo(_imp->userRoISizeKnob.lock());

        KnobIPtr clipToFormatKnob = internalViewerNode[i]->getKnobByName(kViewerInstanceParamClipToFormat);
        clipToFormatKnob->linkTo(_imp->clipToFormatButtonKnob.lock());


        // A ViewerNode is composed of 2 ViewerProcess nodes but it only has 1 layer and 1 alpha channel choices.
        // We thus disable the refreshing of the menu from the 2nd ViewerProcess node.
        if (i == 1) {
            ViewerInstancePtr instance = internalViewerNode[i]->isEffectViewerInstance();
            instance->setRefreshLayerAndAlphaChoiceEnabled(false);
        }
    }

    Q_EMIT internalViewerCreated();
} // createViewerProcessNode
static ActionRetCodeEnum createFrameRenderResultsForView(const ViewerNodePtr& viewer,
                                                         const TreeRenderQueueProviderPtr& provider,
                                                         const ViewerRenderFrameResultsContainerPtr& results,
                                                         ViewIdx view,
                                                         const RenderStatsPtr& stats,
                                                         bool isPlayback,
                                                         const RectD* partialUpdateRoIParam,
                                                         unsigned int mipMapLevel,
                                                         ViewerCompositingOperatorEnum viewerBlend,
                                                         bool byPassCache,
                                                         bool draftModeEnabled,
                                                         bool fullFrameProcessing,
                                                         bool viewerBEqualsViewerA,
                                                         const RotoStrokeItemPtr& activeDrawingStroke)
{

    // Initialize for each view a sub-result.
    // Each view has 2 renders: the A and B viewerprocess
    ViewerRenderFrameSubResultPtr subResult(new ViewerRenderFrameSubResult);
    results->frames.push_back(subResult);
    subResult->view = view;
    subResult->stats = stats;

    if (partialUpdateRoIParam) {
        subResult->textureTransferType = OpenGLViewerI::TextureTransferArgs::eTextureTransferTypeOverlay;
    } else if (activeDrawingStroke && activeDrawingStroke->getRenderCloneCurrentStrokeStartPointIndex() > 0) {
        // Upon painting ticks, we just have to update the viewer for the area that was painted
        subResult->textureTransferType = OpenGLViewerI::TextureTransferArgs::eTextureTransferTypeModify;
    } else {
        subResult->textureTransferType = OpenGLViewerI::TextureTransferArgs::eTextureTransferTypeReplace;
    }

    for (int viewerInputIndex = 0; viewerInputIndex < 2; ++viewerInputIndex) {
        subResult->perInputsData[viewerInputIndex].retCode = eActionStatusFailed;
        if (viewerInputIndex == 1 && (viewerBEqualsViewerA || viewerBlend == eViewerCompositingOperatorNone)) {
            if (viewerBEqualsViewerA && viewerBlend != eViewerCompositingOperatorNone) {
                subResult->copyInputBFromA = true;
            }
            continue;
        }
        if (viewer->isViewerPaused(viewerInputIndex)) {
            subResult->perInputsData[viewerInputIndex].retCode = eActionStatusAborted;
            continue;
        }
        ViewerInstancePtr viewerProcess = viewer->getViewerProcessNode(viewerInputIndex);
        subResult->perInputsData[viewerInputIndex].viewerProcessNode = viewerProcess->getNode();



        TreeRender::CtorArgsPtr initArgs(new TreeRender::CtorArgs);
        initArgs->treeRootEffect = viewerProcess;
        initArgs->provider = provider;
        initArgs->time = results->time;
        initArgs->view = subResult->view;

        // Render by default on disk is always using a mipmap level of 0 but using the proxy scale of the project
        initArgs->mipMapLevel = mipMapLevel;


#pragma message WARN("Todo: set proxy scale here")
        initArgs->proxyScale = RenderScale(1.);

        // Render the RoD if fullframe processing
        if (partialUpdateRoIParam) {
            initArgs->canonicalRoI = *partialUpdateRoIParam;
        } else {
            RectD roi;
            if (!fullFrameProcessing) {
                roi = viewerProcess->getViewerRoI();
            }
            initArgs->canonicalRoI = roi;

        }
        
        initArgs->stats = stats;
        initArgs->activeRotoDrawableItem = activeDrawingStroke;
        initArgs->draftMode = draftModeEnabled;
        initArgs->playback = isPlayback;
        initArgs->byPassCache = byPassCache;
        initArgs->preventConcurrentTreeRenders = (activeDrawingStroke || partialUpdateRoIParam);
        if (!isPlayback && subResult->textureTransferType == OpenGLViewerI::TextureTransferArgs::eTextureTransferTypeReplace && !activeDrawingStroke) {
            subResult->perInputsData[viewerInputIndex].colorPickerNode = viewerInputIndex == 0 ? viewer->getCurrentAInput() : viewer->getCurrentBInput();
            if (subResult->perInputsData[viewerInputIndex].colorPickerNode) {
                // Also sample the "main" input of the color picker node, this is useful for keyers.
                int mainInput = subResult->perInputsData[viewerInputIndex].colorPickerNode->getPreferredInput();
                subResult->perInputsData[viewerInputIndex].colorPickerInputNode = subResult->perInputsData[viewerInputIndex].colorPickerNode->getInput(mainInput);
            }
        }
        if (subResult->perInputsData[viewerInputIndex].colorPickerNode) {
            initArgs->extraNodesToSample.push_back(subResult->perInputsData[viewerInputIndex].colorPickerNode);
        }
        if (subResult->perInputsData[viewerInputIndex].colorPickerInputImage) {
            initArgs->extraNodesToSample.push_back(subResult->perInputsData[viewerInputIndex].colorPickerInputNode);
        }

        subResult->perInputsData[viewerInputIndex].render = TreeRender::create(initArgs);
        if (!subResult->perInputsData[viewerInputIndex].render) {
            return eActionStatusFailed;
        }

    } // for each viewer input
    return eActionStatusOK;
} // createFrameRenderResultsForView
Beispiel #7
0
void
Gui::removeViewerTab(ViewerTab* tab,
                     bool initiatedFromNode,
                     bool deleteData)
{
    assert(tab);
    unregisterTab(tab);

    if (tab == _imp->_activeViewer) {
        _imp->_activeViewer = 0;
    }
    NodeGraph* graph = 0;
    NodeGroupPtr isGrp;
    NodeCollectionPtr collection;
    if ( tab->getInternalNode() && tab->getInternalNode()->getNode() ) {
        NodeCollectionPtr collection = tab->getInternalNode()->getNode()->getGroup();
        isGrp = toNodeGroup(collection);
    }


    if (isGrp) {
        NodeGraphI* graph_i = isGrp->getNodeGraph();
        assert(graph_i);
        graph = dynamic_cast<NodeGraph*>(graph_i);
    } else {
        graph = getNodeGraph();
    }
    assert(graph);
    if (!graph) {
        throw std::logic_error("");
    }

    ViewerTab* lastSelectedViewer = graph->getLastSelectedViewer();

    if (lastSelectedViewer == tab) {
        bool foundOne = false;
        NodesList nodes;
        if (collection) {
            nodes = collection->getNodes();
        }
        for (NodesList::iterator it = nodes.begin(); it != nodes.end(); ++it) {
            ViewerNodePtr isViewer = (*it)->isEffectViewerNode();
            if ( !isViewer || ( isViewer == tab->getInternalNode() ) || !(*it)->isActivated() ) {
                continue;
            }
            OpenGLViewerI* viewerI = isViewer->getUiContext();
            assert(viewerI);
            ViewerGL* glViewer = dynamic_cast<ViewerGL*>(viewerI);
            assert(glViewer);
            if (glViewer) {
                graph->setLastSelectedViewer( glViewer->getViewerTab() );
            }
            foundOne = true;
            break;
        }
        if (!foundOne) {
            graph->setLastSelectedViewer(0);
        }
    }

    ViewerNodePtr viewerNode = tab->getInternalNode();
    ViewerInstancePtr internalViewer;
    if (viewerNode) {
        internalViewer = viewerNode->getInternalViewerNode();
    }
    if (internalViewer) {
        internalViewer->abortAnyEvaluation();
        if (getApp()->getLastViewerUsingTimeline() == internalViewer) {
            getApp()->discardLastViewerUsingTimeline();
        }
    }

    if (!initiatedFromNode) {
        assert(_imp->_nodeGraphArea);
        ///call the deleteNode which will call this function again when the node will be deactivated.
        NodePtr internalNode = tab->getInternalNode()->getNode();
        NodeGuiIPtr guiI = internalNode->getNodeGui();
        NodeGuiPtr gui = boost::dynamic_pointer_cast<NodeGui>(guiI);
        assert(gui);
        NodeGraphI* graph_i = internalNode->getGroup()->getNodeGraph();
        assert(graph_i);
        NodeGraph* graph = dynamic_cast<NodeGraph*>(graph_i);
        assert(graph);
        if (graph) {
            graph->removeNode(gui);
        }
    } else {
        tab->hide();


        TabWidget* container = dynamic_cast<TabWidget*>( tab->parentWidget() );
        if (container) {
            container->removeTab(tab, false);
        }

        if (deleteData) {
            QMutexLocker l(&_imp->_viewerTabsMutex);
            std::list<ViewerTab*>::iterator it = std::find(_imp->_viewerTabs.begin(), _imp->_viewerTabs.end(), tab);
            if ( it != _imp->_viewerTabs.end() ) {
                _imp->_viewerTabs.erase(it);
            }
            tab->notifyGuiClosingPublic();
            tab->deleteLater();
        }
    }
    Q_EMIT viewersChanged();
} // Gui::removeViewerTab
void
ProjectGuiSerialization::initialize(const ProjectGui* projectGui)
{
    NodesList activeNodes;

    projectGui->getInternalProject()->getActiveNodesExpandGroups(&activeNodes);

    _serializedNodes.clear();
    for (NodesList::iterator it = activeNodes.begin(); it != activeNodes.end(); ++it) {
        NodeGuiIPtr nodegui_i = (*it)->getNodeGui();
        if (!nodegui_i) {
            continue;
        }
        NodeGuiPtr nodegui = boost::dynamic_pointer_cast<NodeGui>(nodegui_i);

        if ( nodegui->isVisible() ) {
            NodeCollectionPtr isInCollection = (*it)->getGroup();
            NodeGroupPtr isCollectionAGroup = toNodeGroup( isInCollection );
            if (!isCollectionAGroup) {
                ///Nodes within a group will be serialized recursively in the node group serialization
                NodeGuiSerialization state;
                nodegui->serialize(&state);
                _serializedNodes.push_back(state);
            }
            ViewerInstancePtr viewer = (*it)->isEffectViewerInstance();
            if (viewer) {
                ViewerTab* tab = projectGui->getGui()->getViewerTabForInstance(viewer);
                assert(tab);
                ViewerData viewerData;
                double zoompar;
                tab->getViewer()->getProjection(&viewerData.zoomLeft, &viewerData.zoomBottom, &viewerData.zoomFactor, &zoompar);
                viewerData.userRoI = tab->getViewer()->getUserRegionOfInterest();
                viewerData.userRoIenabled = tab->getViewer()->isUserRegionOfInterestEnabled();
                viewerData.isClippedToProject = tab->isClippedToProject();
                viewerData.autoContrastEnabled = tab->isAutoContrastEnabled();
                viewerData.gain = tab->getGain();
                viewerData.gamma = tab->getGamma();
                viewerData.colorSpace = tab->getColorSpace();
                viewerData.channels = tab->getChannelsString();
                viewerData.renderScaleActivated = tab->getRenderScaleActivated();
                viewerData.mipMapLevel = tab->getMipMapLevel();
                viewerData.zoomOrPanSinceLastFit = tab->getZoomOrPannedSinceLastFit();
                viewerData.wipeCompositingOp = (int)tab->getCompositingOperator();
                viewerData.leftToolbarVisible = tab->isLeftToolbarVisible();
                viewerData.rightToolbarVisible = tab->isRightToolbarVisible();
                viewerData.topToolbarVisible = tab->isTopToolbarVisible();
                viewerData.infobarVisible = tab->isInfobarVisible();
                viewerData.playerVisible = tab->isPlayerVisible();
                viewerData.timelineVisible = tab->isTimelineVisible();
                viewerData.checkerboardEnabled = tab->isCheckerboardEnabled();
                viewerData.isFullFrameProcessEnabled = tab->isFullFrameProcessingEnabled();
                viewerData.fps = tab->getDesiredFps();
                viewerData.fpsLocked = tab->isFPSLocked();
                viewerData.isPauseEnabled[0] = tab->isViewerPaused(0);
                viewerData.isPauseEnabled[1] = tab->isViewerPaused(1);
                viewerData.layerName = tab->getCurrentLayerName().toStdString();
                viewerData.alphaLayerName = tab->getCurrentAlphaLayerName().toStdString();
                tab->getTimelineBounds(&viewerData.leftBound, &viewerData.rightBound);
                tab->getActiveInputs(&viewerData.aChoice, &viewerData.bChoice);
                viewerData.version = VIEWER_DATA_SERIALIZATION_VERSION;
                _viewersData.insert( std::make_pair(viewer->getNode()->getScriptName_mt_safe(), viewerData) );
            }
        }
    }

    ///Init windows
    _layoutSerialization.initialize( projectGui->getGui() );

    ///save histograms
    std::list<Histogram*> histograms = projectGui->getGui()->getHistograms_mt_safe();
    for (std::list<Histogram*>::const_iterator it = histograms.begin(); it != histograms.end(); ++it) {
        _histograms.push_back( (*it)->objectName().toStdString() );
    }

    ///save opened panels by order

    std::list<DockablePanel*> panels = projectGui->getGui()->getVisiblePanels_mt_safe();
    for (std::list<DockablePanel*>::iterator it = panels.begin(); it != panels.end(); ++it) {
        if ( (*it)->isVisible() ) {
            KnobHolderPtr holder = (*it)->getHolder();
            assert(holder);

            EffectInstancePtr isEffect = toEffectInstance(holder);
            ProjectPtr isProj = toProject(holder);

            if (isProj) {
                _openedPanelsOrdered.push_back(kNatronProjectSettingsPanelSerializationName);
            } else if (isEffect) {
                _openedPanelsOrdered.push_back( isEffect->getNode()->getFullyQualifiedName() );
            }
        }
    }

    _scriptEditorInput = projectGui->getGui()->getScriptEditor()->getAutoSavedScript().toStdString();

    std::map<NATRON_PYTHON_NAMESPACE::PyPanel*, std::string> pythonPanels = projectGui->getGui()->getPythonPanels();
    for (std::map<NATRON_PYTHON_NAMESPACE::PyPanel*, std::string>::iterator it = pythonPanels.begin(); it != pythonPanels.end(); ++it) {
        boost::shared_ptr<PythonPanelSerialization> s(new PythonPanelSerialization);
        s->initialize(it->first, it->second);
        _pythonPanels.push_back(s);
    }
} // initialize