|
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
|