- now able to spawn partial circular primitives

Sat, 30 Aug 2014 20:09:30 +0300

author
Teemu Piippo <crimsondusk64@gmail.com>
date
Sat, 30 Aug 2014 20:09:30 +0300
changeset 866
4951b737f8cb
parent 865
6d68840fcb26
child 867
557cb07dbe57

- now able to spawn partial circular primitives

src/editmodes/abstractEditMode.cc file | annotate | diff | comparison | revisions
src/editmodes/abstractEditMode.h file | annotate | diff | comparison | revisions
src/editmodes/circleMode.cc file | annotate | diff | comparison | revisions
src/editmodes/drawMode.cc file | annotate | diff | comparison | revisions
src/editmodes/rectangleMode.cc file | annotate | diff | comparison | revisions
src/glRenderer.cc file | annotate | diff | comparison | revisions
src/glRenderer.h file | annotate | diff | comparison | revisions
src/ldDocument.cc file | annotate | diff | comparison | revisions
src/mainWindow.cc file | annotate | diff | comparison | revisions
src/mainWindow.h file | annotate | diff | comparison | revisions
src/primitives.cc file | annotate | diff | comparison | revisions
ui/ldforge.ui file | annotate | diff | comparison | revisions
--- 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>

mercurial