- reimplemented the Vertex class as a derivative of QVector3D

Wed, 23 Apr 2014 18:25:09 +0300

author
Santeri Piippo <crimsondusk64@gmail.com>
date
Wed, 23 Apr 2014 18:25:09 +0300
changeset 733
cc39df788660
parent 732
220cda74d6b7
child 734
cdce1cbaac7e

- reimplemented the Vertex class as a derivative of QVector3D

src/actionsEdit.cc file | annotate | diff | comparison | revisions
src/addObjectDialog.cc file | annotate | diff | comparison | revisions
src/basics.cc file | annotate | diff | comparison | revisions
src/basics.h file | annotate | diff | comparison | revisions
src/format.h file | annotate | diff | comparison | revisions
src/glRenderer.cc file | annotate | diff | comparison | revisions
src/ldDocument.cc file | annotate | diff | comparison | revisions
src/ldObject.cc file | annotate | diff | comparison | revisions
src/ldObject.h file | annotate | diff | comparison | revisions
src/miscallenous.cc file | annotate | diff | comparison | revisions
src/miscallenous.h file | annotate | diff | comparison | revisions
src/primitives.cc file | annotate | diff | comparison | revisions
--- a/src/actionsEdit.cc	Wed Apr 23 15:39:42 2014 +0300
+++ b/src/actionsEdit.cc	Wed Apr 23 18:25:09 2014 +0300
@@ -364,9 +364,9 @@
 void doMoveObjects (Vertex vect)
 {
 	// Apply the grid values
-	vect[X] *= *currentGrid().confs[Grid::X];
-	vect[Y] *= *currentGrid().confs[Grid::Y];
-	vect[Z] *= *currentGrid().confs[Grid::Z];
+	vect.setX (vect.x() * *currentGrid().confs[Grid::X]);
+	vect.setY (vect.y() * *currentGrid().confs[Grid::Y]);
+	vect.setZ (vect.z() * *currentGrid().confs[Grid::Z]);
 
 	for (LDObject* obj : selection())
 		obj->move (vect);
@@ -420,11 +420,11 @@
 
 // =============================================================================
 //
-static void rotateVertex (Vertex& v, const Vertex& rotpoint, const Matrix& transform)
+static void rotateVertex (Vertex& v, const Vertex& rotpoint, const Matrix& transformer)
 {
-	v.move (-rotpoint);
-	v.transform (transform, g_origin);
-	v.move (rotpoint);
+	v -= rotpoint;
+	v.transform (transformer, g_origin);
+	v += rotpoint;
 }
 
 // =============================================================================
@@ -538,27 +538,20 @@
 			Vertex v = mo->position();
 			Matrix t = mo->transform();
 
-			for_axes (ax)
-				roundToDecimals (v[ax], 3);
-
-			// Let matrix values be rounded to 4 decimals,
-			// they need that extra precision
-			for (int i = 0; i < 9; ++i)
-				roundToDecimals (t[i], 4);
+			// Note: matrix values are to be rounded to 4 decimals.
+			v.apply ([](Axis, double& a) { roundToDecimals (a, 3); });
+			applyToMatrix (t, [](int, double& a) { roundToDecimals (a, 4); });
 
 			mo->setPosition (v);
 			mo->setTransform (t);
-			num += 10;
+			num += 12;
 		}
 		else
 		{
 			for (int i = 0; i < obj->vertices(); ++i)
 			{
 				Vertex v = obj->vertex (i);
-
-				for_axes (ax)
-					roundToDecimals (v[ax], 3);
-
+				v.apply ([](Axis, double& a) { roundToDecimals (a, 3); });
 				obj->setVertex (i, v);
 				num += 3;
 			}
@@ -623,19 +616,20 @@
 		{
 			Vertex v = obj->vertex (i);
 
-			for (Axis ax : sel)
+			v.apply ([&](Axis ax, double& coord)
 			{
-				double& coord = v[ax];
-
-				if (any || coord == search)
+				if (not sel.contains (ax) ||
+					(not any && coord != search))
 				{
-					if (not rel)
-						coord = 0;
+					return;
+				}
 
-					coord += replacement;
-					num++;
-				}
-			}
+				if (not rel)
+					coord = 0;
+
+				coord += replacement;
+				num++;
+			});
 
 			obj->setVertex (i, v);
 		}
@@ -668,8 +662,11 @@
 		{
 			Vertex v = obj->vertex (i);
 
-			for (Axis ax : sel)
-				v[ax] *= -1;
+			v.apply ([&](Axis ax, double& a)
+			{
+				if (sel.contains (ax))
+					a = -a;
+			});
 
 			obj->setVertex (i, v);
 		}
--- a/src/addObjectDialog.cc	Wed Apr 23 15:39:42 2014 +0300
+++ b/src/addObjectDialog.cc	Wed Apr 23 18:25:09 2014 +0300
@@ -192,15 +192,17 @@
 		case LDObject::ECondLine:
 		case LDObject::ETriangle:
 		case LDObject::EQuad:
-
 			// Apply coordinates
-			if (obj)
+			if (obj != null)
 			{
 				for (int i = 0; i < coordCount / 3; ++i)
-					for (int j = 0; j < 3; ++j)
-						dsb_coords[ (i * 3) + j]->setValue (obj->vertex (i).getCoordinate (j));
+				{
+					obj->vertex (i).apply ([&](Axis ax, double value)
+					{
+						dsb_coords[(i * 3) + ax]->setValue (value);
+					});
+				}
 			}
-
 			break;
 
 		case LDObject::EComment:
@@ -230,10 +232,12 @@
 		// le_matrix->setValidator (new QDoubleValidator);
 		Matrix defaultMatrix = g_identity;
 
-		if (mo)
+		if (mo != null)
 		{
-			for_axes (ax)
-				dsb_coords[ax]->setValue (mo->position()[ax]);
+			mo->position().apply ([&](Axis ax, double value)
+			{
+				dsb_coords[ax]->setValue (value);
+			});
 
 			defaultMatrix = mo->transform();
 		}
@@ -380,8 +384,10 @@
 			{
 				Vertex v;
 
-				for_axes (ax)
-					v[ax] = dlg.dsb_coords[ (i * 3) + ax]->value();
+				v.apply ([&](Axis ax, double& value)
+				{
+					value = dlg.dsb_coords[(i * 3) + ax]->value();
+				});
 
 				obj->setVertex (i, v);
 			}
@@ -396,9 +402,7 @@
 		case LDObject::EVertex:
 		{
 			LDVertex* vert = initObj<LDVertex> (obj);
-
-			for_axes (ax)
-				vert->pos[ax] = dlg.dsb_coords[ax]->value();
+			vert->pos.apply ([&](Axis ax, double& value) { value = dlg.dsb_coords[ax]->value(); });
 		}
 		break;
 
--- a/src/basics.cc	Wed Apr 23 15:39:42 2014 +0300
+++ b/src/basics.cc	Wed Apr 23 18:25:09 2014 +0300
@@ -27,148 +27,79 @@
 #include "ldObject.h"
 #include "ldDocument.h"
 
-// =============================================================================
-//
-Vertex::Vertex (double x, double y, double z)
-{
-	m_coords[X] = x;
-	m_coords[Y] = y;
-	m_coords[Z] = z;
-}
+Vertex::Vertex() :
+	QVector3D() {}
+
+Vertex::Vertex (const QVector3D& a) :
+	QVector3D (a) {}
 
-// =============================================================================
-//
-void Vertex::move (const Vertex& other)
+Vertex::Vertex (qreal xpos, qreal ypos, qreal zpos) :
+	QVector3D(xpos, ypos, zpos) {}
+
+
+void Vertex::transform (const Matrix& matr, const Vertex& pos)
 {
-	for_axes (ax)
-		m_coords[ax] += other[ax];
-}
-
-// =============================================================================
-//
-double Vertex::distanceTo (const Vertex& other) const
-{
-	double dx = abs (x() - other.x());
-	double dy = abs (y() - other.y());
-	double dz = abs (z() - other.z());
-	return sqrt ((dx * dx) + (dy * dy) + (dz * dz));
+	double x2 = (matr[0] * x()) + (matr[1] * y()) + (matr[2] * z()) + pos.x();
+	double y2 = (matr[3] * x()) + (matr[4] * y()) + (matr[5] * z()) + pos.y();
+	double z2 = (matr[6] * x()) + (matr[7] * y()) + (matr[8] * z()) + pos.z();
+	setX (x2);
+	setY (y2);
+	setZ (z2);
 }
 
-// =============================================================================
-//
-Vertex Vertex::midpoint (const Vertex& other)
+void Vertex::apply (ApplyFunction func)
 {
-	Vertex mid;
-
-	for_axes (ax)
-		mid[ax] = (getCoordinate (ax) + other[ax]) / 2;
-
-	return mid;
+	double newX = x(), newY = y(), newZ = z();
+	func (X, newX);
+	func (Y, newY);
+	func (Z, newZ);
+	*this = Vertex (newX, newY, newZ);
 }
 
-// =============================================================================
-//
-QString Vertex::toString (bool mangled) const
+void Vertex::apply (ApplyConstFunction func) const
 {
-	QString formatstr = "%1 %2 %3";
-
-	if (mangled)
-		formatstr = "(%1, %2, %3)";
-
-	return format (formatstr, x(), y(), z());
-}
-
-// =============================================================================
-//
-void Vertex::transform (const Matrix& matr, const Vertex& pos)
-{
-	double x2 = (matr[0] * x()) + (matr[1] * y()) + (matr[2] * z()) + pos[X];
-	double y2 = (matr[3] * x()) + (matr[4] * y()) + (matr[5] * z()) + pos[Y];
-	double z2 = (matr[6] * x()) + (matr[7] * y()) + (matr[8] * z()) + pos[Z];
-
-	x() = x2;
-	y() = y2;
-	z() = z2;
-}
-
-// =============================================================================
-//
-Vertex Vertex::operator-() const
-{
-	return Vertex (-m_coords[X], -m_coords[Y], -m_coords[Z]);
+	func (X, x());
+	func (Y, y());
+	func (Z, z());
 }
 
-// =============================================================================
-//
-bool Vertex::operator!= (const Vertex& other) const
+double Vertex::operator[] (Axis ax) const
 {
-	return not operator== (other);
-}
-
-// =============================================================================
-//
-bool Vertex::operator== (const Vertex& other) const
-{
-	return getCoordinate (X) == other[X] &&
-		   getCoordinate (Y) == other[Y] &&
-		   getCoordinate (Z) == other[Z];
-}
+	switch (ax)
+	{
+		case X: return x();
+		case Y: return y();
+		case Z: return z();
+	}
 
-// =============================================================================
-//
-Vertex& Vertex::operator/= (const double d)
-{
-	for_axes (ax)
-		m_coords[ax] /= d;
-
-	return *this;
-}
-
-// =============================================================================
-//
-Vertex Vertex::operator/ (const double d) const
-{
-	Vertex other (*this);
-	return other /= d;
+	assert (false);
+	return 0.0;
 }
 
-// =============================================================================
-//
-Vertex& Vertex::operator+= (const Vertex& other)
+void Vertex::setCoordinate (Axis ax, qreal value)
 {
-	move (other);
-	return *this;
-}
-
-// =============================================================================
-//
-Vertex Vertex::operator+ (const Vertex& other) const
-{
-	Vertex newvert (*this);
-	newvert.move (other);
-	return newvert;
+	switch (ax)
+	{
+		case X: setX (value); break;
+		case Y: setY (value); break;
+		case Z: setZ (value); break;
+	}
 }
 
-// =============================================================================
-//
-int Vertex::operator< (const Vertex& other) const
+QString Vertex::toString (bool mangled) const
 {
-	if (operator== (other))
-		return false;
-
-	if (getCoordinate (X) < other[X])
-		return true;
+	if (mangled)
+		return format ("(%1, %2, %3)", x(), y(), z());
 
-	if (getCoordinate (X) > other[X])
-		return false;
+	return format ("%1 %2 %3", x(), y(), z());
+}
 
-	if (getCoordinate (Y) < other[Y])
-		return true;
-
-	if (getCoordinate (Y) > other[Y])
-		return false;
-
-	return getCoordinate (Z) < other[Z];
+bool Vertex::operator< (const Vertex& other) const
+{
+	if (x() != other.x()) return x() < other.x();
+	if (y() != other.y()) return y() < other.y();
+	if (z() != other.z()) return z() < other.z();
+	return false;
 }
 
 // =============================================================================
@@ -351,12 +282,12 @@
 //
 void LDBoundingBox::calcVertex (const Vertex& vertex)
 {
-	for_axes (ax)
-	{
-		m_vertex0[ax] = min (vertex[ax], m_vertex0[ax]);
-		m_vertex1[ax] = max (vertex[ax], m_vertex1[ax]);
-	}
-
+	m_vertex0.setX (min (vertex.x(), m_vertex0.x()));
+	m_vertex0.setY (min (vertex.y(), m_vertex0.y()));
+	m_vertex0.setZ (min (vertex.z(), m_vertex0.z()));
+	m_vertex1.setX (max (vertex.x(), m_vertex1.x()));
+	m_vertex1.setY (max (vertex.y(), m_vertex1.y()));
+	m_vertex1.setZ (max (vertex.z(), m_vertex1.z()));
 	setEmpty (false);
 }
 
@@ -364,8 +295,8 @@
 //
 void LDBoundingBox::reset()
 {
-	m_vertex0[X] = m_vertex0[Y] = m_vertex0[Z] = 10000.0;
-	m_vertex1[X] = m_vertex1[Y] = m_vertex1[Z] = -10000.0;
+	m_vertex0 = Vertex (10000.0, 10000.0, 10000.0);
+	m_vertex1 = Vertex (-10000.0, -10000.0, -10000.0);
 	setEmpty (true);
 }
 
@@ -373,9 +304,9 @@
 //
 double LDBoundingBox::longestMeasurement() const
 {
-	double xscale = (m_vertex0[X] - m_vertex1[X]);
-	double yscale = (m_vertex0[Y] - m_vertex1[Y]);
-	double zscale = (m_vertex0[Z] - m_vertex1[Z]);
+	double xscale = (m_vertex0.x() - m_vertex1.x());
+	double yscale = (m_vertex0.y() - m_vertex1.y());
+	double zscale = (m_vertex0.z() - m_vertex1.z());
 	double size = zscale;
 
 	if (xscale > yscale)
@@ -386,10 +317,10 @@
 	elif (yscale > zscale)
 		size = yscale;
 
-	if (abs (size) >= 2.0f)
+	if (abs (size) >= 2.0)
 		return abs (size / 2);
 
-	return 1.0f;
+	return 1.0;
 }
 
 // =============================================================================
@@ -397,7 +328,7 @@
 Vertex LDBoundingBox::center() const
 {
 	return Vertex (
-		(m_vertex0[X] + m_vertex1[X]) / 2,
-		(m_vertex0[Y] + m_vertex1[Y]) / 2,
-		(m_vertex0[Z] + m_vertex1[Z]) / 2);
+		(m_vertex0.x() + m_vertex1.x()) / 2,
+		(m_vertex0.y() + m_vertex1.y()) / 2,
+		(m_vertex0.z() + m_vertex1.z()) / 2);
 }
--- a/src/basics.h	Wed Apr 23 15:39:42 2014 +0300
+++ b/src/basics.h	Wed Apr 23 18:25:09 2014 +0300
@@ -21,6 +21,7 @@
 #include <QObject>
 #include <QStringList>
 #include <QMetaType>
+#include <QVector3D>
 #include "macros.h"
 
 class LDObject;
@@ -49,9 +50,35 @@
 // =============================================================================
 //
 class LDObject;
+class Matrix;
 using LDObjectList = QList<LDObject*>;
 
 //!
+//! Derivative of QVector3D: this class is used for the vertices.
+//!
+class Vertex : public QVector3D
+{
+public:
+	using ApplyFunction = std::function<void (Axis, double&)>;
+	using ApplyConstFunction = std::function<void (Axis, double)>;
+
+	Vertex();
+	Vertex (const QVector3D& a);
+	Vertex (qreal xpos, qreal ypos, qreal zpos);
+
+	void	apply (ApplyFunction func);
+	void	apply (ApplyConstFunction func) const;
+	QString	toString (bool mangled = false) const;
+	void	transform (const Matrix& matr, const Vertex& pos);
+	void	setCoordinate (Axis ax, qreal value);
+
+	bool	operator< (const Vertex& other) const;
+	double	operator[] (Axis ax) const;
+};
+
+Q_DECLARE_METATYPE (Vertex)
+
+//!
 //! \brief A mathematical 3 x 3 matrix
 //!
 class Matrix
@@ -139,155 +166,6 @@
 };
 
 //!
-//! \brief A vertex in 3D space
-//!
-//! Contains a single point in 3D space. Not to be confused with
-//! LDVertex, which is a vertex used in an LDraw part file.
-//!
-//! This also sees use as a position vector.
-//!
-class Vertex
-{
-	public:
-		//! Constructs a zero vertex
-		Vertex() :
-			m_coords{0, 0, 0} {}
-
-		//! Constructs a vertex with the given \c x, \c y and \c z.
-		Vertex (double x, double y, double z);
-
-		//! \returns the distance from this vertex to \c other
-		double			distanceTo (const Vertex& other) const;
-
-		//! \returns the vertex at the midpoint between this and \c other
-		Vertex			midpoint (const Vertex& other);
-
-		//! Moves this vertex using \param other as a position vector.
-		void			move (const Vertex& other);
-
-		//! Yields a string representation of the vertex. The string returned
-		//! can possibly be mangled.
-		//! - As mangled: {1.5, 2.8, 3.14}
-		//! - Without mangling: 1.5 2.8 3.14
-		//!
-		//! The mangled version is suitable for printing to the user, the
-		//! non-mangled one is used when writing the vertex to LDraw files.
-		//!
-		//! \returns a string representation of this vertex
-		//! \param mangled whether to return a mangled representation or not
-		QString			toString (bool mangled) const;
-
-		//! Transforms this vertex with \c matr as transformation matrix
-		//! and \c pos as the position column of the 4x4 matrix.
-		void			transform (const Matrix& matr, const Vertex& pos);
-
-		//! An operator overload for \c move().
-		Vertex&			operator+= (const Vertex& other);
-
-		//! An operator overload for \c move(), using a temporary vertex.
-		Vertex			operator+ (const Vertex& other) const;
-
-		//! Divides all values by \c d.
-		Vertex			operator/ (const double d) const;
-
-		//! Divides all values by \c d.
-		Vertex&			operator/= (const double d);
-
-		//! Checks whether this vertex has the same values as \c other.
-		bool			operator== (const Vertex& other) const;
-
-		//! Checks whether this vertex has different values than \c other.
-		bool			operator!= (const Vertex& other) const;
-
-		//! \returns a negated version the vertex
-		Vertex			operator-() const;
-
-		//! \returns whether the vertex has lesser values than \c other.
-		int				operator< (const Vertex& other) const;
-
-		//! An operator overload for \c getCoordinate().
-		inline double& operator[] (const Axis ax)
-		{
-			return getCoordinate ((int) ax);
-		}
-
-		//! An operator overload for \c getCoordinate() const.
-		inline const double& operator[] (const Axis ax) const
-		{
-			return getCoordinate ((int) ax);
-		}
-
-		//! An operator overload for \c getCoordinate().
-		inline double& operator[] (const int ax)
-		{
-			return getCoordinate (ax);
-		}
-
-		//! An operator overload for \c getCoordinate() const.
-		inline const double& operator[] (const int ax) const
-		{
-			return getCoordinate (ax);
-		}
-
-		//! \returns a mutable reference for the coordinate designated by \param n.
-		inline double& getCoordinate (int n)
-		{
-			return m_coords[n];
-		}
-
-		//! An overload of \c getCoordinate for const vertices.
-		//! \returns a const reference for the coordinate designated by \param n.
-		inline const double& getCoordinate (int n) const
-		{
-			return m_coords[n];
-		}
-
-		//! \returns a mutable reference to X.
-		inline double& x()
-		{
-			return m_coords[X];
-		}
-
-		//! An overload of \c x() for const vertices.
-		//! \returns a const reference to X.
-		inline const double& x() const
-		{
-			return m_coords[X];
-		}
-
-		//! \returns a mutable reference to Y.
-		inline double& y()
-		{
-			return m_coords[Y];
-		}
-
-		//! An overload of \c y() for const vertices.
-		//! \returns a const reference to Y.
-		inline const double& y() const
-		{
-			return m_coords[Y];
-		}
-
-		//! \returns a mutable reference to Z.
-		inline double& z()
-		{
-			return m_coords[Z];
-		}
-
-		//! An overload of \c z() for const vertices.
-		//! \returns a const reference to Z.
-		inline const double& z() const
-		{
-			return m_coords[Z];
-		}
-
-	private:
-		double m_coords[3];
-};
-
-Q_DECLARE_METATYPE (Vertex)
-
-//!
 //! Defines a bounding box that encompasses a given set of objects.
 //! vertex0 is the minimum vertex, vertex1 is the maximum vertex.
 //
--- a/src/format.h	Wed Apr 23 15:39:42 2014 +0300
+++ b/src/format.h	Wed Apr 23 18:25:09 2014 +0300
@@ -38,7 +38,7 @@
 		StringFormatArg (long a) : m_text (QString::number (a)) {}
 		StringFormatArg (const float& a) : m_text (QString::number (a)) {}
 		StringFormatArg (const double& a) : m_text (QString::number (a)) {}
-		StringFormatArg (const Vertex& a) : m_text (a.toString (false)) {}
+		StringFormatArg (const Vertex& a) : m_text (a.toString()) {}
 		StringFormatArg (const Matrix& a) : m_text (a.toString()) {}
 		StringFormatArg (const char* a) : m_text (a) {}
 
--- a/src/glRenderer.cc	Wed Apr 23 15:39:42 2014 +0300
+++ b/src/glRenderer.cc	Wed Apr 23 18:25:09 2014 +0300
@@ -271,10 +271,10 @@
 
 	for (int i = 0; i < 3; ++i)
 	{
-		for (int j = 0; j < 3; ++j)
+		for_axes (ax)
 		{
-			axesdata[(i * 6) + j] = g_GLAxes[i].vert.getCoordinate (j);
-			axesdata[(i * 6) + 3 + j] = -g_GLAxes[i].vert.getCoordinate (j);
+			axesdata[(i * 6) + ax] = g_GLAxes[i].vert[ax];
+			axesdata[(i * 6) + 3 + ax] = -g_GLAxes[i].vert[ax];
 		}
 
 		for (int j = 0; j < 2; ++j)
@@ -525,9 +525,9 @@
 	roundToDecimals (cy, 4);
 
 	// Create the vertex from the coordinates
-	pos3d[axisX] = cx;
-	pos3d[axisY] = cy;
-	pos3d[3 - axisX - axisY] = getDepthValue();
+	pos3d.setCoordinate (axisX, cx);
+	pos3d.setCoordinate (axisY, cy);
+	pos3d.setCoordinate ((Axis) (3 - axisX - axisY), getDepthValue());
 	return pos3d;
 }
 
@@ -552,9 +552,9 @@
 	const double z = pos3d.z();
 
 	Vertex transformed;
-	transformed[X] = (m[0] * x) + (m[1] * y) + (m[2] * z) + m[3];
-	transformed[Y] = (m[4] * x) + (m[5] * y) + (m[6] * z) + m[7];
-	transformed[Z] = (m[8] * x) + (m[9] * y) + (m[10] * z) + m[11];
+	transformed.setX ((m[0] * x) + (m[1] * y) + (m[2] * z) + m[3]);
+	transformed.setY ((m[4] * x) + (m[5] * y) + (m[6] * z) + m[7]);
+	transformed.setZ ((m[8] * x) + (m[9] * y) + (m[10] * z) + m[11]);
 
 	double rx = (((transformed[axisX] * negXFac) + m_virtWidth + pan (X)) * m_width) / (2 * m_virtWidth);
 	double ry = (((transformed[axisY] * negYFac) - m_virtHeight + pan (Y)) * m_height) / (2 * m_virtHeight);
@@ -691,7 +691,7 @@
 
 						if (gl_linelengths)
 						{
-							const QString label = QString::number (poly3d[i].distanceTo (poly3d[j]));
+							const QString label = QString::number ((poly3d[j] - poly3d[i]).length());
 							QPoint origin = QLineF (poly[i], poly[j]).pointAt (0.5).toPoint();
 							paint.drawText (origin, label);
 						}
@@ -737,14 +737,14 @@
 				for (int i = 0; i < segs; ++i)
 				{
 					Vertex v = g_origin;
-					v[relX] = m_drawedVerts[0][relX] + (cos (i * angleUnit) * dist0);
-					v[relY] = m_drawedVerts[0][relY] + (sin (i * angleUnit) * dist0);
+					v.setCoordinate (relX, m_drawedVerts[0][relX] + (cos (i * angleUnit) * dist0));
+					v.setCoordinate (relY, m_drawedVerts[0][relY] + (sin (i * angleUnit) * dist0));
 					verts << v;
 
 					if (dist1 != -1)
 					{
-						v[relX] = m_drawedVerts[0][relX] + (cos (i * angleUnit) * dist1);
-						v[relY] = m_drawedVerts[0][relY] + (sin (i * angleUnit) * dist1);
+						v.setCoordinate (relX, m_drawedVerts[0][relX] + (cos (i * angleUnit) * dist1));
+						v.setCoordinate (relY, m_drawedVerts[0][relY] + (sin (i * angleUnit) * dist1));
 						verts2 << v;
 					}
 				}
@@ -1510,9 +1510,9 @@
 					y0 = m_drawedVerts[0][relY];
 
 				Vertex templ;
-				templ[relX] = x0;
-				templ[relY] = y0;
-				templ[relZ] = getDepthValue();
+				templ.setCoordinate (relX, x0);
+				templ.setCoordinate (relY, y0);
+				templ.setCoordinate (relZ, getDepthValue());
 
 				// Calculate circle coords
 				makeCircle (segs, divs, dist0, c0);
@@ -1522,14 +1522,14 @@
 				{
 					Vertex v0, v1, v2, v3;
 					v0 = v1 = v2 = v3 = templ;
-					v0[relX] += c0[i].x1();
-					v0[relY] += c0[i].y1();
-					v1[relX] += c0[i].x2();
-					v1[relY] += c0[i].y2();
-					v2[relX] += c1[i].x2();
-					v2[relY] += c1[i].y2();
-					v3[relX] += c1[i].x1();
-					v3[relY] += c1[i].y1();
+					v0.setCoordinate (relX, v0[relX] + c0[i].x1());
+					v0.setCoordinate (relY, v0[relY] + c0[i].y1());
+					v1.setCoordinate (relX, v1[relX] + c0[i].x2());
+					v1.setCoordinate (relY, v1[relY] + c0[i].y2());
+					v2.setCoordinate (relX, v2[relX] + c1[i].x2());
+					v2.setCoordinate (relY, v2[relY] + c1[i].y2());
+					v3.setCoordinate (relX, v3[relX] + c1[i].x1());
+					v3.setCoordinate (relY, v3[relY] + c1[i].y1());
 
 					LDQuad* q = new LDQuad (v0, v1, v2, v3);
 					q->setColor (maincolor);
@@ -1725,10 +1725,10 @@
 		negYFac = g_FixedCameras[cam].negY ? -1 : 1;
 
 	info.v0 = info.v1 = g_origin;
-	info.v0[x2d] = - (info.ox * info.lw * negXFac) / img->width();
-	info.v0[y2d] = (info.oy * info.lh * negYFac) / img->height();
-	info.v1[x2d] = info.v0[x2d] + info.lw;
-	info.v1[y2d] = info.v0[y2d] + info.lh;
+	info.v0.setCoordinate (x2d, -(info.ox * info.lw * negXFac) / img->width());
+	info.v0.setCoordinate (y2d, (info.oy * info.lh * negYFac) / img->height());
+	info.v1.setCoordinate (x2d, info.v0[x2d] + info.lw);
+	info.v1.setCoordinate (y2d, info.v0[y2d] + info.lh);
 
 	// Set alpha of all pixels to 0.5
 	for (long i = 0; i < img->width(); ++i)
@@ -1933,16 +1933,16 @@
 			   az = (Axis) (3 - ax - ay);
 
 	for (int i = 0; i < 4; ++i)
-		m_rectverts[i][az] = getDepthValue();
+		m_rectverts[i].setCoordinate (az, getDepthValue());
 
-	m_rectverts[0][ax] = v0[ax];
-	m_rectverts[0][ay] = v0[ay];
-	m_rectverts[1][ax] = v1[ax];
-	m_rectverts[1][ay] = v0[ay];
-	m_rectverts[2][ax] = v1[ax];
-	m_rectverts[2][ay] = v1[ay];
-	m_rectverts[3][ax] = v0[ax];
-	m_rectverts[3][ay] = v1[ay];
+	m_rectverts[0].setCoordinate (ax, v0[ax]);
+	m_rectverts[0].setCoordinate (ay, v0[ay]);
+	m_rectverts[1].setCoordinate (ax, v1[ax]);
+	m_rectverts[1].setCoordinate (ay, v0[ay]);
+	m_rectverts[2].setCoordinate (ax, v1[ax]);
+	m_rectverts[2].setCoordinate (ay, v1[ay]);
+	m_rectverts[3].setCoordinate (ax, v0[ax]);
+	m_rectverts[3].setCoordinate (ay, v1[ay]);
 }
 
 // =============================================================================
--- a/src/ldDocument.cc	Wed Apr 23 15:39:42 2014 +0300
+++ b/src/ldDocument.cc	Wed Apr 23 18:25:09 2014 +0300
@@ -819,10 +819,7 @@
 static Vertex parseVertex (QStringList& s, const int n)
 {
 	Vertex v;
-
-	for_axes (ax)
-		v[ax] = s[n + ax].toDouble();
-
+	v.apply ([&] (Axis ax, double& a) { a = s[n + ax].toDouble(); });
 	return v;
 }
 
@@ -892,10 +889,7 @@
 
 						LDVertex* obj = new LDVertex;
 						obj->setColor (tokens[3].toLong());
-
-						for_axes (ax)
-							obj->pos[ax] = tokens[4 + ax].toDouble(); // 4 - 6
-
+						obj->pos.apply ([&](Axis ax, double& value) { value = tokens[4 + ax].toDouble(); });
 						return obj;
 					} elif (tokens[2] == "OVERLAY")
 					{
--- a/src/ldObject.cc	Wed Apr 23 15:39:42 2014 +0300
+++ b/src/ldObject.cc	Wed Apr 23 18:25:09 2014 +0300
@@ -73,7 +73,7 @@
 void LDObject::setVertexCoord (int i, Axis ax, double value)
 {
 	Vertex v = vertex (i);
-	v[ax] = value;
+	v.setCoordinate (ax, value);
 	setVertex (i, v);
 }
 
--- a/src/ldObject.h	Wed Apr 23 15:39:42 2014 +0300
+++ b/src/ldObject.h	Wed Apr 23 18:25:09 2014 +0300
@@ -263,7 +263,14 @@
 		void setCoordinate (const Axis ax, double value)
 		{
 			Vertex v = position();
-			v[ax] = value;
+
+			switch (ax)
+			{
+				case X: v.setX (value); break;
+				case Y: v.setY (value); break;
+				case Z: v.setZ (value); break;
+			}
+
 			setPosition (v);
 		}
 
--- a/src/miscallenous.cc	Wed Apr 23 15:39:42 2014 +0300
+++ b/src/miscallenous.cc	Wed Apr 23 18:25:09 2014 +0300
@@ -277,9 +277,9 @@
 		(ui.worldPoint->isChecked())  ? EWorldOrigin :
 		ECustomPoint;
 
-	edit_customrotpoint.x() = ui.customX->value();
-	edit_customrotpoint.y() = ui.customY->value();
-	edit_customrotpoint.z() = ui.customZ->value();
+	edit_customrotpoint.setX (ui.customX->value());
+	edit_customrotpoint.setY (ui.customY->value());
+	edit_customrotpoint.setZ (ui.customZ->value());
 }
 
 // =============================================================================
@@ -301,3 +301,34 @@
 	assert (decimals >= 0 && decimals < (signed) (sizeof g_e10 / sizeof *g_e10));
 	a = round (a * g_e10[decimals]) / g_e10[decimals];
 }
+
+// =============================================================================
+//
+void applyToMatrix (Matrix& a, ApplyToMatrixFunction func)
+{
+	for (int i = 0; i < 9; ++i)
+		func (i, a[i]);
+}
+
+// =============================================================================
+//
+void applyToMatrix (const Matrix& a, ApplyToMatrixConstFunction func)
+{
+	for (int i = 0; i < 9; ++i)
+		func (i, a[i]);
+}
+
+// =============================================================================
+//
+double getCoordinate (const Vertex& a, Axis ax)
+{
+	switch (ax)
+	{
+		case X: return a.x();
+		case Y: return a.y();
+		case Z: return a.z();
+	}
+
+	assert (false);
+	return 0.0;
+}
--- a/src/miscallenous.h	Wed Apr 23 15:39:42 2014 +0300
+++ b/src/miscallenous.h	Wed Apr 23 18:25:09 2014 +0300
@@ -18,6 +18,7 @@
 
 #pragma once
 #include <QVector>
+#include <functional>
 #include "configuration.h"
 #include "main.h"
 #include "basics.h"
@@ -37,8 +38,14 @@
 // Simplifies the given fraction.
 void simplify (int& numer, int& denom);
 
+using ApplyToMatrixFunction = std::function<void (int, double&)>;
+using ApplyToMatrixConstFunction = std::function<void (int, double)>;
+
 void roundToDecimals (double& a, int decimals);
+void applyToMatrix (Matrix& a, ApplyToMatrixFunction func);
+void applyToMatrix (const Matrix& a, ApplyToMatrixConstFunction func);
 
+double getCoordinate (const Vertex& a, Axis ax);
 QString join (QList< StringFormatArg > vals, QString delim = " ");
 
 // Grid stuff
--- a/src/primitives.cc	Wed Apr 23 15:39:42 2014 +0300
+++ b/src/primitives.cc	Wed Apr 23 18:25:09 2014 +0300
@@ -518,9 +518,9 @@
 		elif (type == Cone)
 		{
 			v1 = Vertex (v0[X] * (num + 1), 0.0f, v0[Z] * (num + 1));
-			v0[X] *= num;
-			v0[Y] = 1.0f;
-			v0[Z] *= num;
+			v0.setX (v0.x() * num);
+			v0.setY (1.0);
+			v0.setZ (v0.z() * num);
 		}
 
 		LDCondLine* line = new LDCondLine;

mercurial