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