src/linetypes/circularprimitive.cpp

changeset 1398
1c70d3447d20
parent 1394
8d9d0532b3df
child 1399
f52ea4078f5d
equal deleted inserted replaced
1397:5d5c11af0268 1398:1c70d3447d20
1 #include "../algorithms/geometry.h"
2 #include "../glShared.h"
3 #include "../model.h"
4 #include "../algorithms/invert.h"
5 #include "circularprimitive.h"
6 #include "quadrilateral.h"
7 #include "primitives.h"
8
9 QString LDCircularPrimitive::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
20 switch (m_type)
21 {
22 case PrimitiveModel::Cylinder:
23 return format("%1%2-%3cyli.dat", prefix, numerator, denominator);
24
25 case PrimitiveModel::Circle:
26 return format("%1%2-%3edge.dat", prefix, numerator, denominator);
27
28 default:
29 Q_ASSERT(false);
30 return "";
31 }
32 }
33
34 LDCircularPrimitive::LDCircularPrimitive(
35 PrimitiveModel::Type type,
36 int segments,
37 int divisions,
38 const Matrix& transformationMatrix,
39 const Vertex& position
40 ) :
41 LDMatrixObject {transformationMatrix, position},
42 m_type {type},
43 m_segments {segments},
44 m_divisions {divisions} {}
45
46 LDObjectType LDCircularPrimitive::type() const
47 {
48 return SubclassType;
49 }
50
51 QString LDCircularPrimitive::asText() const
52 {
53 return LDSubfileReference(buildFilename(), transformationMatrix(), position()).asText();
54 }
55
56 void LDCircularPrimitive::getVertices(DocumentManager* /* context */, QSet<Vertex>& vertices) const
57 {
58 int endSegment = (m_segments == m_divisions) ? m_segments : m_segments + 1;
59
60 for (int i = 0; i < endSegment; i += 1)
61 {
62 QPointF point2d = pointOnLDrawCircumference(i, m_divisions);
63
64 for (double y_value : {0.0, 1.0})
65 {
66 Vertex vertex {point2d.x(), y_value, point2d.y()};
67 vertex.transform(transformationMatrix(), position());
68 vertices.insert(vertex);
69 }
70 }
71 }
72
73 bool LDCircularPrimitive::isRasterizable() const { return true; }
74
75 void LDCircularPrimitive::rasterize(
76 DocumentManager* context,
77 Winding /* parentWinding */,
78 Model& model,
79 bool /* deep */,
80 bool /* render */
81 ) {
82 Model cylinderBody {context};
83 buildPrimitiveBody(cylinderBody);
84
85 for (LDObject* object : cylinderBody.objects())
86 {
87 for (int i = 0; i < object->numVertices(); i += 1)
88 {
89 Vertex vertex = object->vertex(i);
90 vertex.transform(transformationMatrix(), position());
91 object->setVertex(i, vertex);
92 }
93 }
94
95 model.merge(cylinderBody);
96 }
97
98 QVector<LDPolygon> LDCircularPrimitive::rasterizePolygons(DocumentManager* context, Winding winding)
99 {
100 Model cylinderBody {context};
101 buildPrimitiveBody(cylinderBody);
102 QVector<LDPolygon> result;
103 bool cachedShouldInvert = shouldInvert(winding, context);
104
105 for (LDObject* object : cylinderBody.objects())
106 {
107 for (int i = 0; i < object->numVertices(); i += 1)
108 {
109 Vertex vertex = object->vertex(i);
110 vertex.transform(transformationMatrix(), position());
111 object->setVertex(i, vertex);
112 }
113
114 LDPolygon* polygon = object->getPolygon();
115
116 if (polygon)
117 {
118 if (cachedShouldInvert)
119 invertPolygon(*polygon);
120
121 result.append(*polygon);
122 }
123
124 delete polygon;
125 }
126
127 return result;
128 }
129
130 void LDCircularPrimitive::buildPrimitiveBody(Model& model) const
131 {
132 PrimitiveModel primitive;
133 primitive.type = m_type;
134 primitive.segments = m_segments;
135 primitive.divisions = m_divisions;
136 primitive.ringNumber = 0;
137 primitive.generateBody(model);
138 }
139
140 QString LDCircularPrimitive::objectListText() const
141 {
142 QString result = format(
143 "%1 %2 %3, (",
144 PrimitiveModel::typeName(m_type),
145 m_segments / m_divisions,
146 position().toString(true)
147 );
148
149 for (int i = 0; i < 9; ++i)
150 result += format("%1%2", transformationMatrix().value(i), (i != 8) ? " " : "");
151
152 result += ')';
153 return result;
154 }
155
156 int LDCircularPrimitive::triangleCount(DocumentManager*) const
157 {
158 switch (m_type)
159 {
160 case PrimitiveModel::Ring:
161 case PrimitiveModel::Cone:
162 throw std::logic_error("Bad primitive type to LDCircularPrimitive");
163
164 case PrimitiveModel::Cylinder:
165 return 2 * m_segments;
166
167 case PrimitiveModel::Disc:
168 case PrimitiveModel::DiscNegative:
169 return m_segments;
170
171 case PrimitiveModel::Circle:
172 return 0;
173 }
174
175 return 0;
176 }
177
178 QString LDCircularPrimitive::typeName() const
179 {
180 return "circular-primitive";
181 }
182
183 void LDCircularPrimitive::serialize(class Serializer& serializer)
184 {
185 LDMatrixObject::serialize(serializer);
186 serializer << m_segments << m_divisions;
187 }

mercurial