Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "toonz/tpinnedrangeset.h"
Toshihiro Shimizu 890ddd
#include "tstream.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TPinnedRangeSet::TPinnedRangeSet() : m_stageObject() {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int TPinnedRangeSet::getRangeIndex(int frame) const {
Shinya Kitaoka 120a6e
  if (m_ranges.empty()) return -1;
Shinya Kitaoka 120a6e
  if (frame < m_ranges.front().first || m_ranges.back().second < frame)
Shinya Kitaoka 120a6e
    return -1;
Shinya Kitaoka 120a6e
  int start = 0, end = (int)m_ranges.size() - 1;
Shinya Kitaoka 120a6e
  while (start < end) {
Shinya Kitaoka 120a6e
    if (start + 1 == end) {
Shinya Kitaoka 120a6e
      if (m_ranges[end].first <= frame)
Shinya Kitaoka 120a6e
        start = end;
Shinya Kitaoka 120a6e
      else
Shinya Kitaoka 120a6e
        end = start;
Shinya Kitaoka 120a6e
      break;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    int m = (start + end) / 2;
Shinya Kitaoka 120a6e
    assert(start < m && m < end);
Shinya Kitaoka 120a6e
    if (m_ranges[m].first <= frame)
Shinya Kitaoka 120a6e
      start = m;
Shinya Kitaoka 120a6e
    else
Shinya Kitaoka 120a6e
      end = m;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  int index = start;
Shinya Kitaoka 120a6e
  if (m_ranges[index].first <= frame && frame <= m_ranges[index].second)
Shinya Kitaoka 120a6e
    return index;
Shinya Kitaoka 120a6e
  else
Shinya Kitaoka 120a6e
    return -1;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TPinnedRangeSet::setRange(int first, int second) {
Shinya Kitaoka 120a6e
  std::vector<range>::iterator it;</range>
Shinya Kitaoka 120a6e
  // finds the range which could possibly be merged before : range.second+1 >=
Shinya Kitaoka 120a6e
  // first
Shinya Kitaoka 120a6e
  for (it = m_ranges.begin(); it != m_ranges.end(); ++it)
Shinya Kitaoka 120a6e
    if (it->second + 1 >= first) break;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (it == m_ranges.end()) {
Shinya Kitaoka 120a6e
    // not found => for every range : range.second+1 < first. Just add the new
Shinya Kitaoka 120a6e
    // one
Shinya Kitaoka 120a6e
    m_ranges.push_back(Range(first, second));
Shinya Kitaoka 120a6e
  } else if (it->first > second + 1) {
Shinya Kitaoka 120a6e
    // it comes after and can not be merged. Just insert the new one
Shinya Kitaoka 120a6e
    m_ranges.insert(it, Range(first, second));
Shinya Kitaoka 120a6e
  } else {
Shinya Kitaoka 120a6e
    // merge
Shinya Kitaoka 120a6e
    if (first < it->first) it->first = first;
Shinya Kitaoka 120a6e
    // update it->second, and find all the ranges which should be deleted
Shinya Kitaoka 120a6e
    std::vector<range>::iterator it2 = it;</range>
Shinya Kitaoka 120a6e
    for (++it2; it2 != m_ranges.end(); ++it2)
Shinya Kitaoka 120a6e
      if (it2->first > second + 1)
Shinya Kitaoka 120a6e
        break;
Shinya Kitaoka 120a6e
      else
Shinya Kitaoka 120a6e
        it->second                      = it2->second;
Shinya Kitaoka 120a6e
    if (second > it->second) it->second = second;
Shinya Kitaoka 120a6e
    ++it;
Shinya Kitaoka 120a6e
    if (it != it2) m_ranges.erase(it, it2);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TPinnedRangeSet::removeRange(int first, int second) {
Shinya Kitaoka 120a6e
  std::vector<range>::iterator it;</range>
Shinya Kitaoka 120a6e
  // finds the first range which could possibly overlap [first,second] :
Shinya Kitaoka 120a6e
  // range.second>=first
Shinya Kitaoka 120a6e
  for (it = m_ranges.begin(); it != m_ranges.end(); ++it)
Shinya Kitaoka 120a6e
    if (it->second >= first) break;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (it == m_ranges.end() || it->first > second) {
Shinya Kitaoka 120a6e
    // nothing to do: for each range range.second < first or range.first >
Shinya Kitaoka 120a6e
    // second
Shinya Kitaoka 120a6e
  } else if (it->first < first && it->second > second) {
Shinya Kitaoka 120a6e
    // [first,second] is a "hole"
Shinya Kitaoka 120a6e
    Range range(it->first, first - 1);
Shinya Kitaoka 120a6e
    it->first = second + 1;
Shinya Kitaoka 120a6e
    m_ranges.insert(it, range);
Shinya Kitaoka 120a6e
  } else {
Shinya Kitaoka 120a6e
    std::vector<range>::iterator it2;</range>
Shinya Kitaoka 120a6e
    if (it->first < first) {
Shinya Kitaoka 120a6e
      it->second = first - 1;
Shinya Kitaoka 120a6e
      ++it;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    it2 = it;
Shinya Kitaoka 120a6e
    while (it != m_ranges.end() && it->second <= second) ++it;
Shinya Kitaoka 120a6e
    if (it != m_ranges.end() && it->first <= second) it->first = second + 1;
Shinya Kitaoka 120a6e
    if (it2 != it) m_ranges.erase(it2, it);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TPinnedRangeSet::removeAllRanges() { m_ranges.clear(); }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TPinnedRangeSet::setPlacement(const TAffine &placement) {
Shinya Kitaoka 120a6e
  m_placement = placement;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TPinnedRangeSet *TPinnedRangeSet::clone() {
Shinya Kitaoka 120a6e
  TPinnedRangeSet *clonedPinnedRangeSet = new TPinnedRangeSet();
Shinya Kitaoka 120a6e
  clonedPinnedRangeSet->m_stageObject   = m_stageObject;
Shinya Kitaoka 120a6e
  clonedPinnedRangeSet->m_placement     = m_placement;
Shinya Kitaoka 120a6e
  clonedPinnedRangeSet->m_ranges        = m_ranges;
Shinya Kitaoka 120a6e
  return clonedPinnedRangeSet;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TPinnedRangeSet::loadData(TIStream &is) {
Shinya Kitaoka 120a6e
  m_ranges.clear();
Shinya Kitaoka 120a6e
  int prevFrame = 0;
Shinya Kitaoka 120a6e
  int i         = 0;
Shinya Kitaoka 120a6e
  std::string tagName;
Shinya Kitaoka 120a6e
  int count = 0;
Shinya Kitaoka 120a6e
  while (is.matchTag(tagName) && count < 3) {
Shinya Kitaoka 120a6e
    if (tagName == "permanent") {
Shinya Kitaoka 120a6e
      while (!is.matchEndTag()) {
Shinya Kitaoka 120a6e
        i++;
Shinya Kitaoka 120a6e
        int frame = 0;
Shinya Kitaoka 120a6e
        is >> frame;
Shinya Kitaoka 120a6e
        if (i % 2 == 0) m_ranges.push_back(Range(prevFrame, frame));
Shinya Kitaoka 120a6e
        prevFrame = frame;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
      count++;
Shinya Kitaoka 120a6e
    } else if (tagName == "temp") {
Shinya Kitaoka 120a6e
      assert(0);
Shinya Kitaoka 120a6e
      // OBSOLETO
Shinya Kitaoka 120a6e
      while (!is.matchEndTag()) {
Shinya Kitaoka 120a6e
        int frame = 0;
Shinya Kitaoka 120a6e
        is >> frame;
Shinya Kitaoka 120a6e
        // m_tempPinned.push_back(frame);
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
      count++;
Shinya Kitaoka 120a6e
    } else if (tagName == "lockedAngle") {
Shinya Kitaoka 120a6e
      assert(0);
Shinya Kitaoka 120a6e
      // OBSOLETO
Shinya Kitaoka 120a6e
      while (!is.matchEndTag()) {
Shinya Kitaoka 120a6e
        int rangeIndex = -1;
Shinya Kitaoka 120a6e
        is >> rangeIndex;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      count++;
Shinya Kitaoka 120a6e
    } else if (tagName == "placement") {
Shinya Kitaoka 120a6e
      is >> m_placement.a11 >> m_placement.a12 >> m_placement.a13;
Shinya Kitaoka 120a6e
      is >> m_placement.a21 >> m_placement.a22 >> m_placement.a23;
Shinya Kitaoka 120a6e
      is.matchEndTag();
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TPinnedRangeSet::saveData(TOStream &os) {
Shinya Kitaoka 120a6e
  if ((int)m_ranges.size() == 0) return;
Shinya Kitaoka 120a6e
  os.openChild("pinnedStatus");
Shinya Kitaoka 120a6e
  if (m_ranges.size() > 0) {
Shinya Kitaoka 120a6e
    os.openChild("permanent");
Shinya Kitaoka 120a6e
    for (int p = 0; p < (int)m_ranges.size(); p++) {
Shinya Kitaoka 120a6e
      os << m_ranges[p].first << m_ranges[p].second;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    os.closeChild();
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  if (m_placement != TAffine()) {
Shinya Kitaoka 120a6e
    os.openChild("placement");
Shinya Kitaoka 120a6e
    os << m_placement.a11 << m_placement.a12 << m_placement.a13;
Shinya Kitaoka 120a6e
    os << m_placement.a21 << m_placement.a22 << m_placement.a23;
Shinya Kitaoka 120a6e
    os.closeChild();
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  os.closeChild();
Toshihiro Shimizu 890ddd
}