84 qSwap (dist0, dist1); |
84 qSwap (dist0, dist1); |
85 |
85 |
86 if (dist0 == dist1) |
86 if (dist0 == dist1) |
87 { |
87 { |
88 // If the radii are the same, there's no ring space to fill. Use a circle. |
88 // If the radii are the same, there's no ring space to fill. Use a circle. |
89 refFile = GetDocument (MakeRadialFileName (::Circle, segs, segs, 0)); |
89 refFile = GetPrimitive (::Circle, segments, divisions, 0); |
90 transform = getCircleDrawMatrix (dist0); |
90 transform = getCircleDrawMatrix (dist0); |
91 circleOrDisc = true; |
91 circleOrDisc = true; |
92 } |
92 } |
93 elif (dist0 == 0 or dist1 == 0) |
93 elif (dist0 == 0 or dist1 == 0) |
94 { |
94 { |
95 // If either radii is 0, use a disc. |
95 // If either radii is 0, use a disc. |
96 refFile = GetDocument (MakeRadialFileName (::Disc, segs, segs, 0)); |
96 refFile = GetPrimitive (::Disc, segments, divisions, 0); |
97 transform = getCircleDrawMatrix ((dist0 != 0) ? dist0 : dist1); |
97 transform = getCircleDrawMatrix ((dist0 != 0) ? dist0 : dist1); |
98 circleOrDisc = true; |
98 circleOrDisc = true; |
99 } |
99 } |
100 elif (g_RingFinder.findRings (dist0, dist1)) |
100 elif (g_RingFinder.findRings (dist0, dist1)) |
101 { |
101 { |
102 // The ring finder found a solution, use that. Add the component rings to the file. |
102 // The ring finder found a solution, use that. Add the component rings to the file. |
103 for (const RingFinder::Component& cmp : g_RingFinder.bestSolution()->getComponents()) |
103 for (const RingFinder::Component& cmp : g_RingFinder.bestSolution()->getComponents()) |
104 { |
104 { |
105 // Get a ref file for this primitive. If we cannot find it in the |
105 refFile = GetPrimitive (::Ring, segments, divisions, cmp.num); |
106 // LDraw library, generate it. |
|
107 if ((refFile = ::GetDocument (MakeRadialFileName (::Ring, segs, segs, cmp.num))) == null) |
|
108 { |
|
109 refFile = GeneratePrimitive (::Ring, segs, segs, cmp.num); |
|
110 refFile->setImplicit (false); |
|
111 } |
|
112 |
|
113 LDSubfilePtr ref = LDSpawn<LDSubfile>(); |
106 LDSubfilePtr ref = LDSpawn<LDSubfile>(); |
114 ref->setFileInfo (refFile); |
107 ref->setFileInfo (refFile); |
115 ref->setTransform (getCircleDrawMatrix (cmp.scale)); |
108 ref->setTransform (getCircleDrawMatrix (cmp.scale)); |
116 ref->setPosition (m_drawedVerts[0]); |
109 ref->setPosition (m_drawedVerts[0]); |
117 ref->setColor (MainColor()); |
110 ref->setColor (MainColor()); |
132 templ.setCoordinate (localx, x0); |
125 templ.setCoordinate (localx, x0); |
133 templ.setCoordinate (localy, y0); |
126 templ.setCoordinate (localy, y0); |
134 templ.setCoordinate (localz, renderer()->getDepthValue()); |
127 templ.setCoordinate (localz, renderer()->getDepthValue()); |
135 |
128 |
136 // Calculate circle coords |
129 // Calculate circle coords |
137 MakeCircle (segs, divs, dist0, c0); |
130 MakeCircle (segments, divisions, dist0, c0); |
138 MakeCircle (segs, divs, dist1, c1); |
131 MakeCircle (segments, divisions, dist1, c1); |
139 |
132 |
140 for (int i = 0; i < segs; ++i) |
133 for (int i = 0; i < segments; ++i) |
141 { |
134 { |
142 Vertex v0, v1, v2, v3; |
135 Vertex v0, v1, v2, v3; |
143 v0 = v1 = v2 = v3 = templ; |
136 v0 = v1 = v2 = v3 = templ; |
144 v0.setCoordinate (localx, v0[localx] + c0[i].x1()); |
137 v0.setCoordinate (localx, v0[localx] + c0[i].x1()); |
145 v0.setCoordinate (localy, v0[localy] + c0[i].y1()); |
138 v0.setCoordinate (localy, v0[localy] + c0[i].y1()); |
183 { |
176 { |
184 renderer()->drawBlip (painter, renderer()->coordconv3_2 (renderer()->position3D())); |
177 renderer()->drawBlip (painter, renderer()->coordconv3_2 (renderer()->position3D())); |
185 return; |
178 return; |
186 } |
179 } |
187 |
180 |
188 QVector<Vertex> verts, verts2; |
181 QVector<Vertex> innerverts, outerverts; |
189 const double dist0 = getCircleDrawDist (0), |
182 QVector<QPointF> innerverts2d, outerverts2d; |
190 dist1 = (m_drawedVerts.size() >= 2) ? getCircleDrawDist (1) : -1; |
183 const double innerdistance (getCircleDrawDist (0)); |
191 const int segs (g_win->ringToolHiRes() ? HighResolution : LowResolution); |
184 const double outerdistance (m_drawedVerts.size() >= 2 ? getCircleDrawDist (1) : -1); |
192 const double angleUnit = (2 * Pi) / segs; |
185 const int divisions (g_win->ringToolHiRes() ? HighResolution : LowResolution); |
|
186 const int segments (g_win->ringToolSegments()); |
|
187 const double angleUnit (2 * Pi / divisions); |
193 Axis relX, relY; |
188 Axis relX, relY; |
194 QVector<QPoint> ringpoints, circlepoints, circle2points; |
|
195 |
|
196 renderer()->getRelativeAxes (relX, relY); |
189 renderer()->getRelativeAxes (relX, relY); |
197 |
190 |
198 // Calculate the preview positions of vertices |
191 // Calculate the preview positions of vertices |
199 for (int i = 0; i < segs; ++i) |
192 for (int i = 0; i < segments + 1; ++i) |
200 { |
193 { |
201 Vertex v (Origin); |
194 Vertex v (Origin); |
202 v.setCoordinate (relX, m_drawedVerts[0][relX] + (cos (i * angleUnit) * dist0)); |
195 v.setCoordinate (relX, m_drawedVerts[0][relX] + (cos (i * angleUnit) * innerdistance)); |
203 v.setCoordinate (relY, m_drawedVerts[0][relY] + (sin (i * angleUnit) * dist0)); |
196 v.setCoordinate (relY, m_drawedVerts[0][relY] + (sin (i * angleUnit) * innerdistance)); |
204 verts << v; |
197 innerverts << v; |
205 |
198 innerverts2d << renderer()->coordconv3_2 (v); |
206 if (dist1 != -1) |
199 |
207 { |
200 if (outerdistance != -1) |
208 v.setCoordinate (relX, m_drawedVerts[0][relX] + (cos (i * angleUnit) * dist1)); |
201 { |
209 v.setCoordinate (relY, m_drawedVerts[0][relY] + (sin (i * angleUnit) * dist1)); |
202 v.setCoordinate (relX, m_drawedVerts[0][relX] + (cos (i * angleUnit) * outerdistance)); |
210 verts2 << v; |
203 v.setCoordinate (relY, m_drawedVerts[0][relY] + (sin (i * angleUnit) * outerdistance)); |
211 } |
204 outerverts << v; |
212 } |
205 outerverts2d << renderer()->coordconv3_2 (v); |
213 |
206 } |
214 int i = 0; |
207 } |
215 for (const Vertex& v : verts + verts2) |
208 |
216 { |
209 QVector<QLineF> lines (segments); |
217 // Calculate the 2D point of the vertex |
210 |
218 QPoint point (renderer()->coordconv3_2 (v)); |
211 if (outerdistance != -1 and outerdistance != innerdistance) |
219 |
212 { |
220 // Draw a green blip at where it is |
213 painter.setBrush (m_polybrush); |
|
214 painter.setPen (Qt::NoPen); |
|
215 |
|
216 // Compile polygons |
|
217 for (int i = 0; i < segments; ++i) |
|
218 { |
|
219 QVector<QPointF> points; |
|
220 points << innerverts2d[i] |
|
221 << innerverts2d[i + 1] |
|
222 << outerverts2d[i + 1] |
|
223 << outerverts2d[i]; |
|
224 painter.drawPolygon (QPolygonF (points)); |
|
225 lines << QLineF (innerverts2d[i], innerverts2d[i + 1]); |
|
226 lines << QLineF (outerverts2d[i], outerverts2d[i + 1]); |
|
227 } |
|
228 |
|
229 // Add bordering edges for unclosed rings/discs |
|
230 if (segments != divisions) |
|
231 { |
|
232 lines << QLineF (innerverts2d.first(), outerverts2d.first()); |
|
233 lines << QLineF (innerverts2d.last(), outerverts2d.last()); |
|
234 } |
|
235 } |
|
236 else |
|
237 { |
|
238 for (int i = 0; i < segments; ++i) |
|
239 lines << QLineF (innerverts2d[i], innerverts2d[i + 1]); |
|
240 } |
|
241 |
|
242 // Draw a green blips at where the points are |
|
243 for (QPointF const& point : innerverts2d + outerverts2d) |
221 renderer()->drawBlip (painter, point); |
244 renderer()->drawBlip (painter, point); |
222 |
245 |
223 // Add it to the list of points for the green ring fill. |
246 // Draw edge lines |
224 ringpoints << point; |
|
225 |
|
226 // Also add the circle points to separate lists |
|
227 if (i < verts.size()) |
|
228 circlepoints << point; |
|
229 else |
|
230 circle2points << point; |
|
231 |
|
232 ++i; |
|
233 } |
|
234 |
|
235 // Insert the first point as the seventeenth one so that |
|
236 // the ring polygon is closed properly. |
|
237 if (ringpoints.size() >= segs) |
|
238 ringpoints.insert (segs, ringpoints[0]); |
|
239 |
|
240 // Same for the outer ring. Note that the indices are offset by 1 |
|
241 // because of the insertion done above bumps the values. |
|
242 if (ringpoints.size() >= segs * 2 + 1) |
|
243 ringpoints.insert (segs * 2 + 1, ringpoints[segs + 1]); |
|
244 |
|
245 // Draw the ring |
|
246 painter.setBrush ((m_drawedVerts.size() >= 2) ? m_polybrush : Qt::NoBrush); |
|
247 painter.setPen (Qt::NoPen); |
|
248 painter.drawPolygon (QPolygon (ringpoints)); |
|
249 |
|
250 // Draw the circles |
|
251 painter.setBrush (Qt::NoBrush); |
|
252 painter.setPen (renderer()->linePen()); |
247 painter.setPen (renderer()->linePen()); |
253 painter.drawPolygon (QPolygon (circlepoints)); |
248 painter.drawLines (lines); |
254 painter.drawPolygon (QPolygon (circle2points)); |
|
255 |
249 |
256 // Draw the current radius in the middle of the circle. |
250 // Draw the current radius in the middle of the circle. |
257 QPoint origin = renderer()->coordconv3_2 (m_drawedVerts[0]); |
251 QPoint origin = renderer()->coordconv3_2 (m_drawedVerts[0]); |
258 QString label = QString::number (dist0); |
252 QString label = QString::number (innerdistance); |
259 painter.setPen (renderer()->textPen()); |
253 painter.setPen (renderer()->textPen()); |
260 painter.drawText (origin.x() - (metrics.width (label) / 2), origin.y(), label); |
254 painter.drawText (origin.x() - (metrics.width (label) / 2), origin.y(), label); |
261 |
255 |
262 if (m_drawedVerts.size() >= 2) |
256 if (m_drawedVerts.size() >= 2) |
263 { |
257 { |
264 painter.drawText (origin.x() - (metrics.width (label) / 2), |
258 painter.drawText (origin.x() - (metrics.width (label) / 2), |
265 origin.y() + metrics.height(), QString::number (dist1)); |
259 origin.y() + metrics.height(), QString::number (outerdistance)); |
266 } |
260 } |
267 } |
261 } |
268 |
262 |
269 bool CircleMode::mouseReleased (MouseEventData const& data) |
263 bool CircleMode::mouseReleased (MouseEventData const& data) |
270 { |
264 { |