cellSelector.h 3.3 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 112 113 114 115 116
	{
		unsigned int v = m_map.getEmbedding<ORBIT>(d);
		if(!m_cm.isMarked(v))
		{
			m_cells.push_back(d);
			m_cm.mark(v);
117 118 119 120 121
			if(m_isMutuallyExclusive && !m_mutuallyExclusive.empty())
			{
				foreach(CellSelectorGen* cs, m_mutuallyExclusive)
					cs->unselect(d, emitSignal);
			}
122 123
			if(emitSignal)
				emit(selectedCellsChanged());
124 125
			else
				m_selectionChanged = true;
Pierre Kraemer's avatar
Pierre Kraemer committed
126 127 128
		}
	}

129
	inline void unselect(Dart d, bool emitSignal = true)
Pierre Kraemer's avatar
Pierre Kraemer committed
130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145
	{
		unsigned int v = m_map.getEmbedding<ORBIT>(d);
		if(m_cm.isMarked(v))
		{
			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();
146 147
				if(emitSignal)
					emit(selectedCellsChanged());
148 149
				else
					m_selectionChanged = true;
Pierre Kraemer's avatar
Pierre Kraemer committed
150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168
			}
		}
	}

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

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

} // namespace SCHNApps

} // namespace CGoGN

#endif