Sat, 30 Aug 2014 20:09:30 +0300
- now able to spawn partial circular primitives
--- a/src/editmodes/abstractEditMode.cc Sat Aug 30 16:08:05 2014 +0300 +++ b/src/editmodes/abstractEditMode.cc Sat Aug 30 20:09:30 2014 +0300 @@ -174,7 +174,8 @@ m_drawedVerts.clear(); } -void AbstractDrawMode::renderPolygon (QPainter& painter, const QVector<Vertex>& poly3d, bool withangles) const +void AbstractDrawMode::renderPolygon (QPainter& painter, const QVector<Vertex>& poly3d, + bool withlengths, bool withangles) const { QVector<QPoint> poly (poly3d.size()); QFontMetrics metrics = QFontMetrics (QFont()); @@ -200,7 +201,7 @@ } // Draw line lenghts and angle info if appropriate - if (poly3d.size() >= 2) + if (poly3d.size() >= 2 and (withlengths or withangles)) { painter.setPen (renderer()->textPen()); @@ -209,7 +210,7 @@ const int j = (i + 1) % poly3d.size(); const int h = (i - 1 >= 0) ? (i - 1) : (poly3d.size() - 1); - if (cfg::DrawLineLengths) + if (withlengths and cfg::DrawLineLengths) { const QString label = QString::number ((poly3d[j] - poly3d[i]).length()); QPoint origin = QLineF (poly[i], poly[j]).pointAt (0.5).toPoint();
--- a/src/editmodes/abstractEditMode.h Sat Aug 30 16:08:05 2014 +0300 +++ b/src/editmodes/abstractEditMode.h Sat Aug 30 20:09:30 2014 +0300 @@ -49,7 +49,7 @@ virtual ~AbstractEditMode(); virtual bool allowFreeCamera() const = 0; - virtual void render (QPainter&) const {}; + virtual void render (QPainter&) const {} GLRenderer* renderer() const; virtual EditModeType type() const = 0; virtual bool mousePressed (QMouseEvent*) { return false; } @@ -82,7 +82,8 @@ bool mouseReleased (const AbstractEditMode::MouseEventData& data) override; void addDrawnVertex (const Vertex& pos); void finishDraw (const LDObjectList& objs); - void renderPolygon (QPainter& painter, const QVector<Vertex>& poly3d, bool withangles) const; + void renderPolygon (QPainter& painter, const QVector<Vertex>& poly3d, + bool withlengths, bool withangles) const; virtual bool preAddVertex (Vertex const&) {
--- a/src/editmodes/circleMode.cc Sat Aug 30 16:08:05 2014 +0300 +++ b/src/editmodes/circleMode.cc Sat Aug 30 20:09:30 2014 +0300 @@ -72,8 +72,8 @@ void CircleMode::buildCircle() { LDObjectList objs; - const int segs (g_win->ringToolHiRes() ? HighResolution : LowResolution); - const int divs (segs); // TODO: make customizable + const int segments (g_win->ringToolSegments()); + const int divisions (g_win->ringToolHiRes() ? HighResolution : LowResolution); double dist0 (getCircleDrawDist (0)); double dist1 (getCircleDrawDist (1)); LDDocumentPtr refFile; @@ -86,14 +86,14 @@ if (dist0 == dist1) { // If the radii are the same, there's no ring space to fill. Use a circle. - refFile = GetDocument (MakeRadialFileName (::Circle, segs, segs, 0)); + refFile = GetPrimitive (::Circle, segments, divisions, 0); transform = getCircleDrawMatrix (dist0); circleOrDisc = true; } elif (dist0 == 0 or dist1 == 0) { // If either radii is 0, use a disc. - refFile = GetDocument (MakeRadialFileName (::Disc, segs, segs, 0)); + refFile = GetPrimitive (::Disc, segments, divisions, 0); transform = getCircleDrawMatrix ((dist0 != 0) ? dist0 : dist1); circleOrDisc = true; } @@ -102,14 +102,7 @@ // The ring finder found a solution, use that. Add the component rings to the file. for (const RingFinder::Component& cmp : g_RingFinder.bestSolution()->getComponents()) { - // Get a ref file for this primitive. If we cannot find it in the - // LDraw library, generate it. - if ((refFile = ::GetDocument (MakeRadialFileName (::Ring, segs, segs, cmp.num))) == null) - { - refFile = GeneratePrimitive (::Ring, segs, segs, cmp.num); - refFile->setImplicit (false); - } - + refFile = GetPrimitive (::Ring, segments, divisions, cmp.num); LDSubfilePtr ref = LDSpawn<LDSubfile>(); ref->setFileInfo (refFile); ref->setTransform (getCircleDrawMatrix (cmp.scale)); @@ -134,10 +127,10 @@ templ.setCoordinate (localz, renderer()->getDepthValue()); // Calculate circle coords - MakeCircle (segs, divs, dist0, c0); - MakeCircle (segs, divs, dist1, c1); + MakeCircle (segments, divisions, dist0, c0); + MakeCircle (segments, divisions, dist1, c1); - for (int i = 0; i < segs; ++i) + for (int i = 0; i < segments; ++i) { Vertex v0, v1, v2, v3; v0 = v1 = v2 = v3 = templ; @@ -185,84 +178,85 @@ return; } - QVector<Vertex> verts, verts2; - const double dist0 = getCircleDrawDist (0), - dist1 = (m_drawedVerts.size() >= 2) ? getCircleDrawDist (1) : -1; - const int segs (g_win->ringToolHiRes() ? HighResolution : LowResolution); - const double angleUnit = (2 * Pi) / segs; + QVector<Vertex> innerverts, outerverts; + QVector<QPointF> innerverts2d, outerverts2d; + const double innerdistance (getCircleDrawDist (0)); + const double outerdistance (m_drawedVerts.size() >= 2 ? getCircleDrawDist (1) : -1); + const int divisions (g_win->ringToolHiRes() ? HighResolution : LowResolution); + const int segments (g_win->ringToolSegments()); + const double angleUnit (2 * Pi / divisions); Axis relX, relY; - QVector<QPoint> ringpoints, circlepoints, circle2points; - renderer()->getRelativeAxes (relX, relY); // Calculate the preview positions of vertices - for (int i = 0; i < segs; ++i) + for (int i = 0; i < segments + 1; ++i) { Vertex v (Origin); - v.setCoordinate (relX, m_drawedVerts[0][relX] + (cos (i * angleUnit) * dist0)); - v.setCoordinate (relY, m_drawedVerts[0][relY] + (sin (i * angleUnit) * dist0)); - verts << v; + v.setCoordinate (relX, m_drawedVerts[0][relX] + (cos (i * angleUnit) * innerdistance)); + v.setCoordinate (relY, m_drawedVerts[0][relY] + (sin (i * angleUnit) * innerdistance)); + innerverts << v; + innerverts2d << renderer()->coordconv3_2 (v); - if (dist1 != -1) + if (outerdistance != -1) { - v.setCoordinate (relX, m_drawedVerts[0][relX] + (cos (i * angleUnit) * dist1)); - v.setCoordinate (relY, m_drawedVerts[0][relY] + (sin (i * angleUnit) * dist1)); - verts2 << v; + v.setCoordinate (relX, m_drawedVerts[0][relX] + (cos (i * angleUnit) * outerdistance)); + v.setCoordinate (relY, m_drawedVerts[0][relY] + (sin (i * angleUnit) * outerdistance)); + outerverts << v; + outerverts2d << renderer()->coordconv3_2 (v); } } - int i = 0; - for (const Vertex& v : verts + verts2) + QVector<QLineF> lines (segments); + + if (outerdistance != -1 and outerdistance != innerdistance) { - // Calculate the 2D point of the vertex - QPoint point (renderer()->coordconv3_2 (v)); - - // Draw a green blip at where it is - renderer()->drawBlip (painter, point); + painter.setBrush (m_polybrush); + painter.setPen (Qt::NoPen); - // Add it to the list of points for the green ring fill. - ringpoints << point; + // Compile polygons + for (int i = 0; i < segments; ++i) + { + QVector<QPointF> points; + points << innerverts2d[i] + << innerverts2d[i + 1] + << outerverts2d[i + 1] + << outerverts2d[i]; + painter.drawPolygon (QPolygonF (points)); + lines << QLineF (innerverts2d[i], innerverts2d[i + 1]); + lines << QLineF (outerverts2d[i], outerverts2d[i + 1]); + } - // Also add the circle points to separate lists - if (i < verts.size()) - circlepoints << point; - else - circle2points << point; - - ++i; + // Add bordering edges for unclosed rings/discs + if (segments != divisions) + { + lines << QLineF (innerverts2d.first(), outerverts2d.first()); + lines << QLineF (innerverts2d.last(), outerverts2d.last()); + } + } + else + { + for (int i = 0; i < segments; ++i) + lines << QLineF (innerverts2d[i], innerverts2d[i + 1]); } - // Insert the first point as the seventeenth one so that - // the ring polygon is closed properly. - if (ringpoints.size() >= segs) - ringpoints.insert (segs, ringpoints[0]); - - // Same for the outer ring. Note that the indices are offset by 1 - // because of the insertion done above bumps the values. - if (ringpoints.size() >= segs * 2 + 1) - ringpoints.insert (segs * 2 + 1, ringpoints[segs + 1]); + // Draw a green blips at where the points are + for (QPointF const& point : innerverts2d + outerverts2d) + renderer()->drawBlip (painter, point); - // Draw the ring - painter.setBrush ((m_drawedVerts.size() >= 2) ? m_polybrush : Qt::NoBrush); - painter.setPen (Qt::NoPen); - painter.drawPolygon (QPolygon (ringpoints)); - - // Draw the circles - painter.setBrush (Qt::NoBrush); + // Draw edge lines painter.setPen (renderer()->linePen()); - painter.drawPolygon (QPolygon (circlepoints)); - painter.drawPolygon (QPolygon (circle2points)); + painter.drawLines (lines); // Draw the current radius in the middle of the circle. QPoint origin = renderer()->coordconv3_2 (m_drawedVerts[0]); - QString label = QString::number (dist0); + QString label = QString::number (innerdistance); painter.setPen (renderer()->textPen()); painter.drawText (origin.x() - (metrics.width (label) / 2), origin.y(), label); if (m_drawedVerts.size() >= 2) { painter.drawText (origin.x() - (metrics.width (label) / 2), - origin.y() + metrics.height(), QString::number (dist1)); + origin.y() + metrics.height(), QString::number (outerdistance)); } }
--- a/src/editmodes/drawMode.cc Sat Aug 30 16:08:05 2014 +0300 +++ b/src/editmodes/drawMode.cc Sat Aug 30 20:09:30 2014 +0300 @@ -42,7 +42,7 @@ if (poly.size() < 4) poly << renderer()->position3D(); - renderPolygon (painter, poly, true); + renderPolygon (painter, poly, true, true); } bool DrawMode::preAddVertex (Vertex const& pos)
--- a/src/editmodes/rectangleMode.cc Sat Aug 30 16:08:05 2014 +0300 +++ b/src/editmodes/rectangleMode.cc Sat Aug 30 20:09:30 2014 +0300 @@ -34,7 +34,7 @@ void RectangleMode::render (QPainter& painter) const { renderPolygon (painter, (m_drawedVerts.size() > 0) ? m_rectangleVerts : - QVector<Vertex> ({renderer()->position3D()}), false); + QVector<Vertex> ({renderer()->position3D()}), true, false); } bool RectangleMode::mouseReleased (MouseEventData const& data)
--- a/src/glRenderer.cc Sat Aug 30 16:08:05 2014 +0300 +++ b/src/glRenderer.cc Sat Aug 30 20:09:30 2014 +0300 @@ -712,7 +712,7 @@ // ============================================================================= // -void GLRenderer::drawBlip (QPainter& paint, QPoint pos) const +void GLRenderer::drawBlip (QPainter& paint, QPointF pos) const { QPen pen = m_thinBorderPen; const int blipsize = 8;
--- a/src/glRenderer.h Sat Aug 30 16:08:05 2014 +0300 +++ b/src/glRenderer.h Sat Aug 30 20:09:30 2014 +0300 @@ -157,7 +157,7 @@ Vertex coordconv2_3 (const QPoint& pos2d, bool snap) const; QPoint coordconv3_2 (const Vertex& pos3d); EditModeType currentEditModeType() const; - void drawBlip (QPainter& paint, QPoint pos) const; + void drawBlip (QPainter& paint, QPointF pos) const; void drawGLScene(); void forgetObject (LDObjectPtr obj); Axis getCameraAxis (bool y, ECamera camid = (ECamera) -1);
--- a/src/ldDocument.cc Sat Aug 30 16:08:05 2014 +0300 +++ b/src/ldDocument.cc Sat Aug 30 20:09:30 2014 +0300 @@ -226,10 +226,15 @@ // LDDocumentPtr FindDocument (QString name) { - for (LDDocumentWeakPtr file : g_allDocuments) + for (LDDocumentWeakPtr weakfile : g_allDocuments) { - if (file != null and file.toStrongRef()->name() == name) - return file.toStrongRef(); + if (weakfile == null) + continue; + + LDDocumentPtr file (weakfile.toStrongRef()); + + if (Eq (name, file->name(), file->defaultName())) + return file; } return LDDocumentPtr();
--- a/src/mainWindow.cc Sat Aug 30 16:08:05 2014 +0300 +++ b/src/mainWindow.cc Sat Aug 30 20:09:30 2014 +0300 @@ -121,6 +121,7 @@ loadShortcuts (Config::SettingsObject()); setMinimumSize (300, 200); connect (qApp, SIGNAL (aboutToQuit()), this, SLOT (slot_lastSecondCleanup())); + connect (ui->ringToolHiRes, SIGNAL (clicked (bool)), this, SLOT (ringToolHiResClicked (bool))); } MainWindow::~MainWindow() @@ -1058,18 +1059,35 @@ // bool MainWindow::ringToolHiRes() const { - return ui->ringToolHiRes->isChecked(); + return ui->ringToolHiRes->isChecked(); } // ============================================================================= // int MainWindow::ringToolSegments() const { - return ui->ringToolSegments->value(); + return ui->ringToolSegments->value(); } // ============================================================================= // +void MainWindow::ringToolHiResClicked (bool checked) +{ + if (checked) + { + ui->ringToolSegments->setMaximum (HighResolution); + ui->ringToolSegments->setValue (ui->ringToolSegments->value() * 3); + } + else + { + ui->ringToolSegments->setValue (ui->ringToolSegments->value() / 3); + ui->ringToolSegments->setMaximum (LowResolution); + } +} + + +// ============================================================================= +// QImage GetImageFromScreencap (uchar* data, int w, int h) { // GL and Qt formats have R and B swapped. Also, GL flips Y - correct it as well.
--- a/src/mainWindow.h Sat Aug 30 16:08:05 2014 +0300 +++ b/src/mainWindow.h Sat Aug 30 20:09:30 2014 +0300 @@ -172,13 +172,14 @@ void saveShortcuts (QSettings* settings); void applyToActions (std::function<void(QAction*)> function); - bool ringToolHiRes() const; - int ringToolSegments() const; + bool ringToolHiRes() const; + int ringToolSegments() const; public slots: void updatePrimitives(); void changeCurrentFile(); void closeTab (int tabindex); + void ringToolHiResClicked (bool clicked); void slot_action(); void slot_actionNew(); void slot_actionNewFile();
--- a/src/primitives.cc Sat Aug 30 16:08:05 2014 +0300 +++ b/src/primitives.cc Sat Aug 30 20:09:30 2014 +0300 @@ -640,8 +640,11 @@ << LDSpawn<LDBFC> (BFCStatement::CertifyCCW) << LDSpawn<LDEmpty>(); + f->setImplicit (false); + f->history()->setIgnoring (false); f->addObjects (objs); f->addObjects (MakePrimitive (type, segs, divs, num)); + f->addHistoryStep(); return f; }
--- a/ui/ldforge.ui Sat Aug 30 16:08:05 2014 +0300 +++ b/ui/ldforge.ui Sat Aug 30 20:09:30 2014 +0300 @@ -108,7 +108,7 @@ <item row="1" column="1"> <widget class="QSpinBox" name="ringToolSegments"> <property name="enabled"> - <bool>false</bool> + <bool>true</bool> </property> <property name="minimum"> <number>1</number>