Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// TnzCore includes
Toshihiro Shimizu 890ddd
#include "tstencilcontrol.h"
Toshihiro Shimizu 890ddd
#include "tvectorgl.h"
Toshihiro Shimizu 890ddd
#include "tvectorrenderdata.h"
Toshihiro Shimizu 890ddd
#include "tcolorfunctions.h"
Toshihiro Shimizu 890ddd
#include "tpalette.h"
Toshihiro Shimizu 890ddd
#include "tropcm.h"
Toshihiro Shimizu 890ddd
#include "trasterimage.h"
Toshihiro Shimizu 890ddd
#include "tvectorimage.h"
Toshihiro Shimizu 890ddd
#include "tcolorstyles.h"
Toshihiro Shimizu 890ddd
#include "timage_io.h"
Toshihiro Shimizu 890ddd
#include "tofflinegl.h"
Toshihiro Shimizu 890ddd
#include "tpixelutils.h"
Toshihiro Shimizu 890ddd
#include "tstroke.h"
Toshihiro Shimizu 890ddd
#include "tenv.h"
Toshihiro Shimizu 890ddd
#include "tregion.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// TnzLib includes
Toshihiro Shimizu 890ddd
#include "toonz/stage2.h"
Toshihiro Shimizu 890ddd
#include "toonz/stageplayer.h"
Toshihiro Shimizu 890ddd
#include "toonz/stagevisitor.h"
Toshihiro Shimizu 890ddd
#include "toonz/txsheet.h"
Toshihiro Shimizu 890ddd
#include "toonz/txshsimplelevel.h"
Toshihiro Shimizu 890ddd
#include "toonz/txshchildlevel.h"
Toshihiro Shimizu 890ddd
#include "toonz/txshcolumn.h"
Toshihiro Shimizu 890ddd
#include "toonz/txshcell.h"
Toshihiro Shimizu 890ddd
#include "toonz/onionskinmask.h"
Toshihiro Shimizu 890ddd
#include "toonz/dpiscale.h"
Toshihiro Shimizu 890ddd
#include "toonz/imagemanager.h"
Toshihiro Shimizu 890ddd
#include "toonz/tstageobjecttree.h"
Toshihiro Shimizu 890ddd
#include "toonz/preferences.h"
Toshihiro Shimizu 890ddd
#include "toonz/fill.h"
Toshihiro Shimizu 890ddd
#include "toonz/levelproperties.h"
Toshihiro Shimizu 890ddd
#include "toonz/autoclose.h"
Toshihiro Shimizu 890ddd
#include "toonz/txshleveltypes.h"
Toshihiro Shimizu 890ddd
#include "imagebuilders.h"
shun-iwasawa a266be
#include "toonz/toonzscene.h"
shun-iwasawa a266be
#include "toonz/sceneproperties.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// Qt includes
Toshihiro Shimizu 890ddd
#include <qimage></qimage>
Toshihiro Shimizu 890ddd
#include <qpainter></qpainter>
Toshihiro Shimizu 890ddd
#include <qpolygon></qpolygon>
Toshihiro Shimizu 890ddd
#include <qthreadstorage></qthreadstorage>
Toshihiro Shimizu 890ddd
#include <qmatrix></qmatrix>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "toonz/stage.h"
Toshihiro Shimizu 890ddd
shun-iwasawa a266be
// #define  NUOVO_ONION
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
/*! \namespace Stage
Shinya Kitaoka 120a6e
                \brief The Stage namespace provides a set of objects, class and
Shinya Kitaoka 120a6e
   method, useful to view images in display.
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
using namespace Stage;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
typedef std::vector<player> PlayerSet;</player>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*! \var Stage::inch
Shinya Kitaoka 120a6e
                For historical reasons camera stand is defined in a coordinate
Shinya Kitaoka 120a6e
   system in which
Shinya Kitaoka 120a6e
                an inch is equal to 'Stage::inch' unit.
Shinya Kitaoka 120a6e
                Pay attention: modify this value condition apparent line
Shinya Kitaoka 120a6e
   thickness of
Shinya Kitaoka 120a6e
                images .pli.
Toshihiro Shimizu 890ddd
*/
shun_iwasawa bb0d83
const double Stage::inch        = 53.33333;
shun_iwasawa d6df3f
const double Stage::standardDpi = 120;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
namespace {
Shinya Kitaoka 120a6e
void updateOnionSkinSize(const PlayerSet &players) {
Shinya Kitaoka 120a6e
  assert(Player::m_onionSkinFrontSize == 0 && Player::m_onionSkinBackSize == 0);
Shinya Kitaoka 120a6e
  int i;
Jeremy Bullock 1e17ed
  int maxOnionSkinFrontValue = 0, maxOnionSkinBackValue = 0,
manongjohn 40a40e
      firstFrontOnionSkin = 0, firstBackOnionSkin = 0, lastBackVisibleSkin = 0;
Shinya Kitaoka 120a6e
  for (i = 0; i < (int)players.size(); i++) {
Shinya Kitaoka 120a6e
    Player player = players[i];
Shinya Kitaoka 120a6e
    if (player.m_onionSkinDistance == c_noOnionSkin) continue;
Shinya Kitaoka 120a6e
    if (player.m_onionSkinDistance > 0 &&
Shinya Kitaoka 120a6e
        maxOnionSkinFrontValue < player.m_onionSkinDistance)
Shinya Kitaoka 120a6e
      maxOnionSkinFrontValue = player.m_onionSkinDistance;
Shinya Kitaoka 120a6e
    if (player.m_onionSkinDistance < 0 &&
Shinya Kitaoka 120a6e
        maxOnionSkinBackValue > player.m_onionSkinDistance)
Shinya Kitaoka 120a6e
      maxOnionSkinBackValue = player.m_onionSkinDistance;
manongjohn 40a40e
    if (firstFrontOnionSkin == 0 && player.m_onionSkinDistance > 0)
manongjohn 40a40e
      firstFrontOnionSkin = player.m_onionSkinDistance;
manongjohn 40a40e
    else if (player.m_onionSkinDistance > 0 &&
manongjohn 40a40e
             firstFrontOnionSkin > player.m_onionSkinDistance)
manongjohn 40a40e
      firstFrontOnionSkin = player.m_onionSkinDistance;
manongjohn 40a40e
Jeremy Bullock 1e17ed
    if (firstBackOnionSkin == 0 && player.m_onionSkinDistance < 0)
Jeremy Bullock 1e17ed
      firstBackOnionSkin = player.m_onionSkinDistance;
Jeremy Bullock 1e17ed
    else if (player.m_onionSkinDistance < 0 &&
Jeremy Bullock 1e17ed
             firstBackOnionSkin < player.m_onionSkinDistance)
Jeremy Bullock 1e17ed
      firstBackOnionSkin = player.m_onionSkinDistance;
Jeremy Bullock 1e17ed
    // Level Editing Mode can send players at a depth beyond what is visible.
Jeremy Bullock 1e17ed
    if (player.m_onionSkinDistance < lastBackVisibleSkin &&
Jeremy Bullock 1e17ed
        player.m_isVisibleinOSM)
Jeremy Bullock 1e17ed
      lastBackVisibleSkin = player.m_onionSkinDistance;
Shinya Kitaoka 120a6e
  }
Jeremy Bullock 1e17ed
  Player::m_onionSkinFrontSize  = maxOnionSkinFrontValue;
Jeremy Bullock 1e17ed
  Player::m_onionSkinBackSize   = maxOnionSkinBackValue;
manongjohn 40a40e
  Player::m_firstFrontOnionSkin = firstFrontOnionSkin;
Jeremy Bullock 1e17ed
  Player::m_firstBackOnionSkin  = firstBackOnionSkin;
Jeremy Bullock 1e17ed
  Player::m_lastBackVisibleSkin = lastBackVisibleSkin;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
bool descending(int i, int j) { return (i > j); }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//----------------------------------------------------------------
shun-iwasawa 048938
}  // namespace
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
luzpaz 27707d
/*! The ZPlacement class preserve camera position information.
shun-iwasawa 048938
 */
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
class ZPlacement {
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  TAffine m_aff;
Shinya Kitaoka 120a6e
  double m_z;
Shinya Kitaoka 120a6e
  ZPlacement() : m_aff(), m_z(0) {}
Shinya Kitaoka 120a6e
  ZPlacement(const TAffine &aff, double z) : m_aff(aff), m_z(z) {}
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
/*! The class PlayerLt allows a priority operator for player.
Toshihiro Shimizu 890ddd
\n	Compare zdepth of two players.
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
class PlayerLt {
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  PlayerLt() {}
Shinya Kitaoka 120a6e
  inline bool operator()(const Player &a, const Player &b) const {
Shinya Kitaoka 120a6e
    if (a.m_bingoOrder < b.m_bingoOrder)
Shinya Kitaoka 120a6e
      return true;
Shinya Kitaoka 120a6e
    else if (a.m_bingoOrder > b.m_bingoOrder)
Shinya Kitaoka 120a6e
      return false;
Shinya Kitaoka 120a6e
    return a.m_z < b.m_z;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
class StackingOrder {
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  StackingOrder() {}
Shinya Kitaoka 120a6e
  inline bool operator()(const std::pair<double, int=""> &a,</double,>
Shinya Kitaoka 120a6e
                         const std::pair<double, int=""> &b) const {</double,>
Shinya Kitaoka 120a6e
    return a.first < b.first;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
/*! The StageBuilder class finds and provides data for frame visualization.
Shinya Kitaoka 120a6e
\n	The class contains a \b PlayerSet, a vector of player, of all
Shinya Kitaoka 120a6e
necessary information.
Toshihiro Shimizu 890ddd
*/
Shinya Kitaoka 120a6e
// Tutto cio che riguarda una "colonna maschera" non e' utilizzato in TOONZ ma
Shinya Kitaoka 120a6e
// in TAB Pro.
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
class StageBuilder {
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  struct SubXSheet {
Shinya Kitaoka 120a6e
    ZPlacement m_camera;
Shinya Kitaoka 120a6e
    TAffine m_aff, m_zaff;
Shinya Kitaoka 120a6e
    double m_z;
Shinya Kitaoka 120a6e
  };
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  enum ShiftTraceGhostId { NO_GHOST, FIRST_GHOST, SECOND_GHOST, TRACED };
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  PlayerSet m_players;
Shinya Kitaoka 120a6e
  std::vector<playerset *=""> m_maskPool;</playerset>
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  std::vector<zplacement> m_placementStack;</zplacement>
Shinya Kitaoka 120a6e
  ZPlacement m_cameraPlacement;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  std::vector<subxsheet> m_subXSheetStack;</subxsheet>
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  std::vector<int> m_masks;</int>
Shinya Kitaoka 120a6e
  int m_onionSkinDistance;
Shinya Kitaoka 120a6e
  double m_fade;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  ShiftTraceGhostId m_shiftTraceGhostId;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  bool m_camera3d;
Shinya Kitaoka 120a6e
  OnionSkinMask m_onionSkinMask;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  int m_currentColumnIndex;   // application's current column index
Shinya Kitaoka 120a6e
  int m_ancestorColumnIndex;  // index of the column that is the deepest
Shinya Kitaoka 120a6e
                              // ancestor of the column being processed
Shinya Kitaoka 120a6e
  int m_currentXsheetLevel;   // level of the current xsheet, see: editInPlace
Shinya Kitaoka 120a6e
  int m_xsheetLevel;          // xsheet-level of the column being processed
Toshihiro Shimizu 890ddd
Jeremy Bullock 1e17ed
  // for guided drawing
Jeremy Bullock 1e17ed
  TFrameId m_currentFrameId;
Jeremy Bullock 1e17ed
  int m_isGuidedDrawingEnabled;
manongjohn 40a40e
  int m_guidedFrontStroke = -1;
manongjohn 40a40e
  int m_guidedBackStroke  = -1;
Shinya Kitaoka 120a6e
  std::vector<txshcolumn *=""> m_ancestors;</txshcolumn>
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  const ImagePainter::VisualSettings *m_vs;
Toshihiro Shimizu 890ddd
shun-iwasawa 31accf
#if defined(x64)
shun-iwasawa 31accf
  TRasterImageP m_liveViewImage;
shun-iwasawa 31accf
  TRasterImageP m_lineupImage;
shun-iwasawa 31accf
  Stage::Player m_liveViewPlayer;
shun-iwasawa 31accf
  Stage::Player m_lineupPlayer;
shun-iwasawa 31accf
#endif
shun-iwasawa 31accf
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  StageBuilder();
Shinya Kitaoka 120a6e
  virtual ~StageBuilder();
Shinya Kitaoka 120a6e
luzpaz 27707d
  /*! Add in \b players vector information about specify cell.
Shinya Kitaoka 120a6e
  \n	Analyze cell in row \b row and column \b col of xsheet \b xsh. If level
Shinya Kitaoka 120a6e
                  containing this cell is a simple level, \b TXshSimpleLevel,
Shinya Kitaoka 120a6e
  create a Pleyer
luzpaz 27707d
                  object with information of the cell. Else if level is a child
Shinya Kitaoka 120a6e
  level,
Shinya Kitaoka 120a6e
                  \b TXshChildLevel, recall \b addFrame().
Shinya Kitaoka 120a6e
  */
Shinya Kitaoka 120a6e
  void addCell(PlayerSet &players, ToonzScene *scene, TXsheet *xsh, int row,
shun-iwasawa 048938
               int col, int level, int subSheetColIndex = -1);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /*! Verify if onion-skin is active and recall \b addCell().
Shinya Kitaoka 120a6e
  \n	Compute the distance between each cell with active onion-skin and
Shinya Kitaoka 120a6e
  current
Shinya Kitaoka 120a6e
                  cell and recall \b addCell(). If onion-skin is not active
Shinya Kitaoka 120a6e
  recall \b addCell()
Shinya Kitaoka 120a6e
                  with argument current cell.
Shinya Kitaoka 120a6e
  */
Shinya Kitaoka 120a6e
  void addCellWithOnionSkin(PlayerSet &players, ToonzScene *scene, TXsheet *xsh,
shun-iwasawa 048938
                            int row, int col, int level,
shun-iwasawa 048938
                            int subSheetColIndex = -1);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /*!Recall \b addCellWithOnionSkin() for each cell of row \b row.*/
shun-iwasawa 048938
  // if subSheetColIndex >= 0 it means that this function is called on visiting
shun-iwasawa 048938
  // subxsheet images and it indicates the column index in the current (parent)
shun-iwasawa 048938
  // xsheet. Checking options (like Fill Check etc.) will then valuate this
shun-iwasawa 048938
  // index to identify if the column is current.
Shinya Kitaoka 120a6e
  void addFrame(PlayerSet &players, ToonzScene *scene, TXsheet *xsh, int row,
shun-iwasawa 048938
                int level, bool includeUnvisible, bool checkPreviewVisibility,
shun-iwasawa 048938
                int subSheetColIndex = -1);
Shinya Kitaoka 120a6e
luzpaz 27707d
  /*! Add in \b players vector information about \b level cell with \b TFrameId
Shinya Kitaoka 120a6e
  \b fid.
Shinya Kitaoka 120a6e
  \n	Compute information for all cell with active onion-skin, if onion-skin
Shinya Kitaoka 120a6e
  is not active
Shinya Kitaoka 120a6e
                  compute information only for current cell.
Shinya Kitaoka 120a6e
  */
Shinya Kitaoka 120a6e
  void addSimpleLevelFrame(PlayerSet &players, TXshSimpleLevel *level,
Shinya Kitaoka 120a6e
                           const TFrameId &fid);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /*! Recall \b visitor.onImage(player) for each \b player contained in \b
Shinya Kitaoka 120a6e
   * players vector.
shun-iwasawa 048938
   */
Shinya Kitaoka 120a6e
  void visit(PlayerSet &players, Visitor &visitor, bool isPlaying = false);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// debug!
Toshihiro Shimizu 890ddd
#ifdef _DEBUG
Shinya Kitaoka 120a6e
  void dumpPlayerSet(PlayerSet &players, std::ostream &out);
Shinya Kitaoka 120a6e
  void dumpAll(std::ostream &out);
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
StageBuilder::StageBuilder()
Shinya Kitaoka 120a6e
    : m_onionSkinDistance(c_noOnionSkin)
Shinya Kitaoka 120a6e
    , m_camera3d(false)
Shinya Kitaoka 120a6e
    , m_currentColumnIndex(-1)
Shinya Kitaoka 120a6e
    , m_ancestorColumnIndex(-1)
Shinya Kitaoka 120a6e
    , m_fade(0)
Shinya Kitaoka 120a6e
    , m_shiftTraceGhostId(NO_GHOST)
Shinya Kitaoka 120a6e
    , m_currentXsheetLevel(0)
Shinya Kitaoka 120a6e
    , m_xsheetLevel(0) {
Shinya Kitaoka 120a6e
  m_placementStack.push_back(ZPlacement());
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
StageBuilder::~StageBuilder() { clearPointerContainer(m_maskPool); }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef _DEBUG
Shinya Kitaoka 120a6e
void StageBuilder::dumpPlayerSet(PlayerSet &players, std::ostream &out) {
Shinya Kitaoka 120a6e
  out << "[";
Shinya Kitaoka 120a6e
  int m = players.size();
Shinya Kitaoka 120a6e
  for (int i = 0; i < m; i++) {
Shinya Kitaoka 120a6e
    if (i > 0) out << " ";
Shinya Kitaoka 120a6e
    const Player &player = players[i];
Shinya Kitaoka 120a6e
    out << "img";
Shinya Kitaoka 120a6e
    if (!player.m_masks.empty()) {
Shinya Kitaoka 120a6e
      out << "(" << player.m_masks[0];
Shinya Kitaoka 120a6e
      for (unsigned int j = 1; j < player.m_masks.size(); j++)
Shinya Kitaoka 120a6e
        out << "," << player.m_masks[j];
Shinya Kitaoka 120a6e
      out << ")";
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  out << "]";
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void StageBuilder::dumpAll(std::ostream &out) {
Shinya Kitaoka 120a6e
  dumpPlayerSet(m_players, out);
Shinya Kitaoka 120a6e
  for (unsigned int i = 0; i < m_maskPool.size(); i++) {
Shinya Kitaoka 120a6e
    if (i > 0) out << " ";
Shinya Kitaoka 120a6e
    out << " mask:";
Shinya Kitaoka 120a6e
    dumpPlayerSet(*m_maskPool[i], out);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void StageBuilder::addCell(PlayerSet &players, ToonzScene *scene, TXsheet *xsh,
shun-iwasawa 048938
                           int row, int col, int level, int subSheetColIndex) {
Shinya Kitaoka 120a6e
  // Local functions
Shinya Kitaoka 120a6e
  struct locals {
Shinya Kitaoka 120a6e
    static inline bool isMeshDeformed(TXsheet *xsh, TStageObject *obj,
Shinya Kitaoka 120a6e
                                      const ImagePainter::VisualSettings *vs) {
Shinya Kitaoka 120a6e
      const TStageObjectId &parentId = obj->getParent();
Shinya Kitaoka 120a6e
      if (parentId.isColumn() && obj->getParentHandle()[0] != 'H') {
Shinya Kitaoka 120a6e
        TStageObject *parentObj = xsh->getStageObject(parentId);
Shinya Kitaoka 120a6e
        if (!parentObj->getPlasticSkeletonDeformation()) return false;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
        TXshColumn *parentCol = xsh->getColumn(parentId.getIndex());
Shinya Kitaoka 120a6e
        return (parentCol->getColumnType() == TXshColumn::eMeshType) &&
Shinya Kitaoka 120a6e
               (parentCol != vs->m_plasticVisualSettings.m_showOriginalColumn);
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      return false;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    //-----------------------------------------------------------------------------
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    static inline bool applyPlasticDeform(
Shinya Kitaoka 120a6e
        TXshColumn *col, const ImagePainter::VisualSettings *vs) {
Shinya Kitaoka 120a6e
      const PlasticVisualSettings &pvs = vs->m_plasticVisualSettings;
Shinya Kitaoka 120a6e
      return pvs.m_applyPlasticDeformation && (col != pvs.m_showOriginalColumn);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  };  // locals
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TXshColumnP column = xsh->getColumn(col);
Shinya Kitaoka 120a6e
  assert(column);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TStageObject *pegbar = xsh->getStageObject(TStageObjectId::ColumnId(col));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // Build affine placements
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TAffine columnAff     = pegbar->getPlacement(row);
Shinya Kitaoka 120a6e
  double columnZ        = pegbar->getZ(row);
Shinya Kitaoka 120a6e
  double columnNoScaleZ = pegbar->getGlobalNoScaleZ();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TXshCell cell = xsh->getCell(row, col);
Shinya Kitaoka 120a6e
  TXshLevel *xl = cell.m_level.getPointer();
shun-iwasawa 31accf
shun-iwasawa 31accf
#if defined(x64)
shun-iwasawa 31accf
  // check the previous row for a stop motion layer
shun-iwasawa 31accf
  if (!xl) {
shun-iwasawa 31accf
    if (!m_liveViewImage) return;
shun-iwasawa 31accf
    cell = xsh->getCell(row - 1, col);
shun-iwasawa 6bac0f
    xl   = cell.m_level.getPointer();
shun-iwasawa 31accf
    if (!xl) {
shun-iwasawa 31accf
      return;
shun-iwasawa 6bac0f
    } else {
shun-iwasawa 6bac0f
      xl                  = cell.m_level.getPointer();
shun-iwasawa 31accf
      TXshSimpleLevel *sl = xl->getSimpleLevel();
shun-iwasawa 31accf
      if (sl && sl == m_liveViewPlayer.m_sl) {
shun-iwasawa 31accf
        row -= 1;
shun-iwasawa 6bac0f
      } else
shun-iwasawa 31accf
        return;
shun-iwasawa 31accf
    }
shun-iwasawa 31accf
  }
shun-iwasawa 31accf
#else
Shinya Kitaoka 120a6e
  if (!xl) return;
shun-iwasawa 31accf
#endif
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  ZPlacement cameraPlacement;
Shinya Kitaoka 120a6e
  if (m_subXSheetStack.empty())
Shinya Kitaoka 120a6e
    cameraPlacement = m_cameraPlacement;
Shinya Kitaoka 120a6e
  else
Shinya Kitaoka 120a6e
    cameraPlacement = m_subXSheetStack.back().m_camera;
Shinya Kitaoka 120a6e
  TAffine columnZaff;
Shinya Kitaoka 120a6e
  bool columnBehindCamera = TStageObject::perspective(
Shinya Kitaoka 120a6e
      columnZaff, cameraPlacement.m_aff, cameraPlacement.m_z, columnAff,
Shinya Kitaoka 120a6e
      columnZ, columnNoScaleZ);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (!columnBehindCamera) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TXshSimpleLevel *sl = xl->getSimpleLevel();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  bool storePlayer =
Shinya Kitaoka 120a6e
      sl || (xl->getChildLevel() &&
Shinya Kitaoka 120a6e
             locals::applyPlasticDeform(column.getPointer(), m_vs) &&
Shinya Kitaoka 120a6e
             locals::isMeshDeformed(xsh, pegbar, m_vs));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (storePlayer) {
Shinya Kitaoka 120a6e
    // Build and store a player
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    Player player;
Jeremy Bullock 1e17ed
    player.m_sl                     = sl;
Jeremy Bullock 1e17ed
    player.m_fid                    = cell.m_frameId;
Jeremy Bullock 1e17ed
    player.m_xsh                    = xsh;
Jeremy Bullock 1e17ed
    player.m_column                 = col;
Jeremy Bullock 1e17ed
    player.m_frame                  = row;
Jeremy Bullock 1e17ed
    player.m_currentFrameId         = m_currentFrameId;
Jeremy Bullock 1e17ed
    player.m_isGuidedDrawingEnabled = m_isGuidedDrawingEnabled;
manongjohn 40a40e
    player.m_guidedFrontStroke      = m_guidedFrontStroke;
manongjohn 40a40e
    player.m_guidedBackStroke       = m_guidedBackStroke;
Shinya Kitaoka 120a6e
    player.m_dpiAff = sl ? getDpiAffine(sl, cell.m_frameId) : TAffine();
shun-iwasawa 048938
    player.m_onionSkinDistance = m_onionSkinDistance;
shun-iwasawa 048938
    // when visiting the subxsheet, valuate the subxsheet column index
shun-iwasawa a266be
    bool isCurrent               = (subSheetColIndex >= 0)
shun-iwasawa a266be
                                       ? (subSheetColIndex == m_currentColumnIndex)
shun-iwasawa a266be
                                       : (col == m_currentColumnIndex);
shun-iwasawa 048938
    player.m_isCurrentColumn     = isCurrent;
Shinya Kitaoka 120a6e
    player.m_ancestorColumnIndex = m_ancestorColumnIndex;
Shinya Kitaoka 120a6e
    player.m_masks               = m_masks;
Shinya Kitaoka 120a6e
    player.m_opacity             = column->getOpacity();
shun-iwasawa a266be
    player.m_filterColor =
shun-iwasawa a266be
        scene->getProperties()->getColorFilterColor(column->getColorFilterId());
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (m_subXSheetStack.empty()) {
Shinya Kitaoka 120a6e
      player.m_z         = columnZ;
Shinya Kitaoka 120a6e
      player.m_placement = m_camera3d ? columnAff : columnZaff;
Shinya Kitaoka 120a6e
    } else {
Shinya Kitaoka 120a6e
      const SubXSheet &parent = m_subXSheetStack.back();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      player.m_z = parent.m_z;
Shinya Kitaoka 120a6e
      player.m_placement =
Shinya Kitaoka 120a6e
          (m_camera3d ? parent.m_aff : parent.m_zaff) * columnZaff;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (m_shiftTraceGhostId != NO_GHOST) {
shun-iwasawa 2b24e8
      // if F1, F2 or F3 key is pressed, then draw only the corresponding ghost
shun-iwasawa 2b24e8
      int flipKey = m_onionSkinMask.getGhostFlipKey();
shun-iwasawa 2b24e8
      if (Qt::Key_F1 <= flipKey && flipKey <= Qt::Key_F3) {
shun-iwasawa 2b24e8
        if (m_shiftTraceGhostId == TRACED && flipKey == Qt::Key_F2) {
Shinya Kitaoka 120a6e
          players.push_back(player);
shun-iwasawa 2b24e8
        } else if (m_shiftTraceGhostId == FIRST_GHOST &&
shun-iwasawa 2b24e8
                   flipKey == Qt::Key_F1) {
Shinya Kitaoka 120a6e
          player.m_placement =
Shinya Kitaoka 120a6e
              m_onionSkinMask.getShiftTraceGhostAff(0) * player.m_placement;
Shinya Kitaoka 120a6e
          players.push_back(player);
shun-iwasawa 2b24e8
        } else if (m_shiftTraceGhostId == SECOND_GHOST &&
shun-iwasawa 2b24e8
                   flipKey == Qt::Key_F3) {
Shinya Kitaoka 120a6e
          player.m_placement =
Shinya Kitaoka 120a6e
              m_onionSkinMask.getShiftTraceGhostAff(1) * player.m_placement;
shun-iwasawa 2b24e8
          players.push_back(player);
shun-iwasawa 2b24e8
        }
shun-iwasawa 2b24e8
        return;
shun-iwasawa 2b24e8
      }
shun-iwasawa 2b24e8
shun-iwasawa 2b24e8
      else {
shun-iwasawa 2b24e8
        int opacity         = player.m_opacity;
shun-iwasawa 2b24e8
        player.m_bingoOrder = 10;
shun-iwasawa 2b24e8
        if (m_onionSkinMask.getShiftTraceStatus() !=
shun-iwasawa 2b24e8
            OnionSkinMask::ENABLED_WITHOUT_GHOST_MOVEMENTS) {
shun-iwasawa 2b24e8
          if (m_shiftTraceGhostId == FIRST_GHOST) {
shun-iwasawa 2b24e8
            player.m_opacity = 30;
shun-iwasawa 2b24e8
            players.push_back(player);
shun-iwasawa 1d5937
            player.m_opacity           = opacity;
shun-iwasawa 1d5937
            player.m_onionSkinDistance = -1;
shun-iwasawa 2b24e8
            player.m_placement =
shun-iwasawa 2b24e8
                m_onionSkinMask.getShiftTraceGhostAff(0) * player.m_placement;
shun-iwasawa 2b24e8
          } else if (m_shiftTraceGhostId == SECOND_GHOST) {
shun-iwasawa 2b24e8
            player.m_opacity = 30;
shun-iwasawa 2b24e8
            players.push_back(player);
shun-iwasawa 1d5937
            player.m_opacity           = opacity;
shun-iwasawa 1d5937
            player.m_onionSkinDistance = 1;
shun-iwasawa 2b24e8
            player.m_placement =
shun-iwasawa 2b24e8
                m_onionSkinMask.getShiftTraceGhostAff(1) * player.m_placement;
shun-iwasawa 2b24e8
          }
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    players.push_back(player);
Shinya Kitaoka 120a6e
  } else if (TXshChildLevel *cl = xl->getChildLevel()) {
Shinya Kitaoka 120a6e
    int childRow         = cell.m_frameId.getNumber() - 1;
Shinya Kitaoka 120a6e
    TXsheet *childXsheet = cl->getXsheet();
Shinya Kitaoka 120a6e
    TStageObjectId childCameraId =
Shinya Kitaoka 120a6e
        childXsheet->getStageObjectTree()->getCurrentCameraId();
Shinya Kitaoka 120a6e
    TStageObject *childCamera = childXsheet->getStageObject(childCameraId);
Shinya Kitaoka 120a6e
    TAffine childCameraAff    = childCamera->getPlacement(childRow);
Shinya Kitaoka 120a6e
    double childCameraZ       = childCamera->getZ(childRow);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    std::vector<uchar> originalOpacity(childXsheet->getColumnCount());</uchar>
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    for (int c = 0; c < childXsheet->getColumnCount(); c++) {
Shinya Kitaoka 120a6e
      originalOpacity[c] = childXsheet->getColumn(c)->getOpacity();
Shinya Kitaoka 120a6e
      childXsheet->getColumn(c)->setOpacity(column->getOpacity());
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    SubXSheet subXSheet;
Shinya Kitaoka 120a6e
    subXSheet.m_camera = ZPlacement(childCameraAff, childCameraZ);
Shinya Kitaoka 120a6e
    subXSheet.m_z      = columnZ;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    TAffine childCameraZaff =
Shinya Kitaoka 120a6e
        childCameraAff *
Shinya Kitaoka 120a6e
        TScale((1000 + childCameraZ) / 1000);  // TODO: put in some lib
Shinya Kitaoka 120a6e
    TAffine invChildCameraZaff = childCameraZaff.inv();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    subXSheet.m_aff  = columnAff * invChildCameraZaff;
Shinya Kitaoka 120a6e
    subXSheet.m_zaff = columnZaff * invChildCameraZaff;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (!m_subXSheetStack.empty()) {
Shinya Kitaoka 120a6e
      const SubXSheet &parentXSheet = m_subXSheetStack.back();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      subXSheet.m_z =
Shinya Kitaoka 120a6e
          m_subXSheetStack.front().m_z;  // Top-level xsheet cell's z
Shinya Kitaoka 120a6e
      subXSheet.m_aff  = parentXSheet.m_aff * subXSheet.m_aff;
Shinya Kitaoka 120a6e
      subXSheet.m_zaff = parentXSheet.m_zaff * subXSheet.m_zaff;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    m_subXSheetStack.push_back(subXSheet);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    ++m_currentXsheetLevel;
shun-iwasawa 048938
    // inherit the column index when visiting grandchild (sub-sub) sheet
shun-iwasawa 048938
    int subCol = (subSheetColIndex >= 0) ? subSheetColIndex : col;
shun-iwasawa 048938
    addFrame(players, scene, childXsheet, childRow, level + 1, false, false,
shun-iwasawa 048938
             subCol);
Shinya Kitaoka 120a6e
    --m_currentXsheetLevel;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    m_subXSheetStack.pop_back();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    for (int c = 0; c < childXsheet->getColumnCount(); c++)
Shinya Kitaoka 120a6e
      childXsheet->getColumn(c)->setOpacity(originalOpacity[c]);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Campbell Barton b3bd84
static bool alreadyAdded(TXsheet *xsh, int row, int index,
Campbell Barton b3bd84
                         const std::vector<int> &rows, int col) {</int>
Shinya Kitaoka 120a6e
  int i;
Shinya Kitaoka 120a6e
  for (i = 0; i < index; i++)
Shinya Kitaoka 120a6e
    if (xsh->getCell(rows[i], col) == xsh->getCell(rows[index], col))
Shinya Kitaoka 120a6e
      return true;
Shinya Kitaoka 120a6e
  if (xsh->getCell(rows[index], col) == xsh->getCell(row, col)) return true;
Shinya Kitaoka 120a6e
  return false;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void StageBuilder::addCellWithOnionSkin(PlayerSet &players, ToonzScene *scene,
Shinya Kitaoka 120a6e
                                        TXsheet *xsh, int row, int col,
shun-iwasawa 048938
                                        int level, int subSheetColIndex) {
Shinya Kitaoka 120a6e
  struct locals {
Shinya Kitaoka 120a6e
    static inline bool hasOnionSkinnedMeshParent(StageBuilder *sb, TXsheet *xsh,
Shinya Kitaoka 120a6e
                                                 int col) {
Shinya Kitaoka 120a6e
      const TStageObjectId &parentId =
Shinya Kitaoka 120a6e
          xsh->getStageObject(TStageObjectId::ColumnId(col))->getParent();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      return parentId.isColumn() &&
Shinya Kitaoka 120a6e
             (parentId.getIndex() == sb->m_currentColumnIndex);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    //-----------------------------------------------------------------------------
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    static inline bool doStandardOnionSkin(StageBuilder *sb, TXsheet *xsh,
Shinya Kitaoka 120a6e
                                           int level, int col) {
Shinya Kitaoka 120a6e
      const OnionSkinMask &osm = sb->m_onionSkinMask;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      return level == sb->m_xsheetLevel && osm.isEnabled() && !osm.isEmpty() &&
Shinya Kitaoka 120a6e
             (osm.isWholeScene() || col == sb->m_currentColumnIndex ||
Shinya Kitaoka 120a6e
              locals::hasOnionSkinnedMeshParent(sb, xsh, col));
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  };  // locals
Shinya Kitaoka 120a6e
shun-iwasawa 1d5937
  if (m_onionSkinMask.isShiftTraceEnabled()) {
shun-iwasawa 048938
    // when visiting the subxsheet, valuate the subxsheet column index
shun-iwasawa 048938
    bool isCurrent = (subSheetColIndex >= 0)
shun-iwasawa 048938
                         ? (subSheetColIndex == m_currentColumnIndex)
shun-iwasawa 048938
                         : (col == m_currentColumnIndex);
shun-iwasawa 048938
    if (isCurrent) {
shun-iwasawa 1d5937
      TXshCell cell = xsh->getCell(row, col);
shun-iwasawa 1d5937
shun-iwasawa 1d5937
      // First Ghost
shun-iwasawa 1d5937
      int r;
shun-iwasawa 1d5937
      r = row + m_onionSkinMask.getShiftTraceGhostFrameOffset(0);
shun-iwasawa 1d5937
      if (r >= 0 && xsh->getCell(r, col) != cell &&
shun-iwasawa 1d5937
          (cell.getSimpleLevel() == 0 ||
shun-iwasawa 1d5937
           xsh->getCell(r, col).getSimpleLevel() == cell.getSimpleLevel())) {
shun-iwasawa 1d5937
        m_shiftTraceGhostId = FIRST_GHOST;
shun-iwasawa 048938
        addCell(players, scene, xsh, r, col, level, subSheetColIndex);
shun-iwasawa 1d5937
      }
Shinya Kitaoka 120a6e
shun-iwasawa 1d5937
      r = row + m_onionSkinMask.getShiftTraceGhostFrameOffset(1);
shun-iwasawa 1d5937
      if (r >= 0 && xsh->getCell(r, col) != cell &&
shun-iwasawa 1d5937
          (cell.getSimpleLevel() == 0 ||
shun-iwasawa 1d5937
           xsh->getCell(r, col).getSimpleLevel() == cell.getSimpleLevel())) {
shun-iwasawa 1d5937
        m_shiftTraceGhostId = SECOND_GHOST;
shun-iwasawa 048938
        addCell(players, scene, xsh, r, col, level, subSheetColIndex);
shun-iwasawa 1d5937
      }
shun-iwasawa 2b24e8
shun-iwasawa 1d5937
      // draw current working frame
shun-iwasawa 1d5937
      if (!cell.isEmpty()) {
shun-iwasawa 1d5937
        m_shiftTraceGhostId = TRACED;
shun-iwasawa 048938
        addCell(players, scene, xsh, row, col, level, subSheetColIndex);
shun-iwasawa 1d5937
        m_shiftTraceGhostId = NO_GHOST;
shun-iwasawa 1d5937
      }
shun-iwasawa 1d5937
    }
shun-iwasawa 1d5937
    // flip non-current columns as well
shun-iwasawa 1d5937
    else {
shun-iwasawa 1d5937
      int flipKey = m_onionSkinMask.getGhostFlipKey();
shun-iwasawa 1d5937
      if (flipKey == Qt::Key_F1) {
shun-iwasawa 1d5937
        int r = row + m_onionSkinMask.getShiftTraceGhostFrameOffset(0);
shun-iwasawa 048938
        addCell(players, scene, xsh, r, col, level, subSheetColIndex);
shun-iwasawa 1d5937
      } else if (flipKey == Qt::Key_F3) {
shun-iwasawa 1d5937
        int r = row + m_onionSkinMask.getShiftTraceGhostFrameOffset(1);
shun-iwasawa 048938
        addCell(players, scene, xsh, r, col, level, subSheetColIndex);
shun-iwasawa 1d5937
      } else
shun-iwasawa 048938
        addCell(players, scene, xsh, row, col, level, subSheetColIndex);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  } else if (locals::doStandardOnionSkin(this, xsh, level, col)) {
Shinya Kitaoka 120a6e
    std::vector<int> rows;</int>
Shinya Kitaoka 120a6e
    m_onionSkinMask.getAll(row, rows);
Shinya Kitaoka 120a6e
    std::vector<int>::iterator it = rows.begin();</int>
Shinya Kitaoka 120a6e
    while (it != rows.end() && *it < row) it++;
Shinya Kitaoka 120a6e
    std::sort(rows.begin(), it, descending);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    int frontPos = 0, backPos = 0;
Shinya Kitaoka 120a6e
    for (int i = 0; i < (int)rows.size(); i++) {
Shinya Kitaoka 120a6e
      if (rows[i] == row) continue;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef NUOVO_ONION
Shinya Kitaoka 120a6e
      m_onionSkinDistance = rows[i] - row;
Toshihiro Shimizu 890ddd
#else
Shinya Kitaoka 120a6e
      if (!Preferences::instance()->isAnimationSheetEnabled() ||
Shinya Kitaoka 120a6e
          !alreadyAdded(xsh, row, i, rows, col)) {
Shinya Kitaoka 120a6e
        m_onionSkinDistance = (rows[i] - row) < 0 ? --backPos : ++frontPos;
shun-iwasawa 048938
        addCell(players, scene, xsh, rows[i], col, level, subSheetColIndex);
Shinya Kitaoka 120a6e
      }
Toshihiro Shimizu 890ddd
#endif
Shinya Kitaoka 120a6e
    }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    m_onionSkinDistance = 0;
shun-iwasawa 048938
    addCell(players, scene, xsh, row, col, level, subSheetColIndex);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    m_onionSkinDistance = c_noOnionSkin;
Shinya Kitaoka 120a6e
  } else
shun-iwasawa 048938
    addCell(players, scene, xsh, row, col, level, subSheetColIndex);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void StageBuilder::addFrame(PlayerSet &players, ToonzScene *scene, TXsheet *xsh,
Shinya Kitaoka 120a6e
                            int row, int level, bool includeUnvisible,
shun-iwasawa 048938
                            bool checkPreviewVisibility, int subSheetColIndex) {
Shinya Kitaoka 120a6e
  int columnCount        = xsh->getColumnCount();
Shinya Kitaoka 120a6e
  unsigned int maskCount = m_masks.size();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  std::vector<std::pair<double, int="">> shuffle;</std::pair<double,>
Shinya Kitaoka 120a6e
  for (int c = 0; c < columnCount; c++) {
Shinya Kitaoka 120a6e
    TXshColumnP column = xsh->getColumn(c);
Shinya Kitaoka 120a6e
    assert(column);
Shinya Kitaoka 120a6e
    TStageObject *pegbar = xsh->getStageObject(TStageObjectId::ColumnId(c));
Shinya Kitaoka 120a6e
    double columnSO      = pegbar->getSO(row);
Shinya Kitaoka 120a6e
    shuffle.push_back(std::make_pair(columnSO, c));
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  std::stable_sort(shuffle.begin(), shuffle.end(), StackingOrder());
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (int i = 0; i < columnCount; i++) {
Shinya Kitaoka 120a6e
    int c = shuffle[i].second;
Shinya Kitaoka 120a6e
    if (CameraTestCheck::instance()->isEnabled() && c != m_currentColumnIndex)
Shinya Kitaoka 120a6e
      continue;
Shinya Kitaoka 120a6e
    if (level == 0) {
Shinya Kitaoka 120a6e
      // m_isCurrentColumn = (c == m_currentColumnIndex);
Shinya Kitaoka 120a6e
      m_ancestorColumnIndex = c;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    TXshColumn *column = xsh->getColumn(c);
Shinya Kitaoka 120a6e
    bool isMask        = false;
Jeremy Bullock 57507e
    if (column && !column->isEmpty() && !column->getSoundColumn()) {
Shinya Kitaoka 120a6e
      if (!column->isPreviewVisible() && checkPreviewVisibility) continue;
Shinya Kitaoka 120a6e
      if (column->isCamstandVisible() ||
Shinya Kitaoka 120a6e
          includeUnvisible)  // se l'"occhietto" non e' chiuso
Shinya Kitaoka 120a6e
      {
Shinya Kitaoka 120a6e
        if (column->isMask())  // se e' una maschera (usate solo in tab pro)
Shinya Kitaoka 120a6e
        {
Shinya Kitaoka 120a6e
          isMask = true;
Shinya Kitaoka 120a6e
          std::vector<int> saveMasks;</int>
Shinya Kitaoka 120a6e
          saveMasks.swap(m_masks);
Shinya Kitaoka 120a6e
          int maskIndex   = m_maskPool.size();
Shinya Kitaoka 120a6e
          PlayerSet *mask = new PlayerSet();
Shinya Kitaoka 120a6e
          m_maskPool.push_back(mask);
Shinya Kitaoka 120a6e
          addCellWithOnionSkin(*mask, scene, xsh, row, c, level);
Shinya Kitaoka 120a6e
          std::stable_sort(mask->begin(), mask->end(), PlayerLt());
Shinya Kitaoka 120a6e
          saveMasks.swap(m_masks);
Shinya Kitaoka 120a6e
          m_masks.push_back(maskIndex);
Shinya Kitaoka 120a6e
        } else
shun-iwasawa 048938
          addCellWithOnionSkin(players, scene, xsh, row, c, level,
shun-iwasawa 048938
                               subSheetColIndex);
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    if (!isMask) {
Shinya Kitaoka 120a6e
      while (m_masks.size() > maskCount) m_masks.pop_back();
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  if (level == 0) std::stable_sort(players.begin(), players.end(), PlayerLt());
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void StageBuilder::addSimpleLevelFrame(PlayerSet &players,
Shinya Kitaoka 120a6e
                                       TXshSimpleLevel *level,
Shinya Kitaoka 120a6e
                                       const TFrameId &fid) {
shun-iwasawa 2b24e8
  auto addGhost = [&](int ghostIndex, int ghostRow, bool fullOpac = false) {
shun-iwasawa 2b24e8
    const TFrameId &ghostFid = level->index2fid(ghostRow);
shun-iwasawa 2b24e8
shun-iwasawa 2b24e8
    Player player;
shun-iwasawa 2b24e8
    player.m_sl                     = level;
shun-iwasawa 2b24e8
    player.m_frame                  = level->guessIndex(ghostFid);
shun-iwasawa 2b24e8
    player.m_fid                    = ghostFid;
shun-iwasawa 2b24e8
    player.m_isCurrentColumn        = true;
shun-iwasawa 2b24e8
    player.m_isCurrentXsheetLevel   = true;
shun-iwasawa 2b24e8
    player.m_isEditingLevel         = true;
shun-iwasawa 2b24e8
    player.m_currentFrameId         = m_currentFrameId;
shun-iwasawa 2b24e8
    player.m_isGuidedDrawingEnabled = m_isGuidedDrawingEnabled;
manongjohn 40a40e
    player.m_guidedFrontStroke      = m_guidedFrontStroke;
manongjohn 40a40e
    player.m_guidedBackStroke       = m_guidedBackStroke;
shun-iwasawa 2b24e8
    player.m_isVisibleinOSM         = ghostRow >= 0;
shun-iwasawa 2b24e8
    player.m_onionSkinDistance      = m_onionSkinDistance;
shun-iwasawa 2b24e8
    player.m_dpiAff                 = getDpiAffine(level, ghostFid);
shun-iwasawa 2b24e8
    player.m_ancestorColumnIndex    = -1;
shun-iwasawa 2b24e8
shun-iwasawa 2b24e8
    if (fullOpac) {
shun-iwasawa 2b24e8
      player.m_placement = m_onionSkinMask.getShiftTraceGhostAff(ghostIndex) *
shun-iwasawa 2b24e8
                           player.m_placement;
shun-iwasawa 2b24e8
      players.push_back(player);
shun-iwasawa 2b24e8
      return;
shun-iwasawa 2b24e8
    }
shun-iwasawa 2b24e8
shun-iwasawa 2b24e8
    int opacity         = player.m_opacity;
shun-iwasawa 2b24e8
    player.m_bingoOrder = 10;
shun-iwasawa 2b24e8
    if (m_onionSkinMask.getShiftTraceStatus() !=
shun-iwasawa 2b24e8
        OnionSkinMask::ENABLED_WITHOUT_GHOST_MOVEMENTS) {
shun-iwasawa 2b24e8
      player.m_opacity = 30;
shun-iwasawa 2b24e8
      players.push_back(player);
shun-iwasawa 1d5937
      player.m_opacity           = opacity;
shun-iwasawa 1d5937
      player.m_onionSkinDistance = (ghostIndex == 0) ? -1 : 1;
shun-iwasawa 2b24e8
      player.m_placement = m_onionSkinMask.getShiftTraceGhostAff(ghostIndex) *
shun-iwasawa 2b24e8
                           player.m_placement;
shun-iwasawa 2b24e8
    }
shun-iwasawa 2b24e8
    players.push_back(player);
shun-iwasawa 2b24e8
  };
shun-iwasawa 2b24e8
Shinya Kitaoka 120a6e
  int index = -1;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int row = level->guessIndex(fid);
shun-iwasawa 2b24e8
shun-iwasawa 2b24e8
  // Shift & Trace
shun-iwasawa 2b24e8
  if (m_onionSkinMask.isShiftTraceEnabled()) {
shun-iwasawa 2b24e8
    int previousOffset = m_onionSkinMask.getShiftTraceGhostFrameOffset(0);
shun-iwasawa 2b24e8
    int forwardOffset  = m_onionSkinMask.getShiftTraceGhostFrameOffset(1);
shun-iwasawa 2b24e8
shun-iwasawa 2b24e8
    // If F1, F2 or F3 key is pressed, then only
shun-iwasawa 2b24e8
    // display the corresponding ghost
shun-iwasawa 2b24e8
    int flipKey = m_onionSkinMask.getGhostFlipKey();
shun-iwasawa 2b24e8
    if (Qt::Key_F1 <= flipKey && flipKey <= Qt::Key_F3) {
shun-iwasawa 2b24e8
      if (flipKey == Qt::Key_F1 && previousOffset != 0) {
shun-iwasawa 2b24e8
        addGhost(0, row + previousOffset, true);
shun-iwasawa 2b24e8
        return;
shun-iwasawa 2b24e8
      } else if (flipKey == Qt::Key_F3 && forwardOffset != 0) {
shun-iwasawa 2b24e8
        addGhost(1, row + forwardOffset, true);
shun-iwasawa 2b24e8
        return;
shun-iwasawa 2b24e8
      }
shun-iwasawa 2b24e8
    }
shun-iwasawa 2b24e8
shun-iwasawa 2b24e8
    else {
shun-iwasawa 2b24e8
      // draw the first ghost
shun-iwasawa 2b24e8
      if (previousOffset != 0) addGhost(0, row + previousOffset);
shun-iwasawa 2b24e8
      if (forwardOffset != 0) addGhost(1, row + forwardOffset);
shun-iwasawa 2b24e8
    }
shun-iwasawa 2b24e8
  }
shun-iwasawa 2b24e8
  // Onion Skin
shun-iwasawa 2b24e8
  else if (!m_onionSkinMask.isEmpty() && m_onionSkinMask.isEnabled()) {
Shinya Kitaoka 120a6e
    std::vector<int> rows;</int>
Shinya Kitaoka 120a6e
    m_onionSkinMask.getAll(row, rows);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    std::vector<int>::iterator it = rows.begin();</int>
Shinya Kitaoka 120a6e
    while (it != rows.end() && *it < row) ++it;
Shinya Kitaoka 120a6e
    std::sort(rows.begin(), it, descending);
Shinya Kitaoka 120a6e
    m_onionSkinDistance = 0;
Shinya Kitaoka 120a6e
    int frontPos = 0, backPos = 0;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    for (int i = 0; i < (int)rows.size(); i++) {
Shinya Kitaoka 120a6e
      const TFrameId &fid2 = level->index2fid(rows[i]);
Shinya Kitaoka 120a6e
      if (fid2 == fid) continue;
Shinya Kitaoka 120a6e
      players.push_back(Player());
Jeremy Bullock 1e17ed
      Player &player                  = players.back();
Jeremy Bullock 1e17ed
      player.m_sl                     = level;
Jeremy Bullock 1e17ed
      player.m_frame                  = level->guessIndex(fid);
Jeremy Bullock 1e17ed
      player.m_fid                    = fid2;
Jeremy Bullock 1e17ed
      player.m_isCurrentColumn        = true;
Jeremy Bullock 1e17ed
      player.m_isCurrentXsheetLevel   = true;
Jeremy Bullock 1e17ed
      player.m_isEditingLevel         = true;
Jeremy Bullock 1e17ed
      player.m_currentFrameId         = m_currentFrameId;
Jeremy Bullock 1e17ed
      player.m_isGuidedDrawingEnabled = m_isGuidedDrawingEnabled;
manongjohn 40a40e
      player.m_guidedFrontStroke      = m_guidedFrontStroke;
manongjohn 40a40e
      player.m_guidedBackStroke       = m_guidedBackStroke;
Jeremy Bullock 1e17ed
      player.m_isVisibleinOSM         = rows[i] >= 0;
Toshihiro Shimizu 890ddd
#ifdef NUOVO_ONION
Shinya Kitaoka 120a6e
      player.m_onionSkinDistance = rows[i] - row;
Toshihiro Shimizu 890ddd
#else
Shinya Kitaoka 120a6e
      player.m_onionSkinDistance = rows[i] - row < 0 ? --backPos : ++frontPos;
Toshihiro Shimizu 890ddd
#endif
Shinya Kitaoka 120a6e
      player.m_dpiAff = getDpiAffine(level, fid2);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  players.push_back(Player());
Shinya Kitaoka 120a6e
  Player &player = players.back();
Shinya Kitaoka 120a6e
  player.m_sl    = level;
Shinya Kitaoka 120a6e
  player.m_frame = level->guessIndex(fid);
Shinya Kitaoka 120a6e
  player.m_fid   = fid;
Shinya Kitaoka 120a6e
  if (!m_onionSkinMask.isEmpty() && m_onionSkinMask.isEnabled())
shun-iwasawa 048938
    player.m_onionSkinDistance = 0;
Shinya Kitaoka 120a6e
  player.m_isCurrentColumn      = true;
Shinya Kitaoka 120a6e
  player.m_isCurrentXsheetLevel = true;
Jeremy Bullock 1e17ed
  player.m_isEditingLevel       = true;
Shinya Kitaoka 120a6e
  player.m_ancestorColumnIndex  = -1;
Shinya Kitaoka 120a6e
  player.m_dpiAff               = getDpiAffine(level, fid);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void StageBuilder::visit(PlayerSet &players, Visitor &visitor, bool isPlaying) {
Shinya Kitaoka 120a6e
  std::vector<int> masks;</int>
shun-iwasawa 6bac0f
  int m                = players.size();
shun-iwasawa 6bac0f
  int h                = 0;
shun-iwasawa 31accf
  bool stopMotionShown = false;
Shinya Kitaoka 120a6e
  for (; h < m; h++) {
Shinya Kitaoka 120a6e
    Player &player = players[h];
Shinya Kitaoka 120a6e
    unsigned int i = 0;
Shinya Kitaoka 120a6e
    // vale solo per TAB pro
Shinya Kitaoka 120a6e
    for (; i < masks.size() && i < player.m_masks.size(); i++)
Shinya Kitaoka 120a6e
      if (masks[i] != player.m_masks[i]) break;
Shinya Kitaoka 120a6e
    // vale solo per TAB pro
Shinya Kitaoka 120a6e
    if (i < masks.size() || i < player.m_masks.size()) {
Shinya Kitaoka 120a6e
      while (i < masks.size()) {
Shinya Kitaoka 120a6e
        masks.pop_back();
Shinya Kitaoka 120a6e
        visitor.disableMask();
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
      while (i < player.m_masks.size()) {
Shinya Kitaoka 120a6e
        int maskIndex = player.m_masks[i];
Shinya Kitaoka 120a6e
        visitor.beginMask();
Shinya Kitaoka 120a6e
        visit(*m_maskPool[maskIndex], visitor, isPlaying);
Shinya Kitaoka 120a6e
        visitor.endMask();
Shinya Kitaoka 120a6e
        masks.push_back(maskIndex);
Shinya Kitaoka 120a6e
        visitor.enableMask();
Shinya Kitaoka 120a6e
        i++;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    player.m_isPlaying = isPlaying;
shun-iwasawa 31accf
shun-iwasawa 31accf
#if defined(x64)
shun-iwasawa 31accf
    if (m_liveViewImage && player.m_sl == m_liveViewPlayer.m_sl) {
shun-iwasawa 31accf
      if (m_lineupImage) {
shun-iwasawa 31accf
        m_lineupPlayer.m_sl = NULL;
shun-iwasawa 31accf
        visitor.onRasterImage(m_lineupImage.getPointer(), m_lineupPlayer);
shun-iwasawa 31accf
        stopMotionShown = true;
shun-iwasawa 31accf
      }
shun-iwasawa 31accf
      if (m_liveViewImage) {
shun-iwasawa 31accf
        m_liveViewPlayer.m_sl = NULL;
shun-iwasawa 31accf
        visitor.onRasterImage(m_liveViewImage.getPointer(), m_liveViewPlayer);
shun-iwasawa 31accf
        stopMotionShown = true;
shun-iwasawa 31accf
      }
shun-iwasawa 6bac0f
    } else {
shun-iwasawa 31accf
      visitor.onImage(player);
shun-iwasawa 31accf
    }
shun-iwasawa 31accf
  }
shun-iwasawa 31accf
  if (!stopMotionShown && (m_liveViewImage || m_lineupImage)) {
shun-iwasawa 31accf
    if (m_lineupImage) {
shun-iwasawa 31accf
      m_lineupPlayer.m_sl = NULL;
shun-iwasawa 31accf
      visitor.onRasterImage(m_lineupImage.getPointer(), m_lineupPlayer);
shun-iwasawa 31accf
    }
shun-iwasawa 31accf
    if (m_liveViewImage) {
shun-iwasawa 31accf
      m_liveViewPlayer.m_sl = NULL;
shun-iwasawa 31accf
      visitor.onRasterImage(m_liveViewImage.getPointer(), m_liveViewPlayer);
shun-iwasawa 31accf
    }
shun-iwasawa 31accf
#else
Shinya Kitaoka 120a6e
    visitor.onImage(player);
shun-iwasawa 31accf
#endif
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  // vale solo per TAB pro
Shinya Kitaoka 120a6e
  for (h = 0; h < (int)masks.size(); h++) visitor.disableMask();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
/*! Declare a \b StageBuilder object and recall \b StageBuilder::addFrame() and
Shinya Kitaoka 120a6e
                \b StageBuilder::visit().
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void Stage::visit(Visitor &visitor, const VisitArgs &args) {
Shinya Kitaoka 120a6e
  ToonzScene *scene        = args.m_scene;
Shinya Kitaoka 120a6e
  TXsheet *xsh             = args.m_xsh;
Shinya Kitaoka 120a6e
  int row                  = args.m_row;
Shinya Kitaoka 120a6e
  int col                  = args.m_col;
Shinya Kitaoka 120a6e
  const OnionSkinMask *osm = args.m_osm;
Shinya Kitaoka 120a6e
  bool camera3d            = args.m_camera3d;
Shinya Kitaoka 120a6e
  int xsheetLevel          = args.m_xsheetLevel;
Shinya Kitaoka 120a6e
  bool isPlaying           = args.m_isPlaying;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  StageBuilder sb;
Jeremy Bullock 1e17ed
  sb.m_vs                     = &visitor.m_vs;
Jeremy Bullock 1e17ed
  TStageObjectId cameraId     = xsh->getStageObjectTree()->getCurrentCameraId();
Jeremy Bullock 1e17ed
  TStageObject *camera        = xsh->getStageObject(cameraId);
Jeremy Bullock 1e17ed
  TAffine cameraAff           = camera->getPlacement(row);
Jeremy Bullock 1e17ed
  double z                    = camera->getZ(row);
Jeremy Bullock 1e17ed
  sb.m_cameraPlacement        = ZPlacement(cameraAff, z);
Jeremy Bullock 1e17ed
  sb.m_camera3d               = camera3d;
Jeremy Bullock 1e17ed
  sb.m_currentColumnIndex     = col;
Jeremy Bullock 1e17ed
  sb.m_xsheetLevel            = xsheetLevel;
Jeremy Bullock 1e17ed
  sb.m_onionSkinMask          = *osm;
Jeremy Bullock 1e17ed
  sb.m_currentFrameId         = args.m_currentFrameId;
Jeremy Bullock 1e17ed
  sb.m_isGuidedDrawingEnabled = args.m_isGuidedDrawingEnabled;
manongjohn 40a40e
  sb.m_guidedFrontStroke      = args.m_guidedFrontStroke;
manongjohn 40a40e
  sb.m_guidedBackStroke       = args.m_guidedBackStroke;
shun-iwasawa 31accf
#if defined(x64)
shun-iwasawa 31accf
  if (args.m_liveViewImage) {
shun-iwasawa 6bac0f
    sb.m_liveViewImage  = args.m_liveViewImage;
shun-iwasawa 31accf
    sb.m_liveViewPlayer = args.m_liveViewPlayer;
shun-iwasawa 31accf
  }
shun-iwasawa 31accf
  if (args.m_lineupImage) {
shun-iwasawa 6bac0f
    sb.m_lineupImage  = args.m_lineupImage;
shun-iwasawa 31accf
    sb.m_lineupPlayer = args.m_lineupPlayer;
shun-iwasawa 31accf
  }
shun-iwasawa 31accf
#endif
shun-iwasawa 1d5937
  Player::m_onionSkinFrontSize     = 0;
shun-iwasawa 1d5937
  Player::m_onionSkinBackSize      = 0;
manongjohn 40a40e
  Player::m_firstFrontOnionSkin    = 0;
shun-iwasawa 1d5937
  Player::m_firstBackOnionSkin     = 0;
shun-iwasawa 1d5937
  Player::m_lastBackVisibleSkin    = 0;
shun-iwasawa 1d5937
  Player::m_isShiftAndTraceEnabled = osm->isShiftTraceEnabled();
Shinya Kitaoka 120a6e
  sb.addFrame(sb.m_players, scene, xsh, row, 0, args.m_onlyVisible,
Shinya Kitaoka 120a6e
              args.m_checkPreviewVisibility);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  updateOnionSkinSize(sb.m_players);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  sb.visit(sb.m_players, visitor, isPlaying);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void Stage::visit(Visitor &visitor, ToonzScene *scene, TXsheet *xsh, int row) {
Shinya Kitaoka 120a6e
  Stage::VisitArgs args;
Shinya Kitaoka 120a6e
  args.m_scene = scene;
Shinya Kitaoka 120a6e
  args.m_xsh   = xsh;
Shinya Kitaoka 120a6e
  args.m_row   = row;
Shinya Kitaoka 120a6e
  args.m_col   = -1;
Shinya Kitaoka 120a6e
  OnionSkinMask osm;
Shinya Kitaoka 120a6e
  args.m_osm = &osm;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  visit(visitor, args);  // scene, xsh, row, -1, OnionSkinMask(), false, 0);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Shinya Kitaoka 120a6e
/*! Declare a \b StageBuilder object and recall \b
Shinya Kitaoka 120a6e
   StageBuilder::addSimpleLevelFrame()
Shinya Kitaoka 120a6e
                and \b StageBuilder::visit().
Toshihiro Shimizu 890ddd
*/
Shinya Kitaoka 120a6e
void Stage::visit(Visitor &visitor, TXshSimpleLevel *level, const TFrameId &fid,
Jeremy Bullock 1e17ed
                  const OnionSkinMask &osm, bool isPlaying,
manongjohn 40a40e
                  int isGuidedDrawingEnabled, int guidedBackStroke,
manongjohn 40a40e
                  int guidedFrontStroke) {
Shinya Kitaoka 120a6e
  StageBuilder sb;
shun-iwasawa 1d5937
  sb.m_vs                          = &visitor.m_vs;
shun-iwasawa 1d5937
  sb.m_onionSkinMask               = osm;
shun-iwasawa 1d5937
  sb.m_currentFrameId              = fid;
shun-iwasawa 1d5937
  sb.m_isGuidedDrawingEnabled      = isGuidedDrawingEnabled;
manongjohn 40a40e
  sb.m_guidedFrontStroke           = guidedFrontStroke;
manongjohn 40a40e
  sb.m_guidedBackStroke            = guidedBackStroke;
shun-iwasawa 1d5937
  Player::m_onionSkinFrontSize     = 0;
shun-iwasawa 1d5937
  Player::m_onionSkinBackSize      = 0;
manongjohn 40a40e
  Player::m_firstFrontOnionSkin    = 0;
shun-iwasawa 1d5937
  Player::m_firstBackOnionSkin     = 0;
shun-iwasawa 1d5937
  Player::m_lastBackVisibleSkin    = 0;
shun-iwasawa 1d5937
  Player::m_isShiftAndTraceEnabled = osm.isShiftTraceEnabled();
Shinya Kitaoka 120a6e
  sb.addSimpleLevelFrame(sb.m_players, level, fid);
Shinya Kitaoka 120a6e
  updateOnionSkinSize(sb.m_players);
Shinya Kitaoka 120a6e
  sb.visit(sb.m_players, visitor, isPlaying);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void Stage::visit(Visitor &visitor, TXshLevel *level, const TFrameId &fid,
Jeremy Bullock 1e17ed
                  const OnionSkinMask &osm, bool isPlaying,
manongjohn 40a40e
                  double isGuidedDrawingEnabled, int guidedBackStroke,
manongjohn 40a40e
                  int guidedFrontStroke) {
Shinya Kitaoka 120a6e
  if (level && level->getSimpleLevel())
Jeremy Bullock 1e17ed
    visit(visitor, level->getSimpleLevel(), fid, osm, isPlaying,
manongjohn 40a40e
          (int)isGuidedDrawingEnabled, guidedBackStroke, guidedFrontStroke);
Toshihiro Shimizu 890ddd
}