- reimplemented vertex snapping

Fri, 18 Apr 2014 18:46:25 +0300

author
Santeri Piippo <crimsondusk64@gmail.com>
date
Fri, 18 Apr 2014 18:46:25 +0300
changeset 717
fdc285e5952f
parent 716
639a900999bc
child 718
a2cbef633673

- reimplemented vertex snapping

src/glCompiler.cc file | annotate | diff | comparison | revisions
src/glCompiler.h file | annotate | diff | comparison | revisions
src/glRenderer.cc file | annotate | diff | comparison | revisions
src/glShared.h 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
src/partDownloader.cc file | annotate | diff | comparison | revisions
--- a/src/glCompiler.cc	Thu Apr 17 21:51:59 2014 +0300
+++ b/src/glCompiler.cc	Fri Apr 18 18:46:25 2014 +0300
@@ -27,8 +27,6 @@
 #include "glRenderer.h"
 #include "dialogs.h"
 
-cfg (String,	gl_selectcolor,			"#0080FF")
-
 struct GLErrorInfo
 {
 	GLenum	value;
@@ -47,12 +45,13 @@
 	{ GL_STACK_OVERFLOW,				"The operation would have caused an overflow" },
 };
 
+cfg (String, gl_selectcolor, "#0080FF")
 extern_cfg (Bool, gl_blackedges);
 extern_cfg (String, gl_bgcolor);
-static QList<short>		g_warnedColors;
+
+static QList<int>		g_warnedColors;
 static const QColor		g_BFCFrontColor (40, 192, 40);
 static const QColor		g_BFCBackColor (224, 40, 40);
-static QMap<LDObject*, QString> g_objectOrigins;
 
 // =============================================================================
 //
@@ -126,7 +125,7 @@
 
 // =============================================================================
 //
-QColor GLCompiler::polygonColor (LDPolygon& poly, LDObject* topobj) const
+QColor GLCompiler::getColorForPolygon (LDPolygon& poly, LDObject* topobj) const
 {
 	QColor qcol;
 
@@ -149,9 +148,9 @@
 			qcol = col->faceColor;
 	}
 
-	if (qcol.isValid() == false)
+	if (not qcol.isValid())
 	{
-		// The color was unknown. Use main color to make the poly.object at least
+		// The color was unknown. Use main color to make the polygon at least
 		// not appear pitch-black.
 		if (poly.num != 2 && poly.num != 5)
 			qcol = GLRenderer::getMainColor();
@@ -159,7 +158,7 @@
 			qcol = Qt::black;
 
 		// Warn about the unknown color, but only once.
-		if (g_warnedColors.contains (poly.color) == false)
+		if (not g_warnedColors.contains (poly.color))
 		{
 			print ("Unknown color %1!\n", poly.color);
 			g_warnedColors << poly.color;
@@ -232,7 +231,7 @@
 
 	for (auto it = m_objectInfo.begin(); it != m_objectInfo.end(); ++it)
 	{
-		if (it.key()->document() == getCurrentDocument() && it.key()->isHidden() == false)
+		if (it.key()->document() == getCurrentDocument() && not it.key()->isHidden())
 			vbodata += it->data[vbonum];
 	}
 
@@ -264,7 +263,6 @@
 	if (obj->document()->isImplicit())
 		return;
 
-	g_objectOrigins[obj] = obj->document()->getDisplayName() + ":" + QString::number (obj->lineNumber());
 	ObjectVBOInfo info;
 	info.isChanged = true;
 	dropObject (obj);
@@ -286,18 +284,14 @@
 		case 3:	surface = VBOSF_Triangles;	numverts = 3; break;
 		case 4:	surface = VBOSF_Quads;		numverts = 4; break;
 		case 5:	surface = VBOSF_CondLines;	numverts = 2; break;
-
-		default:
-			print ("OMGWTFBBQ weird polygon with number %1 (topobj: #%2, %3), origin: %4",
-				(int) poly.num, topobj->id(), topobj->typeName(), poly.origin);
-			assert (false);
+		default: return;
 	}
 
 	for (int complement = 0; complement < VBOCM_NumComplements; ++complement)
 	{
 		const int vbonum			= vboNumber (surface, (EVBOComplement) complement);
 		QVector<GLfloat>& vbodata	= objinfo->data[vbonum];
-		const QColor normalColor	= polygonColor (poly, topobj);
+		const QColor normalColor	= getColorForPolygon (poly, topobj);
 		const QColor pickColor		= indexColorForID (topobj->id());
 
 		for (int vert = 0; vert < numverts; ++vert)
--- a/src/glCompiler.h	Thu Apr 17 21:51:59 2014 +0300
+++ b/src/glCompiler.h	Fri Apr 18 18:46:25 2014 +0300
@@ -40,7 +40,7 @@
 	void				compileDocument (LDDocument* doc);
 	void				dropObject (LDObject* obj);
 	void				initialize();
-	QColor				polygonColor (LDPolygon& poly, LDObject* topobj) const;
+	QColor				getColorForPolygon (LDPolygon& poly, LDObject* topobj) const;
 	QColor				indexColorForID (int id) const;
 	void				needMerge();
 	void				prepareVBO (int vbonum);
--- a/src/glRenderer.cc	Thu Apr 17 21:51:59 2014 +0300
+++ b/src/glRenderer.cc	Fri Apr 18 18:46:25 2014 +0300
@@ -1011,9 +1011,9 @@
 
 		QPoint curspos = coordconv3_2 (m_hoverpos);
 
-		for (const Vertex& pos3d: m_knownVerts)
+		for (auto it = document()->vertices().begin(); it != document()->vertices().end(); ++it)
 		{
-			QPoint pos2d = coordconv3_2 (pos3d);
+			QPoint pos2d = coordconv3_2 (it.key());
 
 			// Measure squared distance
 			const double dx = abs (pos2d.x() - curspos.x()),
@@ -1026,7 +1026,7 @@
 			if (distsq < mindist)
 			{
 				mindist = distsq;
-				closest = pos3d;
+				closest = it.key();
 				valid = true;
 
 				// If it's only 4 pixels away, I think we found our vertex now.
--- a/src/glShared.h	Thu Apr 17 21:51:59 2014 +0300
+++ b/src/glShared.h	Fri Apr 18 18:46:25 2014 +0300
@@ -28,7 +28,6 @@
 	Vertex		vertices[4];
 	int			id;
 	int			color;
-	QString		origin;
 
 	inline int numVertices() const
 	{
--- a/src/ldDocument.cc	Thu Apr 17 21:51:59 2014 +0300
+++ b/src/ldDocument.cc	Fri Apr 18 18:46:25 2014 +0300
@@ -124,6 +124,7 @@
 // =============================================================================
 //
 LDDocument::LDDocument() :
+	m_flags (0),
 	m_gldata (new LDGLData)
 {
 	setImplicit (true);
@@ -141,7 +142,7 @@
 	// Remove this file from the list of files. This MUST be done FIRST, otherwise
 	// a ton of other functions will think this file is still valid when it is not!
 	g_loadedFiles.removeOne (this);
-
+	m_flags |= DOCF_IsBeingDestroyed;
 	m_history->setIgnoring (true);
 
 	// Clear everything from the model
@@ -471,7 +472,7 @@
 
 // =============================================================================
 //
-LDDocument* openDocument (QString path, bool search)
+LDDocument* openDocument (QString path, bool search, bool implicit)
 {
 	// Convert the file name to lowercase since some parts contain uppercase
 	// file names. I'll assume here that the library will always use lowercase
@@ -497,6 +498,7 @@
 		return null;
 
 	LDDocument* load = new LDDocument;
+	load->setImplicit (implicit);
 	load->setFullPath (fullpath);
 	load->setName (LDDocument::shortenName (load->fullPath()));
 	dprint ("name: %1 (%2)", load->name(), load->fullPath());
@@ -671,7 +673,7 @@
 		return;
 	}
 
-	LDDocument* file = openDocument (path, false);
+	LDDocument* file = openDocument (path, false, false);
 
 	if (not file)
 	{
@@ -1024,7 +1026,7 @@
 
 	// If it's not loaded, try open it
 	if (not doc)
-		doc = openDocument (filename, true);
+		doc = openDocument (filename, true, true);
 
 	return doc;
 }
@@ -1066,9 +1068,7 @@
 {
 	history()->add (new AddHistory (objects().size(), obj));
 	m_objects << obj;
-
-	if (obj->type() == LDObject::EVertex)
-		m_vertices << obj;
+	addKnownVerticesOf (obj);
 
 #ifdef DEBUG
 	if (not isImplicit())
@@ -1097,6 +1097,7 @@
 	m_objects.insert (pos, obj);
 	obj->setDocument (this);
 	g_win->R()->compileObject (obj);
+	addKnownVerticesOf (obj);
 
 #ifdef DEBUG
 	if (not isImplicit())
@@ -1106,14 +1107,61 @@
 
 // =============================================================================
 //
+void LDDocument::addKnownVerticesOf (LDObject* obj)
+{
+	if (isImplicit())
+		return;
+
+	if (obj->type() == LDObject::ESubfile)
+	{
+		for (LDObject* sub : static_cast<LDSubfile*> (obj)->inlineContents (true, false))
+		{
+			addKnownVerticesOf (sub);
+			sub->destroy();
+		}
+	}
+	else
+	{
+		for (int i = 0; i < obj->vertices(); ++i)
+			addKnownVertexReference (obj->vertex (i));
+	}
+}
+
+// =============================================================================
+//
+void LDDocument::removeKnownVerticesOf (LDObject* obj)
+{
+	if (isImplicit())
+		return;
+
+	if (obj->type() == LDObject::ESubfile)
+	{
+		for (LDObject* sub : static_cast<LDSubfile*> (obj)->inlineContents (true, false))
+		{
+			removeKnownVerticesOf (sub);
+			sub->destroy();
+		}
+	}
+	else
+	{
+		for (int i = 0; i < obj->vertices(); ++i)
+			removeKnownVertexReference (obj->vertex (i));
+	}
+}
+
+// =============================================================================
+//
 void LDDocument::forgetObject (LDObject* obj)
 {
 	int idx = obj->lineNumber();
 	obj->unselect();
 	assert (m_objects[idx] == obj);
 
-	if (not history()->isIgnoring())
+	if (not isImplicit() && not (flags() & DOCF_IsBeingDestroyed))
+	{
 		history()->add (new DelHistory (idx, obj));
+		removeKnownVerticesOf (obj);
+	}
 
 	m_objects.removeAt (idx);
 	obj->setDocument (null);
@@ -1121,6 +1169,44 @@
 
 // =============================================================================
 //
+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 (LDDocument* f : g_loadedFiles)
@@ -1144,9 +1230,11 @@
 		*m_history << new EditHistory (idx, oldcode, newcode);
 	}
 
+	removeKnownVerticesOf (m_objects[idx]);
 	m_objects[idx]->unselect();
 	m_objects[idx]->setDocument (null);
 	obj->setDocument (this);
+	addKnownVerticesOf (obj);
 	g_win->R()->compileObject (obj);
 	m_objects[idx] = obj;
 }
@@ -1354,8 +1442,8 @@
 	delete g_logoedStud;
 	delete g_logoedStud2;
 
-	g_logoedStud = openDocument ("stud-logo.dat", true);
-	g_logoedStud2 = openDocument ("stud2-logo.dat", true);
+	g_logoedStud = openDocument ("stud-logo.dat", true, true);
+	g_logoedStud2 = openDocument ("stud2-logo.dat", true, true);
 
 	print (LDDocument::tr ("Logoed studs loaded.\n"));
 }
--- a/src/ldDocument.h	Thu Apr 17 21:51:59 2014 +0300
+++ b/src/ldDocument.h	Fri Apr 18 18:46:25 2014 +0300
@@ -40,6 +40,17 @@
 	QString getError();
 }
 
+//
+// Flags for LDDocument
+//
+enum LDDocumentFlag
+{
+	DOCF_IsBeingDestroyed = (1 << 0),
+};
+
+Q_DECLARE_FLAGS (LDDocumentFlags, LDDocumentFlag)
+Q_DECLARE_OPERATORS_FOR_FLAGS (LDDocumentFlags)
+
 // =============================================================================
 //
 // This class stores a document either as a editable file for the user or for
@@ -55,13 +66,14 @@
 {
 	public:
 		using ReferenceList = QList<LDDocumentPointer*>;
+		using KnownVertexMap = QMap<Vertex, int>;
 
 		Q_OBJECT
 		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,	LDObjectList,	vertices,		setVertices,		STOCK_WRITE)
+		PROPERTY (private,	KnownVertexMap,	vertices,		setVertices,		STOCK_WRITE)
 		PROPERTY (private,	ReferenceList,	references,		setReferences,		STOCK_WRITE)
 		PROPERTY (public,	QString,		fullPath,		setFullPath,		STOCK_WRITE)
 		PROPERTY (public,	QString,		defaultName,	setDefaultName,		STOCK_WRITE)
@@ -69,6 +81,7 @@
 		PROPERTY (public,	long,			savePosition,	setSavePosition,	STOCK_WRITE)
 		PROPERTY (public,	int,			tabIndex,		setTabIndex,		STOCK_WRITE)
 		PROPERTY (public,	QList<LDPolygon>,	polygonData,	setPolygonData,	STOCK_WRITE)
+		PROPERTY (private,	LDDocumentFlags,	flags,			setFlags,		STOCK_WRITE)
 
 	public:
 		LDDocument();
@@ -93,6 +106,9 @@
 		void addReference (LDDocumentPointer* ptr);
 		void removeReference (LDDocumentPointer* ptr);
 		QList<LDPolygon> inlinePolygons();
+		void vertexChanged (const Vertex& a, const Vertex& b);
+		void addKnownVerticesOf(LDObject* obj);
+		void removeKnownVerticesOf (LDObject* sub);
 
 		inline LDDocument& operator<< (LDObject* obj)
 		{
@@ -155,6 +171,9 @@
 		bool					m_needsGLReInit;
 
 		static LDDocument*		m_curdoc;
+
+		void addKnownVertexReference (const Vertex& a);
+		void removeKnownVertexReference (const Vertex& a);
 };
 
 inline LDDocument* getCurrentDocument()
@@ -173,7 +192,7 @@
 
 // Opens the given file and parses the LDraw code within. Returns a pointer
 // to the opened file or null on error.
-LDDocument* openDocument (QString path, bool search);
+LDDocument* openDocument (QString path, bool search, bool implicit);
 
 // Opens the given file and returns a pointer to it, potentially looking in /parts and /p
 QFile* openLDrawFile (QString relpath, bool subdirs, QString* pathpointer = null);
--- a/src/ldObject.cc	Thu Apr 17 21:51:59 2014 +0300
+++ b/src/ldObject.cc	Fri Apr 18 18:46:25 2014 +0300
@@ -354,7 +354,6 @@
 	data->id = id();
 	data->num = num;
 	data->color = color();
-	data->origin = origin();
 
 	for (int i = 0; i < data->numVertices(); ++i)
 		data->vertices[i] = vertex (i);
@@ -733,6 +732,9 @@
 //
 void LDObject::setVertex (int i, const Vertex& vert)
 {
+	if (document() != null)
+		document()->vertexChanged (*m_coords[i], vert);
+
 	changeProperty (this, &m_coords[i], LDSharedVertex::getSharedVertex (vert));
 }
 
@@ -740,7 +742,13 @@
 //
 void LDMatrixObject::setPosition (const Vertex& a)
 {
+	if (linkPointer()->document() != null)
+		linkPointer()->document()->removeKnownVerticesOf (linkPointer());
+
 	changeProperty (linkPointer(), &m_position, LDSharedVertex::getSharedVertex (a));
+
+	if (linkPointer()->document() != null)
+		linkPointer()->document()->addKnownVerticesOf (linkPointer());
 }
 
 // =============================================================================
@@ -866,12 +874,6 @@
 	*/
 
 	LDObject* copy = parseLine (asText());
-
-	if (origin().isEmpty() == false)
-		copy->setOrigin (origin());
-	elif (document() != null)
-		copy->setOrigin (document()->getDisplayName() + ":" + QString::number (lineNumber()));
-
 	return copy;
 }
 
--- a/src/ldObject.h	Thu Apr 17 21:51:59 2014 +0300
+++ b/src/ldObject.h	Fri Apr 18 18:46:25 2014 +0300
@@ -73,7 +73,6 @@
 	PROPERTY (private,		int,			id,				setID,			STOCK_WRITE)
 	PROPERTY (public,		int,			color,			setColor,		CUSTOM_WRITE)
 	PROPERTY (public,		bool,			isGLInit,		setGLInit,		STOCK_WRITE)
-	PROPERTY (public,		QString,		origin,			setOrigin,		STOCK_WRITE)
 
 	public:
 		// Object type codes.
--- a/src/partDownloader.cc	Thu Apr 17 21:51:59 2014 +0300
+++ b/src/partDownloader.cc	Fri Apr 18 18:46:25 2014 +0300
@@ -446,13 +446,11 @@
 	}
 
 	// Try to load this file now.
-	LDDocument* f = openDocument (filePath(), false);
+	LDDocument* f = openDocument (filePath(), false, not isPrimary());
 
 	if (f == null)
 		return;
 
-	f->setImplicit (not isPrimary());
-
 	// Iterate through this file and check for errors. If there's any that stems
 	// from unknown file references, try resolve that by downloading the reference.
 	// This is why downloading a part may end up downloading multiple files, as

mercurial