moved LDObject indices from a global array into Model

Thu, 08 Mar 2018 11:36:55 +0200

author
Santeri Piippo
date
Thu, 08 Mar 2018 11:36:55 +0200
changeset 1278
6e1ea24e5a5e
parent 1277
821c30615069
child 1279
0f6a4a7cafec

moved LDObject indices from a global array into Model

src/glShared.h file | annotate | diff | comparison | revisions
src/glcompiler.cpp file | annotate | diff | comparison | revisions
src/glrenderer.cpp file | annotate | diff | comparison | revisions
src/glrenderer.h file | annotate | diff | comparison | revisions
src/lddocument.cpp file | annotate | diff | comparison | revisions
src/linetypes/modelobject.cpp file | annotate | diff | comparison | revisions
src/linetypes/modelobject.h file | annotate | diff | comparison | revisions
src/model.cpp file | annotate | diff | comparison | revisions
src/model.h file | annotate | diff | comparison | revisions
--- a/src/glShared.h	Wed Mar 07 19:32:05 2018 +0200
+++ b/src/glShared.h	Thu Mar 08 11:36:55 2018 +0200
@@ -38,7 +38,6 @@
 {
 	char		num;
 	Vertex		vertices[4];
-	int			id;
 	int			color;
 
 	inline int numVertices() const
--- a/src/glcompiler.cpp	Wed Mar 07 19:32:05 2018 +0200
+++ b/src/glcompiler.cpp	Thu Mar 08 11:36:55 2018 +0200
@@ -168,8 +168,8 @@
 		return {208, 64, 64};
 
 	case VboSubclass::PickColors:
-		// For the picking scene, determine the color from the owner's ID.
-		return indexColorForID(polygonOwner->id());
+		// For the picking scene, use unique picking colors provided by the model.
+		return m_renderer->model()->pickingColorForObject(polygonOwnerIndex);
 
 	case VboSubclass::RandomColors:
 		// For the random color scene, the owner object has rolled up a random color. Use that.
@@ -366,7 +366,6 @@
 	case LDObjectType::ConditionalEdge:
 		{
 			LDPolygon* poly = object->getPolygon();
-			poly->id = object->id();
 			compilePolygon (*poly, index, info);
 			delete poly;
 			break;
@@ -379,10 +378,7 @@
 			auto data = subfileReference->inlinePolygons(m_documents);
 
 			for (LDPolygon& poly : data)
-			{
-				poly.id = object->id();
 				compilePolygon (poly, index, info);
-			}
 			break;
 		}
 
@@ -390,10 +386,7 @@
 		{
 			LDBezierCurve* curve = static_cast<LDBezierCurve*>(object);
 			for (LDPolygon& polygon : curve->rasterizePolygons(grid()->bezierCurveSegments()))
-			{
-				polygon.id = object->id();
 				compilePolygon (polygon, index, info);
-			}
 		}
 		break;
 
--- a/src/glrenderer.cpp	Wed Mar 07 19:32:05 2018 +0200
+++ b/src/glrenderer.cpp	Thu Mar 08 11:36:55 2018 +0200
@@ -701,6 +701,15 @@
 }
 
 /*
+ * Resolves a pixel pointer to an RGB color.
+ * pixel[0..2] must be valid.
+ */
+static QRgb colorFromPixel(uint8_t* pixel)
+{
+	return pixel[0] << 16 | pixel[1] << 8 | pixel[2] | 0xff000000;
+}
+
+/*
  * Returns the set of objects found in the specified pixel area.
  */
 QItemSelection GLRenderer::pick(const QRect& range)
@@ -733,22 +742,23 @@
 	// Read pixels from the color buffer.
 	glReadPixels(x0, height() - y1, areawidth, areaheight, GL_RGBA, GL_UNSIGNED_BYTE, pixelData.data());
 
-	QSet<qint32> ids;
+	QSet<QRgb> pixelColors;
 
 	// Go through each pixel read and add them to the selection.
-	// Each pixel maps to an LDObject index injectively.
+	// Each pixel maps to an LDObject injectively.
 	// Note: black is background, those indices are skipped.
-	for (unsigned char *pixelCursor = pixelData.begin(); pixelCursor < pixelData.end(); pixelCursor += 4)
+	for (int i : ::range(0, 4, pixelData.size() - 4))
 	{
-		qint32 id = pixelCursor[0] * 0x10000 + pixelCursor[1] * 0x100 + pixelCursor[2] * 0x1;
-		if (id != 0)
-			ids.insert(id);
+		QRgb color = colorFromPixel(&pixelData[i]);
+
+		if (color != BlackRgb)
+			pixelColors.insert(color);
 	}
 
 	// For each index read, resolve the LDObject behind it and add it to the selection.
-	for (qint32 id : ids)
+	for (QRgb color : pixelColors)
 	{
-		QModelIndex index = m_model->indexFromId(id);
+		QModelIndex index = m_model->objectByPickingColor(color);
 
 		if (index.isValid())
 			result.select(index, index);
@@ -769,7 +779,7 @@
 	drawGLScene();
 	unsigned char pixel[4];
 	glReadPixels(mouseX, height() - mouseY, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixel);
-	QModelIndex result = m_model->indexFromId(pixel[0] * 0x10000 + pixel[1] * 0x100 + pixel[2]);
+	QModelIndex result = m_model->objectByPickingColor(colorFromPixel(pixel));
 	setPicking(false);
 	repaint();
 	return result;
@@ -838,7 +848,6 @@
 	currentCamera().setZoom(30.0f);
 	bool lastfilled = false;
 	bool firstrun = true;
-	enum { black = 0xFF000000 };
 	bool inward = true;
 	int runaway = 50;
 
@@ -865,7 +874,7 @@
 		// Check the top and bottom rows
 		for (int i = 0; i < image.width(); ++i)
 		{
-			if (image.pixel (i, 0) != black or image.pixel (i, height() - 1) != black)
+			if (image.pixel (i, 0) != BlackRgb or image.pixel (i, height() - 1) != BlackRgb)
 			{
 				filled = true;
 				break;
@@ -877,7 +886,7 @@
 		{
 			for (int i = 0; i < image.height(); ++i)
 			{
-				if (image.pixel (0, i) != black or image.pixel (width() - 1, i) != black)
+				if (image.pixel (0, i) != BlackRgb or image.pixel (width() - 1, i) != BlackRgb)
 				{
 					filled = true;
 					break;
@@ -939,13 +948,17 @@
 		setPicking (true);
 		drawGLScene();
 		setPicking (false);
-
 		unsigned char pixel[4];
-		glReadPixels (m_mousePosition.x(), height() - m_mousePosition.y(), 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &pixel[0]);
-		qint32 id = pixel[0] * 0x10000 | pixel[1] * 0x100 | pixel[2];
-
-		if (id != 0)
-			newIndex = model()->indexFromId(id);
+		glReadPixels(
+			m_mousePosition.x(),
+			height() - m_mousePosition.y(),
+			1,
+			1,
+			GL_RGBA,
+			GL_UNSIGNED_BYTE,
+			&pixel[0]
+		);
+		newIndex = model()->objectByPickingColor(colorFromPixel(pixel));
 	}
 
 	if (newIndex != oldIndex)
--- a/src/glrenderer.h	Wed Mar 07 19:32:05 2018 +0200
+++ b/src/glrenderer.h	Thu Mar 08 11:36:55 2018 +0200
@@ -53,6 +53,8 @@
 	Q_OBJECT
 
 public:
+	enum { BlackRgb = 0xff000000 };
+
 	GLRenderer(const Model* model, QWidget* parent = nullptr);
 	~GLRenderer();
 
--- a/src/lddocument.cpp	Wed Mar 07 19:32:05 2018 +0200
+++ b/src/lddocument.cpp	Thu Mar 08 11:36:55 2018 +0200
@@ -286,11 +286,6 @@
 		SLOT(handleImminentObjectRemoval(QModelIndex)),
 		Qt::DirectConnection
 	);
-
-#ifdef DEBUG
-	if (not isFrozen())
-		print("Inserted object #%1 (%2) at %3\n", object->id(), object->typeName(), index.row());
-#endif
 }
 
 void LDDocument::objectChanged(const LDObjectState& before, const LDObjectState& after)
--- a/src/linetypes/modelobject.cpp	Wed Mar 07 19:32:05 2018 +0200
+++ b/src/linetypes/modelobject.cpp	Thu Mar 08 11:36:55 2018 +0200
@@ -44,25 +44,9 @@
 LDObject::LDObject() :
 	m_isHidden {false}
 {
-	// Let's hope that nobody goes to create 17 million objects anytime soon...
-	static qint32 nextId = 1; // 0 shalt be null
-	if (nextId < MAX_LDOBJECT_IDS)
-		m_id = nextId++;
-	else
-		m_id = 0;
-
-	if (m_id != 0)
-		g_allObjects[m_id] = this;
-
 	m_randomColor = QColor::fromHsv (rand() % 360, rand() % 256, rand() % 96 + 128);
 }
 
-LDObject::~LDObject()
-{
-	// Remove this object from the list of LDObjects
-	g_allObjects.erase(g_allObjects.find(id()));
-}
-
 // =============================================================================
 //
 QString LDSubfileReference::asText() const
@@ -195,7 +179,6 @@
 		return nullptr;
 
 	LDPolygon* data = new LDPolygon;
-	data->id = id();
 	data->num = num;
 	data->color = color().index();
 
@@ -268,11 +251,6 @@
 	m_isHidden = value;
 }
 
-qint32 LDObject::id() const
-{
-	return m_id;
-}
-
 LDColor LDObject::color() const
 {
 	return m_color;
@@ -283,13 +261,6 @@
 	return m_randomColor;
 }
 
-// =============================================================================
-//
-LDObject* LDObject::fromID(qint32 id)
-{
-	return g_allObjects.value(id);
-}
-
 LDObject* LDObject::newFromType(LDObjectType type)
 {
 	switch (type)
@@ -490,7 +461,6 @@
 	parms.append (pointAt (1.0));
 	LDPolygon poly;
 	poly.color = color().index();
-	poly.id = id();
 	poly.num = 2;
 
 	for (int i = 0; i < segments; ++i)
@@ -591,7 +561,6 @@
 {
 	serializer << m_hasInvertNext;
 	serializer << m_isHidden;
-	serializer << m_id;
 	serializer << m_color;
 	serializer << m_randomColor;
 	serializer << m_coords[0];
--- a/src/linetypes/modelobject.h	Wed Mar 07 19:32:05 2018 +0200
+++ b/src/linetypes/modelobject.h	Thu Mar 08 11:36:55 2018 +0200
@@ -60,7 +60,6 @@
 
 public:
 	LDObject();
-	virtual ~LDObject();
 
 	virtual QString asText() const = 0; // This object as LDraw code
 	LDColor color() const;
@@ -68,7 +67,6 @@
 	LDPolygon* getPolygon();
 	virtual void getVertices (DocumentManager *context, QSet<Vertex>& verts) const;
 	virtual bool hasMatrix() const; // Does this object have a matrix and position? (see LDMatrixObject)
-	qint32 id() const;
 	virtual bool isColored() const;
 	bool isHidden() const;
 	virtual bool isScemantic() const; // Does this object have meaning in the part model?
@@ -88,7 +86,6 @@
 	const Vertex& vertex (int i) const;
 	virtual void serialize(class Serializer& serializer);
 
-	static LDObject* fromID(qint32 id);
 	static LDObject* newFromType(LDObjectType type);
 
 signals:
@@ -101,7 +98,6 @@
 private:
 	bool m_hasInvertNext = false;
 	bool m_isHidden;
-	qint32 m_id;
 	LDColor m_color;
 	QColor m_randomColor;
 	Vertex m_coords[4];
--- a/src/model.cpp	Wed Mar 07 19:32:05 2018 +0200
+++ b/src/model.cpp	Thu Mar 08 11:36:55 2018 +0200
@@ -43,6 +43,13 @@
 	connect(object, SIGNAL(codeChanged(LDObjectState, LDObjectState)), this, SLOT(recountTriangles()));
 	beginInsertRows({}, row, row);
 	_objects.insert(row, object);
+
+	if (this->pickingColorCursor <= 0xffffff)
+	{
+		this->pickingColors[object] = this->pickingColorCursor;
+		this->pickingColorCursor += 1;
+	}
+
 	recountTriangles();
 	emit objectAdded(index(row));
 	endInsertRows();
@@ -628,15 +635,27 @@
 		return nullptr;
 }
 
-QModelIndex Model::indexFromId(qint32 id) const
+QColor Model::pickingColorForObject(const QModelIndex& objectIndex) const
 {
-	for (int row = 0; row < this->size(); ++row)
+	return QColor::fromRgba(this->pickingColors.value(this->lookup(objectIndex)) | 0xff000000);
+}
+
+QModelIndex Model::objectByPickingColor(const QColor& color) const
+{
+	if (color != qRgb(0, 0, 0))
 	{
-		if (this->objects()[row]->id() == id)
-			return index(row);
+		for (int row = 0; row < this->size(); row += 1)
+		{
+			if (this->pickingColorForObject(this->index(row)) == color)
+				return this->index(row);
+		}
+
+		return {};
 	}
-
-	return {};
+	else
+	{
+		return {};
+	}
 }
 
 int countof(Model& model)
--- a/src/model.h	Wed Mar 07 19:32:05 2018 +0200
+++ b/src/model.h	Thu Mar 08 11:36:55 2018 +0200
@@ -108,7 +108,8 @@
 	LDObject* replaceWithFromString(LDObject* object, QString line);
 	IndexGenerator indices() const;
 	LDObject* lookup(const QModelIndex& index) const;
-	QModelIndex indexFromId(qint32 id) const;
+	QColor pickingColorForObject(const QModelIndex& objectIndex) const;
+	QModelIndex objectByPickingColor(const QColor& color) const;
 
 	bool moveRows(
 		const QModelIndex& sourceParent,
@@ -130,6 +131,8 @@
 	template<typename T, typename... Args> T* constructObject(Args&& ...args);
 
 	QVector<LDObject*> _objects;
+	QMap<LDObject*, QRgb> pickingColors;
+	QRgb pickingColorCursor = 0x000001;
 	class DocumentManager* _manager;
 	mutable int _triangleCount = 0;
 	mutable bool _needsTriangleRecount;

mercurial