src/linetypes/cylinder.cpp

changeset 1391
5fa4bf1fc781
child 1394
8d9d0532b3df
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/linetypes/cylinder.cpp	Mon Jun 04 23:12:40 2018 +0300
@@ -0,0 +1,133 @@
+#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, winding);
+	QVector<LDPolygon> result;
+
+	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 (shouldInvert(winding, context))
+				invertPolygon(*polygon);
+
+			result.append(*polygon);
+		}
+
+		delete polygon;
+	}
+
+	return result;
+}
+
+void LDCylinder::buildPrimitiveBody(Model& model, Winding winding) const
+{
+	PrimitiveModel primitive;
+	primitive.type = PrimitiveModel::Cylinder;
+	primitive.segments = m_segments;
+	primitive.divisions = m_divisions;
+	primitive.ringNumber = 0;
+	primitive.generateCylinder(model, winding);
+}
+
+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;
+}

mercurial