changed LDCylinder to LDCircularPrimitive and moved circles to it

Sun, 10 Jun 2018 16:50:14 +0300

author
Teemu Piippo <teemu@hecknology.net>
date
Sun, 10 Jun 2018 16:50:14 +0300
changeset 1398
1c70d3447d20
parent 1397
5d5c11af0268
child 1399
f52ea4078f5d

changed LDCylinder to LDCircularPrimitive and moved circles to it

CMakeLists.txt file | annotate | diff | comparison | revisions
src/linetypes/circularprimitive.cpp file | annotate | diff | comparison | revisions
src/linetypes/circularprimitive.h file | annotate | diff | comparison | revisions
src/linetypes/cylinder.cpp file | annotate | diff | comparison | revisions
src/linetypes/cylinder.h file | annotate | diff | comparison | revisions
src/linetypes/modelobject.cpp file | annotate | diff | comparison | revisions
src/linetypes/modelobject.h file | annotate | diff | comparison | revisions
src/parser.cpp file | annotate | diff | comparison | revisions
src/primitives.cpp file | annotate | diff | comparison | revisions
src/primitives.h file | annotate | diff | comparison | revisions
--- a/CMakeLists.txt	Sun Jun 10 16:04:38 2018 +0300
+++ b/CMakeLists.txt	Sun Jun 10 16:50:14 2018 +0300
@@ -79,9 +79,9 @@
 	src/editmodes/selectMode.cpp
 	src/geometry/linesegment.cpp
 	src/geometry/plane.cpp
+	src/linetypes/circularprimitive.cpp
 	src/linetypes/comment.cpp
 	src/linetypes/conditionaledge.cpp
-	src/linetypes/cylinder.cpp
 	src/linetypes/edgeline.cpp
 	src/linetypes/empty.cpp
 	src/linetypes/modelobject.cpp
@@ -161,9 +161,9 @@
 	src/generics/transform.h
 	src/geometry/linesegment.h
 	src/geometry/plane.h
+	src/linetypes/circularprimitive.h
 	src/linetypes/comment.h
 	src/linetypes/conditionaledge.h
-	src/linetypes/cylinder.h
 	src/linetypes/edgeline.h
 	src/linetypes/empty.h
 	src/linetypes/modelobject.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/linetypes/circularprimitive.cpp	Sun Jun 10 16:50:14 2018 +0300
@@ -0,0 +1,187 @@
+#include "../algorithms/geometry.h"
+#include "../glShared.h"
+#include "../model.h"
+#include "../algorithms/invert.h"
+#include "circularprimitive.h"
+#include "quadrilateral.h"
+#include "primitives.h"
+
+QString LDCircularPrimitive::buildFilename() const
+{
+	int numerator = this->m_segments;
+	int denominator = this->m_divisions;
+	QString prefix;
+
+	if (m_divisions != MediumResolution)
+		prefix = QString::number(m_divisions) + '\\';
+
+	simplify(numerator, denominator);
+
+	switch (m_type)
+	{
+	case PrimitiveModel::Cylinder:
+		return format("%1%2-%3cyli.dat", prefix, numerator, denominator);
+
+	case PrimitiveModel::Circle:
+		return format("%1%2-%3edge.dat", prefix, numerator, denominator);
+
+	default:
+		Q_ASSERT(false);
+		return "";
+	}
+}
+
+LDCircularPrimitive::LDCircularPrimitive(
+	PrimitiveModel::Type type,
+	int segments,
+	int divisions,
+	const Matrix& transformationMatrix,
+	const Vertex& position
+) :
+	LDMatrixObject {transformationMatrix, position},
+	m_type {type},
+	m_segments {segments},
+	m_divisions {divisions} {}
+
+LDObjectType LDCircularPrimitive::type() const
+{
+	return SubclassType;
+}
+
+QString LDCircularPrimitive::asText() const
+{
+	return LDSubfileReference(buildFilename(), transformationMatrix(), position()).asText();
+}
+
+void LDCircularPrimitive::getVertices(DocumentManager* /* context */, QSet<Vertex>& vertices) const
+{
+	int endSegment = (m_segments == m_divisions) ? m_segments : m_segments + 1;
+
+	for (int i = 0; i < endSegment; i += 1)
+	{
+		QPointF point2d = pointOnLDrawCircumference(i, m_divisions);
+
+		for (double y_value : {0.0, 1.0})
+		{
+			Vertex vertex {point2d.x(), y_value, point2d.y()};
+			vertex.transform(transformationMatrix(), position());
+			vertices.insert(vertex);
+		}
+	}
+}
+
+bool LDCircularPrimitive::isRasterizable() const { return true; }
+
+void LDCircularPrimitive::rasterize(
+	DocumentManager* context,
+	Winding /* parentWinding */,
+	Model& model,
+	bool /* deep */,
+	bool /* render */
+) {
+	Model cylinderBody {context};
+	buildPrimitiveBody(cylinderBody);
+
+	for (LDObject* object : cylinderBody.objects())
+	{
+		for (int i = 0; i < object->numVertices(); i += 1)
+		{
+			Vertex vertex = object->vertex(i);
+			vertex.transform(transformationMatrix(), position());
+			object->setVertex(i, vertex);
+		}
+	}
+
+	model.merge(cylinderBody);
+}
+
+QVector<LDPolygon> LDCircularPrimitive::rasterizePolygons(DocumentManager* context, Winding winding)
+{
+	Model cylinderBody {context};
+	buildPrimitiveBody(cylinderBody);
+	QVector<LDPolygon> result;
+	bool cachedShouldInvert = shouldInvert(winding, context);
+
+	for (LDObject* object : cylinderBody.objects())
+	{
+		for (int i = 0; i < object->numVertices(); i += 1)
+		{
+			Vertex vertex = object->vertex(i);
+			vertex.transform(transformationMatrix(), position());
+			object->setVertex(i, vertex);
+		}
+
+		LDPolygon* polygon = object->getPolygon();
+
+		if (polygon)
+		{
+			if (cachedShouldInvert)
+				invertPolygon(*polygon);
+
+			result.append(*polygon);
+		}
+
+		delete polygon;
+	}
+
+	return result;
+}
+
+void LDCircularPrimitive::buildPrimitiveBody(Model& model) const
+{
+	PrimitiveModel primitive;
+	primitive.type = m_type;
+	primitive.segments = m_segments;
+	primitive.divisions = m_divisions;
+	primitive.ringNumber = 0;
+	primitive.generateBody(model);
+}
+
+QString LDCircularPrimitive::objectListText() const
+{
+	QString result = format(
+		"%1 %2 %3, (",
+		PrimitiveModel::typeName(m_type),
+		m_segments / m_divisions,
+		position().toString(true)
+	);
+
+	for (int i = 0; i < 9; ++i)
+		result += format("%1%2", transformationMatrix().value(i), (i != 8) ? " " : "");
+
+	result += ')';
+	return result;
+}
+
+int LDCircularPrimitive::triangleCount(DocumentManager*) const
+{
+	switch (m_type)
+	{
+	case PrimitiveModel::Ring:
+	case PrimitiveModel::Cone:
+		throw std::logic_error("Bad primitive type to LDCircularPrimitive");
+
+	case PrimitiveModel::Cylinder:
+		return 2 * m_segments;
+
+	case PrimitiveModel::Disc:
+	case PrimitiveModel::DiscNegative:
+		return m_segments;
+
+	case PrimitiveModel::Circle:
+		return 0;
+	}
+
+	return 0;
+}
+
+QString LDCircularPrimitive::typeName() const
+{
+	return "circular-primitive";
+}
+
+void LDCircularPrimitive::serialize(class Serializer& serializer)
+{
+	LDMatrixObject::serialize(serializer);
+	serializer << m_segments << m_divisions;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/linetypes/circularprimitive.h	Sun Jun 10 16:50:14 2018 +0300
@@ -0,0 +1,43 @@
+#pragma once
+#include "../primitives.h"
+#include "modelobject.h"
+
+class LDCircularPrimitive : public LDMatrixObject
+{
+public:
+	static const LDObjectType SubclassType = LDObjectType::CircularPrimitive;
+
+	LDCircularPrimitive() = default;
+	LDCircularPrimitive(
+		PrimitiveModel::Type type,
+		int segments,
+		int divisions,
+		const Matrix& transformationMatrix,
+		const Vertex& position
+	);
+
+	LDObjectType type() const override;
+	QString asText() const override;
+	void getVertices(DocumentManager *context, QSet<Vertex>& verts) const override;
+	bool isRasterizable() const override;
+	void rasterize(
+		DocumentManager* context,
+		Winding parentWinding,
+		Model& model,
+		bool deep,
+		bool render
+	) override;
+	QVector<LDPolygon> rasterizePolygons(DocumentManager* context, Winding parentWinding) override;
+	QString objectListText() const override;
+	int triangleCount(DocumentManager*) const override;
+	QString typeName() const override;
+	void serialize(class Serializer& serializer) override;
+
+private:
+	QString buildFilename() const;
+	void buildPrimitiveBody(Model& model) const;
+
+	PrimitiveModel::Type m_type = PrimitiveModel::Circle;
+	int m_segments = MediumResolution;
+	int m_divisions = MediumResolution;
+};
--- a/src/linetypes/cylinder.cpp	Sun Jun 10 16:04:38 2018 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,134 +0,0 @@
-#include "../algorithms/geometry.h"
-#include "../glShared.h"
-#include "../model.h"
-#include "../algorithms/invert.h"
-#include "cylinder.h"
-#include "quadrilateral.h"
-#include "primitives.h"
-
-QString LDCylinder::buildFilename() const
-{
-	int numerator = this->m_segments;
-	int denominator = this->m_divisions;
-	QString prefix;
-
-	if (m_divisions != MediumResolution)
-		prefix = QString::number(m_divisions) + '\\';
-
-	simplify(numerator, denominator);
-	return format("%1%2-%3cyli.dat", prefix, numerator, denominator);
-}
-
-LDCylinder::LDCylinder(
-	int segments,
-	int divisions,
-	const Matrix& transformationMatrix,
-	const Vertex& position
-) :
-	LDMatrixObject {transformationMatrix, position},
-	m_segments {segments},
-	m_divisions {divisions} {}
-
-QString LDCylinder::asText() const
-{
-	return LDSubfileReference(buildFilename(), transformationMatrix(), position()).asText();
-}
-
-void LDCylinder::getVertices(DocumentManager* /* context */, QSet<Vertex>& vertices) const
-{
-	int endSegment = (m_segments == m_divisions) ? m_segments : m_segments + 1;
-
-	for (int i = 0; i < endSegment; i += 1)
-	{
-		QPointF point2d = pointOnLDrawCircumference(i, m_divisions);
-
-		for (double y_value : {0.0, 1.0})
-		{
-			Vertex vertex {point2d.x(), y_value, point2d.y()};
-			vertex.transform(transformationMatrix(), position());
-			vertices.insert(vertex);
-		}
-	}
-}
-
-void LDCylinder::rasterize(
-	DocumentManager* context,
-	Winding /* parentWinding */,
-	Model& model,
-	bool /* deep */,
-	bool /* render */
-) {
-	Model cylinderBody {context};
-	buildPrimitiveBody(cylinderBody);
-
-	for (LDObject* object : cylinderBody.objects())
-	{
-		for (int i = 0; i < object->numVertices(); i += 1)
-		{
-			Vertex vertex = object->vertex(i);
-			vertex.transform(transformationMatrix(), position());
-			object->setVertex(i, vertex);
-		}
-	}
-
-	model.merge(cylinderBody);
-}
-
-QVector<LDPolygon> LDCylinder::rasterizePolygons(DocumentManager* context, Winding winding)
-{
-	Model cylinderBody {context};
-	buildPrimitiveBody(cylinderBody);
-	QVector<LDPolygon> result;
-	bool cachedShouldInvert = shouldInvert(winding, context);
-
-	for (LDObject* object : cylinderBody.objects())
-	{
-		for (int i = 0; i < object->numVertices(); i += 1)
-		{
-			Vertex vertex = object->vertex(i);
-			vertex.transform(transformationMatrix(), position());
-			object->setVertex(i, vertex);
-		}
-
-		LDPolygon* polygon = object->getPolygon();
-
-		if (polygon)
-		{
-			if (cachedShouldInvert)
-				invertPolygon(*polygon);
-
-			result.append(*polygon);
-		}
-
-		delete polygon;
-	}
-
-	return result;
-}
-
-void LDCylinder::buildPrimitiveBody(Model& model) const
-{
-	PrimitiveModel primitive;
-	primitive.type = PrimitiveModel::Cylinder;
-	primitive.segments = m_segments;
-	primitive.divisions = m_divisions;
-	primitive.ringNumber = 0;
-	primitive.generateCylinder(model);
-}
-
-QString LDCylinder::objectListText() const
-{
-	QString result = format("Cylinder %1 %2, (", m_segments / m_divisions, position().toString(true));
-
-	for (int i = 0; i < 9; ++i)
-		result += format("%1%2", transformationMatrix().value(i), (i != 8) ? " " : "");
-
-	result += ')';
-	return result;
-}
-
-void LDCylinder::serialize(class Serializer& serializer)
-{
-	LDMatrixObject::serialize(serializer);
-	serializer << m_segments << m_divisions;
-}
--- a/src/linetypes/cylinder.h	Sun Jun 10 16:04:38 2018 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,39 +0,0 @@
-#pragma once
-#include "modelobject.h"
-
-class LDCylinder : public LDMatrixObject
-{
-public:
-	static const LDObjectType SubclassType = LDObjectType::Cylinder;
-
-	LDCylinder() = default;
-	LDCylinder(int segments, int divisions, const Matrix& transformationMatrix, const Vertex& position);
-
-	virtual LDObjectType type() const override
-	{
-		return SubclassType;
-	}
-
-	virtual QString asText() const override;
-	virtual void getVertices(DocumentManager *context, QSet<Vertex>& verts) const override;
-	bool isRasterizable() const override { return true; }
-	void rasterize(
-		DocumentManager* context,
-		Winding parentWinding,
-		Model& model,
-		bool deep,
-		bool render
-	) override;
-	QVector<LDPolygon> rasterizePolygons(DocumentManager* context, Winding parentWinding) override;
-	QString objectListText() const override;
-	int triangleCount(DocumentManager*) const override { return 2 * m_segments; }
-	QString typeName() const override { return "cylinder"; }
-	void serialize(class Serializer& serializer) override;
-
-private:
-	QString buildFilename() const;
-	void buildPrimitiveBody(Model& model) const;
-
-	int m_segments;
-	int m_divisions;
-};
--- a/src/linetypes/modelobject.cpp	Sun Jun 10 16:04:38 2018 +0300
+++ b/src/linetypes/modelobject.cpp	Sun Jun 10 16:50:14 2018 +0300
@@ -31,7 +31,7 @@
 #include "conditionaledge.h"
 #include "comment.h"
 #include "empty.h"
-#include "cylinder.h"
+#include "circularprimitive.h"
 
 // List of all LDObjects
 QMap<qint32, LDObject*> g_allObjects;
@@ -356,8 +356,8 @@
 	case LDObjectType::BezierCurve:
 		return new LDBezierCurve {};
 
-	case LDObjectType::Cylinder:
-		return new LDCylinder {};
+	case LDObjectType::CircularPrimitive:
+		return new LDCircularPrimitive {};
 
 	case LDObjectType::_End:
 		break;
--- a/src/linetypes/modelobject.h	Sun Jun 10 16:04:38 2018 +0300
+++ b/src/linetypes/modelobject.h	Sun Jun 10 16:50:14 2018 +0300
@@ -40,7 +40,7 @@
 	Error,				//	Object is the result of failed parsing
 	Empty,				//	Object represents an empty line
 	BezierCurve,		//	Object represents a Bézier curve
-	Cylinder,
+	CircularPrimitive,
 	_End
 };
 
--- a/src/parser.cpp	Sun Jun 10 16:04:38 2018 +0300
+++ b/src/parser.cpp	Sun Jun 10 16:50:14 2018 +0300
@@ -24,7 +24,7 @@
 #include "linetypes/empty.h"
 #include "linetypes/quadrilateral.h"
 #include "linetypes/triangle.h"
-#include "linetypes/cylinder.h"
+#include "linetypes/circularprimitive.h"
 
 /*
  * Constructs an LDraw parser
@@ -389,20 +389,32 @@
 				for (int i = 0; i < 9; ++i)
 					transform.value(i) = tokens[i + 5].toDouble(); // 5 - 13
 
-				static const QRegExp cylinderRegexp {R"((?:(\d+)\\)?(\d+)-(\d+)cyli\.dat)"};
+				static const QRegExp circularPrimitiveRegexp {R"((?:(\d+)\\)?(\d+)-(\d+)(cyli|edge)\.dat)"};
 				LDObject* obj;
 
-				if (cylinderRegexp.exactMatch(referenceName))
+				if (circularPrimitiveRegexp.exactMatch(referenceName))
 				{
 					int resolution = MediumResolution;
 
-					if (not cylinderRegexp.capturedTexts()[1].isEmpty())
-						resolution = cylinderRegexp.capturedTexts()[1].toInt();
+					if (not circularPrimitiveRegexp.capturedTexts()[1].isEmpty())
+						resolution = circularPrimitiveRegexp.capturedTexts()[1].toInt();
+
+					int numerator = circularPrimitiveRegexp.capturedTexts()[2].toInt();
+					int denominator = circularPrimitiveRegexp.capturedTexts()[3].toInt();
+					int segments = (numerator * resolution) / denominator;
+					PrimitiveModel::Type type = PrimitiveModel::Cylinder;
 
-					int numerator = cylinderRegexp.capturedTexts()[2].toInt();
-					int denominator = cylinderRegexp.capturedTexts()[3].toInt();
-					int segments = (numerator * resolution) / denominator;
-					obj = model.emplaceAt<LDCylinder>(position, segments, resolution, transform, displacement);
+					if (circularPrimitiveRegexp.capturedTexts()[4] == "edge")
+						type = PrimitiveModel::Circle;
+
+					obj = model.emplaceAt<LDCircularPrimitive>(
+						position,
+						type,
+						segments,
+						resolution,
+						transform,
+						displacement
+					);
 				}
 				else
 				{
--- a/src/primitives.cpp	Sun Jun 10 16:04:38 2018 +0300
+++ b/src/primitives.cpp	Sun Jun 10 16:50:14 2018 +0300
@@ -325,12 +325,41 @@
 	}
 }
 
+/*
+ * Builds a circle primitive.
+ */
+void PrimitiveModel::generateCircle(Model& model) const
+{
+	QVector<QLineF> circle = makeCircle(segments, divisions, 1);
+
+	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();
+
+		LDEdgeLine* line = model.emplace<LDEdgeLine>();
+		line->setVertex(0, Vertex {x0, 0.0f, z0});
+		line->setVertex(1, Vertex {x1, 0.0f, z1});
+		line->setColor(EdgeColor);
+	}
+}
+
 void PrimitiveModel::generateBody(Model& model) const
 {
-	if (this->type == Cylinder)
+	switch (type)
 	{
-		this->generateCylinder(model);
+	case Cylinder:
+		generateCylinder(model);
 		return;
+
+	case Circle:
+		generateCircle(model);
+		return;
+
+	default:
+		break;
 	}
 
 	QVector<int> conditionalLineSegments;
@@ -345,15 +374,6 @@
 
 		switch (type)
 		{
-		case Circle:
-		    {
-			    LDEdgeLine* line = model.emplace<LDEdgeLine>();
-				line->setVertex(0, Vertex {x0, 0.0f, z0});
-				line->setVertex(1, Vertex {x1, 0.0f, z1});
-				line->setColor(EdgeColor);
-			}
-			break;
-
 		case Ring:
 		case Cone:
 			{
@@ -421,6 +441,7 @@
 			}
 			break;
 
+		case Circle:
 		case Cylinder:
 			break;
 		}
--- a/src/primitives.h	Sun Jun 10 16:04:38 2018 +0300
+++ b/src/primitives.h	Sun Jun 10 16:50:14 2018 +0300
@@ -58,6 +58,7 @@
 	QString typeName() const;
 	void generateBody(Model& model) const;
 	void generateCylinder(Model& model, Winding winding = CounterClockwise) const;
+	void generateCircle(Model& model) const;
 	static QString typeName(Type type);
 	QString makeFileName(FilenameStyle style) const;
 };

mercurial