StageObjectsData *StageObjectsData::clone() const { StageObjectsData *data = new StageObjectsData(); // Clone each element (the new data gets ownership) int i, elementsCount = m_elements.size(); for (i = 0; i < elementsCount; ++i) data->m_elements.append(m_elements[i]->clone()); // Clone each spline (the new data gets ownership) for (i = 0; i < m_splines.size(); ++i) data->m_splines.append(m_splines[i]->clone()); // Same for internal fxs std::map<TFx *, TFx *> fxTable; // And trace the pairings with the originals std::set<TFx *>::const_iterator it; for (it = m_fxs.begin(); it != m_fxs.end(); ++it) { TFx *fxOrig = *it; assert(fxOrig); assert(fxTable.count(fxOrig) == 0); TFx *fx = fxOrig->clone(false); fx->getAttributes()->setId(fxOrig->getAttributes()->getId()); fx->getAttributes()->passiveCacheDataIdx() = -1; fx->setName(fxOrig->getName()); fx->setFxId(fxOrig->getFxId()); fxTable[fxOrig] = fx; fx->addRef(); data->m_fxs.insert(fx); } // Same with terminals for (it = m_terminalFxs.begin(); it != m_terminalFxs.end(); ++it) { TFx *fxOrig = *it; assert(fxOrig); // If the fx was not already cloned above, do it now TFx *fx = searchFx(fxTable, fxOrig); if (!fx) { fx = fxOrig->clone(false); fx->getAttributes()->setId(fxOrig->getAttributes()->getId()); fx->getAttributes()->passiveCacheDataIdx() = -1; fx->setName(fxOrig->getName()); fx->setFxId(fxOrig->getFxId()); fxTable[fxOrig] = fx; } fx->addRef(); data->m_terminalFxs.insert(fx); } if (!fxTable.empty()) updateFxLinks(fxTable); // Applies the traced map pairings to every fx descendant // of each fx stored in the map. // WARNING: m_fxsTable is NOT COPIED / CLONED !! return data; }
TFx *TMacroFx::getFxById(const wstring &id) const { int i; for (i = 0; i < (int)m_fxs.size(); i++) { TFx *fx = m_fxs[i].getPointer(); if (fx->getFxId() == id) return fx; } return 0; }
void MultimediaRenderer::Imp::start() { //Retrieve some useful infos double stretchTo = m_renderSettings.m_timeStretchTo; double stretchFrom = m_renderSettings.m_timeStretchFrom; double timeStretchFactor = stretchFrom / stretchTo; bool fieldRendering = m_renderSettings.m_fieldPrevalence != TRenderSettings::NoField; std::wstring modeStr; switch (m_multimediaMode) { case COLUMNS: modeStr = L"_col"; break; case LAYERS: modeStr = L"_lay"; break; default: assert(0); } //Build the post processing fxs tree std::vector<TFxP> postFxs(m_framesToRender.size()); std::set<double>::iterator jt; int j; for (j = 0, jt = m_framesToRender.begin(); jt != m_framesToRender.end(); ++j, ++jt) postFxs[j] = buildPostSceneFx(m_scene, *jt, m_renderSettings.m_shrinkX, false); // Adds camera and camera dpi transforms //For each node to be rendered int i, count = m_fxsToRender.getFxCount(); for (i = 0; i < count; ++i) { //In case the process has been canceled, return if (m_canceled) return; //Then, build the scene fx for each frame to be rendered std::vector<std::pair<double, TFxPair>> pairsToBeRendered; //NOTE: The above pairs should not be directly added to a previously declared movierenderer, //since an output level would be created even before knowing if any cell to be rendered is //actually available. const BSFX_Transforms_Enum transforms = // Do NOT add camera and BSFX_Transforms_Enum(BSFX_COLUMN_TR); // camera dpi transforms int j; for (j = 0, jt = m_framesToRender.begin(); jt != m_framesToRender.end(); ++j, ++jt) { TFxPair fx; if (m_renderSettings.m_stereoscopic) m_scene->shiftCameraX(-m_renderSettings.m_stereoscopicShift / 2); fx.m_frameA = buildSceneFx(m_scene, *jt, 0, m_fxsToRender.getFx(i), transforms); if (m_renderSettings.m_stereoscopic) { m_scene->shiftCameraX(m_renderSettings.m_stereoscopicShift); fx.m_frameB = buildSceneFx(m_scene, *jt, 0, m_fxsToRender.getFx(i), transforms); m_scene->shiftCameraX(-m_renderSettings.m_stereoscopicShift / 2); } else if (fieldRendering) fx.m_frameB = buildSceneFx(m_scene, *jt + 0.5 * timeStretchFactor, 0, m_fxsToRender.getFx(i), transforms); else fx.m_frameB = TRasterFxP(); //Substitute with the post-process... if (fx.m_frameA) fx.m_frameA = addPostProcessing(fx.m_frameA, postFxs[j]); if (fx.m_frameB) fx.m_frameB = addPostProcessing(fx.m_frameB, postFxs[j]); if (fx.m_frameA) //Could be 0, if the corresponding cell is void / not rendered pairsToBeRendered.push_back(std::pair<double, TFxPair>(*jt, fx)); } if (pairsToBeRendered.size() == 0) continue; //Could be, if no cell for this column was in the frame range. //Build the output name TColumnFx *colFx = searchColumn(m_fxsToRender.getFx(i)); TFx *currFx = m_fxsToRender.getFx(i); assert(colFx); if (!colFx) continue; int columnIndex = colFx->getColumnIndex(); std::wstring columnName(colFx->getColumnName()); std::wstring columnId(colFx->getColumnId()); std::wstring fxName(currFx->getName()); std::wstring fxNameNoSpaces(::removeSpaces(fxName)); std::wstring fxId(currFx->getFxId()); std::wstring fpName = m_fp.getWideName() + L"_" + columnName + (columnId == columnName ? L"" : L"(" + columnId + L")") + (fxId.empty() ? L"" : L"_" + fxName + (fxId == fxNameNoSpaces ? L"" : L"(" + fxId + L")")); TFilePath movieFp(m_fp.withName(fpName)); //Initialize a MovieRenderer with our infos MovieRenderer movieRenderer(m_scene, movieFp, m_threadCount, false); movieRenderer.setRenderSettings(m_renderSettings); movieRenderer.setDpi(m_xDpi, m_yDpi); movieRenderer.enablePrecomputing(m_precomputingEnabled); movieRenderer.addListener(this); for (unsigned int j = 0; j < pairsToBeRendered.size(); ++j) { std::pair<double, TFxPair> ¤tPair = pairsToBeRendered[j]; movieRenderer.addFrame(currentPair.first, currentPair.second); } //Finally, start rendering currently initialized MovieRenderer. m_currentFx = i; m_currentFrame = m_framesToRender.begin(); m_currentTRenderer = movieRenderer.getTRenderer(); movieRenderer.start(); //I don't recall Toonz currently supports different, simultaneous rendering processes. //However, one rendering process is supposed to be exhausting the machine's resources //on its own - so, we'll just set up an idle (but GUI-reactive) loop here. //It will quit looping whenever the "onSequenceCompleted" notification gets called. m_eventLoop.exec(); //---------------------- Loops here -------------------------- } //Lastly, inform everyone that rendering stopped onRenderCompleted(); }