Made history work with most things

Thu, 13 Jun 2013 02:55:47 +0300

author
Santeri Piippo <crimsondusk64@gmail.com>
date
Thu, 13 Jun 2013 02:55:47 +0300
changeset 276
a21e49914264
parent 275
7b5afec27688
child 277
246ca26620ce

Made history work with most things

src/addObjectDialog.cpp file | annotate | diff | comparison | revisions
src/bbox.cpp file | annotate | diff | comparison | revisions
src/file.cpp file | annotate | diff | comparison | revisions
src/gldraw.cpp file | annotate | diff | comparison | revisions
src/gui.cpp file | annotate | diff | comparison | revisions
src/gui_editactions.cpp file | annotate | diff | comparison | revisions
src/history.cpp file | annotate | diff | comparison | revisions
src/ldtypes.cpp file | annotate | diff | comparison | revisions
src/ldtypes.h file | annotate | diff | comparison | revisions
--- a/src/addObjectDialog.cpp	Thu Jun 13 01:13:06 2013 +0300
+++ b/src/addObjectDialog.cpp	Thu Jun 13 02:55:47 2013 +0300
@@ -221,7 +221,7 @@
 		if (obj) {
 			for (short i = 0; i < coordCount / 3; ++i)
 			for (short j = 0; j < 3; ++j)
-				dsb_coords[(i * 3) + j]->setValue (obj->coords[i].coord (j));
+				dsb_coords[(i * 3) + j]->setValue (obj->getVertex (i).coord (j));
 		}
 		break;
 	
@@ -401,9 +401,13 @@
 		if (!obj)
 			obj = LDObject::getDefault (type);
 		
-		for (short i = 0; i < obj->vertices (); ++i)
+		for (short i = 0; i < obj->vertices (); ++i) {
+			vertex v;
 			for (const Axis ax : g_Axes)
-				obj->coords[i][ax] = dlg.dsb_coords[(i * 3) + ax]->value ();
+				v[ax] = dlg.dsb_coords[(i * 3) + ax]->value ();
+			
+			obj->setVertex (i, v);
+		}
 		break;
 	
 	case LDObject::BFC:
--- a/src/bbox.cpp	Thu Jun 13 01:13:06 2013 +0300
+++ b/src/bbox.cpp	Thu Jun 13 02:55:47 2013 +0300
@@ -47,35 +47,11 @@
 void bbox::calcObject (LDObject* obj) {
 	switch (obj->getType ()) {
 	case LDObject::Line:
-		{
-			LDLine* line = static_cast<LDLine*> (obj);
-			for (short i = 0; i < 2; ++i)
-				calcVertex (line->coords[i]);
-		}
-		break;
-	
 	case LDObject::Triangle:
-		{
-			LDTriangle* tri = static_cast<LDTriangle*> (obj);
-			for (short i = 0; i < 3; ++i)
-				calcVertex (tri->coords[i]);
-		}
-		break;
-	
 	case LDObject::Quad:
-		{
-			LDQuad* quad = static_cast<LDQuad*> (obj);
-			for (short i = 0; i < 4; ++i)
-				calcVertex (quad->coords[i]);
-		}
-		break;
-	
 	case LDObject::CondLine:
-		{
-			LDCondLine* line = static_cast<LDCondLine*> (obj);
-			for (short i = 0; i < 4; ++i)
-				calcVertex (line->coords[i]);
-		}
+		for (short i = 0; i < obj->vertices (); ++i)
+			calcVertex (obj->getVertex (i));
 		break;
 	
 	case LDObject::Subfile:
--- a/src/file.cpp	Thu Jun 13 01:13:06 2013 +0300
+++ b/src/file.cpp	Thu Jun 13 02:55:47 2013 +0300
@@ -710,7 +710,7 @@
 			LDLine* obj = new LDLine;
 			obj->setColor (atol (tokens[1]));
 			for (short i = 0; i < 2; ++i)
-				obj->coords[i] = parseVertex (tokens, 2 + (i * 3)); // 2 - 7
+				obj->setVertex (i, parseVertex (tokens, 2 + (i * 3))); // 2 - 7
 			return obj;
 		}
 	
@@ -724,7 +724,7 @@
 			obj->setColor (atol (tokens[1]));
 			
 			for (short i = 0; i < 3; ++i)
-				obj->coords[i] = parseVertex (tokens, 2 + (i * 3)); // 2 - 10
+				obj->setVertex (i, parseVertex (tokens, 2 + (i * 3))); // 2 - 10
 			
 			return obj;
 		}
@@ -739,7 +739,7 @@
 			obj->setColor (atol (tokens[1]));
 			
 			for (short i = 0; i < 4; ++i)
-				obj->coords[i] = parseVertex (tokens, 2 + (i * 3)); // 2 - 13
+				obj->setVertex (i, parseVertex (tokens, 2 + (i * 3))); // 2 - 13
 			
 			return obj;
 		}
@@ -754,7 +754,7 @@
 			obj->setColor (atol (tokens[1]));
 			
 			for (short i = 0; i < 4; ++i)
-				obj->coords[i] = parseVertex (tokens, 2 + (i * 3)); // 2 - 13
+				obj->setVertex (i, parseVertex (tokens, 2 + (i * 3))); // 2 - 13
 			
 			return obj;
 		}
@@ -919,6 +919,11 @@
 // =============================================================================
 void LDOpenFile::setObject (ulong idx, LDObject* obj) {
 	assert (idx < numObjs ());
+	
+	str oldcode = m_objs[idx]->raw ();
+	str newcode = obj->raw ();
+	m_history << new EditHistory (idx, oldcode, newcode);
+	
 	m_objs[idx] = obj;
 }
 
--- a/src/gldraw.cpp	Thu Jun 13 01:13:06 2013 +0300
+++ b/src/gldraw.cpp	Thu Jun 13 02:55:47 2013 +0300
@@ -701,10 +701,10 @@
 	
 	if (g_glInvert == false)
 		for (short i = 0; i < numverts; ++i)
-			compileVertex (obj->coords[i]);
+			compileVertex (obj->m_coords[i]);
 	else
 		for (short i = numverts - 1; i >= 0; --i)
-			compileVertex (obj->coords[i]);
+			compileVertex (obj->m_coords[i]);
 	
 	glEnd ();
 }
@@ -1239,7 +1239,9 @@
 		
 		// Copy the vertices from m_rectverts
 		updateRectVerts ();
-		memcpy (quad->coords, m_rectverts, sizeof quad->coords);
+		
+		for (int i = 0; i < quad->vertices (); ++i)
+			quad->setVertex (i, m_rectverts[i]);
 		
 		quad->setColor (maincolor);
 		obj = quad;
@@ -1254,10 +1256,8 @@
 		
 		case 2:
 			// 2 verts - make a line
-			obj = new LDLine;
+			obj = new LDLine (verts[0], verts[1]);
 			obj->setColor (edgecolor);
-			for (ushort i = 0; i < 2; ++i)
-				obj->coords[i] = verts[i];
 			break;
 			
 		case 3:
@@ -1268,7 +1268,7 @@
 			
 			obj->setColor (maincolor);
 			for (ushort i = 0; i < obj->vertices (); ++i)
-				obj->coords[i] = verts[i];
+				obj->setVertex (i, verts[i]);
 			break;
 		}
 	}
@@ -1290,7 +1290,7 @@
 	
 	if (obj->vertices () >= 2)
 		for (int i = 0; i < obj->vertices (); ++i)
-			verts << obj->coords[i];
+			verts << obj->getVertex (i);
 	else if (obj->getType () == LDObject::Subfile || obj->getType () == LDObject::Radial) {
 		vector<LDObject*> objs;
 		
--- a/src/gui.cpp	Thu Jun 13 01:13:06 2013 +0300
+++ b/src/gui.cpp	Thu Jun 13 02:55:47 2013 +0300
@@ -618,7 +618,7 @@
 				if (i != 0)
 					descr += ", ";
 				
-				descr += obj->coords[i].stringRep (true).chars();
+				descr += obj->getVertex (i).stringRep (true);
 			}
 			break;
 		
--- a/src/gui_editactions.cpp	Thu Jun 13 01:13:06 2013 +0300
+++ b/src/gui_editactions.cpp	Thu Jun 13 02:55:47 2013 +0300
@@ -89,9 +89,10 @@
 		LDObject* copy = obj->clone ();
 		g_curfile->insertObj (idx++, copy);
 		g_win->sel () << copy;
+		g_win->R ()->compileObject (copy);
 	}
 	
-	g_win->fullRefresh ();
+	g_win->refresh ();
 	g_win->scrollToSelection ();
 }
 
@@ -296,17 +297,17 @@
 			numLines = 4;
 			
 			LDQuad* quad = static_cast<LDQuad*> (obj);
-			lines[0] = new LDLine (quad->coords[0], quad->coords[1]);
-			lines[1] = new LDLine (quad->coords[1], quad->coords[2]);
-			lines[2] = new LDLine (quad->coords[2], quad->coords[3]);
-			lines[3] = new LDLine (quad->coords[3], quad->coords[0]);
+			lines[0] = new LDLine (quad->getVertex (0), quad->getVertex (1));
+			lines[1] = new LDLine (quad->getVertex (1), quad->getVertex (2));
+			lines[2] = new LDLine (quad->getVertex (2), quad->getVertex (3));
+			lines[3] = new LDLine (quad->getVertex (3), quad->getVertex (0));
 		} else {
 			numLines = 3;
 			
 			LDTriangle* tri = static_cast<LDTriangle*> (obj);
-			lines[0] = new LDLine (tri->coords[0], tri->coords[1]);
-			lines[1] = new LDLine (tri->coords[1], tri->coords[2]);
-			lines[2] = new LDLine (tri->coords[2], tri->coords[0]); 
+			lines[0] = new LDLine (tri->getVertex (0), tri->getVertex (1));
+			lines[1] = new LDLine (tri->getVertex (1), tri->getVertex (2));
+			lines[2] = new LDLine (tri->getVertex (2), tri->getVertex (0)); 
 		}
 		
 		for (short i = 0; i < numLines; ++i) {
@@ -334,7 +335,7 @@
 		ulong idx = obj->getIndex (g_curfile);
 		for (short i = 0; i < obj->vertices(); ++i) {
 			LDVertex* vert = new LDVertex;
-			vert->pos = obj->coords[i];
+			vert->pos = obj->getVertex (i);
 			vert->setColor (obj->color ());
 			
 			g_curfile->insertObj (++idx, vert);
@@ -432,6 +433,12 @@
 }
 
 // =============================================================================
+static void rotateVertex (vertex& v, const vertex& rotpoint, const matrix& transform) {
+	v.move (-rotpoint);
+	v.transform (transform, g_origin);
+	v.move (rotpoint);
+}
+
 static void doRotate (const short l, const short m, const short n) {
 	vector<LDObject*> sel = g_win->sel ();
 	vector<vertex*> queue;
@@ -456,29 +463,30 @@
 		(n * n * (1 - cosangle)) + cosangle
 	});
 	
-	// Apply the above matrix to everything - first, mark down
-	// which vertices to transform
+	// Apply the above matrix to everything
 	for (LDObject* obj : sel) {
-		if (obj->vertices ())
-			for (short i = 0; i < obj->vertices (); ++i)
-				queue << &obj->coords[i];
-		else if (obj->hasMatrix ()) {
-			LDMatrixObject* mo = static_cast<LDSubfile*> (obj);
-			queue << const_cast<vertex*> (&mo->position ()); // TEMPORARY HACK
+		if (obj->vertices ()) {
+			for (short i = 0; i < obj->vertices (); ++i) {
+				vertex v = obj->getVertex (i);
+				rotateVertex (v, rotpoint, transform);
+				obj->setVertex (i, v);
+			}
+		} else if (obj->hasMatrix ()) {
+			LDMatrixObject* mo = dynamic_cast<LDMatrixObject*> (obj);
+			vertex v = mo->position ();
+			rotateVertex (v, rotpoint, transform);
+			mo->setPosition (v);
 			mo->setTransform (mo->transform () * transform);
-		} else if (obj->getType () == LDObject::Vertex)
-			queue << &static_cast<LDVertex*> (obj)->pos;
+		} else if (obj->getType () == LDObject::Vertex) {
+			LDVertex* vert = static_cast<LDVertex*> (obj);
+			vertex v = vert->pos;
+			rotateVertex (v, rotpoint, transform);
+			vert->pos = v;
+		}
 		
 		g_win->R ()->compileObject (obj);
 	}
 	
-	// Now do the actual transformations
-	for (vertex* v : queue) {
-		v->move (-rotpoint);
-		v->transform (transform, g_origin);
-		v->move (rotpoint);
-	}
-	
 	g_win->refresh ();
 }
 
@@ -518,9 +526,14 @@
 	setlocale (LC_ALL, "C");
 	
 	for (LDObject* obj : g_win->sel ())
-	for (short i = 0; i < obj->vertices (); ++i)
-	for (const Axis ax : g_Axes)
-		obj->coords[i][ax] = atof (fmt ("%.3f", obj->coords[i][ax]));
+	for (short i = 0; i < obj->vertices (); ++i) {
+		vertex v = obj->getVertex (i);
+		
+		for (const Axis ax : g_Axes)
+			v[ax] = atof (fmt ("%.3f", v[ax]));
+		
+		obj->setVertex (i, v);
+	}
 	
 	g_win->fullRefresh ();
 }
@@ -576,10 +589,11 @@
 	
 	vector<int> sel = dlg.axes ();
 	
-	for (LDObject* obj : g_win->sel ()) {
-		for (short i = 0; i < obj->vertices (); ++i)
+	for (LDObject* obj : g_win->sel ())
+	for (short i = 0; i < obj->vertices (); ++i) {
+		vertex v = obj->getVertex (i);
 		for (int ax : sel) {
-			double& coord = obj->coords[i][(Axis) ax];
+			double& coord = v[(Axis) ax];
 			
 			if (any || coord == search) {
 				if (!rel)
@@ -588,14 +602,16 @@
 				coord += replacement;
 			}
 		}
+		
+		obj->setVertex (i, v);
 	}
 	
 	g_win->fullRefresh ();
 }
 
-// =========================================================================================================================================
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-// =========================================================================================================================================
+// =================================================================================================
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+// =================================================================================================
 class FlipDialog : public QDialog {
 public:
 	explicit FlipDialog (QWidget* parent = 0, Qt::WindowFlags f = 0) : QDialog (parent, f) {
@@ -623,9 +639,14 @@
 	vector<int> sel = dlg.axes ();
 	
 	for (LDObject* obj : g_win->sel ())
-	for (short i = 0; i < obj->vertices (); ++i)
-	for (int ax : sel)
-		obj->coords[i][(Axis) ax] *= -1;
+	for (short i = 0; i < obj->vertices (); ++i) {
+		vertex v = obj->getVertex (i);
+		
+		for (int ax : sel)
+			v[(Axis) ax] *= -1;
+		
+		obj->setVertex (i, v);
+	}
 	
 	g_win->fullRefresh ();
 }
--- a/src/history.cpp	Thu Jun 13 01:13:06 2013 +0300
+++ b/src/history.cpp	Thu Jun 13 02:55:47 2013 +0300
@@ -26,6 +26,8 @@
 EXTERN_ACTION (undo)
 EXTERN_ACTION (redo)
 
+bool g_fullRefresh = false;
+
 History::History () {
 	setPos (-1);
 }
@@ -35,13 +37,19 @@
 		return;
 	
 	const list& set = changeset (pos ());
+	g_fullRefresh = false;
 	
 	// Iterate the list in reverse and undo all actions
 	for (const AbstractHistoryEntry* change : c_rev<AbstractHistoryEntry*> (set))
 		change->undo ();
 	
 	setPos (pos () - 1);
-	g_win->refresh ();
+	
+	if (!g_fullRefresh)
+		g_win->refresh ();
+	else
+		g_win->fullRefresh ();
+	
 	updateActions ();
 }
 
@@ -50,13 +58,19 @@
 		return;
 	
 	const list& set = changeset (pos () + 1);
+	g_fullRefresh = false;
 	
 	// Redo things - in the order as they were done in the first place
 	for (const AbstractHistoryEntry* change : set)
 		change->redo ();
 	
 	setPos (pos () + 1);
-	g_win->refresh ();
+	
+	if (!g_fullRefresh)
+		g_win->refresh ();
+	else
+		g_win->fullRefresh ();
+	
 	updateActions ();
 }
 
@@ -110,6 +124,8 @@
 	LDObject* obj = f->object (index ());
 	f->forgetObject (obj);
 	delete obj;
+	
+	g_fullRefresh = true;
 }
 
 void AddHistory::redo () const {
@@ -135,6 +151,8 @@
 	LDObject* obj = f->object (index ());
 	f->forgetObject (obj);
 	delete obj;
+	
+	g_fullRefresh = true;
 }
 
 DelHistory::~DelHistory () {}
--- a/src/ldtypes.cpp	Thu Jun 13 01:13:06 2013 +0300
+++ b/src/ldtypes.cpp	Thu Jun 13 02:55:47 2013 +0300
@@ -67,10 +67,8 @@
 	m_glinit = false;
 }
 
-LDGibberish::LDGibberish (str _zContent, str _zReason) {
-	contents = _zContent;
-	reason = _zReason;
-}
+LDGibberish::LDGibberish () {}
+LDGibberish::LDGibberish (str contents, str reason) : contents (contents), reason (reason) {}
 
 // =============================================================================
 str LDComment::raw () {
@@ -89,7 +87,7 @@
 	str val = fmt ("2 %d", color ());
 	
 	for (ushort i = 0; i < 2; ++i)
-		val += fmt  (" %s", coords[i].stringRep (false).chars ());
+		val += fmt  (" %s", getVertex (i).stringRep (false).chars ());
 	
 	return val;
 }
@@ -98,7 +96,7 @@
 	str val = fmt ("3 %d", color ());
 	
 	for (ushort i = 0; i < 3; ++i)
-		val += fmt  (" %s", coords[i].stringRep (false).chars ());
+		val += fmt  (" %s", getVertex (i).stringRep (false).chars ());
 	
 	return val;
 }
@@ -107,7 +105,7 @@
 	str val = fmt ("4 %d", color ());
 	
 	for (ushort i = 0; i < 4; ++i)
-		val += fmt  (" %s", coords[i].stringRep (false).chars ());
+		val += fmt  (" %s", getVertex (i).stringRep (false).chars ());
 	
 	return val;
 }
@@ -117,7 +115,7 @@
 	
 	// Add the coordinates
 	for (ushort i = 0; i < 4; ++i)
-		val += fmt  (" %s", coords[i].stringRep (false).chars ());
+		val += fmt  (" %s", getVertex (i).stringRep (false).chars ());
 	
 	return val;
 }
@@ -160,15 +158,8 @@
 	// |   |  =  | /    / |
 	// |   |     |/    /  |
 	// 1---2     1    1---2
-	LDTriangle* tri1 = new LDTriangle;
-	tri1->coords[0] = coords[0];
-	tri1->coords[1] = coords[1];
-	tri1->coords[2] = coords[3];
-	
-	LDTriangle* tri2 = new LDTriangle;
-	tri2->coords[0] = coords[1];
-	tri2->coords[1] = coords[2];
-	tri2->coords[2] = coords[3];
+	LDTriangle* tri1 = new LDTriangle (getVertex (0), getVertex (1), getVertex (3));
+	LDTriangle* tri2 = new LDTriangle (getVertex (1), getVertex (2), getVertex (3));
 	
 	// The triangles also inherit the quad's color
 	tri1->setColor (color ());
@@ -184,13 +175,11 @@
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 // =============================================================================
 void LDObject::replace (LDObject* replacement) {
+	long idx = getIndex (g_curfile);
+	assert (idx != -1);
+	
 	// Replace the instance of the old object with the new object
-	for (LDObject*& obj : *g_curfile) {
-		if (obj == this) {
-			obj = replacement;
-			break;
-		}
-	}
+	g_curfile->setObject (idx, replacement);
 	
 	// Remove the old object
 	delete this;
@@ -209,8 +198,8 @@
 }
 
 LDLine::LDLine (vertex v1, vertex v2) {
-	coords[0] = v1;
-	coords[1] = v2;
+	setVertex (0, v1);
+	setVertex (1, v2);
 }
 
 LDObject::~LDObject () {
@@ -232,8 +221,11 @@
 	case LDObject::CondLine:
 	case LDObject::Triangle:
 	case LDObject::Quad:
-		for (short i = 0; i < obj->vertices (); ++i)
-			obj->coords[i].transform (transform, pos);
+		for (short i = 0; i < obj->vertices (); ++i) {
+			vertex v = obj->getVertex (i);
+			v.transform (transform, pos);
+			obj->setVertex (i, v);
+		}
 		break;
 	
 	case LDObject::Subfile:
@@ -473,22 +465,22 @@
 
 void LDLine::move (vertex vect) {
 	for (short i = 0; i < 2; ++i)
-		coords[i] += vect;
+		setVertex (i, getVertex (i) + vect);
 }
 
 void LDTriangle::move (vertex vect) {
 	for (short i = 0; i < 3; ++i)
-		coords[i] += vect;
+		setVertex (i, getVertex (i) + vect);
 }
 
 void LDQuad::move (vertex vect) {
 	for (short i = 0; i < 4; ++i)
-		coords[i] += vect;
+		setVertex (i, getVertex (i) + vect);
 }
 
 void LDCondLine::move (vertex vect) {
 	for (short i = 0; i < 4; ++i)
-		coords[i] += vect;
+		setVertex (i, getVertex (i) + vect);
 }
 
 // =============================================================================
@@ -533,8 +525,8 @@
 					v1 (x1, 0.0f, z1);
 				
 				LDLine* line = new LDLine;
-				line->coords[0] = v0;
-				line->coords[1] = v1;
+				line->setVertex (0, v0);
+				line->setVertex (1, v1);
 				line->setColor (edgecolor);
 				line->setParent (this);
 				
@@ -582,10 +574,10 @@
 					v3 (x3, y3, z3);
 				
 				LDQuad* quad = new LDQuad;
-				quad->coords[0] = v0;
-				quad->coords[1] = v1;
-				quad->coords[2] = v2;
-				quad->coords[3] = v3;
+				quad->setVertex (0, v0);
+				quad->setVertex (1, v1);
+				quad->setVertex (2, v2);
+				quad->setVertex (3, v3);
 				
 				quad->setColor (color ());
 				quad->setParent (this);
@@ -611,15 +603,19 @@
 					v2 (x2, 0.0f, z2);
 				
 				LDTriangle* seg = new LDTriangle;
-				seg->coords[0] = v0;
-				seg->coords[1] = v1;
-				seg->coords[2] = v2;
+				seg->setVertex (0, v0);
+				seg->setVertex (1, v1);
+				seg->setVertex (2, v2);
 				seg->setColor (color ());
 				seg->setParent (this);
 				
-				if (applyTransform)
-					for (int i = 0; i < 3; ++i)
-						seg->coords[i].transform (transform (), position ());
+				if (applyTransform) {
+					for (int i = 0; i < 3; ++i) {
+						vertex v = seg->getVertex (i);
+						v.transform (transform (), position ());
+						seg->setVertex (i, v);
+					}
+				}
 				
 				obj = seg;
 			}
@@ -630,9 +626,13 @@
 		}
 		
 		if (obj) {
-			if (applyTransform)
-				for (int i = 0; i < obj->vertices (); ++i)
-					obj->coords[i].transform (transform (), position ());
+			if (applyTransform) {
+				for (int i = 0; i < obj->vertices (); ++i) {
+					vertex v = obj->getVertex (i);
+					v.transform (transform (), position ());
+					obj->setVertex (i, v);
+				}
+			}
 			
 			objs << obj;
 		}
@@ -727,9 +727,9 @@
 void LDTriangle::invert () {
 	// Triangle goes 0 -> 1 -> 2, reversed: 0 -> 2 -> 1.
 	// Thus, we swap 1 and 2.
-	vertex tmp = coords[1];
-	coords[1] = coords[2];
-	coords[2] = tmp;
+	vertex tmp = getVertex (1);
+	setVertex (1, getVertex (2));
+	setVertex (2, tmp);
 	
 	return;
 }
@@ -738,9 +738,9 @@
 	// Quad: 0 -> 1 -> 2 -> 3
 	// rev:  0 -> 3 -> 2 -> 1
 	// Thus, we swap 1 and 3.
-	vertex tmp = coords[1];
-	coords[1] = coords[3];
-	coords[3] = tmp;
+	vertex tmp = getVertex (1);
+	setVertex (1, getVertex (3));
+	setVertex (3, tmp);
 }
 
 static void invertSubfile (LDObject* obj) {
@@ -779,9 +779,9 @@
 static void invertLine (LDObject* line) {
 	// For lines, we swap the vertices. I don't think that a
 	// cond-line's control points need to be swapped, do they?
-	vertex tmp = line->coords[0];
-	line->coords[0] = line->coords[1];
-	line->coords[1] = tmp;
+	vertex tmp = line->getVertex (0);
+	line->setVertex (0, line->getVertex (1));
+	line->setVertex (1, tmp);
 }
 
 void LDLine::invert () {
@@ -797,22 +797,48 @@
 // =============================================================================
 LDLine* LDCondLine::demote () {
 	LDLine* repl = new LDLine;
-	memcpy (repl->coords, coords, sizeof coords);
+	
+	for (int i = 0; i < repl->vertices (); ++i)
+		repl->setVertex (i, getVertex (i));
+	
 	repl->setColor (color ());
 	
 	replace (repl);
 	return repl;
 }
 
-READ_ACCESSOR (short, LDObject::color) { return m_color; }
-SET_ACCESSOR (short, LDObject::setColor) {
+// =============================================================================
+template<class T> void changeProperty (LDObject* obj, T* ptr, const T& val) {
 	long idx;
-	if ((idx = getIndex (g_curfile)) != -1) {
-		str before = raw ();
-		m_color = val;
-		str after = raw ();
+	if ((idx = obj->getIndex (g_curfile)) != -1) {
+		str before = obj->raw ();
+		*ptr = val;
+		str after = obj->raw ();
 		
 		g_curfile->addToHistory (new EditHistory (idx, before, after));
 	} else
-		m_color = val;
+		*ptr = val;
+}
+
+READ_ACCESSOR (short, LDObject::color) { return m_color; }
+SET_ACCESSOR (short, LDObject::setColor) {
+	changeProperty (this, &m_color, val);
+}
+
+const vertex& LDObject::getVertex (int i) const {
+	return m_coords[i];
+}
+
+void LDObject::setVertex (int i, const vertex& vert) {
+	changeProperty (this, &m_coords[i], vert);
+}
+
+READ_ACCESSOR (vertex, LDMatrixObject::position) { return m_position; }
+SET_ACCESSOR (vertex, LDMatrixObject::setPosition) {
+	changeProperty (linkPointer (), &m_position, val);
+}
+
+READ_ACCESSOR (matrix, LDMatrixObject::transform) { return m_transform; }
+SET_ACCESSOR (matrix, LDMatrixObject::setTransform) {
+	changeProperty (linkPointer (), &m_transform, val);
 }
\ No newline at end of file
--- a/src/ldtypes.h	Thu Jun 13 01:13:06 2013 +0300
+++ b/src/ldtypes.h	Thu Jun 13 02:55:47 2013 +0300
@@ -23,7 +23,6 @@
 #include "types.h"
 
 #define LDOBJ(T) \
-	LD##T () {} \
 	virtual ~LD##T () {} \
 	virtual LDObject::Type getType () const { \
 		return LDObject::T; \
@@ -57,8 +56,9 @@
 // Common code for objects with matrices
 // =============================================================================
 class LDMatrixObject {
-	PROPERTY (matrix, transform, setTransform)
-	PROPERTY (vertex, position, setPosition)
+	DECLARE_PROPERTY (matrix, transform, setTransform)
+	DECLARE_PROPERTY (vertex, position, setPosition)
+	PROPERTY (LDObject*, linkPointer, setLinkPointer)
 	
 public:
 	LDMatrixObject () {}
@@ -115,9 +115,6 @@
 	// OpenGL list for this object
 	uint glLists[4];
 	
-	// Vertices of this object
-	vertex coords[4];
-	
 	// Type enumerator of this object
 	virtual LDObject::Type getType () const {
 		return LDObject::Unidentified;
@@ -168,10 +165,16 @@
 	virtual void        invert          ();
 	LDObject*           next            () const;
 	LDObject*           prev            () const;
+	void                setVertex       (int i, const vertex& vert);
+	const vertex&       getVertex       (int i) const;
+	void                setVertexCoord  (int i, const Axis ax, double value);
 
 protected:
 	bool m_glinit;
 	friend class GLRenderer;
+	
+private:
+	vertex m_coords[4];
 };
 
 // =============================================================================
@@ -190,6 +193,7 @@
 	LDOBJ_SCEMANTIC
 	LDOBJ_NO_MATRIX
 	
+	LDGibberish ();
 	LDGibberish (str _zContent, str _zReason);
 	
 	// Content of this unknown line
@@ -227,6 +231,7 @@
 	LDOBJ_NON_SCEMANTIC
 	LDOBJ_NO_MATRIX
 	
+	LDComment () {}
 	LDComment (str text) : text (text) {}
 	
 	str text; // The text of this comment
@@ -238,7 +243,7 @@
 // Represents a 0 BFC statement in the LDraw code. eStatement contains the type
 // of this statement.
 // =============================================================================
-class LDBFC : public LDComment {
+class LDBFC : public LDObject {
 public:
 	enum Type { CertifyCCW, CCW, CertifyCW, CW, NoCertify, InvertNext, NumStatements };
 	
@@ -248,6 +253,7 @@
 	LDOBJ_CUSTOM_SCEMANTIC { return (type == InvertNext); }
 	LDOBJ_NO_MATRIX
 	
+	LDBFC () {}
 	LDBFC (const LDBFC::Type type) : type (type) {}
 	
 	// Statement strings
@@ -271,6 +277,10 @@
 	LDOBJ_SCEMANTIC
 	LDOBJ_HAS_MATRIX
 	
+	LDSubfile () {
+		setLinkPointer (this);
+	}
+	
 	// Inlines this subfile. Note that return type is an array of heap-allocated
 	// LDObject-clones, they must be deleted one way or another.
 	vector<LDObject*> inlineContents (bool deep, bool cache);
@@ -291,6 +301,7 @@
 	LDOBJ_SCEMANTIC
 	LDOBJ_NO_MATRIX
 	
+	LDLine () {}
 	LDLine (vertex v1, vertex v2);
 };
 
@@ -308,6 +319,7 @@
 	LDOBJ_SCEMANTIC
 	LDOBJ_NO_MATRIX
 	
+	LDCondLine () {}
 	LDLine* demote ();
 };
 
@@ -326,10 +338,11 @@
 	LDOBJ_SCEMANTIC
 	LDOBJ_NO_MATRIX
 	
-	LDTriangle (vertex _v0, vertex _v1, vertex _v2) {
-		coords[0] = _v0;
-		coords[1] = _v1;
-		coords[2] = _v2;
+	LDTriangle () {}
+	LDTriangle (vertex v0, vertex v1, vertex v2) {
+		setVertex (0, v0);
+		setVertex (1, v1);
+		setVertex (2, v2);
 	}
 };
 
@@ -347,6 +360,8 @@
 	LDOBJ_SCEMANTIC
 	LDOBJ_NO_MATRIX
 	
+	LDQuad () {}
+	
 	// Split this quad into two triangles (note: heap-allocated)
 	vector<LDTriangle*> splitToTriangles ();
 };
@@ -367,6 +382,8 @@
 	LDOBJ_NON_SCEMANTIC
 	LDOBJ_NO_MATRIX
 	
+	LDVertex () {}
+	
 	vertex pos;
 };
 
@@ -403,9 +420,13 @@
 	LDOBJ_SCEMANTIC
 	LDOBJ_HAS_MATRIX
 	
+	LDRadial () { setLinkPointer (this); }
 	LDRadial (LDRadial::Type radType, vertex pos, matrix transform, short divs, short segs, short ringNum) :
 		LDMatrixObject (transform, pos), PROP_NAME (type) (radType), PROP_NAME (divisions) (divs),
-		PROP_NAME (segments) (segs), PROP_NAME (number) (ringNum) {}
+		PROP_NAME (segments) (segs), PROP_NAME (number) (ringNum)
+	{
+		setLinkPointer (this);
+	}
 	
 	// Returns a set of objects that provide the equivalent of this radial.
 	// Note: objects are heap-allocated.

mercurial