added the disc and disc negative to the circular primitive type

Sun, 10 Jun 2018 17:17:42 +0300

author
Teemu Piippo <teemu@hecknology.net>
date
Sun, 10 Jun 2018 17:17:42 +0300
changeset 1399
f52ea4078f5d
parent 1398
1c70d3447d20
child 1400
ae83213bdd63

added the disc and disc negative to the circular primitive type

src/editmodes/circleMode.cpp file | annotate | diff | comparison | revisions
src/linetypes/circularprimitive.cpp file | annotate | diff | comparison | revisions
src/linetypes/circularprimitive.h file | annotate | diff | comparison | revisions
src/parser.cpp file | annotate | diff | comparison | revisions
--- a/src/editmodes/circleMode.cpp	Sun Jun 10 16:50:14 2018 +0300
+++ b/src/editmodes/circleMode.cpp	Sun Jun 10 17:17:42 2018 +0300
@@ -27,6 +27,7 @@
 #include "../grid.h"
 #include "../linetypes/modelobject.h"
 #include "../linetypes/quadrilateral.h"
+#include "../linetypes/circularprimitive.h"
 #include "../algorithms/geometry.h"
 
 CircleMode::CircleMode(Canvas* canvas) :
@@ -88,16 +89,11 @@
 void CircleMode::endDraw()
 {
 	Model model {m_documents};
-	PrimitiveModel primitiveModel;
-	primitiveModel.segments = m_window->ringToolSegments();
-	primitiveModel.divisions = m_window->ringToolDivisions();
-	primitiveModel.ringNumber = 0;
-	double dist0 (getCircleDrawDist (0));
-	double dist1 (getCircleDrawDist (1));
-	LDDocument* primitiveFile;
-	Matrix transform;
-
-	bool circleOrDisc = false;
+	int segments = m_window->ringToolSegments();
+	int divisions = m_window->ringToolDivisions();
+	double dist0 = getCircleDrawDist(0);
+	double dist1 = getCircleDrawDist(1);
+	Vertex displacement = m_drawedVerts.first();
 
 	if (dist1 < dist0)
 		qSwap(dist0, dist1);
@@ -105,32 +101,33 @@
 	if (qFuzzyCompare(dist0, dist1))
 	{
 		// Special case: radii are the same, there's no area. Use a circle.
-		primitiveModel.type = PrimitiveModel::Circle;
-		primitiveFile = primitives()->getPrimitive(primitiveModel);
 		// transform = shearMatrixForPlane(renderer());
-		transform = Matrix::fromQMatrix(renderer()->currentCamera().transformationMatrix(1));
+		Matrix transform = Matrix::fromQMatrix(renderer()->currentCamera().transformationMatrix(1));
 		transform *= Matrix::scaleMatrix(dist0);
-		circleOrDisc = true;
+		model.emplace<LDCircularPrimitive>(PrimitiveModel::Circle, segments, divisions, transform, displacement);
+		return;
 	}
 	else if (qFuzzyCompare(dist0, 0) or qFuzzyCompare(dist1, 0))
 	{
 		// Special case #2: one radius is 0, so use a disc.
-		primitiveModel.type = PrimitiveModel::Disc;
-		primitiveFile = primitives()->getPrimitive(primitiveModel);
 		//transform = shearMatrixForPlane(renderer());
-		transform = Matrix::fromQMatrix(renderer()->currentCamera().transformationMatrix(1));
+		Matrix transform = Matrix::fromQMatrix(renderer()->currentCamera().transformationMatrix(1));
 		transform *= Matrix::scaleMatrix(max(dist0, dist1));
-		circleOrDisc = true;
+		model.emplace<LDCircularPrimitive>(PrimitiveModel::Disc, segments, divisions, transform, displacement);
+		return;
 	}
 	else if (g_RingFinder.findRings(dist0, dist1)) // Consult the ring finder now
 	{
 		// The ring finder found a solution, use that. Add the component rings to the file.
+		PrimitiveModel primitiveModel;
+		primitiveModel.segments = m_window->ringToolSegments();
+		primitiveModel.divisions = m_window->ringToolDivisions();
 		primitiveModel.type = PrimitiveModel::Ring;
 
 		for (const RingFinder::Component& component : g_RingFinder.bestSolution()->getComponents())
 		{
 			primitiveModel.ringNumber = component.num;
-			primitiveFile = primitives()->getPrimitive(primitiveModel);
+			LDDocument* primitiveFile = primitives()->getPrimitive(primitiveModel);
 			Matrix matrix = Matrix::fromQMatrix(renderer()->currentCamera().transformationMatrix(component.scale));
 			// matrix = shearMatrixForPlane(renderer()) * matrix;
 			model.emplace<LDSubfileReference>(primitiveFile->name(), matrix, m_drawedVerts.first());
@@ -149,10 +146,10 @@
 		templ.setCoordinate(localy, y0);
 
 		// Calculate circle coords
-		QVector<QLineF> c0 = makeCircle(primitiveModel.segments, primitiveModel.divisions, dist0);
-		QVector<QLineF> c1 = makeCircle(primitiveModel.segments, primitiveModel.divisions, dist1);
+		QVector<QLineF> c0 = makeCircle(segments, divisions, dist0);
+		QVector<QLineF> c1 = makeCircle(segments, divisions, dist1);
 
-		for (int i = 0; i < primitiveModel.segments; ++i)
+		for (int i = 0; i < segments; ++i)
 		{
 			Vertex v0, v1, v2, v3;
 			v0 = v1 = v2 = v3 = templ;
@@ -178,11 +175,6 @@
 		}
 	}
 
-	if (circleOrDisc and primitiveFile)
-	{
-		model.emplace<LDSubfileReference>(primitiveFile->name(), transform, m_drawedVerts.first());
-	}
-
 	finishDraw (model);
 }
 
--- a/src/linetypes/circularprimitive.cpp	Sun Jun 10 16:50:14 2018 +0300
+++ b/src/linetypes/circularprimitive.cpp	Sun Jun 10 17:17:42 2018 +0300
@@ -17,18 +17,14 @@
 
 	simplify(numerator, denominator);
 
-	switch (m_type)
+	// Ensure that the denominator is at least 4, expand if necessary
+	if (denominator < 4)
 	{
-	case PrimitiveModel::Cylinder:
-		return format("%1%2-%3cyli.dat", prefix, numerator, denominator);
+		numerator = static_cast<int>(round(numerator * 4.0 / denominator));
+		denominator = 4;
+	}
 
-	case PrimitiveModel::Circle:
-		return format("%1%2-%3edge.dat", prefix, numerator, denominator);
-
-	default:
-		Q_ASSERT(false);
-		return "";
-	}
+	return format("%1%2-%3%4.dat", prefix, numerator, denominator, stem());
 }
 
 LDCircularPrimitive::LDCircularPrimitive(
@@ -70,7 +66,10 @@
 	}
 }
 
-bool LDCircularPrimitive::isRasterizable() const { return true; }
+bool LDCircularPrimitive::isRasterizable() const
+{
+	return true;
+}
 
 void LDCircularPrimitive::rasterize(
 	DocumentManager* context,
@@ -137,6 +136,27 @@
 	primitive.generateBody(model);
 }
 
+QString LDCircularPrimitive::stem() const
+{
+	switch (m_type)
+	{
+	case PrimitiveModel::Cylinder:
+		return "cyli";
+
+	case PrimitiveModel::Circle:
+		return "edge";
+
+	case PrimitiveModel::Disc:
+		return "disc";
+
+	case PrimitiveModel::DiscNegative:
+		return "ndis";
+
+	default:
+		throw std::logic_error("Bad primitive type to LDCircularPrimitive");
+	}
+}
+
 QString LDCircularPrimitive::objectListText() const
 {
 	QString result = format(
--- a/src/linetypes/circularprimitive.h	Sun Jun 10 16:50:14 2018 +0300
+++ b/src/linetypes/circularprimitive.h	Sun Jun 10 17:17:42 2018 +0300
@@ -36,6 +36,7 @@
 private:
 	QString buildFilename() const;
 	void buildPrimitiveBody(Model& model) const;
+	QString stem() const;
 
 	PrimitiveModel::Type m_type = PrimitiveModel::Circle;
 	int m_segments = MediumResolution;
--- a/src/parser.cpp	Sun Jun 10 16:50:14 2018 +0300
+++ b/src/parser.cpp	Sun Jun 10 17:17:42 2018 +0300
@@ -389,7 +389,7 @@
 				for (int i = 0; i < 9; ++i)
 					transform.value(i) = tokens[i + 5].toDouble(); // 5 - 13
 
-				static const QRegExp circularPrimitiveRegexp {R"((?:(\d+)\\)?(\d+)-(\d+)(cyli|edge)\.dat)"};
+				static const QRegExp circularPrimitiveRegexp {R"((?:(\d+)\\)?(\d+)-(\d+)(cyli|edge|disc|ndis)\.dat)"};
 				LDObject* obj;
 
 				if (circularPrimitiveRegexp.exactMatch(referenceName))
@@ -401,11 +401,16 @@
 
 					int numerator = circularPrimitiveRegexp.capturedTexts()[2].toInt();
 					int denominator = circularPrimitiveRegexp.capturedTexts()[3].toInt();
+					QString stem = circularPrimitiveRegexp.capturedTexts()[4];
 					int segments = (numerator * resolution) / denominator;
 					PrimitiveModel::Type type = PrimitiveModel::Cylinder;
 
-					if (circularPrimitiveRegexp.capturedTexts()[4] == "edge")
+					if (stem == "edge")
 						type = PrimitiveModel::Circle;
+					else if (stem == "disc")
+						type = PrimitiveModel::Disc;
+					else if (stem == "ndis")
+						type = PrimitiveModel::DiscNegative;
 
 					obj = model.emplaceAt<LDCircularPrimitive>(
 						position,

mercurial