Moved more business logic out of GLRenderer into Canvas. GLRenderer::pick(const QRange&) now returns a set of LDObjects without modifying them. Replaced the GLRenderer::pick(int, int) overload with GLRenderer::pickOneObject.

Thu, 09 Feb 2017 19:57:43 +0200

author
Teemu Piippo <teemu@hecknology.net>
date
Thu, 09 Feb 2017 19:57:43 +0200
changeset 1110
ec3ee7da7806
parent 1109
a55b2608a395
child 1111
471572db2fe1

Moved more business logic out of GLRenderer into Canvas. GLRenderer::pick(const QRange&) now returns a set of LDObjects without modifying them. Replaced the GLRenderer::pick(int, int) overload with GLRenderer::pickOneObject.

src/canvas.cpp file | annotate | diff | comparison | revisions
src/canvas.h file | annotate | diff | comparison | revisions
src/editmodes/magicWandMode.cpp file | annotate | diff | comparison | revisions
src/editmodes/selectMode.cpp file | annotate | diff | comparison | revisions
src/editmodes/selectMode.h file | annotate | diff | comparison | revisions
src/glRenderer.cpp file | annotate | diff | comparison | revisions
src/glRenderer.h file | annotate | diff | comparison | revisions
--- a/src/canvas.cpp	Thu Feb 09 19:32:41 2017 +0200
+++ b/src/canvas.cpp	Thu Feb 09 19:57:43 2017 +0200
@@ -309,4 +309,15 @@
 		int ry = (((position3d[axisY] * signY) - virtualHeight() + panning(Y)) * height()) / (2 * virtualHeight());
 		return {rx, -ry};
 	}
-}
\ No newline at end of file
+}
+
+void Canvas::contextMenuEvent(QContextMenuEvent* event)
+{
+	m_window->spawnContextMenu(event->globalPos());
+}
+
+void Canvas::dragEnterEvent(QDragEnterEvent* event)
+{
+	if (m_window and event->source() == m_window->getPrimitivesTree() and m_window->getPrimitivesTree()->currentItem())
+		event->acceptProposedAction();
+}
--- a/src/canvas.h	Thu Feb 09 19:32:41 2017 +0200
+++ b/src/canvas.h	Thu Feb 09 19:57:43 2017 +0200
@@ -43,6 +43,8 @@
 	void setEditMode(EditModeType type);
 
 protected:
+	void contextMenuEvent(QContextMenuEvent* event) override;
+	void dragEnterEvent(QDragEnterEvent* event) override;
 	void dropEvent(QDropEvent* event) override;
 	bool freeCameraAllowed() const override;
 	void keyReleaseEvent(QKeyEvent* event) override;
--- a/src/editmodes/magicWandMode.cpp	Thu Feb 09 19:32:41 2017 +0200
+++ b/src/editmodes/magicWandMode.cpp	Thu Feb 09 19:57:43 2017 +0200
@@ -210,7 +210,7 @@
 		else if (data.keymods & Qt::ControlModifier)
 			wandtype = MagicWandMode::Subtractive;
 
-		doMagic (renderer()->pickOneObject (data.ev->x(), data.ev->y()), wandtype);
+		doMagic (renderer()->pick (data.ev->x(), data.ev->y()), wandtype);
 		return true;
 	}
 
--- a/src/editmodes/selectMode.cpp	Thu Feb 09 19:32:41 2017 +0200
+++ b/src/editmodes/selectMode.cpp	Thu Feb 09 19:57:43 2017 +0200
@@ -66,23 +66,23 @@
 		if (not data.mouseMoved or m_rangepick)
 		{
 			QRect area;
-			int const mx = data.ev->x();
-			int const my = data.ev->y();
+			int mx = data.ev->x();
+			int my = data.ev->y();
 
 			if (not m_rangepick)
 			{
-				area = QRect (mx, my, 1, 1);
+				area = {mx, my, 1, 1};
 			}
 			else
 			{
-				int const x = qMin (m_rangeStart.x(), mx);
-				int const y = qMin (m_rangeStart.y(), my);
-				int const width = qAbs (m_rangeStart.x() - mx);
-				int const height = qAbs (m_rangeStart.y() - my);
-				area = QRect (x, y, width, height);
+				int x = qMin(m_rangeStart.x(), mx);
+				int y = qMin(m_rangeStart.y(), my);
+				int width = qAbs(m_rangeStart.x() - mx);
+				int height = qAbs(m_rangeStart.y() - my);
+				area = {x, y, width, height};
 			}
 
-			renderer()->pick (area, m_addpick);
+			doSelection(area);
 		}
 
 		m_rangepick = false;
@@ -92,6 +92,29 @@
 	return false;
 }
 
+void SelectMode::doSelection(const QRect& area)
+{
+	QSet<LDObject*> priorSelection = selectedObjects();
+	QSet<LDObject*> newSelection = renderer()->pick(area);
+
+	// If we're doing an additive pick, use a symmetric difference to keep the existing ones, and filter out objects that were selected
+	// once over again.
+	if (m_addpick)
+		newSelection = (newSelection - priorSelection) | (priorSelection - newSelection);
+
+	newSelection.unite(renderer()->pick(area));
+
+	// Select all objects that we now have selected that were not selected before.
+	for (LDObject* object : newSelection - priorSelection)
+		currentDocument()->addToSelection(object);
+
+	// Likewise, deselect whatever was selected that isn't anymore.
+	for (LDObject* object : priorSelection - newSelection)
+		currentDocument()->removeFromSelection(object);
+
+	m_window->updateSelection();
+}
+
 bool SelectMode::mousePressed (QMouseEvent* ev)
 {
 	if (Super::mousePressed (ev))
@@ -117,7 +140,7 @@
 	if (ev->buttons() & Qt::LeftButton)
 	{
 		currentDocument()->clearSelection();
-		LDObject* obj = renderer()->pickOneObject (ev->x(), ev->y());
+		LDObject* obj = renderer()->pick (ev->x(), ev->y());
 
 		if (obj)
 		{
--- a/src/editmodes/selectMode.h	Thu Feb 09 19:32:41 2017 +0200
+++ b/src/editmodes/selectMode.h	Thu Feb 09 19:57:43 2017 +0200
@@ -30,6 +30,7 @@
 public:
 	SelectMode (Canvas* canvas);
 
+	void doSelection(const QRect& area);
 	void render (QPainter& painter) const override;
 	bool mousePressed (QMouseEvent* ev) override;
 	bool mouseReleased (MouseEventData const& data) override;
--- a/src/glRenderer.cpp	Thu Feb 09 19:32:41 2017 +0200
+++ b/src/glRenderer.cpp	Thu Feb 09 19:57:43 2017 +0200
@@ -675,13 +675,6 @@
 
 // =============================================================================
 //
-void GLRenderer::contextMenuEvent(QContextMenuEvent* event)
-{
-	m_window->spawnContextMenu(event->globalPos());
-}
-
-// =============================================================================
-//
 void GLRenderer::setCamera(Camera camera)
 {
 	// The edit mode may forbid the free camera.
@@ -692,26 +685,14 @@
 	}
 }
 
-// =============================================================================
-//
-void GLRenderer::pick (int mouseX, int mouseY, bool additive)
-{
-	pick (QRect (mouseX, mouseY, mouseX + 1, mouseY + 1), additive);
-}
-
-// =============================================================================
-//
-void GLRenderer::pick(const QRect& range, bool additive)
+/*
+ * Returns the set of objects found in the specified pixel area.
+ */
+QSet<LDObject*> GLRenderer::pick(const QRect& range)
 {
 	makeCurrent();
-	QSet<LDObject*> priorSelection = selectedObjects();
 	QSet<LDObject*> newSelection;
 
-	// If we're doing an additive selection, we start off with the existing selection.
-	// Otherwise we start selecting from scratch.
-	if (additive)
-		newSelection = priorSelection;
-
 	// Paint the picking scene
 	setPicking(true);
 	drawGLScene();
@@ -757,48 +738,25 @@
 		LDObject* object = LDObject::fromID(index);
 
 		if (object != nullptr)
-		{
-			// If this is an additive single pick and the object is currently selected,
-			// we remove it from selection instead.
-			if (additive and newSelection.contains(object))
-				newSelection.remove(object);
-			else
-				newSelection.insert(object);
-		}
-	}
-
-	// Select all objects that we now have selected that were not selected before.
-	for (LDObject* object : newSelection - priorSelection)
-	{
-		currentDocument()->addToSelection(object);
-		compileObject(object);
+			newSelection.insert(object);
 	}
 
-	// Likewise, deselect whatever was selected that isn't anymore.
-	for (LDObject* object : priorSelection - newSelection)
-	{
-		currentDocument()->removeFromSelection(object);
-		compileObject(object);
-	}
-
-	m_window->updateSelection();
 	setPicking(false);
 	repaint();
+	return newSelection;
 }
 
-//
-// Simpler version of GLRenderer::pick which simply picks whatever object on the cursor
-//
-LDObject* GLRenderer::pickOneObject (int mouseX, int mouseY)
+/*
+ * Simpler version of GLRenderer::pick which simply picks whatever object on the cursor
+ */
+LDObject* GLRenderer::pick(int mouseX, int mouseY)
 {
 	unsigned char pixel[4];
 	makeCurrent();
 	setPicking(true);
 	drawGLScene();
 	glReadPixels(mouseX, m_height - mouseY, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixel);
-	LDObject* object = LDObject::fromID(pixel[0] * 0x10000 +
-	                                    pixel[1] * 0x100 +
-	                                    pixel[2] * 0x1);
+	LDObject* object = LDObject::fromID(pixel[0] * 0x10000 + pixel[1] * 0x100 + pixel[2]);
 	setPicking(false);
 	repaint();
 	return object;
@@ -1055,12 +1013,6 @@
 	update();
 }
 
-void GLRenderer::dragEnterEvent (QDragEnterEvent* ev)
-{
-	if (m_window and ev->source() == m_window->getPrimitivesTree() and m_window->getPrimitivesTree()->currentItem())
-		ev->acceptProposedAction();
-}
-
 const CameraInfo& GLRenderer::cameraInfo (Camera camera) const
 {
 	if (valueInEnum<Camera>(camera))
--- a/src/glRenderer.h	Thu Feb 09 19:32:41 2017 +0200
+++ b/src/glRenderer.h	Thu Feb 09 19:57:43 2017 +0200
@@ -97,9 +97,8 @@
 	QPointF const& mousePositionF() const;
 	void needZoomToFit();
 	LDObject* objectAtCursor() const;
-	void pick(int mouseX, int mouseY, bool additive);
-	void pick(const QRect& range, bool additive);
-	LDObject* pickOneObject(int mouseX, int mouseY);
+	QSet<LDObject*> pick(const QRect& range);
+	LDObject* pick(int mouseX, int mouseY);
 	void refresh();
 	void resetAllAngles();
 	void resetAngles();
@@ -115,8 +114,6 @@
 	static const QPen thinBorderPen;
 
 protected:
-	void contextMenuEvent(QContextMenuEvent* event);
-	void dragEnterEvent(QDragEnterEvent* event);
 	void initializeGL();
 	void keyPressEvent(QKeyEvent* event);
 	void keyReleaseEvent(QKeyEvent* event);

mercurial