Shinya Kitaoka 810553
#pragma once
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifndef CONTROLPOINT_SELECTION_INCLUDED
Toshihiro Shimizu 890ddd
#define CONTROLPOINT_SELECTION_INCLUDED
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "toonzqt/selection.h"
Toshihiro Shimizu 890ddd
#include "tool.h"
Toshihiro Shimizu 890ddd
#include "tstroke.h"
Toshihiro Shimizu 890ddd
#include "tcurves.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
// ControlPointEditorStroke
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
/*!La classe ControlPointEditorStroke effettua tutte le operazioni matematiche
Shinya Kitaoka 120a6e
 * sullo Stroke */
Shinya Kitaoka 120a6e
class ControlPointEditorStroke {
Toshihiro Shimizu 890ddd
private:
Shinya Kitaoka 120a6e
  //! Punti di controllo comprensivi di SpeedIn e SpeenOut
Shinya Kitaoka 120a6e
  class ControlPoint {
Shinya Kitaoka 120a6e
  public:
Shinya Kitaoka 120a6e
    int m_indexPoint;
Shinya Kitaoka 120a6e
    TPointD m_speedIn;
Shinya Kitaoka 120a6e
    TPointD m_speedOut;
Shinya Kitaoka 120a6e
    bool m_isCusp;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    ControlPoint(int i, TPointD speedIn, TPointD speedOut, bool isCusp = true)
Shinya Kitaoka 120a6e
        : m_indexPoint(i)
Shinya Kitaoka 120a6e
        , m_speedIn(speedIn)
Shinya Kitaoka 120a6e
        , m_speedOut(speedOut)
Shinya Kitaoka 120a6e
        , m_isCusp(isCusp) {}
Shinya Kitaoka 120a6e
    ControlPoint() {}
Shinya Kitaoka 120a6e
  };
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  vector<controlpoint> m_controlPoints;</controlpoint>
Shinya Kitaoka 120a6e
  TStroke *m_stroke;
Shinya Kitaoka 120a6e
  int m_strokeIndex;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /*! Viene riempito il vettore \b m_controlPoints scegliendo da \b m_stroke
Shinya Kitaoka 120a6e
  soltanto
Shinya Kitaoka 120a6e
  i punti di controllo nelle posizioni pari.
Shinya Kitaoka 120a6e
  */
Shinya Kitaoka 120a6e
  void updateControlPoints();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  //! Viene settato il valore \b p.m_isCusp osservando lo SpeedIn e SpeedOut del
Shinya Kitaoka 120a6e
  //! punto.
Shinya Kitaoka 120a6e
  void setCusp(ControlPoint &p);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  void setSpeedIn(ControlPoint &cp, const TPointD &p) {
Shinya Kitaoka 120a6e
    cp.m_speedIn = m_stroke->getControlPoint(cp.m_indexPoint) - p;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  void setSpeedOut(ControlPoint &cp, const TPointD &p) {
Shinya Kitaoka 120a6e
    cp.m_speedOut = p - m_stroke->getControlPoint(cp.m_indexPoint);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /*! Inserisce un punto nel chunk di lunghezza maggiore selezionato tra quelli
Shinya Kitaoka 120a6e
     compresi
Shinya Kitaoka 120a6e
          tra il chunk \b indexA e \b indexB.
Shinya Kitaoka 120a6e
  */
Shinya Kitaoka 120a6e
  void insertPoint(int indexA, int indexB);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /*! Verifica che in \b m_stroke tra due cuspidi sia sempre presente un numero
Shinya Kitaoka 120a6e
  pari
Shinya Kitaoka 120a6e
  di Chunk: in caso contrario richiama la \b insertPoint;
Shinya Kitaoka 120a6e
  */
Shinya Kitaoka 120a6e
  void adjustChunkParity();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  //! Sposta il punto di controllo \b index di un fattore delta
Shinya Kitaoka 120a6e
  void moveSingleControlPoint(int indexPoint, const TPointD &delta);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /*! Sposta i punti di controllo precedenti al punto \b index di un fattore
Shinya Kitaoka 120a6e
delta.
Shinya Kitaoka 120a6e
Se \b moveSpeed==true e' usato per movimento degli speed, altrimenti per
Shinya Kitaoka 120a6e
            movimento dei punti di controllo.
Shinya Kitaoka 120a6e
  */
Shinya Kitaoka 120a6e
  void movePrecControlPoints(int indexPoint, const TPointD &delta,
Shinya Kitaoka 120a6e
                             bool moveSpeed);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /*! Sposta i punti di controllo successivi al punto \b index di un fattore
Shinya Kitaoka 120a6e
delta.
Shinya Kitaoka 120a6e
Se \b moveSpeed==true e' usato per movimento degli speed, altrimenti per
Shinya Kitaoka 120a6e
            movimento dei punti di controllo.
Shinya Kitaoka 120a6e
  */
Shinya Kitaoka 120a6e
  void moveNextControlPoints(int indexPoint, const TPointD &delta,
Shinya Kitaoka 120a6e
                             bool moveSpeed);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  ControlPointEditorStroke() : m_stroke(0), m_strokeIndex(-1) {}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /*!Viene modificato lo stroke in modo tale che tra due cuspidi esista sempre
Shinya Kitaoka 120a6e
  un
Shinya Kitaoka 120a6e
  numero pari di chunk.
Shinya Kitaoka 120a6e
  ATTENZIONE: poiche' puo' aggiungere punti di controllo allo stroke, e' bene
Shinya Kitaoka 120a6e
  richiamare
Shinya Kitaoka 120a6e
  tale funzione solo quando e' necessario.
Shinya Kitaoka 120a6e
  */
Shinya Kitaoka 120a6e
  void setStroke(TStroke *stroke, int strokeIndex);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  void setStrokeIndex(int strokeIndex) { m_strokeIndex = strokeIndex; }
Shinya Kitaoka 120a6e
  int getStrokeIndex() { return m_strokeIndex; }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TThickPoint getControlPoint(int index) const {
Shinya Kitaoka 120a6e
    assert(m_stroke && 0 <= index && index < (int)m_controlPoints.size());
Shinya Kitaoka 120a6e
    return m_stroke->getControlPoint(m_controlPoints[index].m_indexPoint);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  TThickPoint getSpeedIn(int index) const {
Shinya Kitaoka 120a6e
    assert(m_stroke && 0 <= index && index < (int)m_controlPoints.size());
Shinya Kitaoka 120a6e
    return m_controlPoints[index].m_speedIn;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  TThickPoint getSpeedOut(int index) const {
Shinya Kitaoka 120a6e
    assert(m_stroke && 0 <= index && index < (int)m_controlPoints.size());
Shinya Kitaoka 120a6e
    return m_controlPoints[index].m_speedOut;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int getControlPointCount() const { return m_controlPoints.size(); }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  //! Ritorna \b true se il punto index e' una cuspide.
Shinya Kitaoka 120a6e
  bool getIsCusp(int index) const {
Shinya Kitaoka 120a6e
    assert(m_stroke && 0 <= index && index < (int)getControlPointCount());
Shinya Kitaoka 120a6e
    return m_controlPoints[index].m_isCusp;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  //! Viene settato il valore \b m_isCusp del punto index-esimo a \b isCusp.
Shinya Kitaoka 120a6e
  void linkUnlinkSpeeds(int index, bool isCusp) {
Shinya Kitaoka 120a6e
    m_controlPoints[index].m_isCusp = isCusp;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /*! Sposta il ControlPoint \b index di un fattore delta con continuita',
Shinya Kitaoka 120a6e
            cioe' spostando anche i punti di controllo adiacenti se
Shinya Kitaoka 120a6e
     necessario.*/
Shinya Kitaoka 120a6e
  void moveControlPoint(int index, const TPointD &delta);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  //! Cancella il punto di controllo \b point.
Shinya Kitaoka 120a6e
  void deleteControlPoint(int index);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /*! Aggiunge il punto di controllo \b point.
Shinya Kitaoka 120a6e
                  Ritorna l'indice del punto di controllo appena inserito.*/
Shinya Kitaoka 120a6e
  int addControlPoint(const TPointD &pos);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /*! Ritorna l'indice del cp piu' vicino al punto pos.
Shinya Kitaoka 120a6e
            distance2 riceve il valore del quadrato della distanza
Shinya Kitaoka 120a6e
            se la ControlPointEditorStroke e' vuota ritorna -1.*/
Shinya Kitaoka 120a6e
  int getClosestControlPoint(const TPointD &pos, double &distance2) const;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  //! Ritorna true sse e' definita una curva e se pos e' abbastanza vicino alla
Shinya Kitaoka 120a6e
  //! curva
Shinya Kitaoka 120a6e
  bool isCloseTo(const TPointD &pos, double pixelSize) const;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /*! Ritorna l'indice del cp il cui bilancino e' piu' vicino al punto pos.
Shinya Kitaoka 120a6e
                  \b minDistance2 riceve il valore del quadrato della distanza
Shinya Kitaoka 120a6e
            se la ControlPointEditorStroke e' vuota ritorna -1. \b isIn e' true
Shinya Kitaoka 120a6e
     se il bilancino cliccato
Shinya Kitaoka 120a6e
            corrisponde allo SpeedIn.*/
Shinya Kitaoka 120a6e
  int getClosestSpeed(const TPointD &pos, double &minDistance2,
Shinya Kitaoka 120a6e
                      bool &isIn) const;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /*! Sposta il bilancino del punto \b index di un fattore delta. \b isIn deve
Shinya Kitaoka 120a6e
     essere
Shinya Kitaoka 120a6e
                  true se si vuole spostare lo SpeedIn.*/
Shinya Kitaoka 120a6e
  void moveSpeed(int index, const TPointD &delta, bool isIn, double pixelSize);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /*! Se isLinear e' true setta a "0" il valore dello speedIn e il valore dello
Shinya Kitaoka 120a6e
     speedOut;
Shinya Kitaoka 120a6e
                  altrimenti li setta ad un valore di default. Ritorna vero se
Shinya Kitaoka 120a6e
     almeno un punto e' ststo modificato.*/
Shinya Kitaoka 120a6e
  bool setLinear(int index, bool isLinear);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  void setLinearSpeedIn(int index);
Shinya Kitaoka 120a6e
  void setLinearSpeedOut(int index);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  bool isSpeedInLinear(int index);
Shinya Kitaoka 120a6e
  bool isSpeedOutLinear(int index);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  bool isSelfLoop() { return m_stroke->isSelfLoop(); }
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
// ControlPointSelection
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
class ControlPointSelection : public QObject, public TSelection {
Shinya Kitaoka 120a6e
  Q_OBJECT
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
private:
Shinya Kitaoka 120a6e
  std::set<int> m_selectedPoints;</int>
Shinya Kitaoka 120a6e
  ControlPointEditorStroke *m_controlPointEditorStroke;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  ControlPointSelection() : m_controlPointEditorStroke(0) {}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  void setControlPointEditorStroke(
Shinya Kitaoka 120a6e
      ControlPointEditorStroke *controlPointEditorStroke) {
Shinya Kitaoka 120a6e
    m_controlPointEditorStroke = controlPointEditorStroke;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  bool isEmpty() const { return m_selectedPoints.empty(); }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  void selectNone() { m_selectedPoints.clear(); }
Shinya Kitaoka 120a6e
  bool isSelected(int index) const;
Shinya Kitaoka 120a6e
  void select(int index);
Shinya Kitaoka 120a6e
  void unselect(int index);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  void deleteControlPoints();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  void addMenuItems(QMenu *menu);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  void enableCommands();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
protected slots:
Shinya Kitaoka 120a6e
  void setLinear();
Shinya Kitaoka 120a6e
  void setUnlinear();
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
#endif  // CONTROLPOINT_SELECTION_INCLUDED