Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// TnzCore includes
Toshihiro Shimizu 890ddd
#include "tundo.h"
Toshihiro Shimizu 890ddd
#include "tgl.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// TnzExt includes
Toshihiro Shimizu 890ddd
#include "ext/plasticdeformerstorage.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// TnzLib includes
Toshihiro Shimizu 890ddd
#include "toonz/txshcell.h"
Toshihiro Shimizu 890ddd
#include "toonz/txshsimplelevel.h"
Toshihiro Shimizu 890ddd
#include "toonz/tframehandle.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// tcg includes
Toshihiro Shimizu 890ddd
#include "tcg/tcg_point_ops.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// boost includes
Toshihiro Shimizu 890ddd
#include <boost noncopyable.hpp=""></boost>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "plastictool.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
using namespace PlasticToolLocals;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//****************************************************************************************
Toshihiro Shimizu 890ddd
//    Local namespace  stuff
Toshihiro Shimizu 890ddd
//****************************************************************************************
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
namespace {
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
enum { RIGID_IDX = 0, FLEX_IDX };
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
}  // namespace
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//****************************************************************************************
Toshihiro Shimizu 890ddd
//    Undo  definitions
Toshihiro Shimizu 890ddd
//****************************************************************************************
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
namespace {
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
class PaintRigidityUndo : public TUndo {
Shinya Kitaoka 120a6e
  TXshCell m_cell;  //!< Affected image (cell == level + frame)
Shinya Kitaoka 120a6e
  std::vector<std::map<int, double="">> m_vertices;  //!< Affected vertices</std::map<int,>
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  double m_paintValue;  //!< Rigidity value the vertices were
Shinya Kitaoka 120a6e
                        //!< painted with
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  PaintRigidityUndo(const TXshCell &cell,
Shinya Kitaoka 120a6e
                    const std::vector<std::map<int, double="">> &vertices,</std::map<int,>
Shinya Kitaoka 120a6e
                    double paintValue)
Shinya Kitaoka 120a6e
      : m_cell(cell), m_vertices(vertices), m_paintValue(paintValue) {}
Shinya Kitaoka 120a6e
Shinya Kitaoka 473e70
  int getSize() const override { return 1 << 20; }
Shinya Kitaoka 120a6e
Shinya Kitaoka 473e70
  void redo() const override {
Shinya Kitaoka 120a6e
    TXshSimpleLevel *sl =
Shinya Kitaoka 120a6e
        static_cast<txshsimplelevel *="">(m_cell.m_level.getPointer());</txshsimplelevel>
Shinya Kitaoka 120a6e
    sl->setDirtyFlag(true);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    TMeshImageP mi(sl->getFrame(m_cell.m_frameId, true));
Shinya Kitaoka 120a6e
    if (!mi || mi->meshes().size() != m_vertices.size()) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    int m, mCount = int(mi->meshes().size());
Shinya Kitaoka 120a6e
    for (m = 0; m != mCount; ++m) {
Shinya Kitaoka 120a6e
      TTextureMesh &mesh = *mi->meshes()[m];
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      std::map<int, double="">::const_iterator vt, vEnd(m_vertices[m].end());</int,>
Shinya Kitaoka 120a6e
      for (vt = m_vertices[m].begin(); vt != vEnd; ++vt)
Shinya Kitaoka 120a6e
        mesh.vertex(vt->first).P().rigidity = m_paintValue;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    PlasticDeformerStorage::instance()->invalidateMeshImage(
Shinya Kitaoka 120a6e
        mi.getPointer(), PlasticDeformerStorage::MESH);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 473e70
  void undo() const override {
Shinya Kitaoka 120a6e
    TXshSimpleLevel *sl =
Shinya Kitaoka 120a6e
        static_cast<txshsimplelevel *="">(m_cell.m_level.getPointer());</txshsimplelevel>
Shinya Kitaoka 120a6e
    sl->setDirtyFlag(true);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    TMeshImageP mi(sl->getFrame(m_cell.m_frameId, true));
Shinya Kitaoka 120a6e
    if (!mi || mi->meshes().size() != m_vertices.size()) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    int m, mCount = int(mi->meshes().size());
Shinya Kitaoka 120a6e
    for (m = 0; m != mCount; ++m) {
Shinya Kitaoka 120a6e
      TTextureMesh &mesh = *mi->meshes()[m];
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      std::map<int, double="">::const_iterator vt, vEnd(m_vertices[m].end());</int,>
Shinya Kitaoka 120a6e
      for (vt = m_vertices[m].begin(); vt != vEnd; ++vt)
Shinya Kitaoka 120a6e
        mesh.vertex(vt->first).P().rigidity = vt->second;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    PlasticDeformerStorage::instance()->invalidateMeshImage(
Shinya Kitaoka 120a6e
        mi.getPointer(), PlasticDeformerStorage::MESH);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
}  // namespace
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//****************************************************************************************
Toshihiro Shimizu 890ddd
//    RigidityPainter  definition
Toshihiro Shimizu 890ddd
//****************************************************************************************
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
namespace {
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
class RigidityPainter : public tcg::polymorphic {
Shinya Kitaoka 120a6e
  std::vector<std::map<int, double="">></std::map<int,>
Shinya Kitaoka 120a6e
      m_oldRigidities;         //!< The original values of painted vertices
Shinya Kitaoka 120a6e
  double m_sqRadius, m_value;  //!< Drawing parameters
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  RigidityPainter() : m_sqRadius(), m_value() {}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  void startPainting(double radius, int rigidIdx);
Shinya Kitaoka 120a6e
  void paint(const TPointD &pos);
Shinya Kitaoka 120a6e
  void commit();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
private:
Shinya Kitaoka 120a6e
  void reset() {
Shinya Kitaoka 120a6e
    m_sqRadius = 0.0, m_value = 0.0;
Shinya Kitaoka 120a6e
    std::vector<std::map<int, double="">>().swap(m_oldRigidities);</std::map<int,>
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void RigidityPainter::startPainting(double radius, int rigidIdx) {
Shinya Kitaoka 120a6e
  m_sqRadius = sq(radius);
Shinya Kitaoka 120a6e
  m_value    = (rigidIdx == RIGID_IDX) ? 1e4 : 1.0;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  assert(m_oldRigidities.empty());
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void RigidityPainter::paint(const TPointD &pos) {
Shinya Kitaoka 120a6e
  const TXshCell &cell = ::xshCell();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TXshSimpleLevel *sl =
Shinya Kitaoka 120a6e
      dynamic_cast<txshsimplelevel *="">(cell.m_level.getPointer());</txshsimplelevel>
Shinya Kitaoka 120a6e
  if (!sl) return;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TMeshImageP meshImg = TTool::getImage(true);
Shinya Kitaoka 120a6e
  if (!meshImg) return;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // Soil the level - schedules it for save
Shinya Kitaoka 120a6e
  sl->setDirtyFlag(true);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // Paint all mesh vertices inside the circle with center pos and given radius
Shinya Kitaoka 120a6e
  const std::vector<ttexturemeshp> &meshes = meshImg->meshes();</ttexturemeshp>
Shinya Kitaoka 120a6e
  int m, mCount = int(meshImg->meshes().size());
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  m_oldRigidities.resize(mCount);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  for (m = 0; m != mCount; ++m) {
Shinya Kitaoka 120a6e
    TTextureMesh &mesh = *meshes[m];
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    int v, vCount = mesh.verticesCount();
Shinya Kitaoka 120a6e
    for (v = 0; v != vCount; ++v) {
Shinya Kitaoka 120a6e
      RigidPoint &vxPos = mesh.vertex(v).P();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
      if (tcg::point_ops::dist2(pos, (const TPointD &)vxPos) < m_sqRadius) {
Shinya Kitaoka 120a6e
        if (!m_oldRigidities[m].count(v))
Shinya Kitaoka 120a6e
          m_oldRigidities[m][v] = vxPos.rigidity;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
        vxPos.rigidity = m_value;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  PlasticDeformerStorage::instance()->invalidateMeshImage(
Shinya Kitaoka 120a6e
      meshImg.getPointer(), PlasticDeformerStorage::MESH);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void RigidityPainter::commit() {
Shinya Kitaoka 120a6e
  TUndoManager::manager()->add(
Shinya Kitaoka 120a6e
      new PaintRigidityUndo(::xshCell(), m_oldRigidities, m_value));
Shinya Kitaoka 120a6e
  reset();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
}  // namespace
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//****************************************************************************************
Toshihiro Shimizu 890ddd
//    PlasticTool  functions
Toshihiro Shimizu 890ddd
//****************************************************************************************
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
std::auto_ptr<tcg::polymorphic> PlasticTool::createRigidityPainter() {</tcg::polymorphic>
Shinya Kitaoka 120a6e
  return std::auto_ptr<tcg::polymorphic>(new RigidityPainter);</tcg::polymorphic>
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void PlasticTool::mouseMove_rigidity(const TPointD &pos, const TMouseEvent &e) {
Shinya Kitaoka 120a6e
  // Track mouse position
Shinya Kitaoka 120a6e
  m_pos = pos;  // Needs to be done now - ensures m_pos is valid
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  invalidate();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void PlasticTool::leftButtonDown_rigidity(const TPointD &pos,
Shinya Kitaoka 120a6e
                                          const TMouseEvent &) {
Shinya Kitaoka 120a6e
  // Track mouse position
Shinya Kitaoka 120a6e
  m_pressedPos = m_pos = pos;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  RigidityPainter *painter =
Shinya Kitaoka 120a6e
      static_cast<rigiditypainter *="">(m_rigidityPainter.get());</rigiditypainter>
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  painter->startPainting(m_thickness.getValue(), m_rigidValue.getIndex());
Shinya Kitaoka 120a6e
  painter->paint(m_pos);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  invalidate();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void PlasticTool::leftButtonDrag_rigidity(const TPointD &pos,
Shinya Kitaoka 120a6e
                                          const TMouseEvent &) {
Shinya Kitaoka 120a6e
  // Track mouse position
Shinya Kitaoka 120a6e
  m_pos = pos;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  RigidityPainter *painter =
Shinya Kitaoka 120a6e
      static_cast<rigiditypainter *="">(m_rigidityPainter.get());</rigiditypainter>
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  painter->paint(m_pos);
Shinya Kitaoka 120a6e
  invalidate();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void PlasticTool::leftButtonUp_rigidity(const TPointD &pos,
Shinya Kitaoka 120a6e
                                        const TMouseEvent &) {
Shinya Kitaoka 120a6e
  // Track mouse position
Shinya Kitaoka 120a6e
  m_pos = pos;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  RigidityPainter *painter =
Shinya Kitaoka 120a6e
      static_cast<rigiditypainter *="">(m_rigidityPainter.get());</rigiditypainter>
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  painter->commit();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void PlasticTool::addContextMenuActions_rigidity(QMenu *menu) {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void PlasticTool::draw_rigidity() {
Shinya Kitaoka 120a6e
  if (TTool::getApplication()->getCurrentFrame()->isEditingScene()) {
Shinya Kitaoka 120a6e
    // In the rigidity case, we're editing the mesh level - so the implicit
Shinya Kitaoka 120a6e
    // transformation affine loaded by OpenGL gets multiplied by the level's
Shinya Kitaoka 120a6e
    // dpi scale. We have to revert the scale before showing column-related
Shinya Kitaoka 120a6e
    // data.
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    const TPointD &dpiScale = TTool::getViewer()->getDpiScale();
Shinya Kitaoka 120a6e
    glPushMatrix();
Shinya Kitaoka 120a6e
    {
Shinya Kitaoka 120a6e
      tglMultMatrix(TScale(1.0 / dpiScale.x, 1.0 / dpiScale.y));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      double pixelSize = sqrt(tglGetPixelSize2());
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      // Draw original skeleton
Shinya Kitaoka 120a6e
      const PlasticSkeletonP &skeleton = this->skeleton();
Shinya Kitaoka 120a6e
      if (skeleton) {
Shinya Kitaoka 120a6e
        drawOnionSkinSkeletons_build(pixelSize);
Shinya Kitaoka 120a6e
        drawSkeleton(*skeleton, pixelSize);
Shinya Kitaoka 120a6e
        drawSelections(m_sd, *skeleton, pixelSize);
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    glPopMatrix();
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // Draw a circle centered at m_pos with m_thickness radius
Shinya Kitaoka 120a6e
  glColor3f(1.0f, 0.0f, 0.0f);  // Red
Shinya Kitaoka 120a6e
  tglDrawCircle(m_pos, m_thickness.getValue());
Toshihiro Shimizu 890ddd
}