- reimplemented vertex tracking using a method similar to what the GL compiler uses

Sun, 13 Jul 2014 16:48:29 +0300

author
Teemu Piippo <crimsondusk64@gmail.com>
date
Sun, 13 Jul 2014 16:48:29 +0300
changeset 835
268413885cb1
parent 834
3e697ba996e8
child 836
a522e1cd92af

- reimplemented vertex tracking using a method similar to what the GL compiler uses

src/editmodes/abstractEditMode.cc file | annotate | diff | comparison | revisions
src/ldDocument.cc file | annotate | diff | comparison | revisions
src/ldDocument.h file | annotate | diff | comparison | revisions
src/ldObject.cc file | annotate | diff | comparison | revisions
src/ldObject.h file | annotate | diff | comparison | revisions
--- a/src/editmodes/abstractEditMode.cc	Mon Jul 07 18:52:10 2014 +0300
+++ b/src/editmodes/abstractEditMode.cc	Sun Jul 13 16:48:29 2014 +0300
@@ -97,14 +97,7 @@
 		Vertex			cursorPosition = renderer()->coordconv2_3 (data.ev->pos(), false);
 		QPoint			cursorPosition2D (data.ev->pos());
 		const Axis		relZ = renderer()->getRelativeZ();
-		QVector<Vertex>	vertices;
-
-		for (auto it = renderer()->document()->vertices().begin();
-			it != renderer()->document()->vertices().end();
-			++it)
-		{
-			vertices << it.key();
-		}
+		QVector<Vertex>	vertices = renderer()->document()->inlineVertices();
 
 		// Sort the vertices in order of distance to camera
 		std::sort (vertices.begin(), vertices.end(), [&](const Vertex& a, const Vertex& b) -> bool
--- a/src/ldDocument.cc	Mon Jul 07 18:52:10 2014 +0300
+++ b/src/ldDocument.cc	Sun Jul 13 16:48:29 2014 +0300
@@ -126,6 +126,8 @@
 LDDocument::LDDocument (LDDocumentPtr* selfptr) :
 	m_isImplicit (true),
 	m_flags (0),
+	_verticesOutdated (true),
+	_needVertexMerge (true),
 	m_gldata (new LDGLData)
 {
 	*selfptr = LDDocumentPtr (this);
@@ -1094,7 +1096,7 @@
 {
 	history()->add (new AddHistory (objects().size(), obj));
 	m_objects << obj;
-	addKnownVerticesOf (obj);
+	addKnownVertices (obj);
 
 #ifdef DEBUG
 	if (not isImplicit())
@@ -1108,11 +1110,13 @@
 
 // =============================================================================
 //
-void LDDocument::addObjects (const LDObjectList objs)
+void LDDocument::addObjects (const LDObjectList& objs)
 {
 	for (LDObjectPtr obj : objs)
-		if (obj)
+	{
+		if (obj != null)
 			addObject (obj);
+	}
 }
 
 // =============================================================================
@@ -1123,7 +1127,7 @@
 	m_objects.insert (pos, obj);
 	obj->setDocument (this);
 	g_win->R()->compileObject (obj);
-	addKnownVerticesOf (obj);
+	
 
 #ifdef DEBUG
 	if (not isImplicit())
@@ -1133,50 +1137,17 @@
 
 // =============================================================================
 //
-void LDDocument::addKnownVerticesOf (LDObjectPtr obj)
+void LDDocument::addKnownVertices (LDObjectPtr obj)
 {
-	if (isImplicit())
-		return;
-
-	if (obj->type() == OBJ_Subfile)
-	{
-		LDSubfilePtr ref = obj.staticCast<LDSubfile>();
-
-		for (Vertex vrt : ref->fileInfo()->inlineVertices())
-		{
-			vrt.transform (ref->transform(), ref->position());
-			addKnownVertexReference (vrt);
-		}
-	}
-	else
-	{
-		for (int i = 0; i < obj->numVertices(); ++i)
-			addKnownVertexReference (obj->vertex (i));
-	}
-}
+	auto it = _objectVertices.find (obj);
 
-// =============================================================================
-//
-void LDDocument::removeKnownVerticesOf (LDObjectPtr obj)
-{
-	if (isImplicit())
-		return;
-
-	if (obj->type() == OBJ_Subfile)
-	{
-		LDSubfilePtr ref = obj.staticCast<LDSubfile>();
+	if (it == _objectVertices.end())
+		it = _objectVertices.insert (obj, QVector<Vertex>());
+	else
+		it->clear();
 
-		for (Vertex vrt : ref->fileInfo()->inlineVertices())
-		{
-			vrt.transform (ref->transform(), ref->position());
-			removeKnownVertexReference (vrt);
-		}
-	}
-	else
-	{
-		for (int i = 0; i < obj->numVertices(); ++i)
-			removeKnownVertexReference (obj->vertex (i));
-	}
+	obj->getVertices (*it);
+	needVertexMerge();
 }
 
 // =============================================================================
@@ -1190,7 +1161,7 @@
 	if (not isImplicit() && not (flags() & DOCF_IsBeingDestroyed))
 	{
 		history()->add (new DelHistory (idx, obj));
-		removeKnownVerticesOf (obj);
+		_objectVertices.remove (obj);
 	}
 
 	m_objects.removeAt (idx);
@@ -1199,44 +1170,6 @@
 
 // =============================================================================
 //
-void LDDocument::vertexChanged (const Vertex& a, const Vertex& b)
-{
-	removeKnownVertexReference (a);
-	addKnownVertexReference (b);
-}
-
-// =============================================================================
-//
-void LDDocument::addKnownVertexReference (const Vertex& a)
-{
-	if (isImplicit())
-		return;
-
-	auto it = m_vertices.find (a);
-
-	if (it == m_vertices.end())
-		m_vertices[a] = 1;
-	else
-		++it.value();
-}
-
-// =============================================================================
-//
-void LDDocument::removeKnownVertexReference (const Vertex& a)
-{
-	if (isImplicit())
-		return;
-
-	auto it = m_vertices.find (a);
-	assert (it != m_vertices.end());
-
-	// If there's no more references to a given vertex, it is to be removed.
-	if (--it.value() == 0)
-		m_vertices.erase (it);
-}
-
-// =============================================================================
-//
 bool safeToCloseAll()
 {
 	for (LDDocumentPtr f : LDDocument::explicitDocuments())
@@ -1262,23 +1195,18 @@
 		*m_history << new EditHistory (idx, oldcode, newcode);
 	}
 
-	removeKnownVerticesOf (m_objects[idx]);
+	_objectVertices.remove (m_objects[idx]);
 	m_objects[idx]->deselect();
 	m_objects[idx]->setDocument (LDDocumentPtr());
 	obj->setDocument (this);
-	addKnownVerticesOf (obj);
+	addKnownVertices (obj);
 	g_win->R()->compileObject (obj);
 	m_objects[idx] = obj;
+	needVertexMerge();
 }
 
 // =============================================================================
 //
-// Close all documents we don't need anymore
-//
-void LDDocument::closeUnused() {}
-
-// =============================================================================
-//
 LDObjectPtr LDDocument::getObject (int pos) const
 {
 	if (m_objects.size() <= pos)
@@ -1318,28 +1246,51 @@
 //
 void LDDocument::initializeCachedData()
 {
-	if (not m_needsReCache)
-		return;
-
-	m_storedVertices.clear();
-
-	for (LDObjectPtr obj : inlineContents (true, true))
+	if (m_needsReCache)
 	{
-		assert (obj->type() != OBJ_Subfile);
-		LDPolygon* data = obj->getPolygon();
+		_vertices.clear();
 
-		if (data != null)
+		for (LDObjectPtr obj : inlineContents (true, true))
 		{
-			m_polygonData << *data;
-			delete data;
+			assert (obj->type() != OBJ_Subfile);
+			LDPolygon* data = obj->getPolygon();
+
+			if (data != null)
+			{
+				m_polygonData << *data;
+				delete data;
+			}
 		}
 
-		for (int i = 0; i < obj->numVertices(); ++i)
-			m_storedVertices << obj->vertex (i);
+		m_needsReCache = false;
+	}
+
+	if (_verticesOutdated)
+	{
+		_objectVertices.clear();
+
+		for (LDObjectPtr obj : inlineContents (true, false))
+			addKnownVertices (obj);
+
+		mergeVertices();
+		_verticesOutdated = false;
 	}
 
-	removeDuplicates (m_storedVertices);
-	m_needsReCache = false;
+	if (_needVertexMerge)
+		mergeVertices();
+}
+
+// =============================================================================
+//
+void LDDocument::mergeVertices()
+{
+	_vertices.clear();
+
+	for (QVector<Vertex> const& verts : _objectVertices)
+		_vertices << verts;
+
+	removeDuplicates (_vertices);
+	_needVertexMerge = false;
 }
 
 // =============================================================================
@@ -1529,8 +1480,18 @@
 
 // =============================================================================
 //
-QList<Vertex> LDDocument::inlineVertices()
+QVector<Vertex> const& LDDocument::inlineVertices()
 {
 	initializeCachedData();
-	return m_storedVertices;
+	return _vertices;
 }
+
+void LDDocument::redoVertices()
+{
+	_verticesOutdated = true;
+}
+
+void LDDocument::needVertexMerge()
+{
+	_needVertexMerge = true;
+}
--- a/src/ldDocument.h	Mon Jul 07 18:52:10 2014 +0300
+++ b/src/ldDocument.h	Sun Jul 13 16:48:29 2014 +0300
@@ -63,13 +63,10 @@
 class LDDocument : public QObject
 {
 public:
-	using KnownVertexMap = QMap<Vertex, int>;
-
 	PROPERTY (public,	QString,				name,			setName,			STOCK_WRITE)
 	PROPERTY (private,	LDObjectList,		objects, 		setObjects,			STOCK_WRITE)
 	PROPERTY (private,	LDObjectList,		cache, 			setCache,			STOCK_WRITE)
 	PROPERTY (private,	History*,			history,		setHistory,			STOCK_WRITE)
-	PROPERTY (private,	KnownVertexMap,		vertices,		setVertices,		STOCK_WRITE)
 	PROPERTY (public,	QString,				fullPath,		setFullPath,		STOCK_WRITE)
 	PROPERTY (public,	QString,				defaultName,	setDefaultName,		STOCK_WRITE)
 	PROPERTY (public,	bool,				isImplicit,		setImplicit,		CUSTOM_WRITE)
@@ -79,12 +76,17 @@
 	PROPERTY (private,	LDDocumentFlags,	flags,			setFlags,			STOCK_WRITE)
 	PROPERTY (private,	LDDocumentWeakPtr,	self,			setSelf,			STOCK_WRITE)
 
+	QMap<LDObjectPtr, QVector<Vertex>> _objectVertices;
+	QVector<Vertex> _vertices;
+	bool _verticesOutdated;
+	bool _needVertexMerge;
+
 public:
 	LDDocument(LDDocumentPtr* selfptr);
 	~LDDocument();
 
 	int addObject (LDObjectPtr obj); // Adds an object to this file at the end of the file.
-	void addObjects (const LDObjectList objs);
+	void addObjects (const LDObjectList& objs);
 	void clearSelection();
 	void forgetObject (LDObjectPtr obj); // Deletes the given object from the object chain.
 	QString getDisplayName();
@@ -101,10 +103,11 @@
 	void setObject (int idx, LDObjectPtr obj);
 	QList<LDPolygon> inlinePolygons();
 	void vertexChanged (const Vertex& a, const Vertex& b);
-	void addKnownVerticesOf(LDObjectPtr obj);
-	void removeKnownVerticesOf (LDObjectPtr sub);
-	QList<Vertex> inlineVertices();
+	const QVector<Vertex>& inlineVertices();
 	void clear();
+	void addKnownVertices (LDObjectPtr obj);
+	void redoVertices();
+	void needVertexMerge();
 
 	inline LDDocument& operator<< (LDObjectPtr obj)
 	{
@@ -142,7 +145,6 @@
 		setImplicit (true);
 	}
 
-	static void closeUnused();
 	static LDDocumentPtr current();
 	static void setCurrent (LDDocumentPtr f);
 	static void closeInitialFile();
@@ -152,6 +154,7 @@
 	// Turns a full path into a relative path
 	static QString shortenName (QString a);
 	static QList<LDDocumentPtr> const& explicitDocuments();
+	void mergeVertices();
 
 protected:
 	void addToSelection (LDObjectPtr obj);
@@ -168,14 +171,10 @@
 private:
 	LDObjectList			m_sel;
 	LDGLData*				m_gldata;
-	QList<Vertex>			m_storedVertices;
 
 	// If set to true, next polygon inline of this document discards the
 	// stored polygon data and re-builds it.
 	bool					m_needsReCache;
-
-	void addKnownVertexReference (const Vertex& a);
-	void removeKnownVertexReference (const Vertex& a);
 };
 
 inline LDDocumentPtr getCurrentDocument()
--- a/src/ldObject.cc	Mon Jul 07 18:52:10 2014 +0300
+++ b/src/ldObject.cc	Sun Jul 13 16:48:29 2014 +0300
@@ -811,6 +811,7 @@
 		{
 			obj->document().toStrongRef()->addToHistory (new EditHistory (idx, before, after));
 			g_win->R()->compileObject (obj);
+			getCurrentDocument()->redoVertices();
 		}
 	}
 	else
@@ -835,9 +836,6 @@
 //
 void LDObject::setVertex (int i, const Vertex& vert)
 {
-	if (document() != null)
-		document().toStrongRef()->vertexChanged (m_coords[i], vert);
-
 	changeProperty (self(), &m_coords[i], vert);
 }
 
@@ -846,14 +844,7 @@
 void LDMatrixObject::setPosition (const Vertex& a)
 {
 	LDObjectPtr ref = linkPointer().toStrongRef();
-
-	if (ref->document() != null)
-		ref->document().toStrongRef()->removeKnownVerticesOf (ref);
-
 	changeProperty (ref, &m_position, a);
-
-	if (ref->document() != null)
-		ref->document().toStrongRef()->addKnownVerticesOf (ref);
 }
 
 // =============================================================================
@@ -861,14 +852,7 @@
 void LDMatrixObject::setTransform (const Matrix& val)
 {
 	LDObjectPtr ref = linkPointer().toStrongRef();
-
-	if (ref->document() != null)
-		ref->document().toStrongRef()->removeKnownVerticesOf (ref);
-
 	changeProperty (ref, &m_transform, val);
-
-	if (ref->document() != null)
-		ref->document().toStrongRef()->addKnownVerticesOf (ref);
 }
 
 // =============================================================================
@@ -931,9 +915,6 @@
 //
 void LDSubfile::setFileInfo (const LDDocumentPtr& a)
 {
-	if (document() != null)
-		document().toStrongRef()->removeKnownVerticesOf (self());
-
 	m_fileInfo = a;
 
 	// If it's an immediate subfile reference (i.e. this subfile belongs in an
@@ -945,7 +926,20 @@
 	{
 		a->initializeCachedData();
 	}
+};
 
-	if (document() != null)
-		document().toStrongRef()->addKnownVerticesOf (self());
-};
+void LDObject::getVertices (QVector<Vertex>& verts) const
+{
+	for (int i = 0; i < numVertices(); ++i)
+		verts << vertex (i);
+}
+
+void LDSubfile::getVertices (QVector<Vertex>& verts) const
+{
+	verts << fileInfo()->inlineVertices();
+}
+
+void LDVertex::getVertices (QVector<Vertex>& verts) const
+{
+	verts.append (pos);
+}
--- a/src/ldObject.h	Mon Jul 07 18:52:10 2014 +0300
+++ b/src/ldObject.h	Sun Jul 13 16:48:29 2014 +0300
@@ -120,6 +120,8 @@
 	// Removes this object from selection
 	void						deselect();
 
+	virtual void				getVertices (QVector<Vertex>& verts) const;
+
 	// Does this object have a matrix and position? (see LDMatrixObject)
 	virtual bool				hasMatrix() const = 0;
 
@@ -441,6 +443,7 @@
 	// Inlines this subfile.
 	LDObjectList inlineContents (bool deep, bool render);
 	QList<LDPolygon> inlinePolygons();
+	virtual void getVertices (QVector<Vertex>& verts) const override;
 };
 
 Q_DECLARE_OPERATORS_FOR_FLAGS (LDSubfile::InlineFlags)
@@ -565,6 +568,7 @@
 
 public:
 	Vertex pos;
+	virtual void getVertices (QVector<Vertex>& verts) const override;
 };
 
 using LDVertexPtr = QSharedPointer<LDVertex>;

mercurial