| |
| |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| typedef std::pair<TDoubleParamP, TPixelParamP> ColorKeyParam; |
| |
| |
| |
| class TSpectrumParamImp { |
| TSpectrumParam *m_sp; |
| |
| std::vector<ColorKeyParam> m_keys; |
| |
| public: |
| bool m_draggingEnabled; |
| bool m_notificationEnabled; |
| bool m_isMatteEnabled; |
| |
| std::set<TParamObserver *> m_observers; |
| |
| public: |
| TSpectrumParamImp(TSpectrumParam *sp) |
| : m_sp(sp) |
| , m_keys() |
| , m_draggingEnabled(false) |
| , m_notificationEnabled(true) |
| , m_isMatteEnabled(true) {} |
| |
| TSpectrumParamImp(const TSpectrumParamImp &s) { copy(s); } |
| |
| void copy(const TSpectrumParamImp &src) { |
| m_keys.clear(); |
| |
| std::vector<ColorKeyParam>::const_iterator it = src.m_keys.begin(); |
| for (; it != src.m_keys.end(); ++it) { |
| TDoubleParamP s(it->first->clone()); |
| TPixelParamP c(it->second->clone()); |
| m_keys.push_back(std::make_pair(s, c)); |
| } |
| } |
| |
| void addKey(const ColorKeyParam &colorKey) { |
| |
| |
| |
| |
| m_keys.push_back(colorKey); |
| } |
| |
| void insertKey(int index, ColorKeyParam &colorKey) { |
| |
| |
| |
| |
| std::vector<ColorKeyParam>::iterator it = m_keys.begin() + index; |
| m_keys.insert(it, colorKey); |
| } |
| |
| void eraseKey(int index) { |
| std::vector<ColorKeyParam>::iterator colorKeyIt = m_keys.begin() + index; |
| |
| |
| |
| |
| m_keys.erase(colorKeyIt); |
| } |
| |
| int getKeyCount() const { return m_keys.size(); } |
| |
| ColorKeyParam getKey(int index) const { return m_keys[index]; } |
| |
| void clearKeys() { m_keys.clear(); } |
| |
| void notify(const TParamChange &change) { |
| for (std::set<TParamObserver *>::iterator it = m_observers.begin(); |
| it != m_observers.end(); ++it) |
| (*it)->onChange(change); |
| } |
| |
| private: |
| TSpectrumParamImp &operator=(const TSpectrumParamImp &); |
| }; |
| |
| |
| |
| PERSIST_IDENTIFIER(TSpectrumParam, "spectrumParam") |
| |
| |
| |
| TSpectrumParam::TSpectrumParam() |
| : m_imp(new TSpectrumParamImp(this)) |
| { |
| ColorKeyParam ck1(TDoubleParamP(0.0), TPixelParamP(TPixel32::Black)); |
| ColorKeyParam ck2(TDoubleParamP(1.0), TPixelParamP(TPixel32::White)); |
| m_imp->addKey(ck1); |
| m_imp->addKey(ck2); |
| } |
| |
| |
| |
| TSpectrumParam::TSpectrumParam(const TSpectrumParam &src) |
| : TParam(src.getName()), m_imp(new TSpectrumParamImp(*src.m_imp)) {} |
| |
| |
| |
| void TSpectrumParam::addObserver(TParamObserver *obs) { |
| m_imp->m_observers.insert(obs); |
| } |
| |
| |
| |
| void TSpectrumParam::removeObserver(TParamObserver *obs) { |
| m_imp->m_observers.erase(obs); |
| } |
| |
| |
| |
| TSpectrumParam::TSpectrumParam(int keyCount, TSpectrum::ColorKey keys[]) |
| : m_imp(new TSpectrumParamImp(this)) { |
| for (int i = 0; i < keyCount; i++) { |
| double v = keys[i].first; |
| TPixel32 pix = keys[i].second; |
| TDoubleParamP dp(v); |
| TPixelParamP pp(pix); |
| pp->enableMatte(m_imp->m_isMatteEnabled); |
| ColorKeyParam ck(dp, pp); |
| m_imp->addKey(ck); |
| } |
| } |
| |
| |
| |
| void TSpectrumParam::copy(TParam *src) { |
| TSpectrumParam *p = dynamic_cast<TSpectrumParam *>(src); |
| if (!p) throw TException("invalid source for copy"); |
| setName(src->getName()); |
| m_imp->copy(*(p->m_imp)); |
| } |
| |
| |
| |
| TSpectrumParam::~TSpectrumParam() {} |
| |
| |
| |
| TSpectrum TSpectrumParam::getValue(double frame) const { |
| assert(m_imp); |
| std::vector<TSpectrum::ColorKey> keys; |
| int keyCount = m_imp->getKeyCount(); |
| for (int i = 0; i < keyCount; i++) { |
| ColorKeyParam paramKey = m_imp->getKey(i); |
| TSpectrum::ColorKey key(paramKey.first->getValue(frame), |
| paramKey.second->getValue(frame)); |
| keys.push_back(key); |
| } |
| return TSpectrum(keys.size(), &keys[0]); |
| } |
| |
| |
| |
| TSpectrum64 TSpectrumParam::getValue64(double frame) const { |
| assert(m_imp); |
| std::vector<TSpectrum64::ColorKey> keys; |
| int keyCount = m_imp->getKeyCount(); |
| for (int i = 0; i < keyCount; i++) { |
| ColorKeyParam paramKey = m_imp->getKey(i); |
| TSpectrum64::ColorKey key(paramKey.first->getValue(frame), |
| toPixel64(paramKey.second->getValue(frame))); |
| keys.push_back(key); |
| } |
| return TSpectrum64(keys.size(), &keys[0]); |
| } |
| |
| |
| void TSpectrumParam::setValue(double frame, const TSpectrum &spectrum, |
| bool undoing) { |
| assert(getKeyCount() == spectrum.getKeyCount()); |
| int keyCount = getKeyCount(); |
| for (int i = 0; i < keyCount; i++) { |
| TSpectrum::Key key = spectrum.getKey(i); |
| setValue(frame, i, key.first, key.second, undoing); |
| } |
| } |
| |
| |
| |
| TDoubleParamP TSpectrumParam::getPosition(int index) const { |
| assert(index <= m_imp->getKeyCount()); |
| return m_imp->getKey(index).first; |
| } |
| |
| |
| |
| TPixelParamP TSpectrumParam::getColor(int index) const { |
| assert(index <= m_imp->getKeyCount()); |
| return m_imp->getKey(index).second; |
| } |
| |
| |
| |
| int TSpectrumParam::getKeyCount() const { |
| assert(m_imp); |
| return m_imp->getKeyCount(); |
| } |
| |
| |
| |
| void TSpectrumParam::setValue(double frame, int index, double s, |
| const TPixel32 &color, bool undoing) { |
| assert(m_imp); |
| int keyCount = m_imp->getKeyCount(); |
| if (index < 0 || index >= keyCount) |
| throw TException("TSpectrumParam::setValue. Index out of range"); |
| |
| ColorKeyParam key = m_imp->getKey(index); |
| |
| |
| key.first->setValue(frame, s); |
| key.second->setValue(frame, color); |
| |
| |
| m_imp->notify(TParamChange(this, TParamChange::m_minFrame, |
| TParamChange::m_maxFrame, true, |
| m_imp->m_draggingEnabled, false)); |
| } |
| |
| |
| |
| void TSpectrumParam::setDefaultValue(const TSpectrum &value) { |
| assert(value.getKeyCount() == getKeyCount()); |
| for (int i = 0; i < getKeyCount(); i++) { |
| ColorKeyParam dstKeyParam = m_imp->getKey(i); |
| TSpectrum::Key srcKey = value.getKey(i); |
| dstKeyParam.first->setDefaultValue(srcKey.first); |
| dstKeyParam.second->setDefaultValue(srcKey.second); |
| } |
| } |
| |
| |
| |
| void TSpectrumParam::insertKey(int index, double s, const TPixel32 &color) { |
| assert(m_imp); |
| int keyCount = m_imp->getKeyCount(); |
| if (index < 0) |
| index = 0; |
| else if (index >= keyCount) |
| index = keyCount; |
| TDoubleParamP dp(s); |
| TPixelParamP pp(color); |
| pp->enableMatte(m_imp->m_isMatteEnabled); |
| ColorKeyParam ck(dp, pp); |
| |
| m_imp->insertKey(index, ck); |
| } |
| |
| |
| |
| void TSpectrumParam::addKey(double s, const TPixel32 &color) { |
| |
| |
| |
| |
| int index = m_imp->getKeyCount(); |
| assert(m_imp); |
| int keyCount = m_imp->getKeyCount(); |
| if (index < 0) |
| index = 0; |
| else if (index >= keyCount) |
| index = keyCount; |
| TDoubleParamP dp(s); |
| TPixelParamP pp(color); |
| pp->enableMatte(m_imp->m_isMatteEnabled); |
| ColorKeyParam ck(dp, pp); |
| |
| m_imp->insertKey(index, ck); |
| } |
| |
| |
| |
| void TSpectrumParam::removeKey(int index) { |
| assert(m_imp); |
| int keyCount = m_imp->getKeyCount(); |
| if (index < 0 || index >= keyCount) |
| throw TException("TSpectrumParam::removeKey. Index out of range"); |
| m_imp->eraseKey(index); |
| } |
| |
| |
| |
| bool TSpectrumParam::isKeyframe(double frame) const { |
| int keyCount = m_imp->getKeyCount(); |
| for (int i = 0; i < keyCount; i++) { |
| ColorKeyParam currentKey = m_imp->getKey(i); |
| if (currentKey.first->isKeyframe(frame)) return true; |
| if (currentKey.second->isKeyframe(frame)) return true; |
| } |
| return false; |
| } |
| |
| |
| |
| void TSpectrumParam::deleteKeyframe(double frame) { |
| int keyCount = m_imp->getKeyCount(); |
| for (int i = 0; i < keyCount; i++) { |
| ColorKeyParam currentKey = m_imp->getKey(i); |
| currentKey.first->deleteKeyframe(frame); |
| currentKey.second->deleteKeyframe(frame); |
| } |
| } |
| |
| |
| |
| void TSpectrumParam::clearKeyframes() { |
| assert(m_imp); |
| |
| int k, keyCount = m_imp->getKeyCount(); |
| for (k = 0; k < keyCount; ++k) { |
| const ColorKeyParam &key = m_imp->getKey(k); |
| |
| key.first->clearKeyframes(); |
| key.second->clearKeyframes(); |
| } |
| |
| m_imp->notify(TParamChange(this, TParamChange::m_minFrame, |
| TParamChange::m_maxFrame, true, |
| m_imp->m_draggingEnabled, false)); |
| } |
| |
| |
| |
| void TSpectrumParam::assignKeyframe(double frame, const TParamP &src, |
| double srcFrame, bool changedOnly) { |
| TSpectrumParamP spectrum = src; |
| if (!spectrum) return; |
| int keyCount = m_imp->getKeyCount(); |
| if (keyCount != spectrum->m_imp->getKeyCount()) return; |
| for (int i = 0; i < keyCount; i++) { |
| ColorKeyParam dstKey = m_imp->getKey(i); |
| ColorKeyParam srcKey = spectrum->m_imp->getKey(i); |
| dstKey.first->setValue(frame, srcKey.first->getValue(srcFrame)); |
| dstKey.second->setValue(frame, srcKey.second->getValue(srcFrame)); |
| } |
| } |
| |
| |
| |
| void TSpectrumParam::loadData(TIStream &is) { |
| assert(m_imp); |
| m_imp->clearKeys(); |
| std::string tagName; |
| is.openChild(tagName); |
| assert(tagName == "spectrum"); |
| while (!is.eos()) { |
| TDoubleParamP pos(0.0); |
| TPixelParamP color(TPixel32::Black); |
| is.openChild(tagName); |
| pos->loadData(is); |
| is.closeChild(); |
| is.openChild(tagName); |
| color->loadData(is); |
| is.closeChild(); |
| ColorKeyParam ck(pos, color); |
| m_imp->addKey(ck); |
| } |
| is.closeChild(); |
| } |
| |
| |
| |
| void TSpectrumParam::saveData(TOStream &os) { |
| assert(m_imp); |
| int keyCount = m_imp->getKeyCount(); |
| os.openChild("spectrum"); |
| for (int i = 0; i < keyCount; i++) { |
| ColorKeyParam key = m_imp->getKey(i); |
| os.openChild("s_value"); |
| key.first->saveData(os); |
| os.closeChild(); |
| os.openChild("col_value"); |
| key.second->saveData(os); |
| os.closeChild(); |
| } |
| os.closeChild(); |
| } |
| |
| |
| |
| void TSpectrumParam::enableDragging(bool on) { m_imp->m_draggingEnabled = on; } |
| |
| |
| |
| void TSpectrumParam::enableNotification(bool on) { |
| m_imp->m_notificationEnabled = on; |
| } |
| |
| |
| |
| bool TSpectrumParam::isNotificationEnabled() const { |
| return m_imp->m_notificationEnabled; |
| } |
| |
| |
| |
| namespace { |
| |
| inline std::string to_string(const TPixel32 &color) { |
| std::string alias = "("; |
| alias += std::to_string(color.r) + ","; |
| alias += std::to_string(color.g) + ","; |
| alias += std::to_string(color.b) + ","; |
| alias += std::to_string(color.m); |
| alias += ")"; |
| return alias; |
| } |
| |
| inline std::string toString(const TSpectrum::ColorKey &key, int precision) { |
| std::string alias = "("; |
| alias += ::to_string(key.first, precision) + ","; |
| alias += to_string(key.second); |
| alias += ")"; |
| return alias; |
| } |
| |
| } |
| |
| std::string TSpectrumParam::getValueAlias(double frame, int precision) { |
| std::vector<TSpectrum::ColorKey> keys; |
| int keyCount = m_imp->getKeyCount(); |
| for (int i = 0; i < keyCount; i++) { |
| ColorKeyParam paramKey = m_imp->getKey(i); |
| TSpectrum::ColorKey key(paramKey.first->getValue(frame), |
| paramKey.second->getValue(frame)); |
| keys.push_back(key); |
| } |
| |
| std::string alias = "("; |
| |
| if (!keys.empty()) { |
| std::vector<TSpectrum::ColorKey>::iterator it = keys.begin(); |
| std::vector<TSpectrum::ColorKey>::iterator end = keys.begin(); |
| std::advance(end, keys.size() - 1); |
| for (; it != end; ++it) { |
| alias += toString(*it, precision); |
| alias += ","; |
| } |
| alias += toString(*it, precision); |
| } |
| |
| alias += ")"; |
| return alias; |
| } |
| |
| |
| |
| |
| |
| void TSpectrumParam::enableMatte(bool on) { m_imp->m_isMatteEnabled = on; } |
| |
| |
| bool TSpectrumParam::isMatteEnabled() const { return m_imp->m_isMatteEnabled; } |
| |
| |
| |
| bool TSpectrumParam::hasKeyframes() const { |
| int keyCount = m_imp->getKeyCount(); |
| for (int i = 0; i < keyCount; i++) { |
| ColorKeyParam currentKey = m_imp->getKey(i); |
| if (currentKey.first->hasKeyframes() || currentKey.second->hasKeyframes()) |
| return true; |
| } |
| return false; |
| } |
| |
| |
| void TSpectrumParam::getKeyframes(std::set<double> &frames) const { |
| int keyCount = m_imp->getKeyCount(); |
| for (int i = 0; i < keyCount; i++) { |
| ColorKeyParam currentKey = m_imp->getKey(i); |
| currentKey.first->getKeyframes(frames); |
| currentKey.second->getKeyframes(frames); |
| } |
| } |
| |
| |
| |
| int TSpectrumParam::getNextKeyframe(double frame) const { |
| std::set<double> frames; |
| getKeyframes(frames); |
| std::set<double>::iterator it = frames.upper_bound(frame); |
| if (it == frames.end()) |
| return -1; |
| else |
| return std::distance(frames.begin(), it); |
| } |
| |
| |
| |
| int TSpectrumParam::getPrevKeyframe(double frame) const { |
| std::set<double> frames; |
| getKeyframes(frames); |
| std::set<double>::iterator it = frames.lower_bound(frame); |
| if (it == frames.begin()) |
| return -1; |
| else { |
| --it; |
| return std::distance(frames.begin(), it); |
| } |
| } |
| |
| |
| double TSpectrumParam::keyframeIndexToFrame(int index) const { |
| std::set<double> frames; |
| getKeyframes(frames); |
| assert(0 <= index && index < (int)frames.size()); |
| std::set<double>::const_iterator it = frames.begin(); |
| std::advance(it, index); |
| return *it; |
| } |
| |
| TIStream &operator>>(TIStream &in, TSpectrumParamP &p) { |
| TPersist *tmp; |
| in >> tmp; |
| p = TSpectrumParamP(dynamic_cast<TSpectrumParam *>(tmp)); |
| return in; |
| } |
| |