cellSelector.h 3.51 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
	virtual void rebuild() = 0;

61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81
	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;
		}
	}

82 83 84 85
signals:
	void selectedCellsChanged();

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

	bool m_selectionChanged;

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

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

	~CellSelector()
	{}

	inline unsigned int getOrbit() { return ORBIT; }

110 111
	inline const CellMarker<ORBIT>& getMarker() { return m_cm; }

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

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

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

160 161 162 163 164 165 166 167 168 169 170 171
	void rebuild()
	{
		m_cells.clear();
		TraversorCell<GenericMap, ORBIT> t(m_map, true);
		for(Dart d = t.begin(); d != t.end(); d = t.next())
		{
			if(m_cm.isMarked(d))
				m_cells.push_back(d);
		}
		emit(selectedCellsChanged());
	}

Pierre Kraemer's avatar
Pierre Kraemer committed
172 173 174 175 176 177 178 179 180 181
private:
	GenericMap& m_map;
	CellMarker<ORBIT> m_cm;
};

} // namespace SCHNApps

} // namespace CGoGN

#endif