|
1 #include "../algorithms/geometry.h" |
|
2 #include "../glShared.h" |
|
3 #include "../model.h" |
|
4 #include "../algorithms/invert.h" |
|
5 #include "cylinder.h" |
|
6 #include "quadrilateral.h" |
|
7 #include "primitives.h" |
|
8 |
|
9 QString LDCylinder::buildFilename() const |
|
10 { |
|
11 int numerator = this->m_segments; |
|
12 int denominator = this->m_divisions; |
|
13 QString prefix; |
|
14 |
|
15 if (m_divisions != MediumResolution) |
|
16 prefix = QString::number(m_divisions) + '\\'; |
|
17 |
|
18 simplify(numerator, denominator); |
|
19 return format("%1%2-%3cyli.dat", prefix, numerator, denominator); |
|
20 } |
|
21 |
|
22 LDCylinder::LDCylinder( |
|
23 int segments, |
|
24 int divisions, |
|
25 const Matrix& transformationMatrix, |
|
26 const Vertex& position |
|
27 ) : |
|
28 LDMatrixObject {transformationMatrix, position}, |
|
29 m_segments {segments}, |
|
30 m_divisions {divisions} {} |
|
31 |
|
32 QString LDCylinder::asText() const |
|
33 { |
|
34 return LDSubfileReference(buildFilename(), transformationMatrix(), position()).asText(); |
|
35 } |
|
36 |
|
37 void LDCylinder::getVertices(DocumentManager* /* context */, QSet<Vertex>& vertices) const |
|
38 { |
|
39 int endSegment = (m_segments == m_divisions) ? m_segments : m_segments + 1; |
|
40 |
|
41 for (int i = 0; i < endSegment; i += 1) |
|
42 { |
|
43 QPointF point2d = pointOnLDrawCircumference(i, m_divisions); |
|
44 |
|
45 for (double y_value : {0.0, 1.0}) |
|
46 { |
|
47 Vertex vertex {point2d.x(), y_value, point2d.y()}; |
|
48 vertex.transform(transformationMatrix(), position()); |
|
49 vertices.insert(vertex); |
|
50 } |
|
51 } |
|
52 } |
|
53 |
|
54 void LDCylinder::rasterize( |
|
55 DocumentManager* context, |
|
56 Winding /* parentWinding */, |
|
57 Model& model, |
|
58 bool /* deep */, |
|
59 bool /* render */ |
|
60 ) { |
|
61 Model cylinderBody {context}; |
|
62 buildPrimitiveBody(cylinderBody); |
|
63 |
|
64 for (LDObject* object : cylinderBody.objects()) |
|
65 { |
|
66 for (int i = 0; i < object->numVertices(); i += 1) |
|
67 { |
|
68 Vertex vertex = object->vertex(i); |
|
69 vertex.transform(transformationMatrix(), position()); |
|
70 object->setVertex(i, vertex); |
|
71 } |
|
72 } |
|
73 |
|
74 model.merge(cylinderBody); |
|
75 } |
|
76 |
|
77 QVector<LDPolygon> LDCylinder::rasterizePolygons(DocumentManager* context, Winding winding) |
|
78 { |
|
79 Model cylinderBody {context}; |
|
80 buildPrimitiveBody(cylinderBody, winding); |
|
81 QVector<LDPolygon> result; |
|
82 |
|
83 for (LDObject* object : cylinderBody.objects()) |
|
84 { |
|
85 for (int i = 0; i < object->numVertices(); i += 1) |
|
86 { |
|
87 Vertex vertex = object->vertex(i); |
|
88 vertex.transform(transformationMatrix(), position()); |
|
89 object->setVertex(i, vertex); |
|
90 } |
|
91 |
|
92 LDPolygon* polygon = object->getPolygon(); |
|
93 |
|
94 if (polygon) |
|
95 { |
|
96 if (shouldInvert(winding, context)) |
|
97 invertPolygon(*polygon); |
|
98 |
|
99 result.append(*polygon); |
|
100 } |
|
101 |
|
102 delete polygon; |
|
103 } |
|
104 |
|
105 return result; |
|
106 } |
|
107 |
|
108 void LDCylinder::buildPrimitiveBody(Model& model, Winding winding) const |
|
109 { |
|
110 PrimitiveModel primitive; |
|
111 primitive.type = PrimitiveModel::Cylinder; |
|
112 primitive.segments = m_segments; |
|
113 primitive.divisions = m_divisions; |
|
114 primitive.ringNumber = 0; |
|
115 primitive.generateCylinder(model, winding); |
|
116 } |
|
117 |
|
118 QString LDCylinder::objectListText() const |
|
119 { |
|
120 QString result = format("Cylinder %1 %2, (", m_segments / m_divisions, position().toString(true)); |
|
121 |
|
122 for (int i = 0; i < 9; ++i) |
|
123 result += format("%1%2", transformationMatrix().value(i), (i != 8) ? " " : ""); |
|
124 |
|
125 result += ')'; |
|
126 return result; |
|
127 } |
|
128 |
|
129 void LDCylinder::serialize(class Serializer& serializer) |
|
130 { |
|
131 LDMatrixObject::serialize(serializer); |
|
132 serializer << m_segments << m_divisions; |
|
133 } |