Beispiel #1
0
std::vector<const TFx *> calculateSortedFxs(TRasterFxP rootFx) {
  std::map<const TFx *, std::set<const TFx *>> E; /* 辺の情報 */
  std::set<const TFx *> Sources; /* 入次数0のノード群 */

  std::queue<const TFx *> Q;
  Q.push(rootFx.getPointer());

  E[rootFx.getPointer()] = std::set<const TFx *>();

  while (!Q.empty()) {
    const TFx *vptr = Q.front();
    Q.pop();
    if (!vptr) {
      continue;
    }

    /* 繋がっている入力ポートの先の Fx を訪問する
入力ポートが無ければ終了 */
    int portCount = vptr->getInputPortCount();
    if (portCount < 1) {
      Sources.insert(vptr);
      continue;
    }
    for (int i = 0; i < portCount; i++) {
      TFxPort *port = vptr->getInputPort(i);
      if (!port) {
        continue;
      }
      TFxP u          = port->getFx();
      const TFx *uptr = u.getPointer();
      if (E.count(uptr) == 0) {
        E[uptr] = std::set<const TFx *>();
      }
      if (E[uptr].count(vptr) == 0) {
        E[uptr].insert(vptr);
      }
      Q.push(uptr);
    }
  }

  /* トポロジカルソート */
  std::set<const TFx *> visited;
  std::vector<const TFx *> L;
  std::function<void(const TFx *)> visit = [&visit, &visited, &E,
                                            &L](const TFx *fx) {
    if (visited.count(fx)) return;
    visited.insert(fx);
    auto edge = E[fx];
    for (auto i = edge.cbegin(); i != edge.cend(); i++) {
      visit(*i);
    }
    L.insert(L.begin(), fx);
  };
  for (auto i = E.cbegin(); i != E.cend(); i++) {
    visit(i->first);
  }
  return L;
}
void SwatchCacheManager::setFx(const TFxP &fx)
{
	QMutexLocker locker(&m_mutex);

	//Update the fxs id data
	if (fx == TFxP()) {
		//Clear if no fx is set
		m_setFxId = 0;
		m_childrenFxIds.clear();
	} else {
		m_setFxId = fx->getIdentifier();
		m_childrenFxIds.clear();
		assert(m_setFxId != 0);

		TRasterFx *rfx = dynamic_cast<TRasterFx *>(fx.getPointer());
		assert(rfx);

		for (int i = 0; i < fx->getInputPortCount(); ++i) {
			//Fxs not allowing cache on the input port are skipped
			if (!rfx->allowUserCacheOnPort(i))
				continue;

			TFxPort *iport = fx->getInputPort(i);
			if (iport && iport->isConnected()) {
				TFx *child = iport->getFx();

				//In the zerary case, extract the actual fx
				TZeraryColumnFx *zcfx = dynamic_cast<TZeraryColumnFx *>(child);
				if (zcfx)
					child = zcfx->getZeraryFx();

				assert(child && child->getIdentifier() != 0);
				m_childrenFxIds.insert(child->getIdentifier());
			}
		}
	}

	//NOTE: Check if this should be avoided in some case...

	//Release the locks and clear the resources
	if (m_currEditedFxResult)
		m_currEditedFxResult->releaseLock();
	m_currEditedFxResult = TCacheResourceP();

	std::set<TCacheResourceP>::iterator it;
	for (it = m_swatchCacheContainer.begin(); it != m_swatchCacheContainer.end(); ++it)
		(*it)->releaseLock();
	m_swatchCacheContainer.clear();

#ifdef USE_SQLITE_HDPOOL
	TCacheResourcePool::instance()->releaseReferences("S");
#else
	for (it = m_genericCacheContainer.begin(); it != m_genericCacheContainer.end(); ++it)
		(*it)->releaseLock();
	m_genericCacheContainer.clear();
#endif
}
TFxP MultimediaRenderer::Imp::addPostProcessing(TFxP fx, TFxP postProc)
{
	if (dynamic_cast<TXsheetFx *>(postProc.getPointer()))
		return fx;

	//Clone the postProcessing tree and substitute recursively
	postProc = postProc->clone(true);
	addPostProcessingRecursive(fx, postProc);

	return postProc;
}
bool FxSelection::isSelected(TFxP fx) const {
  int i;
  for (i = 0; i < m_selectedFxs.size(); i++) {
    TFx *selectedFx      = m_selectedFxs[i].getPointer();
    TZeraryColumnFx *zfx = dynamic_cast<TZeraryColumnFx *>(selectedFx);
    if (zfx &&
        (fx.getPointer() == zfx || fx.getPointer() == zfx->getZeraryFx()))
      return true;
    if (fx.getPointer() == selectedFx) return true;
  }
  return false;
}
void MultimediaRenderer::Imp::addPostProcessingRecursive(TFxP fx, TFxP postProc)
{
	if (!postProc)
		return;

	int i, count = postProc->getInputPortCount();
	for (i = 0; i < count; ++i) {
		TFxPort *port = postProc->getInputPort(i);
		TFx *childFx = port->getFx();

		if (dynamic_cast<TXsheetFx *>(childFx))
			port->setFx(fx.getPointer());
		else
			addPostProcessingRecursive(fx, childFx);
	}
}
void SwatchViewer::setFx(const TFxP &fx, const TFxP &actualFx, int frame)
{
	m_fx = m_actualFxClone = fx;
	m_frame = frame;
	m_points.clear();
	m_pointPairs.clear();

	if (!fx) {
		::setFxForCaching(0);
		computeContent();
		return;
	}

	// abilita la cache nel nuovo effetto corrente
	::setFxForCaching(actualFx.getPointer());

	if (NaAffineFx *affFx = dynamic_cast<NaAffineFx *>(m_fx.getPointer()))
		m_fxAff = affFx->getPlacement(m_frame);
	else
		m_fxAff = TAffine();
	int i;
	for (i = 0; i < actualFx->getParams()->getParamCount(); i++) {
		TPointParam *pointParam =
			dynamic_cast<TPointParam *>(actualFx->getParams()->getParam(i));
		if (pointParam)
			m_points.push_back(Point(i, pointParam));
	}
	// cerco i segmenti
	int n = m_points.size();
	for (i = 0; i < n; i++) {
		string name = m_points[i].m_param->getName();
		string prefix = matchSuffix(name, "_a");
		if (prefix == "")
			continue;
		string otherName = prefix + "_b";
		int j;
		for (j = 0; j < n; j++)
			if (i != j && m_points[j].m_param->getName() == otherName)
				break;
		if (j < n) {
			m_pointPairs.push_back(std::make_pair(i, j));
			m_points[i].m_pairFlag = m_points[j].m_pairFlag = true;
		}
	}
	computeContent();
}
void SwatchCacheManager::getResource(
	TCacheResourceP &resource, const string &alias,
	const TFxP &fx, double frame, const TRenderSettings &rs,
	ResourceDeclaration *resData)
{
	//Only FX RESULTS are interesting - plus, avoid if we're not currently
	//editing an fx.
	if (!(fx && m_setFxId > 0))
		return;

	QMutexLocker locker(&m_mutex);

	//Cache the result in case the fx's id is among the stored ones.
	unsigned long fxId = fx->getIdentifier();

	if (fxId == m_setFxId && rs.m_isSwatch) {
		if (!resource)
			resource = TCacheResourceP(alias, true);

		resource->addLock();
		if (m_currEditedFxResult)
			m_currEditedFxResult->releaseLock();

		m_currEditedFxResult = resource;
		return;
	}

	if (m_childrenFxIds.find(fxId) != m_childrenFxIds.end()) {
		if (!resource)
			resource = TCacheResourceP(alias, true);

		if (rs.m_isSwatch) {
			std::set<TCacheResourceP>::iterator it =
				m_swatchCacheContainer.find(resource);

			if (it == m_swatchCacheContainer.end()) {
				resource->addLock();
				m_swatchCacheContainer.insert(resource);
			}
		} else {
#ifdef USE_SQLITE_HDPOOL
			resource->enableBackup();
			TCacheResourcePool::instance()->addReference(resource, "S");
#else
			std::set<TCacheResourceP>::iterator it =
				m_genericCacheContainer.find(resource);

			if (it == m_genericCacheContainer.end()) {
				resource->addLock();
				m_genericCacheContainer.insert(resource);
			}
#endif
		}
	}
}
Beispiel #8
0
bool TMacroFx::analyze(const vector<TFxP> &fxs,
					   TFxP &root,
					   vector<TFxP> &roots,
					   vector<TFxP> &leafs)
{
	if (fxs.size() == 1)
		return false;
	else {
		leafs.clear();
		roots.clear();
		std::vector<TFxP>::const_iterator it = fxs.begin();
		for (; it != fxs.end(); ++it) {
			TFxP fx = *it;
			int inputInternalConnection = 0;
			int inputExternalConnection = 0;
			int outputInternalConnection = 0;
			int outputExternalConnection = 0;

			int i;

			// calcola se ci sono connessioni in input dall'esterno
			// verso l'interno e/o internamente a orderedFxs
			int inputPortCount = fx->getInputPortCount();
			for (i = 0; i < inputPortCount; ++i) {
				TFxPort *inputPort = fx->getInputPort(i);
				TFx *inputPortFx = inputPort->getFx();
				if (inputPortFx) {
					if (std::find_if(fxs.begin(), fxs.end(), MatchesFx(inputPortFx)) != fxs.end())
						++inputInternalConnection;
					else
						++inputExternalConnection;
				}
			}

			// calcola se ci sono connessioni in output dall'interno
			// verso l'esterno e/o internamente a orderedFxs
			int outputPortCount = fx->getOutputConnectionCount();
			for (i = 0; i < outputPortCount; ++i) {
				TFxPort *outputPort = fx->getOutputConnection(i);
				TFx *outputFx = outputPort->getOwnerFx();
				if (outputFx) {
					if (std::find_if(fxs.begin(), fxs.end(), MatchesFx(outputFx)) != fxs.end())
						++outputInternalConnection;
					else
						++outputExternalConnection;
				}
			}

			// se fx e' una radice
			if ((outputExternalConnection > 0) ||
				(outputExternalConnection == 0 && outputInternalConnection == 0)) {
				root = fx;
				roots.push_back(fx);
			}

			// se fx e' una foglia
			if (inputExternalConnection > 0 || fx->getInputPortCount() == 0 ||
				(inputExternalConnection == 0 && inputInternalConnection < fx->getInputPortCount())) {
				leafs.push_back(fx);
			}
		}

		if (roots.size() != 1)
			return false;
		else {
			if (leafs.size() == 0)
				return false;
		}

		return true;
	}
}
Beispiel #9
0
TMacroFx *TMacroFx::create(const vector<TFxP> &fxs)
{
	std::vector<TFxP> leafs;
	std::vector<TFxP> roots;
	TFxP root = 0;

	vector<TFxP> orederedFxs = sortFxs(fxs);

	// verifica che gli effetti selezionati siano idonei ad essere raccolti
	// in una macro. Ci deve essere un solo nodo terminale
	// (roots.size()==1, roots[0] == root) e uno o piu' nodi di ingresso
	// (assert leafs.size()>0)
	if (!analyze(orederedFxs, root, roots, leafs))
		return 0;

	// -----------------------------

	TMacroFx *macroFx = new TMacroFx;

	// tutti i nodi vengono spostati (e non copiati) nella macro stessa
	std::vector<TFxP>::const_iterator it = orederedFxs.begin();
	for (; it != orederedFxs.end(); ++it)
		macroFx->m_fxs.push_back(*it);

	// i nodi di ingresso vengono messi in collegamento con le
	// porte di ingresso della macro
	for (int i = 0; i < (int)leafs.size(); i++) {
		TFxP fx = leafs[i];
		int k = 0;
		int count = fx->getInputPortCount();
		for (; k < count; k++) {
			TFxPort *port = fx->getInputPort(k);
			string portName = fx->getInputPortName(k);
			string fxId = toString(fx->getFxId());
			portName += "_" + toString(macroFx->getInputPortCount()) + "_" + fxId;
			TFx *portFx = port->getFx();
			if (portFx) {
				// se la porta k-esima del nodo di ingresso i-esimo e' collegata
				// ad un effetto, la porta viene inserita solo se l'effetto non fa
				// gia' parte della macro
				if (std::find_if(orederedFxs.begin(), orederedFxs.end(), MatchesFx(portFx)) == orederedFxs.end())
					macroFx->addInputPort(portName, *port);
			} else
				macroFx->addInputPort(portName, *port);
		}
	}

	// le porte di uscita di root diventano le porte di uscita della macro
	int count = root->getOutputConnectionCount();
	int k = count - 1;
	for (; k >= 0; --k) {
		TFxPort *port = root->getOutputConnection(k);
		port->setFx(macroFx);
	}

	macroFx->setRoot(root.getPointer());

	// tutti i parametri delle funzioni figlie diventano parametri della macro
	collectParams(macroFx);
	return macroFx;
}