cellSelector.h 3.25 KB
Newer Older
Pierre Kraemer's avatar
Pierre Kraemer committed
1 2 3
#ifndef _CELL_SELECTOR_H_
#define _CELL_SELECTOR_H_

4
#include <QObject>
Pierre Kraemer's avatar
Pierre Kraemer committed
5
#include <QString>
6
#include <QList>
Pierre Kraemer's avatar
Pierre Kraemer committed
7 8 9 10 11 12 13 14 15 16 17

#include "Topology/generic/dart.h"
#include "Topology/generic/genericmap.h"
#include "Topology/generic/cellmarker.h"

namespace CGoGN
{

namespace SCHNApps
{

18
class CellSelectorGen : public QObject
Pierre Kraemer's avatar
Pierre Kraemer committed
19
{
20 21
	Q_OBJECT

Pierre Kraemer's avatar
Pierre Kraemer committed
22 23 24 25 26 27 28 29 30 31 32 33 34
public:
	static unsigned int selectorCount;

	CellSelectorGen(const QString& name);
	virtual ~CellSelectorGen()
	{}

	inline const QString& getName() { return m_name; }

	inline const std::vector<Dart>& getSelectedCells() { return m_cells; }

	virtual unsigned int getOrbit() = 0;

35 36
	virtual void select(Dart d, bool emitSignal = true) = 0;
	virtual void unselect(Dart d, bool emitSignal = true) = 0;
Pierre Kraemer's avatar
Pierre Kraemer committed
37

38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
	inline void select(const std::vector<Dart>& d)
	{
		for(unsigned int i = 0; i < d.size(); ++i)
			select(d[i], false);
		checkChange();
		if(m_isMutuallyExclusive && !m_mutuallyExclusive.empty())
		{
			foreach(CellSelectorGen* cs, m_mutuallyExclusive)
				cs->checkChange();
		}
	}

	inline void unselect(const std::vector<Dart>& d)
	{
		for(unsigned int i = 0; i < d.size(); ++i)
			unselect(d[i], false);
		checkChange();
	}
Pierre Kraemer's avatar
Pierre Kraemer committed
56

57
	virtual bool isSelected(Dart d) = 0;
Pierre Kraemer's avatar
Pierre Kraemer committed
58

59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
	inline void setMutuallyExclusive(bool b) { m_isMutuallyExclusive = b; }
	inline bool isMutuallyExclusive() const { return m_isMutuallyExclusive; }
	inline void setMutuallyExclusiveSet(const QList<CellSelectorGen*>& mex)
	{
		m_mutuallyExclusive.clear();
		foreach(CellSelectorGen* cs, mex)
		{
			if(cs != this)
				m_mutuallyExclusive.append(cs);
		}
	}

	inline void checkChange()
	{
		if(m_selectionChanged)
		{
			emit(selectedCellsChanged());
			m_selectionChanged = false;
		}
	}

80 81 82 83
signals:
	void selectedCellsChanged();

protected:
Pierre Kraemer's avatar
Pierre Kraemer committed
84 85
	QString m_name;
	std::vector<Dart> m_cells;
86 87 88 89 90

	bool m_selectionChanged;

	bool m_isMutuallyExclusive;
	QList<CellSelectorGen*> m_mutuallyExclusive;
Pierre Kraemer's avatar
Pierre Kraemer committed
91 92 93 94 95 96
};

template <unsigned int ORBIT>
class CellSelector : public CellSelectorGen
{
public:
97
	CellSelector(GenericMap& map, const QString& name, unsigned int thread = 0) :
Pierre Kraemer's avatar
Pierre Kraemer committed
98
		CellSelectorGen(name),
99 100
		m_map(map),
		m_cm(map, thread)
Pierre Kraemer's avatar
Pierre Kraemer committed
101 102 103 104 105 106 107
	{}

	~CellSelector()
	{}

	inline unsigned int getOrbit() { return ORBIT; }

108 109
	inline const CellMarker<ORBIT>& getMarker() { return m_cm; }

110
	inline void select(Dart d, bool emitSignal = true)
Pierre Kraemer's avatar
Pierre Kraemer committed
111
	{
Pierre Kraemer's avatar
Pierre Kraemer committed
112
		if(!m_cm.isMarked(d))
Pierre Kraemer's avatar
Pierre Kraemer committed
113 114
		{
			m_cells.push_back(d);
Pierre Kraemer's avatar
Pierre Kraemer committed
115
			m_cm.mark(d);
116 117 118 119 120
			if(m_isMutuallyExclusive && !m_mutuallyExclusive.empty())
			{
				foreach(CellSelectorGen* cs, m_mutuallyExclusive)
					cs->unselect(d, emitSignal);
			}
121 122
			if(emitSignal)
				emit(selectedCellsChanged());
123 124
			else
				m_selectionChanged = true;
Pierre Kraemer's avatar
Pierre Kraemer committed
125 126 127
		}
	}

128
	inline void unselect(Dart d, bool emitSignal = true)
Pierre Kraemer's avatar
Pierre Kraemer committed
129
	{
Pierre Kraemer's avatar
Pierre Kraemer committed
130
		if(m_cm.isMarked(d))
Pierre Kraemer's avatar
Pierre Kraemer committed
131
		{
Pierre Kraemer's avatar
Pierre Kraemer committed
132
			unsigned int v = m_map.getEmbedding<ORBIT>(d);
Pierre Kraemer's avatar
Pierre Kraemer committed
133 134 135 136 137 138 139 140 141 142 143 144
			bool found = false;
			unsigned int i;
			for(i = 0; i < m_cells.size() && !found; ++i)
			{
				if(m_map.getEmbedding<ORBIT>(m_cells[i]) == v)
					found = true ;
			}
			if(found)
			{
				m_cm.unmark(m_cells[i-1]);
				m_cells[i-1] = m_cells.back();
				m_cells.pop_back();
145 146
				if(emitSignal)
					emit(selectedCellsChanged());
147 148
				else
					m_selectionChanged = true;
Pierre Kraemer's avatar
Pierre Kraemer committed
149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167
			}
		}
	}

	inline bool isSelected(Dart d)
	{
		return m_cm.isMarked(d);
	}

private:
	GenericMap& m_map;
	CellMarker<ORBIT> m_cm;
};

} // namespace SCHNApps

} // namespace CGoGN

#endif