LDVertexObject stuff (ultimately not worth it)

Tue, 22 Sep 2015 00:59:21 +0300

author
Teemu Piippo <crimsondusk64@gmail.com>
date
Tue, 22 Sep 2015 00:59:21 +0300
changeset 996
9ecc878c7dea
parent 995
7986584e7498
child 1007
998f1a04ef03

LDVertexObject stuff (ultimately not worth it)

src/addObjectDialog.cpp file | annotate | diff | comparison | revisions
src/basics.cpp file | annotate | diff | comparison | revisions
src/basics.h file | annotate | diff | comparison | revisions
src/colors.cpp file | annotate | diff | comparison | revisions
src/colors.h file | annotate | diff | comparison | revisions
src/dialogs/colorselector.cpp file | annotate | diff | comparison | revisions
src/editmodes/circleMode.cpp file | annotate | diff | comparison | revisions
src/editmodes/drawMode.cpp file | annotate | diff | comparison | revisions
src/editmodes/magicWandMode.cpp file | annotate | diff | comparison | revisions
src/editmodes/magicWandMode.h file | annotate | diff | comparison | revisions
src/glCompiler.cpp file | annotate | diff | comparison | revisions
src/glRenderer.cpp file | annotate | diff | comparison | revisions
src/ldDocument.cpp file | annotate | diff | comparison | revisions
src/ldObject.cpp file | annotate | diff | comparison | revisions
src/ldObject.h file | annotate | diff | comparison | revisions
src/ldObjectMath.cpp file | annotate | diff | comparison | revisions
src/main.cpp file | annotate | diff | comparison | revisions
src/mainwindow.cpp file | annotate | diff | comparison | revisions
src/toolsets/algorithmtoolset.cpp file | annotate | diff | comparison | revisions
--- a/src/addObjectDialog.cpp	Sun Sep 06 20:45:51 2015 +0300
+++ b/src/addObjectDialog.cpp	Tue Sep 22 00:59:21 2015 +0300
@@ -147,39 +147,41 @@
 
 	switch (type)
 	{
-		case OBJ_Line:
-		case OBJ_CondLine:
-		case OBJ_Triangle:
-		case OBJ_Quad:
-			// Apply coordinates
-			if (obj)
-			{
-				for (int i = 0; i < coordCount / 3; ++i)
-				{
-					obj->vertex (i).apply ([&](Axis ax, double value)
-					{
-						dsb_coords[(i * 3) + ax]->setValue (value);
-					});
-				}
-			}
-			break;
+	case OBJ_Line:
+	case OBJ_CondLine:
+	case OBJ_Triangle:
+	case OBJ_Quad:
+		// Apply coordinates
+		if (obj)
+		{
+			LDVertexObject* vo = static_cast<LDVertexObject*> (obj);
 
-		case OBJ_Comment:
-			layout->addWidget (le_comment, 0, 1);
-			break;
-
-		case OBJ_Bfc:
-			layout->addWidget (rb_bfcType, 0, 1);
-			break;
+			for (int i = 0; i < coordCount / 3; ++i)
+			{
+				vo->vertex (i).apply ([&](Axis ax, double value)
+				{
+					dsb_coords[(i * 3) + ax]->setValue (value);
+				});
+			}
+		}
+		break;
 
-		case OBJ_Subfile:
-			layout->addWidget (tw_subfileList, 1, 1, 1, 2);
-			layout->addWidget (lb_subfileName, 2, 1);
-			layout->addWidget (le_subfileName, 2, 2);
-			break;
+	case OBJ_Comment:
+		layout->addWidget (le_comment, 0, 1);
+		break;
+
+	case OBJ_Bfc:
+		layout->addWidget (rb_bfcType, 0, 1);
+		break;
 
-		default:
-			break;
+	case OBJ_Subfile:
+		layout->addWidget (tw_subfileList, 1, 1, 1, 2);
+		layout->addWidget (lb_subfileName, 2, 1);
+		layout->addWidget (le_subfileName, 2, 2);
+		break;
+
+	default:
+		break;
 	}
 
 	if (defaults->hasMatrix())
@@ -197,7 +199,7 @@
 				dsb_coords[ax]->setValue (value);
 			});
 
-			defaultMatrix = mo->transform();
+			defaultMatrix = mo->transformationMatrix();
 		}
 
 		le_matrix->setText (defaultMatrix.toString());
@@ -222,6 +224,7 @@
 	QWidget::connect (bbx_buttons, SIGNAL (accepted()), this, SLOT (accept()));
 	QWidget::connect (bbx_buttons, SIGNAL (rejected()), this, SLOT (reject()));
 	layout->addWidget (bbx_buttons, 5, 0, 1, 4);
+	defaults->destroy();
 	setLayout (layout);
 	setWindowTitle (format (tr ("Edit %1"), typeName));
 	setWindowIcon (icon);
@@ -335,7 +338,8 @@
 			if (not obj)
 				obj = LDObject::getDefault (type);
 
-			for (int i = 0; i < obj->numVertices(); ++i)
+			LDVertexObject* vo = static_cast<LDVertexObject*> (obj);
+			for (int i = 0; i < vo->numVertices(); ++i)
 			{
 				Vertex v;
 
@@ -344,7 +348,7 @@
 					value = dlg.dsb_coords[(i * 3) + ax]->value();
 				});
 
-				obj->setVertex (i, v);
+				vo->setVertex (i, v);
 			}
 		} break;
 
@@ -376,7 +380,7 @@
 			for_axes (ax)
 				ref->setCoordinate (ax, dlg.dsb_coords[ax]->value());
 
-			ref->setTransform (transform);
+			ref->setTransformationMatrix (transform);
 			ref->setFileInfo (file);
 		} break;
 
--- a/src/basics.cpp	Sun Sep 06 20:45:51 2015 +0300
+++ b/src/basics.cpp	Tue Sep 22 00:59:21 2015 +0300
@@ -101,6 +101,11 @@
 	return false;
 }
 
+unsigned int qHash (const Vertex& vertex)
+{
+	return qHash (vertex.toString());
+}
+
 // =============================================================================
 //
 Matrix::Matrix (double vals[])
@@ -221,26 +226,21 @@
 //
 void LDBoundingBox::calcObject (LDObject* obj)
 {
-	switch (obj->type())
+	LDSubfile* ref;
+
+	if (obj->hasVertices())
 	{
-	case OBJ_Line:
-	case OBJ_Triangle:
-	case OBJ_Quad:
-	case OBJ_CondLine:
-		for (int i = 0; i < obj->numVertices(); ++i)
-			calcVertex (obj->vertex (i));
-		break;
-
-	case OBJ_Subfile:
-		for (LDObject* it : static_cast<LDSubfile*> (obj)->inlineContents (true, false))
+		LDVertexObject* vo = static_cast<LDVertexObject*> (obj);
+		for (int i = 0; i < vo->numVertices(); ++i)
+			calcVertex (vo->vertex (i));
+	}
+	else if ((ref = dynamic_cast<LDSubfile*> (obj)) != nullptr)
+	{
+		for (LDObject* it : ref->inlineContents (true, false))
 		{
 			calcObject (it);
 			it->destroy();
 		}
-		break;
-
-	default:
-		break;
 	}
 }
 
--- a/src/basics.h	Sun Sep 06 20:45:51 2015 +0300
+++ b/src/basics.h	Tue Sep 22 00:59:21 2015 +0300
@@ -74,6 +74,7 @@
 	double	operator[] (Axis ax) const;
 };
 
+unsigned int qHash (const Vertex& vertex);
 Q_DECLARE_METATYPE (Vertex)
 
 //
--- a/src/colors.cpp	Sun Sep 06 20:45:51 2015 +0300
+++ b/src/colors.cpp	Tue Sep 22 00:59:21 2015 +0300
@@ -33,7 +33,7 @@
 
 static ColorDataEntry ColorData[512];
 
-void InitColors()
+void initColors()
 {
 	print ("Initializing color information.\n");
 
@@ -108,7 +108,7 @@
 QColor LDColor::edgeColor() const
 {
 	if (isDirect())
-		return Luma (faceColor()) < 48 ? Qt::white : Qt::black;
+		return luma() < 48 ? Qt::white : Qt::black;
 	else if (isLDConfigColor())
 		return ColorData[index()].edgeColor;
 	else
@@ -117,12 +117,12 @@
 
 int LDColor::luma() const
 {
-	return Luma (faceColor());
+	return ::luma (faceColor());
 }
 
 int LDColor::edgeLuma() const
 {
-	return Luma (edgeColor());
+	return ::luma (edgeColor());
 }
 
 qint32 LDColor::index() const
@@ -143,16 +143,11 @@
 	return index() >= 0x02000000;
 }
 
-int Luma (const QColor& col)
+int luma (const QColor& col)
 {
 	return (0.2126f * col.red()) + (0.7152f * col.green()) + (0.0722f * col.blue());
 }
 
-int CountLDConfigColors()
-{
-	return countof (ColorData);
-}
-
 void parseLDConfig()
 {
 	QFile* fp = OpenLDrawFile ("LDConfig.ldr", false);
--- a/src/colors.h	Sun Sep 06 20:45:51 2015 +0300
+++ b/src/colors.h	Tue Sep 22 00:59:21 2015 +0300
@@ -82,9 +82,8 @@
 	int m_pos;
 };
 
-void InitColors();
-int Luma (const QColor& col);
-int CountLDConfigColors();
+void initColors();
+int luma (const QColor& col);
 void parseLDConfig();
 
 enum
--- a/src/dialogs/colorselector.cpp	Sun Sep 06 20:45:51 2015 +0300
+++ b/src/dialogs/colorselector.cpp	Tue Sep 22 00:59:21 2015 +0300
@@ -59,7 +59,7 @@
 				color.setAlphaF (m_config->mainColorAlpha());
 			}
 
-			QString color2name (Luma (color) < 80 ? "white" : "black");
+			QString color2name (luma (color) < 80 ? "white" : "black");
 			button->setAutoFillBackground (true);
 			button->setStyleSheet (format ("background-color: rgba(%1, %2, %3, %4); color: %5",
 				color.red(), color.green(), color.blue(), color.alpha(), color2name));
--- a/src/editmodes/circleMode.cpp	Sun Sep 06 20:45:51 2015 +0300
+++ b/src/editmodes/circleMode.cpp	Tue Sep 22 00:59:21 2015 +0300
@@ -110,7 +110,7 @@
 			refFile = GetPrimitive (::Ring, segments, divisions, cmp.num);
 			LDSubfile* ref = LDSpawn<LDSubfile>();
 			ref->setFileInfo (refFile);
-			ref->setTransform (getCircleDrawMatrix (cmp.scale));
+			ref->setTransformationMatrix (getCircleDrawMatrix (cmp.scale));
 			ref->setPosition (m_drawedVerts[0]);
 			ref->setColor (MainColor);
 			objs << ref;
@@ -163,7 +163,7 @@
 	{
 		LDSubfile* ref = LDSpawn<LDSubfile>();
 		ref->setFileInfo (refFile);
-		ref->setTransform (transform);
+		ref->setTransformationMatrix (transform);
 		ref->setPosition (m_drawedVerts[0]);
 		ref->setColor (MainColor);
 		objs << ref;
--- a/src/editmodes/drawMode.cpp	Sun Sep 06 20:45:51 2015 +0300
+++ b/src/editmodes/drawMode.cpp	Tue Sep 22 00:59:21 2015 +0300
@@ -92,21 +92,21 @@
 
 	switch (verts.size())
 	{
-		case 2:
+	case 2:
 		{
 			// 2 verts - make a line
 			LDLine* obj = LDSpawn<LDLine> (verts[0], verts[1]);
 			obj->setColor (EdgeColor);
 			objs << obj;
-			break;
 		}
+		break;
 
-		case 3:
-		case 4:
+	case 3:
+	case 4:
 		{
-			LDObject* obj = (verts.size() == 3) ?
-				static_cast<LDObject*> (LDSpawn<LDTriangle>()) :
-				static_cast<LDObject*> (LDSpawn<LDQuad>());
+			LDVertexObject* obj = (verts.size() == 3) ?
+				static_cast<LDVertexObject*> (LDSpawn<LDTriangle>()) :
+				static_cast<LDVertexObject*> (LDSpawn<LDQuad>());
 
 			obj->setColor (MainColor);
 
@@ -114,8 +114,8 @@
 				obj->setVertex (i, verts[i]);
 
 			objs << obj;
-			break;
 		}
+		break;
 	}
 
 	finishDraw (objs);
--- a/src/editmodes/magicWandMode.cpp	Sun Sep 06 20:45:51 2015 +0300
+++ b/src/editmodes/magicWandMode.cpp	Tue Sep 22 00:59:21 2015 +0300
@@ -30,8 +30,12 @@
 	{
 		// Note: this deliberately only takes vertex-objects into account.
 		// The magic wand does not process subparts.
-		for (int i = 0; i < obj->numVertices(); ++i)
-			m_vertices[obj->vertex (i)] << obj;
+		if (obj->hasVertices())
+		{
+			LDVertexObject* vo = static_cast<LDVertexObject*> (obj);
+			for (int i = 0; i < vo->numVertices(); ++i)
+				m_vertices[vo->vertex (i)] << vo;
+		}
 	}
 }
 
@@ -40,11 +44,11 @@
 	return EditModeType::MagicWand;
 }
 
-void MagicWandMode::fillBoundaries (LDObject* obj, QVector<BoundaryType>& boundaries, QVector<LDObject*>& candidates)
+void MagicWandMode::fillBoundaries (LDVertexObject* obj, Boundaries& boundaries, Candidates& candidates)
 {
 	// All boundaries obviously share vertices with the object, therefore they're all in the list
 	// of candidates.
-	for (LDObject* candidate : candidates)
+	for (LDVertexObject* candidate : candidates)
 	{
 		if (not isOneOf (candidate->type(), OBJ_Line, OBJ_CondLine) or candidate->vertex (0) == candidate->vertex (1))
 			continue;
@@ -64,16 +68,15 @@
 					m_selection << candidate;
 				else
 					boundaries.append (std::make_tuple (candidate->vertex (0), candidate->vertex (1)));
-
 				break;
 			}
 		}
 	}
 }
 
-void MagicWandMode::doMagic (LDObject* obj, MagicWandMode::MagicType type)
+void MagicWandMode::doMagic (LDObject* input, MagicType type)
 {
-	if (obj == nullptr)
+	if (input == nullptr or not input->hasVertices())
 	{
 		if (type == Set)
 		{
@@ -84,8 +87,9 @@
 		return;
 	}
 
-	int matchesneeded = 0;
-	QVector<BoundaryType> boundaries;
+	LDVertexObject* obj = static_cast<LDVertexObject*> (input);
+	int matchesneeded = (obj->numVertices() == 2) ? 1 : 2;
+	Boundaries boundaries;
 	LDObjectType objtype = obj->type();
 
 	if (type != InternalRecursion)
@@ -94,23 +98,7 @@
 		m_selection.append (obj);
 	}
 
-	switch (obj->type())
-	{
-		case OBJ_Line:
-		case OBJ_CondLine:
-			matchesneeded = 1;
-			break;
-
-		case OBJ_Triangle:
-		case OBJ_Quad:
-			matchesneeded = 2;
-			break;
-
-		default:
-			return;
-	}
-
-	QVector<LDObject*> candidates;
+	Candidates candidates;
 
 	// Get the list of objects that touch this object, i.e. share a vertex
 	// with this.
@@ -123,57 +111,38 @@
 	if (matchesneeded > 1)
 		fillBoundaries (obj, boundaries, candidates);
 
-	for (LDObject* candidate : candidates)
+	for (LDVertexObject* candidate : candidates)
 	{
-		try
-		{
-			// If we're doing this on lines, we need exact type match. Surface types (quads and
-			// triangles) can be mixed. Also don't consider self a candidate, and don't consider
-			// objects we have already processed.
-			if ((candidate == obj) or
-				(candidate->color() != obj->color()) or
-				(m_selection.contains (candidate)) or
-				(matchesneeded == 1 and (candidate->type() != objtype)) or
-				((candidate->numVertices() > 2) ^ (matchesneeded == 2)))
-			{
-				throw 0;
-			}
-
-			// Now ensure the two objects share enough vertices.
-			QVector<Vertex> matches;
-
-			for (int i = 0; i < obj->numVertices(); ++i)
-			{
-				for (int j = 0; j < candidate->numVertices(); ++j)
-				{
-					if (obj->vertex(i) == candidate->vertex(j))
-					{
-						matches << obj->vertex(i);
-						break;
-					}
-				}
-			}
-
-			if (matches.size() < matchesneeded)
-				throw 0; // Not enough matches.
-
-			// Check if a boundary gets in between the objects.
-			for (auto boundary : boundaries)
-			{
-				if (isOneOf (matches[0], std::get<0> (boundary), std::get<1> (boundary)) and
-					isOneOf (matches[1], std::get<0> (boundary), std::get<1> (boundary)))
-				{
-					throw 0;
-				}
-			}
-
-			m_selection.append (candidate);
-			doMagic (candidate, InternalRecursion);
-		}
-		catch (int&)
+		// If we're doing this on lines, we need exact type match. Surface types (quads and
+		// triangles) can be mixed. Also don't consider self a candidate, and don't consider
+		// objects we have already processed.
+		if ((candidate == obj) or
+			(candidate->color() != obj->color()) or
+			(m_selection.contains (candidate)) or
+			(matchesneeded == 1 and (candidate->type() != objtype)) or
+			((candidate->numVertices() > 2) ^ (matchesneeded == 2)))
 		{
 			continue;
 		}
+
+		// Now ensure the two objects share enough vertices.
+		QSet<Vertex> matches = obj->vertexSet();
+		matches.intersect (candidate->vertexSet());
+
+		if (matches.size() < matchesneeded)
+			goto skipthis; // Not enough matches.
+
+		// Check if a boundary gets in between the objects.
+		for (const Boundary& boundary : boundaries)
+		{
+			if (matches.contains (std::get<0>(boundary)) and matches.contains (std::get<1>(boundary)))
+				goto skipthis;
+		}
+
+		m_selection.append (candidate);
+		doMagic (candidate, InternalRecursion);
+skipthis:
+		continue;
 	}
 
 	switch (type)
@@ -212,7 +181,8 @@
 		else if (data.keymods & Qt::ControlModifier)
 			wandtype = MagicWandMode::Subtractive;
 
-		doMagic (renderer()->pickOneObject (data.ev->x(), data.ev->y()), wandtype);
+		LDObject* obj = renderer()->pickOneObject (data.ev->x(), data.ev->y());
+		doMagic (obj, wandtype);
 		return true;
 	}
 
--- a/src/editmodes/magicWandMode.h	Sun Sep 06 20:45:51 2015 +0300
+++ b/src/editmodes/magicWandMode.h	Tue Sep 22 00:59:21 2015 +0300
@@ -22,15 +22,19 @@
 #include <QMap>
 #include <QVector>
 
+class LDVertexObject;
+
 class MagicWandMode : public AbstractSelectMode
 {
-	QMap<Vertex, QVector<LDObject*>> m_vertices;
-	QVector<LDObject*> m_selection;
+	QMap<Vertex, QVector<LDVertexObject*>> m_vertices;
+	QVector<LDVertexObject*> m_selection;
 
 	DEFINE_CLASS (MagicWandMode, AbstractSelectMode)
 
 public:
-	using BoundaryType = std::tuple<Vertex, Vertex>;
+	using Boundary = std::tuple<Vertex, Vertex>;
+	using Boundaries = QVector<Boundary>;
+	using Candidates = QVector<LDVertexObject*>;
 	enum MagicType
 	{
 		Set,
@@ -45,5 +49,5 @@
 	virtual bool mouseReleased (MouseEventData const& data) override;
 
 private:
-	void fillBoundaries (LDObject* obj, QVector<BoundaryType>& boundaries, QVector<LDObject*>& candidates);
+	void fillBoundaries (LDVertexObject* obj, Boundaries& boundaries, Candidates& candidates);
 };
--- a/src/glCompiler.cpp	Sun Sep 06 20:45:51 2015 +0300
+++ b/src/glCompiler.cpp	Tue Sep 22 00:59:21 2015 +0300
@@ -151,7 +151,7 @@
 		}
 		else if (poly.color == EdgeColor)
 		{
-			qcol = Luma (QColor (m_config->backgroundColor())) > 40 ? Qt::black : Qt::white;
+			qcol = luma (QColor (m_config->backgroundColor())) > 40 ? Qt::black : Qt::white;
 		}
 		else
 		{
@@ -308,37 +308,26 @@
 	info.isChanged = true;
 	dropObjectInfo (obj);
 
-	switch (obj->type())
+	if (obj->hasVertices())
+	{
+		LDVertexObject* vo = static_cast<LDVertexObject*> (obj);
+		LDPolygon* poly = vo->getPolygon();
+		poly->id = obj->id();
+		compilePolygon (*poly, obj, &info);
+		delete poly;
+	}
+	else if (obj->type() == OBJ_Subfile)
 	{
 		// Note: We cannot split quads into triangles here, it would mess up the
 		// wireframe view. Quads must go into separate vbos.
-		case OBJ_Triangle:
-		case OBJ_Quad:
-		case OBJ_Line:
-		case OBJ_CondLine:
-		{
-			LDPolygon* poly = obj->getPolygon();
-			poly->id = obj->id();
-			compilePolygon (*poly, obj, &info);
-			delete poly;
-			break;
-		}
+		LDSubfile* ref = static_cast<LDSubfile*> (obj);
+		QList<LDPolygon> polygons = ref->inlinePolygons();
 
-		case OBJ_Subfile:
+		for (LDPolygon& polygon : polygons)
 		{
-			LDSubfile* ref = static_cast<LDSubfile*> (obj);
-			auto data = ref->inlinePolygons();
-
-			for (LDPolygon& poly : data)
-			{
-				poly.id = obj->id();
-				compilePolygon (poly, obj, &info);
-			}
-			break;
+			polygon.id = obj->id();
+			compilePolygon (polygon, obj, &info);
 		}
-
-		default:
-			break;
 	}
 
 	m_objectInfo[obj] = info;
--- a/src/glRenderer.cpp	Sun Sep 06 20:45:51 2015 +0300
+++ b/src/glRenderer.cpp	Tue Sep 22 00:59:21 2015 +0300
@@ -336,7 +336,7 @@
 		return;
 
 	color.setAlpha (255);
-	m_useDarkBackground = Luma (color) < 80;
+	m_useDarkBackground = luma (color) < 80;
 	m_backgroundColor = color;
 	qglClearColor (color);
 }
@@ -607,7 +607,7 @@
 {
 	QPen linepen (m_thinBorderPen);
 	linepen.setWidth (2);
-	linepen.setColor (Luma (m_backgroundColor) < 40 ? Qt::white : Qt::black);
+	linepen.setColor (luma (m_backgroundColor) < 40 ? Qt::white : Qt::black);
 	return linepen;
 }
 
@@ -1583,7 +1583,7 @@
 		ref->setColor (MainColor);
 		ref->setFileInfo (GetDocument (primitiveName));
 		ref->setPosition (Origin);
-		ref->setTransform (IdentityMatrix);
+		ref->setTransformationMatrix (IdentityMatrix);
 		currentDocument()->insertObj (m_window->suggestInsertPoint(), ref);
 		ref->select();
 		m_window->buildObjectList();
--- a/src/ldDocument.cpp	Sun Sep 06 20:45:51 2015 +0300
+++ b/src/ldDocument.cpp	Tue Sep 22 00:59:21 2015 +0300
@@ -830,7 +830,7 @@
 				for (int i = 0; i < 9; ++i)
 					transform[i] = tokens[i + 5].toDouble(); // 5 - 13
 
-				obj->setTransform (transform);
+				obj->setTransformationMatrix (transform);
 				obj->setFileInfo (load);
 				return obj;
 			}
@@ -872,7 +872,7 @@
 				CheckTokenNumbers (tokens, 1, 13);
 
 				// Quadrilateral / Conditional line
-				LDObject* obj;
+				LDVertexObject* obj;
 
 				if (num == 4)
 					obj = LDSpawn<LDQuad>();
@@ -1117,12 +1117,15 @@
 				continue;
 			}
 
-			LDPolygon* data = obj->getPolygon();
-
-			if (data)
+			if (obj->hasVertices())
 			{
-				m_polygonData << *data;
-				delete data;
+				LDPolygon* polygon = static_cast<LDVertexObject*> (obj)->getPolygon();
+	
+				if (polygon)
+				{
+					m_polygonData << *polygon;
+					delete polygon;
+				}
 			}
 		}
 
--- a/src/ldObject.cpp	Sun Sep 06 20:45:51 2015 +0300
+++ b/src/ldObject.cpp	Tue Sep 22 00:59:21 2015 +0300
@@ -52,8 +52,6 @@
 	if (document)
 		document->addObject (this);
 
-	memset (m_coords, 0, sizeof m_coords);
-
 	// Let's hope that nobody goes to create 17 million objects anytime soon...
 	static int32 nextId = 1; // 0 shalt be null
 	if (nextId < MAX_LDOBJECT_IDS)
@@ -72,10 +70,10 @@
 
 LDOBJ_DEFAULT_CTOR (LDEmpty, LDObject)
 LDOBJ_DEFAULT_CTOR (LDError, LDObject)
-LDOBJ_DEFAULT_CTOR (LDLine, LDObject)
-LDOBJ_DEFAULT_CTOR (LDTriangle, LDObject)
+LDOBJ_DEFAULT_CTOR (LDLine, LDVertexObject)
+LDOBJ_DEFAULT_CTOR (LDTriangle, LDVertexObject)
 LDOBJ_DEFAULT_CTOR (LDCondLine, LDLine)
-LDOBJ_DEFAULT_CTOR (LDQuad, LDObject)
+LDOBJ_DEFAULT_CTOR (LDQuad, LDVertexObject)
 LDOBJ_DEFAULT_CTOR (LDOverlay, LDObject)
 LDOBJ_DEFAULT_CTOR (LDBfc, LDObject)
 LDOBJ_DEFAULT_CTOR (LDComment, LDObject)
@@ -98,7 +96,7 @@
 QString LDSubfile::asText() const
 {
 	QString val = format ("1 %1 %2 ", color(), position());
-	val += transform().toString();
+	val += transformationMatrix().toString();
 	val += ' ';
 	val += fileInfo()->name();
 	return val;
@@ -225,7 +223,7 @@
 // =============================================================================
 //
 LDLine::LDLine (Vertex v1, Vertex v2, LDDocument* document) :
-	LDObject (document)
+	LDVertexObject (document)
 {
 	setVertex (0, v1);
 	setVertex (1, v2);
@@ -234,7 +232,7 @@
 // =============================================================================
 //
 LDTriangle::LDTriangle (const Vertex& v1, const Vertex& v2, const Vertex& v3, LDDocument* document) :
-	LDObject (document)
+	LDVertexObject (document)
 {
 	setVertex (0, v1);
 	setVertex (1, v2);
@@ -244,7 +242,7 @@
 // =============================================================================
 //
 LDQuad::LDQuad (const Vertex& v1, const Vertex& v2, const Vertex& v3, const Vertex& v4, LDDocument* document) :
-	LDObject (document)
+	LDVertexObject (document)
 {
 	setVertex (0, v1);
 	setVertex (1, v2);
@@ -295,41 +293,30 @@
 		m_isSelected = false;
 }
 
-// =============================================================================
-//
-static void TransformObject (LDObject* obj, Matrix transform, Vertex pos, LDColor parentcolor)
+LDVertexObject::LDVertexObject (LDDocument* document) :
+	LDObject (document)
 {
-	switch (obj->type())
-	{
-	case OBJ_Line:
-	case OBJ_CondLine:
-	case OBJ_Triangle:
-	case OBJ_Quad:
-		for (int i = 0; i < obj->numVertices(); ++i)
-		{
-			Vertex v = obj->vertex (i);
-			v.transform (transform, pos);
-			obj->setVertex (i, v);
-		}
-		break;
+	memset (m_coordinates, 0, sizeof m_coordinates);
+}
+
+void LDObject::transform (const Matrix&, const Vertex&) {}
 
-	case OBJ_Subfile:
-		{
-			LDSubfile* ref = static_cast<LDSubfile*> (obj);
-			Matrix newMatrix = transform * ref->transform();
-			Vertex newpos = ref->position();
-			newpos.transform (transform, pos);
-			ref->setPosition (newpos);
-			ref->setTransform (newMatrix);
-		}
-		break;
+void LDVertexObject::transform (const Matrix& transformationMatrix, const Vertex& position)
+{
+	for (int i = 0; i < numVertices(); ++i)
+	{
+		Vertex vertex = this->vertex (i);
+		vertex.transform (transformationMatrix, position);
+		setVertex (i, vertex);
+	}
+}
 
-	default:
-		break;
-	}
-
-	if (obj->color() == MainColor)
-		obj->setColor (parentcolor);
+void LDMatrixObject::transform (const Matrix& transformationMatrix, const Vertex& position)
+{
+	Vertex newPosition = this->position();
+	newPosition.transform (transformationMatrix, position);
+	setPosition (newPosition);
+	setTransformationMatrix (transformationMatrix * this->transformationMatrix());
 }
 
 // =============================================================================
@@ -340,14 +327,19 @@
 
 	// Transform the objects
 	for (LDObject* obj : objs)
-		TransformObject (obj, transform(), position(), color());
+	{
+		obj->transform (transformationMatrix(), position());
+
+		if (obj->color() == MainColor)
+			obj->setColor (color());
+	}
 
 	return objs;
 }
 
 // =============================================================================
 //
-LDPolygon* LDObject::getPolygon()
+LDPolygon* LDVertexObject::getPolygon()
 {
 	LDObjectType ot = type();
 	int num = (ot == OBJ_Line)		? 2
@@ -379,7 +371,7 @@
 	for (LDPolygon& entry : data)
 	{
 		for (int i = 0; i < entry.numVertices(); ++i)
-			entry.vertices[i].transform (transform(), position());
+			entry.vertices[i].transform (transformationMatrix(), position());
 	}
 
 	return data;
@@ -545,10 +537,11 @@
 		LDMatrixObject* mo = static_cast<LDMatrixObject*> (this);
 		mo->setPosition (mo->position() + vect);
 	}
-	else
+	else if (hasVertices())
 	{
-		for (int i = 0; i < numVertices(); ++i)
-			setVertex (i, vertex (i) + vect);
+		LDVertexObject* vo = static_cast<LDVertexObject*> (this);
+		for (int i = 0; i < vo->numVertices(); ++i)
+			vo->setVertex (i, vo->vertex (i) + vect);
 	}
 }
 
@@ -661,9 +654,13 @@
 
 	for (LDObject* obj : objs)
 	{
-		for (int i = 0; i < obj->numVertices(); ++i)
+		if (not obj->hasVertices())
+			continue;
+
+		LDVertexObject* vo = static_cast<LDVertexObject*> (obj);
+		for (int i = 0; i < vo->numVertices(); ++i)
 		{
-			Vertex const& vrt = obj->vertex (i);
+			Vertex const& vrt = vo->vertex (i);
 
 			if (axisSet & (1 << X) and vrt.x() != 0.0)
 				axisSet &= ~(1 << X);
@@ -694,27 +691,28 @@
 		if (axisSet & (1 << Z))
 			matrixModifier[8] = -1;
 
-		setTransform (transform() * matrixModifier);
-		return;
+		setTransformationMatrix (transformationMatrix() * matrixModifier);
 	}
-
-	// Subfile is not flat. Resort to invertnext.
-	int idx = lineNumber();
-
-	if (idx > 0)
+	else
 	{
-		LDBfc* bfc = dynamic_cast<LDBfc*> (previous());
-
-		if (bfc and bfc->statement() == BfcStatement::InvertNext)
+		// Subfile is not flat. Resort to invertnext.
+		int idx = lineNumber();
+	
+		if (idx > 0)
 		{
-			// This is prefixed with an invertnext, thus remove it.
-			bfc->destroy();
-			return;
+			LDBfc* bfc = dynamic_cast<LDBfc*> (previous());
+	
+			if (bfc and bfc->statement() == BfcStatement::InvertNext)
+			{
+				// This is prefixed with an invertnext, thus remove it.
+				bfc->destroy();
+				return;
+			}
 		}
+	
+		// Not inverted, thus prefix it with a new invertnext.
+		document()->insertObj (idx, new LDBfc (BfcStatement::InvertNext));
 	}
-
-	// Not inverted, thus prefix it with a new invertnext.
-	document()->insertObj (idx, new LDBfc (BfcStatement::InvertNext));
 }
 
 // =============================================================================
@@ -817,28 +815,38 @@
 //
 // Get a vertex by index
 //
-const Vertex& LDObject::vertex (int i) const
+const Vertex& LDVertexObject::vertex (int i) const
+{
+	return m_coordinates[i];
+}
+
+QSet<Vertex> LDVertexObject::vertexSet() const
 {
-	return m_coords[i];
+	QSet<Vertex> result;
+
+	for (int i = 0; i < numVertices(); ++i)
+		result.insert (vertex (i));
+
+	return result;
 }
 
 // =============================================================================
 //
 // Set a vertex to the given value
 //
-void LDObject::setVertex (int i, const Vertex& vert)
+void LDVertexObject::setVertex (int i, const Vertex& vert)
 {
-	changeProperty (this, &m_coords[i], vert);
+	changeProperty (this, &m_coordinates[i], vert);
 }
 
 LDMatrixObject::LDMatrixObject (LDDocument* document) :
 	LDObject (document),
 	m_position (Origin) {}
 
-LDMatrixObject::LDMatrixObject (const Matrix& transform, const Vertex& pos, LDDocument* document) :
+LDMatrixObject::LDMatrixObject (const Matrix& transformationMatrix, const Vertex& position, LDDocument* document) :
 	LDObject (document),
-	m_position (pos),
-	m_transform (transform) {}
+	m_position (position),
+	m_transformationMatrix (transformationMatrix) {}
 
 void LDMatrixObject::setCoordinate (const Axis ax, double value)
 {
@@ -868,14 +876,14 @@
 
 // =============================================================================
 //
-const Matrix& LDMatrixObject::transform() const
+const Matrix& LDMatrixObject::transformationMatrix() const
 {
-	return m_transform;
+	return m_transformationMatrix;
 }
 
-void LDMatrixObject::setTransform (const Matrix& val)
+void LDMatrixObject::setTransformationMatrix (const Matrix& val)
 {
-	changeProperty (this, &m_transform, val);
+	changeProperty (this, &m_transformationMatrix, val);
 }
 
 LDError::LDError (QString contents, QString reason, LDDocument* document) :
@@ -1084,9 +1092,11 @@
 	{
 		document->initializeCachedData();
 	}
-};
+}
 
-void LDObject::getVertices (QVector<Vertex>& verts) const
+void LDObject::getVertices (QVector<Vertex>&) const {}
+
+void LDVertexObject::getVertices (QVector<Vertex>& verts) const
 {
 	for (int i = 0; i < numVertices(); ++i)
 		verts << vertex (i);
--- a/src/ldObject.h	Sun Sep 06 20:45:51 2015 +0300
+++ b/src/ldObject.h	Tue Sep 22 00:59:21 2015 +0300
@@ -37,7 +37,6 @@
 	virtual void invert() override;								\
 
 #define LDOBJ_NAME(N)          public: virtual QString typeName() const override { return #N; }
-#define LDOBJ_VERTICES(V)      public: virtual int numVertices() const override { return V; }
 #define LDOBJ_SETCOLORED(V)    public: virtual bool isColored() const override { return V; }
 #define LDOBJ_COLORED          LDOBJ_SETCOLORED (true)
 #define LDOBJ_UNCOLORED        LDOBJ_SETCOLORED (false) LDOBJ_DEFAULTCOLOR (MainColor)
@@ -54,7 +53,6 @@
 class QListWidgetItem;
 class LDSubfile;
 class LDDocument;
-
 class LDBfc;
 
 //
@@ -99,9 +97,9 @@
 	void deselect(); 
 	void destroy();
 	LDDocument* document() const;
-	LDPolygon* getPolygon();
 	virtual void getVertices (QVector<Vertex>& verts) const;
-	virtual bool hasMatrix() const = 0; // Does this object have a matrix and position? (see LDMatrixObject)
+	virtual bool hasMatrix() const { return false; }
+	virtual bool hasVertices() const { return false; }
 	qint32 id() const;
 	virtual void invert() = 0; // Inverts this object (winding is reversed)
 	virtual bool isColored() const = 0;
@@ -112,7 +110,6 @@
 	int lineNumber() const;
 	void move (Vertex vect);
 	LDObject* next() const;
-	virtual int numVertices() const = 0;
 	LDObject* previous() const;
 	bool previousIsInvertnext (LDBfc*& ptr);
 	QColor randomColor() const;
@@ -121,12 +118,10 @@
 	void setColor (LDColor color);
 	void setDocument (LDDocument* document);
 	void setHidden (bool value);
-	void setVertex (int i, const Vertex& vert);
 	void swap (LDObject* other);
-	LDObject* topLevelParent();
+	virtual void transform (const Matrix& transformationMatrix, const Vertex& position);
 	virtual LDObjectType type() const = 0;
 	virtual QString typeName() const = 0;
-	const Vertex& vertex (int i) const;
 
 	static QString describeObjects (const LDObjectList& objs);
 	static LDObject* fromID (int id);
@@ -141,12 +136,10 @@
 	bool m_isHidden;
 	bool m_isSelected;
 	bool m_isDestroyed;
-	LDObject* m_parent;
 	LDDocument* m_document;
 	qint32 m_id;
 	LDColor m_color;
 	QColor m_randomColor;
-	Vertex m_coords[4];
 };
 
 template<typename T, typename... Args>
@@ -176,20 +169,39 @@
 //
 class LDMatrixObject : public LDObject
 {
-	Vertex m_position;
-
 public:
 	LDMatrixObject (LDDocument* document = nullptr);
-	LDMatrixObject (const Matrix& transform, const Vertex& pos, LDDocument* document = nullptr);
+	LDMatrixObject (const Matrix& transformationMatrix, const Vertex& position, LDDocument* document = nullptr);
 
+	virtual bool hasMatrix() const { return true; }
 	const Vertex& position() const;
 	void setCoordinate (const Axis ax, double value);
 	void setPosition (const Vertex& a);
-	const Matrix& transform() const;
-	void setTransform (const Matrix& value);
+	void setTransformationMatrix (const Matrix& value);
+	virtual void transform (const Matrix& transformationMatrix, const Vertex& position);
+	const Matrix& transformationMatrix() const;
 
 private:
-	Matrix m_transform;
+	Vertex m_position;
+	Matrix m_transformationMatrix;
+};
+
+class LDVertexObject : public LDObject
+{
+public:
+	LDVertexObject (LDDocument* document = nullptr);
+
+	LDPolygon* getPolygon();
+	virtual void getVertices (QVector<Vertex>& verts) const;
+	virtual bool hasVertices() const { return true; }
+	virtual int numVertices() const = 0;
+	void setVertex (int i, const Vertex& vert);
+	virtual void transform (const Matrix& transformationMatrix, const Vertex& position);
+	const Vertex& vertex (int i) const;
+	QSet<Vertex> vertexSet() const;
+
+private:
+	Vertex m_coordinates[4];
 };
 
 //
@@ -202,16 +214,14 @@
 {
 	LDOBJ (Error)
 	LDOBJ_NAME (error)
-	LDOBJ_VERTICES (0)
 	LDOBJ_UNCOLORED
 	LDOBJ_SCEMANTIC
-	LDOBJ_NO_MATRIX
-
 public:
 	LDError (QString contents, QString reason, LDDocument* document = nullptr);
-	QString reason() const;
+
 	QString contents() const;
 	QString fileReferenced() const;
+	QString reason() const;
 	void setFileReferenced (QString value);
 
 private:
@@ -228,10 +238,8 @@
 {
 	LDOBJ (Empty)
 	LDOBJ_NAME (empty)
-	LDOBJ_VERTICES (0)
 	LDOBJ_UNCOLORED
 	LDOBJ_NON_SCEMANTIC
-	LDOBJ_NO_MATRIX
 };
 
 //
@@ -242,10 +250,8 @@
 {
 	LDOBJ (Comment)
 	LDOBJ_NAME (comment)
-	LDOBJ_VERTICES (0)
 	LDOBJ_UNCOLORED
 	LDOBJ_NON_SCEMANTIC
-	LDOBJ_NO_MATRIX
 
 public:
 	LDComment (QString text, LDDocument* document = nullptr);
@@ -282,16 +288,14 @@
 public:
 	LDOBJ (Bfc)
 	LDOBJ_NAME (bfc)
-	LDOBJ_VERTICES (0)
 	LDOBJ_UNCOLORED
 	LDOBJ_CUSTOM_SCEMANTIC { return (statement() == BfcStatement::InvertNext); }
-	LDOBJ_NO_MATRIX
 
 public:
 	LDBfc (const BfcStatement type, LDDocument* document = nullptr);
 
+	void setStatement (BfcStatement value);
 	BfcStatement statement() const;
-	void setStatement (BfcStatement value);
 	QString statementToString() const;
 
 	static QString statementToString (BfcStatement statement);
@@ -309,11 +313,9 @@
 {
 	LDOBJ (Subfile)
 	LDOBJ_NAME (subfile)
-	LDOBJ_VERTICES (0)
 	LDOBJ_COLORED
 	LDOBJ_DEFAULTCOLOR (MainColor)
 	LDOBJ_SCEMANTIC
-	LDOBJ_HAS_MATRIX
 
 public:
 	// Inlines this subfile.
@@ -332,18 +334,17 @@
 //
 // Represents a single code-2 line in the LDraw code file.
 //
-class LDLine : public LDObject
+class LDLine : public LDVertexObject
 {
 	LDOBJ (Line)
 	LDOBJ_NAME (line)
-	LDOBJ_VERTICES (2)
 	LDOBJ_COLORED
 	LDOBJ_DEFAULTCOLOR (EdgeColor)
 	LDOBJ_SCEMANTIC
-	LDOBJ_NO_MATRIX
 
 public:
 	LDLine (Vertex v1, Vertex v2, LDDocument* document = nullptr);
+	int numVertices() const override { return 2; }
 };
 
 //
@@ -355,15 +356,14 @@
 {
 	LDOBJ (CondLine)
 	LDOBJ_NAME (condline)
-	LDOBJ_VERTICES (4)
 	LDOBJ_COLORED
 	LDOBJ_DEFAULTCOLOR (EdgeColor)
 	LDOBJ_SCEMANTIC
-	LDOBJ_NO_MATRIX
 
 public:
 	LDCondLine (const Vertex& v0, const Vertex& v1, const Vertex& v2, const Vertex& v3, LDDocument* document = nullptr);
 	LDLine* toEdgeLine();
+	int numVertices() const override { return 4; }
 };
 
 //
@@ -373,18 +373,17 @@
 // and v2 contain the end-points of this triangle. dColor is the color the
 // triangle is colored with.
 //
-class LDTriangle : public LDObject
+class LDTriangle : public LDVertexObject
 {
 	LDOBJ (Triangle)
 	LDOBJ_NAME (triangle)
-	LDOBJ_VERTICES (3)
 	LDOBJ_COLORED
 	LDOBJ_DEFAULTCOLOR (MainColor)
 	LDOBJ_SCEMANTIC
-	LDOBJ_NO_MATRIX
 
 public:
 	LDTriangle (Vertex const& v1, Vertex const& v2, Vertex const& v3, LDDocument* document = nullptr);
+	int numVertices() const override { return 3; }
 };
 
 //
@@ -393,21 +392,20 @@
 // Represents a single code-4 quadrilateral. v0, v1, v2 and v3 are the end points
 // of the quad, dColor is the color used for the quad.
 //
-class LDQuad : public LDObject
+class LDQuad : public LDVertexObject
 {
 	LDOBJ (Quad)
 	LDOBJ_NAME (quad)
-	LDOBJ_VERTICES (4)
 	LDOBJ_COLORED
 	LDOBJ_DEFAULTCOLOR (MainColor)
 	LDOBJ_SCEMANTIC
-	LDOBJ_NO_MATRIX
 
 public:
 	LDQuad (const Vertex& v1, const Vertex& v2, const Vertex& v3, const Vertex& v4, LDDocument* document = nullptr);
 
 	// Split this quad into two triangles
 	QList<LDTriangle*> splitToTriangles();
+	int numVertices() const override { return 4; }
 };
 
 //
@@ -419,10 +417,8 @@
 {
 	LDOBJ (Overlay)
 	LDOBJ_NAME (overlay)
-	LDOBJ_VERTICES (0)
 	LDOBJ_UNCOLORED
 	LDOBJ_NON_SCEMANTIC
-	LDOBJ_NO_MATRIX
 
 public:
 	int camera() const;
--- a/src/ldObjectMath.cpp	Sun Sep 06 20:45:51 2015 +0300
+++ b/src/ldObjectMath.cpp	Tue Sep 22 00:59:21 2015 +0300
@@ -20,8 +20,6 @@
 #include "ldObject.h"
 #include "miscallenous.h"
 
-// =============================================================================
-//
 static void RotateVertex (Vertex& v, const Vertex& rotpoint, const Matrix& transformer)
 {
 	v -= rotpoint;
@@ -29,8 +27,6 @@
 	v += rotpoint;
 }
 
-// =============================================================================
-//
 void RotateObjects (const int l, const int m, const int n, double angle, LDObjectList const& objects)
 {
 	QList<Vertex*> queue;
@@ -57,13 +53,14 @@
 	// Apply the above matrix to everything
 	for (LDObject* obj : objects)
 	{
-		if (obj->numVertices())
+		if (obj->hasVertices())
 		{
-			for (int i = 0; i < obj->numVertices(); ++i)
+			LDVertexObject* vo = static_cast<LDVertexObject*> (obj);
+			for (int i = 0; i < vo->numVertices(); ++i)
 			{
-				Vertex v = obj->vertex (i);
+				Vertex v = vo->vertex (i);
 				RotateVertex (v, rotpoint, transform);
-				obj->setVertex (i, v);
+				vo->setVertex (i, v);
 			}
 		}
 		else if (obj->hasMatrix())
@@ -76,7 +73,7 @@
 			mo->setPosition (v);
 
 			// Transform the matrix
-			mo->setTransform (transform * mo->transform());
+			mo->setTransformationMatrix (transform * mo->transformationMatrix());
 		}
 	}
 }
--- a/src/main.cpp	Sun Sep 06 20:45:51 2015 +0300
+++ b/src/main.cpp	Tue Sep 22 00:59:21 2015 +0300
@@ -51,7 +51,7 @@
 	LDPaths* paths = new LDPaths (win);
 	paths->checkPaths();
 	paths->deleteLater();
-	InitColors();
+	initColors();
 	LoadPrimitives();
 	win->show();
 
--- a/src/mainwindow.cpp	Sun Sep 06 20:45:51 2015 +0300
+++ b/src/mainwindow.cpp	Tue Sep 22 00:59:21 2015 +0300
@@ -387,76 +387,64 @@
 	{
 		QString descr;
 
-		switch (obj->type())
+		if (obj->hasVertices())
 		{
-			case OBJ_Comment:
-			{
-				descr = static_cast<LDComment*> (obj)->text();
+			LDVertexObject* vo = static_cast<LDVertexObject*> (obj);
 
-				// Remove leading whitespace
-				while (descr[0] == ' ')
-					descr.remove (0, 1);
-
-				break;
-			}
-
-			case OBJ_Empty:
-				break; // leave it empty
+			for (int i = 0; i < vo->numVertices(); ++i)
+			{
+				if (i != 0)
+					descr += ", ";
 
-			case OBJ_Line:
-			case OBJ_Triangle:
-			case OBJ_Quad:
-			case OBJ_CondLine:
-			{
-				for (int i = 0; i < obj->numVertices(); ++i)
-				{
-					if (i != 0)
-						descr += ", ";
+				descr += vo->vertex (i).toString (true);
+			}
+			break;
+		}
+		else switch (obj->type())
+		{
+		case OBJ_Comment:
+			descr = static_cast<LDComment*> (obj)->text();
 
-					descr += obj->vertex (i).toString (true);
-				}
-				break;
-			}
+			// Remove leading whitespace
+			while (descr[0] == ' ')
+				descr.remove (0, 1);
+			break;
 
-			case OBJ_Error:
-			{
-				descr = format ("ERROR: %1", obj->asText());
-				break;
-			}
+		case OBJ_Empty:
+			break; // leave it empty
 
-			case OBJ_Subfile:
+		case OBJ_Error:
+			descr = format ("ERROR: %1", obj->asText());
+			break;
+
+		case OBJ_Subfile:
 			{
 				LDSubfile* ref = static_cast<LDSubfile*> (obj);
-
 				descr = format ("%1 %2, (", ref->fileInfo()->getDisplayName(), ref->position().toString (true));
 
 				for (int i = 0; i < 9; ++i)
-					descr += format ("%1%2", ref->transform()[i], (i != 8) ? " " : "");
+					descr += format ("%1%2", ref->transformationMatrix()[i], (i != 8) ? " " : "");
 
 				descr += ')';
-				break;
 			}
+			break;
 
-			case OBJ_Bfc:
-			{
-				descr = static_cast<LDBfc*> (obj)->statementToString();
-				break;
-			}
+		case OBJ_Bfc:
+			descr = static_cast<LDBfc*> (obj)->statementToString();
+			break;
 
-			case OBJ_Overlay:
+		case OBJ_Overlay:
 			{
 				LDOverlay* ovl = static_cast<LDOverlay*> (obj);
 				descr = format ("[%1] %2 (%3, %4), %5 x %6", renderer()->cameraName ((ECamera) ovl->camera()),
 					Basename (ovl->fileName()), ovl->x(), ovl->y(),
 					ovl->width(), ovl->height());
-				break;
 			}
+			break;
 
-			default:
-			{
-				descr = obj->typeName();
-				break;
-			}
+		default:
+			descr = obj->typeName();
+			break;
 		}
 
 		QListWidgetItem* item = new QListWidgetItem (descr);
--- a/src/toolsets/algorithmtoolset.cpp	Sun Sep 06 20:45:51 2015 +0300
+++ b/src/toolsets/algorithmtoolset.cpp	Tue Sep 22 00:59:21 2015 +0300
@@ -156,7 +156,7 @@
 		if (mo)
 		{
 			Vertex v = mo->position();
-			Matrix t = mo->transform();
+			Matrix t = mo->transformationMatrix();
 
 			v.apply ([&](Axis, double& a)
 			{
@@ -169,19 +169,20 @@
 			});
 
 			mo->setPosition (v);
-			mo->setTransform (t);
+			mo->setTransformationMatrix (t);
 			num += 12;
 		}
-		else
+		else if (obj->hasVertices())
 		{
-			for (int i = 0; i < obj->numVertices(); ++i)
+			LDVertexObject* vo = static_cast<LDVertexObject*> (obj);
+			for (int i = 0; i < vo->numVertices(); ++i)
 			{
-				Vertex v = obj->vertex (i);
+				Vertex v = vo->vertex (i);
 				v.apply ([&](Axis, double& a)
 				{
 					RoundToDecimals (a, m_config->roundPositionPrecision());
 				});
-				obj->setVertex (i, v);
+				vo->setVertex (i, v);
 				num += 3;
 			}
 		}
@@ -214,6 +215,10 @@
 
 	for (LDObject* obj : selectedObjects())
 	{
+		if (not obj->hasVertices())
+			continue;
+
+		LDVertexObject* vo = static_cast<LDVertexObject*> (obj);
 		for (int i = 0; i < obj->numVertices(); ++i)
 		{
 			Vertex v = obj->vertex (i);
@@ -575,7 +580,7 @@
 		ref->setColor (MainColor);
 		ref->setFileInfo (doc);
 		ref->setPosition (Origin);
-		ref->setTransform (IdentityMatrix);
+		ref->setTransformationMatrix (IdentityMatrix);
 		currentDocument()->insertObj (refidx, ref);
 
 		// Refresh stuff

mercurial