Refactor primitives

Wed, 16 Nov 2016 01:28:42 +0200

author
Teemu Piippo <teemu@hecknology.net>
date
Wed, 16 Nov 2016 01:28:42 +0200
changeset 1053
2a48c0fff107
parent 1052
6fd1597b688e
child 1054
1f4c8a369e7c

Refactor primitives

src/basics.cpp file | annotate | diff | comparison | revisions
src/basics.h file | annotate | diff | comparison | revisions
src/dialogs/generateprimitivedialog.cpp file | annotate | diff | comparison | revisions
src/dialogs/generateprimitivedialog.h file | annotate | diff | comparison | revisions
src/editmodes/circleMode.cpp file | annotate | diff | comparison | revisions
src/primitives.cpp file | annotate | diff | comparison | revisions
src/primitives.h file | annotate | diff | comparison | revisions
src/toolsets/filetoolset.cpp file | annotate | diff | comparison | revisions
--- a/src/basics.cpp	Wed Nov 16 00:52:22 2016 +0200
+++ b/src/basics.cpp	Wed Nov 16 01:28:42 2016 +0200
@@ -272,3 +272,41 @@
 {
 	return qHash(key.x()) ^ rotl10(qHash(key.y())) ^ rotl20(qHash(key.z()));
 }
+
+/*
+ * getRadialPoint
+ *
+ * Gets an ordinate of a point in circle.
+ * If func == sin, then this gets the Y co-ordinate, if func == cos, then X co-ordinate.
+ */
+double getRadialPoint(int segment, int divisions, double(*func)(double))
+{
+	return (*func)((segment * 2 * pi) / divisions);
+}
+
+/*
+ * makeCircle
+ *
+ * Creates a possibly partial circle rim.
+ * Divisions is how many segments the circle makes if up if it's full.
+ * Segments is now many segments are added.
+ * Radius is the radius of the circle.
+ *
+ * If divisions == segments, this yields a full circle rim.
+ * The rendered circle is returned as a vector of lines.
+ */
+QVector<QLineF> makeCircle(int segments, int divisions, double radius)
+{
+	QVector<QLineF> lines;
+
+	for (int i = 0; i < segments; ++i)
+	{
+		double x0 = radius * getRadialPoint(i, divisions, cos);
+		double x1 = radius * getRadialPoint(i + 1, divisions, cos);
+		double z0 = radius * getRadialPoint(i, divisions, sin);
+		double z1 = radius * getRadialPoint(i + 1, divisions, sin);
+		lines.append(QLineF {QPointF {x0, z0}, QPointF {x1, z1}});
+	}
+
+	return lines;
+}
--- a/src/basics.h	Wed Nov 16 00:52:22 2016 +0200
+++ b/src/basics.h	Wed Nov 16 01:28:42 2016 +0200
@@ -205,4 +205,7 @@
 bool valueInEnum(typename std::underlying_type<Enum>::type x)
 {
 	return x >= EnumLimits<Enum>::First and x <= EnumLimits<Enum>::Last;
-}
\ No newline at end of file
+}
+
+double getRadialPoint(int segment, int divisions, double(*func)(double));
+QVector<QLineF> makeCircle(int segments, int divisions, double radius);
--- a/src/dialogs/generateprimitivedialog.cpp	Wed Nov 16 00:52:22 2016 +0200
+++ b/src/dialogs/generateprimitivedialog.cpp	Wed Nov 16 01:28:42 2016 +0200
@@ -46,18 +46,18 @@
 }
 
 
-PrimitiveSpec GeneratePrimitiveDialog::spec() const
+PrimitiveModel GeneratePrimitiveDialog::primitiveModel() const
 {
-	PrimitiveSpec result;
+	PrimitiveModel result;
 	result.type =
-		ui.typeCircle->isChecked()       ? Circle :
-		ui.typeCylinder->isChecked()     ? Cylinder :
-		ui.typeDisc->isChecked()         ? Disc :
-		ui.typeDiscNegative->isChecked() ? DiscNegative :
-		ui.typeRing->isChecked()         ? Ring :
-										   Cone;
+		ui.typeCircle->isChecked()       ? PrimitiveModel::Circle :
+		ui.typeCylinder->isChecked()     ? PrimitiveModel::Cylinder :
+		ui.typeDisc->isChecked()         ? PrimitiveModel::Disc :
+		ui.typeDiscNegative->isChecked() ? PrimitiveModel::DiscNegative :
+		ui.typeRing->isChecked()         ? PrimitiveModel::Ring :
+		                                   PrimitiveModel::Cone;
 	result.divisions = ui.highResolution->isChecked() ? HighResolution : LowResolution;
 	result.segments = ui.segments->value();
 	result.ringNumber = ui.ringNumber->value();
 	return result;
-}
\ No newline at end of file
+}
--- a/src/dialogs/generateprimitivedialog.h	Wed Nov 16 00:52:22 2016 +0200
+++ b/src/dialogs/generateprimitivedialog.h	Wed Nov 16 01:28:42 2016 +0200
@@ -29,7 +29,7 @@
 public:
 	GeneratePrimitiveDialog(QWidget* parent = nullptr, Qt::WindowFlags f = 0);
 	virtual ~GeneratePrimitiveDialog();
-	PrimitiveSpec spec() const;
+	PrimitiveModel primitiveModel() const;
 
 public slots:
 	void highResolutionToggled (bool on);
--- a/src/editmodes/circleMode.cpp	Wed Nov 16 00:52:22 2016 +0200
+++ b/src/editmodes/circleMode.cpp	Wed Nov 16 01:28:42 2016 +0200
@@ -87,13 +87,13 @@
 void CircleMode::endDraw()
 {
 	LDObjectList objs;
-	PrimitiveSpec spec;
-	spec.segments = m_window->ringToolSegments();
-	spec.divisions = m_window->ringToolHiRes() ? HighResolution : LowResolution;
-	spec.ringNumber = 0;
+	PrimitiveModel model;
+	model.segments = m_window->ringToolSegments();
+	model.divisions = m_window->ringToolHiRes() ? HighResolution : LowResolution;
+	model.ringNumber = 0;
 	double dist0 (getCircleDrawDist (0));
 	double dist1 (getCircleDrawDist (1));
-	LDDocument* refFile;
+	LDDocument* primitiveFile;
 	Matrix transform;
 	bool circleOrDisc = false;
 
@@ -103,31 +103,31 @@
 	if (dist0 == dist1)
 	{
 		// If the radii are the same, there's no ring space to fill. Use a circle.
-		spec.type = ::Circle;
-		refFile = primitives()->getPrimitive(spec);
+		model.type = PrimitiveModel::Circle;
+		primitiveFile = primitives()->getPrimitive(model);
 		transform = getCircleDrawMatrix (dist0);
 		circleOrDisc = true;
 	}
 	else if (dist0 == 0 or dist1 == 0)
 	{
 		// If either radii is 0, use a disc.
-		spec.type = ::Disc;
-		refFile = primitives()->getPrimitive(spec);
+		model.type = PrimitiveModel::Disc;
+		primitiveFile = primitives()->getPrimitive(model);
 		transform = getCircleDrawMatrix ((dist0 != 0) ? dist0 : dist1);
 		circleOrDisc = true;
 	}
 	else if (g_RingFinder.findRings (dist0, dist1))
 	{
 		// The ring finder found a solution, use that. Add the component rings to the file.
-		spec.type = ::Ring;
+		model.type = PrimitiveModel::Ring;
 
-		for (const RingFinder::Component& cmp : g_RingFinder.bestSolution()->getComponents())
+		for (const RingFinder::Component& component : g_RingFinder.bestSolution()->getComponents())
 		{
-			spec.ringNumber = cmp.num;
-			refFile = primitives()->getPrimitive(spec);
+			model.ringNumber = component.num;
+			primitiveFile = primitives()->getPrimitive(model);
 			LDSubfileReference* ref = LDSpawn<LDSubfileReference>();
-			ref->setFileInfo (refFile);
-			ref->setTransformationMatrix (getCircleDrawMatrix (cmp.scale));
+			ref->setFileInfo (primitiveFile);
+			ref->setTransformationMatrix (getCircleDrawMatrix (component.scale));
 			ref->setPosition (m_drawedVerts[0]);
 			ref->setColor (MainColor);
 			objs << ref;
@@ -136,7 +136,6 @@
 	else
 	{
 		// Ring finder failed, last resort: draw the ring with quads
-		QList<QLineF> c0, c1;
 		Axis localx, localy, localz;
 		renderer()->getRelativeAxes (localx, localy);
 		localz = (Axis) (3 - localx - localy);
@@ -149,10 +148,10 @@
 		templ.setCoordinate (localz, renderer()->getDepthValue());
 
 		// Calculate circle coords
-		primitives()->makeCircle(spec.segments, spec.divisions, dist0, c0);
-		primitives()->makeCircle(spec.segments, spec.divisions, dist1, c1);
+		QVector<QLineF> c0 = makeCircle(model.segments, model.divisions, dist0);
+		QVector<QLineF> c1 = makeCircle(model.segments, model.divisions, dist1);
 
-		for (int i = 0; i < spec.segments; ++i)
+		for (int i = 0; i < model.segments; ++i)
 		{
 			Vertex v0, v1, v2, v3;
 			v0 = v1 = v2 = v3 = templ;
@@ -176,10 +175,10 @@
 		}
 	}
 
-	if (circleOrDisc and refFile)
+	if (circleOrDisc and primitiveFile)
 	{
 		LDSubfileReference* ref = LDSpawn<LDSubfileReference>();
-		ref->setFileInfo (refFile);
+		ref->setFileInfo (primitiveFile);
 		ref->setTransformationMatrix (transform);
 		ref->setPosition (m_drawedVerts[0]);
 		ref->setColor (MainColor);
--- a/src/primitives.cpp	Wed Nov 16 00:52:22 2016 +0200
+++ b/src/primitives.cpp	Wed Nov 16 01:28:42 2016 +0200
@@ -257,54 +257,28 @@
 	f.close();
 }
 
-
-double getRadialPoint(int i, int divs, double(*func)(double))
-{
-	return (*func)((i * 2 * pi) / divs);
-};
-
-
-// TODO: this doesn't really belong here.
-void PrimitiveManager::makeCircle (int segs, int divs, double radius, QList<QLineF>& lines)
+LDObjectList PrimitiveModel::generateBody() const
 {
-	for (int i = 0; i < segs; ++i)
-	{
-		double x0 = radius * getRadialPoint(i, divs, cos);
-		double x1 = radius * getRadialPoint(i + 1, divs, cos);
-		double z0 = radius * getRadialPoint(i, divs, sin);
-		double z1 = radius * getRadialPoint(i + 1, divs, sin);
-		lines << QLineF(QPointF(x0, z0), QPointF(x1, z1));
-	}
-}
+	LDObjectList objects;
+	QVector<int> conditionalLineSegments;
+	QVector<QLineF> circle = makeCircle(segments, divisions, 1);
 
-
-LDObjectList PrimitiveManager::makePrimitiveBody(const PrimitiveSpec& spec)
-{
-	LDObjectList objs;
-	QList<int> conditionalLineSegments;
-	QList<QLineF> circle;
-
-	makeCircle (spec.segments, spec.divisions, 1, circle);
-
-	for (int i = 0; i < spec.segments; ++i)
+	for (int i = 0; i < segments; ++i)
 	{
 		double x0 = circle[i].x1();
 		double x1 = circle[i].x2();
 		double z0 = circle[i].y1();
 		double z1 = circle[i].y2();
 
-		switch (spec.type)
+		switch (type)
 		{
 		case Circle:
 			{
-				Vertex v0 (x0, 0.0f, z0),
-				  v1 (x1, 0.0f, z1);
-
-				LDLine* line (LDSpawn<LDLine>());
-				line->setVertex (0, v0);
-				line->setVertex (1, v1);
-				line->setColor (EdgeColor);
-				objs << line;
+				LDLine* line = LDSpawn<LDLine>();
+				line->setVertex(0, Vertex {x0, 0.0f, z0});
+				line->setVertex(1, Vertex {x1, 0.0f, z1});
+				line->setColor(EdgeColor);
+				objects.append(line);
 			}
 			break;
 
@@ -315,29 +289,27 @@
 				double x2, x3, z2, z3;
 				double y0, y1, y2, y3;
 
-				if (spec.type == Cylinder)
+				if (type == Cylinder)
 				{
 					x2 = x1;
 					x3 = x0;
 					z2 = z1;
 					z3 = z0;
-
 					y0 = y1 = 0.0f;
 					y2 = y3 = 1.0f;
 				}
 				else
 				{
-					x2 = x1 * (spec.ringNumber + 1);
-					x3 = x0 * (spec.ringNumber + 1);
-					z2 = z1 * (spec.ringNumber + 1);
-					z3 = z0 * (spec.ringNumber + 1);
+					x2 = x1 * (ringNumber + 1);
+					x3 = x0 * (ringNumber + 1);
+					z2 = z1 * (ringNumber + 1);
+					z3 = z0 * (ringNumber + 1);
+					x0 *= ringNumber;
+					x1 *= ringNumber;
+					z0 *= ringNumber;
+					z1 *= ringNumber;
 
-					x0 *= spec.ringNumber;
-					x1 *= spec.ringNumber;
-					z0 *= spec.ringNumber;
-					z1 *= spec.ringNumber;
-
-					if (spec.type == Ring)
+					if (type == Ring)
 						y0 = y1 = y2 = y3 = 0.0f;
 					else
 					{
@@ -346,21 +318,20 @@
 					}
 				}
 
-				Vertex v0 (x0, y0, z0);
-				Vertex v1 (x1, y1, z1);
-				Vertex v2 (x2, y2, z2);
-				Vertex v3 (x3, y3, z3);
-
-				LDQuad* quad (LDSpawn<LDQuad> (v0, v1, v2, v3));
+				Vertex v0 = {x0, y0, z0};
+				Vertex v1 = {x1, y1, z1};
+				Vertex v2 = {x2, y2, z2};
+				Vertex v3 = {x3, y3, z3};
+				LDQuad* quad = LDSpawn<LDQuad>(v0, v1, v2, v3);
 				quad->setColor (MainColor);
 
-				if (spec.type == Cylinder)
+				if (type == Cylinder)
 					quad->invert();
 
-				objs << quad;
+				objects.append(quad);
 
-				if (spec.type == Cylinder or spec.type == Cone)
-					conditionalLineSegments << i;
+				if (type == Cylinder or type == Cone)
+					conditionalLineSegments.append(i);
 			}
 			break;
 
@@ -369,26 +340,28 @@
 			{
 				double x2, z2;
 
-				if (spec.type == Disc)
-					x2 = z2 = 0.0f;
+				if (type == Disc)
+				{
+					x2 = z2 = 0.0;
+				}
 				else
 				{
-					x2 = (x0 >= 0.0f) ? 1.0f : -1.0f;
-					z2 = (z0 >= 0.0f) ? 1.0f : -1.0f;
+					x2 = (x0 >= 0.0) ? 1.0 : -1.0;
+					z2 = (z0 >= 0.0) ? 1.0 : -1.0;
 				}
 
-				Vertex v0 (x0, 0.0f, z0),
-					   v1 (x1, 0.0f, z1),
-					   v2 (x2, 0.0f, z2);
+				Vertex v0 = {x0, 0.0, z0};
+				Vertex v1 = {x1, 0.0, z1};
+				Vertex v2 = {x2, 0.0, z2};
 
 				// Disc negatives need to go the other way around, otherwise
 				// they'll end up upside-down.
-				LDTriangle* seg (LDSpawn<LDTriangle>());
-				seg->setColor (MainColor);
-				seg->setVertex (spec.type == Disc ? 0 : 2, v0);
-				seg->setVertex (1, v1);
-				seg->setVertex (spec.type == Disc ? 2 : 0, v2);
-				objs << seg;
+				LDTriangle* segment = LDSpawn<LDTriangle>();
+				segment->setColor(MainColor);
+				segment->setVertex(type == Disc ? 0 : 2, v0);
+				segment->setVertex(1, v1);
+				segment->setVertex(type == Disc ? 2 : 0, v2);
+				objects.append(segment);
 			}
 			break;
 		}
@@ -396,45 +369,49 @@
 
 	// If this is not a full circle, we need a conditional line at the other
 	// end, too.
-	if (spec.segments < spec.divisions and not conditionalLineSegments.isEmpty())
-		conditionalLineSegments << spec.segments;
+	if (segments < divisions and not conditionalLineSegments.isEmpty())
+		conditionalLineSegments << segments;
 
 	for (int i : conditionalLineSegments)
 	{
-		Vertex v0 (getRadialPoint (i, spec.divisions, cos), 0.0f, getRadialPoint (i, spec.divisions, sin));
+		Vertex v0 = {getRadialPoint(i, divisions, cos), 0.0f, getRadialPoint(i, divisions, sin)};
 		Vertex v1;
-		Vertex v2 (getRadialPoint (i + 1, spec.divisions, cos), 0.0f, getRadialPoint (i + 1, spec.divisions, sin));
-		Vertex v3 (getRadialPoint (i - 1, spec.divisions, cos), 0.0f, getRadialPoint (i - 1, spec.divisions, sin));
+		Vertex v2 = {getRadialPoint(i + 1, divisions, cos), 0.0f, getRadialPoint(i + 1, divisions, sin)};
+		Vertex v3 = {getRadialPoint(i - 1, divisions, cos), 0.0f, getRadialPoint(i - 1, divisions, sin)};
 
-		if (spec.type == Cylinder)
+		if (type == Cylinder)
 		{
-			v1 = Vertex (v0[X], 1.0f, v0[Z]);
+			v1 = {v0[X], 1.0f, v0[Z]};
 		}
-		else if (spec.type == Cone)
+		else if (type == Cone)
 		{
-			v1 = Vertex (v0[X] * (spec.ringNumber + 1), 0.0f, v0[Z] * (spec.ringNumber + 1));
-			v0.setX (v0.x() * spec.ringNumber);
-			v0.setY (1.0);
-			v0.setZ (v0.z() * spec.ringNumber);
+			v1 = {v0[X] * (ringNumber + 1), 0.0, v0[Z] * (ringNumber + 1)};
+			v0 = {v0[X] * ringNumber, 1.0, v0[Z] * ringNumber};
 		}
 
-		LDCondLine* line = (LDSpawn<LDCondLine>());
-		line->setColor (EdgeColor);
-		line->setVertex (0, v0);
-		line->setVertex (1, v1);
-		line->setVertex (2, v2);
-		line->setVertex (3, v3);
-		objs << line;
+		LDCondLine* line = LDSpawn<LDCondLine>();
+		line->setColor(EdgeColor);
+		line->setVertex(0, v0);
+		line->setVertex(1, v1);
+		line->setVertex(2, v2);
+		line->setVertex(3, v3);
+		objects.append(line);
 	}
 
-	return objs;
+	return objects;
 }
 
 
-QString PrimitiveManager::primitiveTypeName (PrimitiveType type)
+QString PrimitiveModel::typeName() const
+{
+	return typeName(type);
+}
+
+
+QString PrimitiveModel::typeName(PrimitiveModel::Type type)
 {
 	// Not translated as primitives are in English.
-	const char* names[] = { "Circle", "Cylinder", "Disc", "Disc Negative", "Ring", "Cone" };
+	const char* names[] = {"Circle", "Cylinder", "Disc", "Disc Negative", "Ring", "Cone"};
 
 	if (type >= 0 and type < countof(names))
 		return names[type];
@@ -443,66 +420,65 @@
 }
 
 
-QString PrimitiveManager::makeRadialFileName(const PrimitiveSpec& spec)
+QString PrimitiveModel::makeFileName() const
 {
-	int numerator = spec.segments;
-	int denominator = spec.divisions;
+	int numerator = segments;
+	int denominator = divisions;
 
 	// Simplify the fractional part, but the denominator must be at least 4.
-	simplify (numerator, denominator);
+	simplify(numerator, denominator);
 
 	if (denominator < 4)
 	{
-		const int factor = 4 / denominator;
+		int factor = 4 / denominator;
 		numerator *= factor;
 		denominator *= factor;
 	}
 
 	// Compose some general information: prefix, fraction, root, ring number
-	QString prefix = (spec.divisions == LowResolution) ? "" : format ("%1/", spec.divisions);
+	QString prefix = (divisions == LowResolution) ? "" : format ("%1/", divisions);
 	QString frac = format ("%1-%2", numerator, denominator);
-	static const char* roots[] = { "edge", "cyli", "disc", "ndis", "ring", "con" };
-	QString root = roots[spec.type];
-	QString numstr = (spec.type == Ring or spec.type == Cone) ? format ("%1", spec.ringNumber) : "";
+	static const char* roots[] = {"edge", "cyli", "disc", "ndis", "ring", "con"};
+	QString root = roots[type];
+	QString numberString = (type == Ring or type == Cone) ? format ("%1", ringNumber) : "";
 
 	// Truncate the root if necessary (7-16rin4.dat for instance).
 	// However, always keep the root at least 2 characters.
-	int extra = (frac.length() + numstr.length() + root.length()) - 8;
-	root.chop (qBound (0, extra, 2));
+	int extra = (frac.length() + numberString.length() + root.length()) - 8;
+	root.chop(qBound(0, extra, 2));
 
 	// Stick them all together and return the result.
-	return prefix + frac + root + numstr + ".dat";
+	return prefix + frac + root + numberString + ".dat";
 }
 
 
-LDDocument* PrimitiveManager::generatePrimitive(const PrimitiveSpec& spec)
+LDDocument* PrimitiveManager::generatePrimitive(const PrimitiveModel& spec)
 {
 	// Make the description
 	QString fraction = QString::number ((float) spec.segments / spec.divisions);
-	QString name = makeRadialFileName(spec);
+	QString fileName = spec.makeFileName();
 	QString description;
 
 	// Ensure that there's decimals, even if they're 0.
 	if (fraction.indexOf (".") == -1)
 		fraction += ".0";
 
-	if (spec.type == Ring or spec.type == Cone)
+	if (spec.type == PrimitiveModel::Ring or spec.type == PrimitiveModel::Cone)
 	{
 		QString spacing =
 			(spec.ringNumber < 10) ? "  " :
 			(spec.ringNumber < 100) ? " "  : "";
-
-		description = format ("%1 %2%3 x %4", primitiveTypeName (spec.type), spacing, spec.ringNumber, fraction);
+		description = format ("%1 %2%3 x %4", PrimitiveModel::typeName(spec.type), spacing, spec.ringNumber, fraction);
 	}
 	else
-		description = format ("%1 %2", primitiveTypeName (spec.type), fraction);
+		description = format ("%1 %2", PrimitiveModel::typeName(spec.type), fraction);
 
 	// Prepend "Hi-Res" if 48/ primitive.
 	if (spec.divisions == HighResolution)
 		description.insert (0, "Hi-Res ");
 
 	LDDocument* document = m_window->newDocument();
-	document->setDefaultName (name);
+	document->setDefaultName(fileName);
 
 	QString author = APPNAME;
 	QString license = "";
@@ -516,60 +492,66 @@
 
 	LDObjectList objs;
 
-	objs << LDSpawn<LDComment> (description)
-		 << LDSpawn<LDComment> (format ("Name: %1", name))
-		 << LDSpawn<LDComment> (format ("Author: %1", author))
-		 << LDSpawn<LDComment> (format ("!LDRAW_ORG Unofficial_%1Primitive", hires ?  "48_" : ""))
-		 << LDSpawn<LDComment> (license)
-		 << LDSpawn<LDEmpty>()
-		 << LDSpawn<LDBfc> (BfcStatement::CertifyCCW)
-		 << LDSpawn<LDEmpty>();
-
+	objs.append(LDSpawn<LDComment>(description));
+	objs.append(LDSpawn<LDComment>(format("Name: %1", fileName)));
+	objs.append(LDSpawn<LDComment>(format("Author: %1", author)));
+	objs.append(LDSpawn<LDComment>(format("!LDRAW_ORG Unofficial_%1Primitive", hires ?  "48_" : "")));
+	objs.append(LDSpawn<LDComment>(license));
+	objs.append(LDSpawn<LDEmpty>());
+	objs.append(LDSpawn<LDBfc> (BfcStatement::CertifyCCW));
+	objs.append(LDSpawn<LDEmpty>());
 	document->openForEditing();
-	document->history()->setIgnoring (false);
-	document->addObjects (objs);
-	document->addObjects (makePrimitiveBody(spec));
+	document->history()->setIgnoring(false);
+	document->addObjects(objs);
+	document->addObjects(spec.generateBody());
 	document->addHistoryStep();
 	return document;
 }
 
-
-// Gets a primitive by the given spec. If the primitive cannot be found, it will be automatically generated.
-LDDocument* PrimitiveManager::getPrimitive(const PrimitiveSpec& spec)
+/*
+ * PrimitiveManager :: getPrimitive
+ *
+ * Gets a primitive by the given model. If the primitive cannot be found, it will be automatically generated.
+ */
+LDDocument* PrimitiveManager::getPrimitive(const PrimitiveModel& model)
 {
-	QString name = makeRadialFileName(spec);
+	QString name = model.makeFileName();
 	LDDocument* document = m_window->documents()->getDocumentByName (name);
 
 	if (document)
 		return document;
-
-	return generatePrimitive(spec);
+	else
+		return generatePrimitive(model);
 }
 
-
+/*
+ * PrimitiveManager :: populateTreeWidget
+ *
+ * Fills in a tree widget with all known primitives.
+ */
 void PrimitiveManager::populateTreeWidget(QTreeWidget* tree, const QString& selectByDefault)
 {
 	tree->clear();
 
 	for (PrimitiveCategory* category : m_categories)
 	{
-		PrimitiveTreeItem* parentItem = new PrimitiveTreeItem (tree, nullptr);
-		parentItem->setText (0, category->name());
+		PrimitiveTreeItem* parentItem = new PrimitiveTreeItem {tree, nullptr};
+		parentItem->setText(0, category->name());
 		QList<QTreeWidgetItem*> subfileItems;
 
-		for (Primitive& prim : category->primitives)
+		for (Primitive& primitive : category->primitives)
 		{
-			PrimitiveTreeItem* item = new PrimitiveTreeItem (parentItem, &prim);
-			item->setText (0, format ("%1 - %2", prim.name, prim.title));
-			subfileItems << item;
+			PrimitiveTreeItem* item = new PrimitiveTreeItem {parentItem, &primitive};
+			item->setText(0, format("%1 - %2", primitive.name, primitive.title));
+			subfileItems.append(item);
 
 			// If this primitive is the one the current object points to,
 			// select it by default
-			if (selectByDefault == prim.name)
-				tree->setCurrentItem (item);
+			if (selectByDefault == primitive.name)
+				tree->setCurrentItem(item);
 		}
 
-		tree->addTopLevelItem (parentItem);
+		tree->addTopLevelItem(parentItem);
 	}
 }
 
--- a/src/primitives.h	Wed Nov 16 00:52:22 2016 +0200
+++ b/src/primitives.h	Wed Nov 16 01:28:42 2016 +0200
@@ -35,22 +35,25 @@
 	PrimitiveCategory* category;
 };
 
-enum PrimitiveType
+struct PrimitiveModel
 {
-	Circle,
-	Cylinder,
-	Disc,
-	DiscNegative,
-	Ring,
-	Cone,
-};
-
-struct PrimitiveSpec
-{
-	PrimitiveType type;
+	enum Type
+	{
+		Circle,
+		Cylinder,
+		Disc,
+		DiscNegative,
+		Ring,
+		Cone,
+	} type;
 	int segments;
 	int divisions;
 	int ringNumber;
+
+	QString typeName() const;
+	LDObjectList generateBody() const;
+	static QString typeName(Type type);
+	QString makeFileName() const;
 };
 
 class PrimitiveCategory : public QObject
@@ -89,24 +92,22 @@
 	PrimitiveManager(QObject* parent);
 
 	PrimitiveScanner* activeScanner();
-	LDDocument* generatePrimitive(const PrimitiveSpec &spec);
-	LDDocument* getPrimitive(const PrimitiveSpec &spec);
+	LDDocument* generatePrimitive(const PrimitiveModel &spec);
+	LDDocument* getPrimitive(const PrimitiveModel &spec);
 	QString getPrimitivesCfgPath() const;
 	void loadPrimitives();
-	void makeCircle(int segs, int divs, double radius, QList<QLineF>& lines);
-	QString makeRadialFileName(const PrimitiveSpec &spec);
-	void populateTreeWidget(QTreeWidget* tree, const QString& selectByDefault = QString());
-	QString primitiveTypeName(PrimitiveType type);
-	Q_SLOT void scanDone();
+	void populateTreeWidget(QTreeWidget* tree, const QString& selectByDefault = {});
 	void startScan();
 
+public slots:
+	void scanDone();
+
 private:
 	QList<PrimitiveCategory*> m_categories;
 	PrimitiveScanner* m_activeScanner;
 	QList<Primitive> m_primitives;
 	PrimitiveCategory* m_unmatched;
 
-	LDObjectList makePrimitiveBody(const PrimitiveSpec &spec);
 	void loadCategories();
 	void populateCategories();
 	void clearCategories();
--- a/src/toolsets/filetoolset.cpp	Wed Nov 16 00:52:22 2016 +0200
+++ b/src/toolsets/filetoolset.cpp	Wed Nov 16 01:28:42 2016 +0200
@@ -186,7 +186,7 @@
 
 void FileToolset::downloadFrom()
 {
-	PartDownloader* dialog = new PartDownloader (m_window);
+	PartDownloader* dialog = new PartDownloader {m_window};
 	connect(dialog, &PartDownloader::primaryFileDownloaded, [&]()
 	{
 		m_window->changeDocument (dialog->primaryFile());
@@ -198,11 +198,11 @@
 
 void FileToolset::makePrimitive()
 {
-	GeneratePrimitiveDialog* dialog = new GeneratePrimitiveDialog(m_window);
+	GeneratePrimitiveDialog* dialog = new GeneratePrimitiveDialog {m_window};
 
 	if (dialog->exec())
 	{
-		LDDocument* primitive = primitives()->generatePrimitive(dialog->spec());
+		LDDocument* primitive = primitives()->generatePrimitive(dialog->primitiveModel());
 		primitive->openForEditing();
 		m_window->save(primitive, false);
 	}

mercurial