- circle tool is now able to rotate the partial circular primitives spawned

Sun, 31 Aug 2014 20:39:30 +0300

author
Teemu Piippo <crimsondusk64@gmail.com>
date
Sun, 31 Aug 2014 20:39:30 +0300
changeset 869
7184f3bae695
parent 868
6e03c68c81ba
child 870
9e9e71ebfbe7

- circle tool is now able to rotate the partial circular primitives spawned

CMakeLists.txt file | annotate | diff | comparison | revisions
src/actionsEdit.cc file | annotate | diff | comparison | revisions
src/editmodes/circleMode.cc file | annotate | diff | comparison | revisions
src/editmodes/circleMode.h file | annotate | diff | comparison | revisions
src/glRenderer.cc file | annotate | diff | comparison | revisions
src/glRenderer.h file | annotate | diff | comparison | revisions
src/ldObjectMath.cpp file | annotate | diff | comparison | revisions
src/ldObjectMath.h file | annotate | diff | comparison | revisions
src/mainWindow.cc file | annotate | diff | comparison | revisions
--- a/CMakeLists.txt	Sun Aug 31 14:38:53 2014 +0300
+++ b/CMakeLists.txt	Sun Aug 31 20:39:30 2014 +0300
@@ -54,6 +54,7 @@
 	src/ldConfig.cc
 	src/ldDocument.cc
 	src/ldObject.cc
+    src/ldObjectMath.cpp
 	src/main.cc
 	src/mainWindow.cc
 	src/messageLog.cc
@@ -81,6 +82,7 @@
 	src/ldConfig.h
 	src/partDownloader.h
 	src/ldObject.h
+    src/ldObjectMath.h
 	src/primitives.h
 	src/miscallenous.h
 	src/messageLog.h
--- a/src/actionsEdit.cc	Sun Aug 31 14:38:53 2014 +0300
+++ b/src/actionsEdit.cc	Sun Aug 31 20:39:30 2014 +0300
@@ -1,4 +1,4 @@
-/*
+/*
  *  LDForge: LDraw parts authoring CAD
  *  Copyright (C) 2013, 2014 Teemu Piippo
  *
@@ -31,6 +31,7 @@
 #include "glRenderer.h"
 #include "dialogs.h"
 #include "colors.h"
+#include "ldObjectMath.h"
 #include "ui_replcoords.h"
 #include "ui_editraw.h"
 #include "ui_flip.h"
@@ -407,101 +408,34 @@
 
 // =============================================================================
 //
-static void RotateVertex (Vertex& v, const Vertex& rotpoint, const Matrix& transformer)
+static double GetRotateActionAngle()
 {
-	v -= rotpoint;
-	v.transform (transformer, Origin);
-	v += rotpoint;
+	return (Pi * *CurrentGrid().angleSnap) / 180;
 }
 
-// =============================================================================
-//
-static void RotateObjects (const int l, const int m, const int n)
-{
-	LDObjectList sel = Selection();
-	QList<Vertex*> queue;
-	const Vertex rotpoint = GetRotationPoint (sel);
-	const double angle = (Pi * *CurrentGrid().angleSnap) / 180,
-				 cosangle = cos (angle),
-				 sinangle = sin (angle);
-
-	// ref: http://en.wikipedia.org/wiki/Transformation_matrix#Rotation_2
-	Matrix transform (
-	{
-		(l* l * (1 - cosangle)) + cosangle,
-		(m* l * (1 - cosangle)) - (n* sinangle),
-		(n* l * (1 - cosangle)) + (m* sinangle),
-
-		(l* m * (1 - cosangle)) + (n* sinangle),
-		(m* m * (1 - cosangle)) + cosangle,
-		(n* m * (1 - cosangle)) - (l* sinangle),
-
-		(l* n * (1 - cosangle)) - (m* sinangle),
-		(m* n * (1 - cosangle)) + (l* sinangle),
-		(n* n * (1 - cosangle)) + cosangle
-	});
-
-	// Apply the above matrix to everything
-	for (LDObjectPtr obj : sel)
-	{
-		if (obj->numVertices())
-		{
-			for (int i = 0; i < obj->numVertices(); ++i)
-			{
-				Vertex v = obj->vertex (i);
-				RotateVertex (v, rotpoint, transform);
-				obj->setVertex (i, v);
-			}
-		}
-		elif (obj->hasMatrix())
-		{
-			LDMatrixObjectPtr mo = obj.dynamicCast<LDMatrixObject>();
-
-			// Transform the position
-			Vertex v = mo->position();
-			RotateVertex (v, rotpoint, transform);
-			mo->setPosition (v);
-
-			// Transform the matrix
-			mo->setTransform (transform * mo->transform());
-		}
-		elif (obj->type() == OBJ_Vertex)
-		{
-			LDVertexPtr vert = obj.staticCast<LDVertex>();
-			Vertex v = vert->pos;
-			RotateVertex (v, rotpoint, transform);
-			vert->pos = v;
-		}
-	}
-
-	g_win->refresh();
-}
-
-// =============================================================================
-//
 void MainWindow::slot_actionRotateXPos()
 {
-	RotateObjects (1, 0, 0);
+	RotateObjects (1, 0, 0, GetRotateActionAngle(), Selection());
 }
 void MainWindow::slot_actionRotateYPos()
 {
-	RotateObjects (0, 1, 0);
+	RotateObjects (0, 1, 0, GetRotateActionAngle(), Selection());
 }
 void MainWindow::slot_actionRotateZPos()
 {
-	RotateObjects (0, 0, 1);
+	RotateObjects (0, 0, 1, GetRotateActionAngle(), Selection());
 }
 void MainWindow::slot_actionRotateXNeg()
 {
-	RotateObjects (-1, 0, 0);
+	RotateObjects (-1, 0, 0, GetRotateActionAngle(), Selection());
 }
 void MainWindow::slot_actionRotateYNeg()
 {
-	RotateObjects (0, -1, 0);
+	RotateObjects (0, -1, 0, GetRotateActionAngle(), Selection());
 }
 void MainWindow::slot_actionRotateZNeg()
 {
-	RotateObjects (0, 0, -1);
+	RotateObjects (0, 0, -1, GetRotateActionAngle(), Selection());
 }
 
 void MainWindow::slot_actionRotationPoint()
--- a/src/editmodes/circleMode.cc	Sun Aug 31 14:38:53 2014 +0300
+++ b/src/editmodes/circleMode.cc	Sun Aug 31 20:39:30 2014 +0300
@@ -25,6 +25,7 @@
 #include "../primitives.h"
 #include "../glRenderer.h"
 #include "../mainWindow.h"
+#include "../ldObjectMath.h"
 
 CircleMode::CircleMode (GLRenderer* renderer) :
 	Super (renderer) {}
@@ -164,9 +165,34 @@
 		objs << ref;
 	}
 
+	unless (objs.isEmpty())
+	{
+		LDFixedCamera const& fixedcam = GetFixedCamera (renderer()->camera());
+		Axis relZ = renderer()->getRelativeZ();
+		const double angleoffset (-getAngleOffset());
+		const int l (relZ == X ? 1 : 0);
+		const int m (relZ == Y ? 1 : 0);
+		const int n (relZ == Z ? 1 : 0);
+		RotateObjects (l, m, n, angleoffset, objs);
+	}
+
 	finishDraw (objs);
 }
 
+double CircleMode::getAngleOffset() const
+{
+	const int divisions (g_win->ringToolHiRes() ? HighResolution : LowResolution);
+	QPointF originspot (renderer()->coordconv3_2 (m_drawedVerts.first()));
+	QLineF bearing (originspot, renderer()->mousePositionF());
+	QLineF bearing2 (originspot, QPointF (originspot.x(), 0.0));
+	double angleoffset (-bearing.angleTo (bearing2) + 90);
+	angleoffset /= (360.0 / divisions); // convert angle to 0-16 scale
+	angleoffset = round (angleoffset); // round to nearest 16th
+	angleoffset *= ((2 * Pi) / divisions); // convert to radians
+	angleoffset *= renderer()->depthNegateFactor(); // negate based on camera
+	return angleoffset;
+}
+
 void CircleMode::render (QPainter& painter) const
 {
 	QFontMetrics metrics = QFontMetrics (QFont());
@@ -187,20 +213,23 @@
 	const double angleUnit (2 * Pi / divisions);
 	Axis relX, relY;
 	renderer()->getRelativeAxes (relX, relY);
+	const double angleoffset (getAngleOffset());
 
 	// Calculate the preview positions of vertices
 	for (int i = 0; i < segments + 1; ++i)
 	{
+		const double sinangle (sin (angleoffset + i * angleUnit));
+		const double cosangle (cos (angleoffset + i * angleUnit));
 		Vertex v (Origin);
-		v.setCoordinate (relX, m_drawedVerts[0][relX] + (cos (i * angleUnit) * innerdistance));
-		v.setCoordinate (relY, m_drawedVerts[0][relY] + (sin (i * angleUnit) * innerdistance));
+		v.setCoordinate (relX, m_drawedVerts[0][relX] + (cosangle * innerdistance));
+		v.setCoordinate (relY, m_drawedVerts[0][relY] + (sinangle * innerdistance));
 		innerverts << v;
 		innerverts2d << renderer()->coordconv3_2 (v);
 
 		if (outerdistance != -1)
 		{
-			v.setCoordinate (relX, m_drawedVerts[0][relX] + (cos (i * angleUnit) * outerdistance));
-			v.setCoordinate (relY, m_drawedVerts[0][relY] + (sin (i * angleUnit) * outerdistance));
+			v.setCoordinate (relX, m_drawedVerts[0][relX] + (cosangle * outerdistance));
+			v.setCoordinate (relY, m_drawedVerts[0][relY] + (sinangle * outerdistance));
 			outerverts << v;
 			outerverts2d << renderer()->coordconv3_2 (v);
 		}
--- a/src/editmodes/circleMode.h	Sun Aug 31 14:38:53 2014 +0300
+++ b/src/editmodes/circleMode.h	Sun Aug 31 20:39:30 2014 +0300
@@ -35,4 +35,5 @@
 
 private:
 	void buildCircle();
+	double getAngleOffset() const;
 };
--- a/src/glRenderer.cc	Sun Aug 31 14:38:53 2014 +0300
+++ b/src/glRenderer.cc	Sun Aug 31 20:39:30 2014 +0300
@@ -42,7 +42,7 @@
 #include "glCompiler.h"
 #include "primitives.h"
 
-static const LDFixedCamera g_FixedCameras[6] =
+const LDFixedCamera g_FixedCameras[6] =
 {
 	{{  1,  0, 0 }, X, Z, false, false, false }, // top
 	{{  0,  0, 0 }, X, Y, false,  true, false }, // front
@@ -827,6 +827,7 @@
 
 	// Update 2d position
 	m_mousePosition = ev->pos();
+	m_mousePositionF = ev->posF();
 	m_globalpos = ev->globalPos();
 
 	// Calculate 3d position of the cursor
@@ -1626,8 +1627,24 @@
 	return m_mousePosition;
 }
 
+QPointF const& GLRenderer::mousePositionF() const
+{
+	return m_mousePositionF;
+}
+
 void GLRenderer::doMakeCurrent()
 {
 	makeCurrent();
 	initializeOpenGLFunctions();
 }
+
+int GLRenderer::depthNegateFactor() const
+{
+	return g_FixedCameras[camera()].negatedDepth ? -1 : 1;
+}
+
+LDFixedCamera const& GetFixedCamera (ECamera cam)
+{
+	assert (cam != EFreeCamera);
+	return g_FixedCameras[cam];
+}
--- a/src/glRenderer.h	Sun Aug 31 14:38:53 2014 +0300
+++ b/src/glRenderer.h	Sun Aug 31 20:39:30 2014 +0300
@@ -157,6 +157,7 @@
 	Vertex					coordconv2_3 (const QPoint& pos2d, bool snap) const;
 	QPoint					coordconv3_2 (const Vertex& pos3d);
 	EditModeType			currentEditModeType() const;
+	int						depthNegateFactor() const;
 	void					drawBlip (QPainter& paint, QPointF pos) const;
 	void					drawGLScene();
 	void					forgetObject (LDObjectPtr obj);
@@ -175,6 +176,7 @@
 	QPen					linePen() const;
 	bool					mouseHasMoved() const;
 	QPoint const&			mousePosition() const;
+	QPointF const&			mousePositionF() const;
 	void					needZoomToFit();
 	void					pick (int mouseX, int mouseY, bool additive);
 	void					pick (QRect const& range, bool additive);
@@ -224,6 +226,7 @@
 							m_panning;
 	QPoint					m_mousePosition,
 							m_globalpos;
+	QPointF					m_mousePositionF;
 	QPen					m_thinBorderPen;
 	ECamera					m_camera,
 							m_toolTipCamera;
@@ -295,4 +298,6 @@
 	return currentDocumentData().zoom[camera()];
 }
 
+LDFixedCamera const& GetFixedCamera (ECamera cam);
+
 extern const char* g_CameraNames[7];
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ldObjectMath.cpp	Sun Aug 31 20:39:30 2014 +0300
@@ -0,0 +1,89 @@
+/*
+ *  LDForge: LDraw parts authoring CAD
+ *  Copyright (C) 2013, 2014 Teemu Piippo
+ *
+ *  This program is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "ldObjectMath.h"
+#include "ldObject.h"
+#include "miscallenous.h"
+
+// =============================================================================
+//
+static void RotateVertex (Vertex& v, const Vertex& rotpoint, const Matrix& transformer)
+{
+	v -= rotpoint;
+	v.transform (transformer, Origin);
+	v += rotpoint;
+}
+
+// =============================================================================
+//
+void RotateObjects (const int l, const int m, const int n, double angle, LDObjectList const& objects)
+{
+	QList<Vertex*> queue;
+	const Vertex rotpoint = GetRotationPoint (objects);
+	const double cosangle = cos (angle),
+				 sinangle = sin (angle);
+
+	// ref: http://en.wikipedia.org/wiki/Transformation_matrix#Rotation_2
+	Matrix transform (
+	{
+		(l* l * (1 - cosangle)) + cosangle,
+		(m* l * (1 - cosangle)) - (n* sinangle),
+		(n* l * (1 - cosangle)) + (m* sinangle),
+
+		(l* m * (1 - cosangle)) + (n* sinangle),
+		(m* m * (1 - cosangle)) + cosangle,
+		(n* m * (1 - cosangle)) - (l* sinangle),
+
+		(l* n * (1 - cosangle)) - (m* sinangle),
+		(m* n * (1 - cosangle)) + (l* sinangle),
+		(n* n * (1 - cosangle)) + cosangle
+	});
+
+	// Apply the above matrix to everything
+	for (LDObjectPtr obj : objects)
+	{
+		if (obj->numVertices())
+		{
+			for (int i = 0; i < obj->numVertices(); ++i)
+			{
+				Vertex v = obj->vertex (i);
+				RotateVertex (v, rotpoint, transform);
+				obj->setVertex (i, v);
+			}
+		}
+		elif (obj->hasMatrix())
+		{
+			LDMatrixObjectPtr mo = obj.dynamicCast<LDMatrixObject>();
+
+			// Transform the position
+			Vertex v = mo->position();
+			RotateVertex (v, rotpoint, transform);
+			mo->setPosition (v);
+
+			// Transform the matrix
+			mo->setTransform (transform * mo->transform());
+		}
+		elif (obj->type() == OBJ_Vertex)
+		{
+			LDVertexPtr vert = obj.staticCast<LDVertex>();
+			Vertex v = vert->pos;
+			RotateVertex (v, rotpoint, transform);
+			vert->pos = v;
+		}
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ldObjectMath.h	Sun Aug 31 20:39:30 2014 +0300
@@ -0,0 +1,23 @@
+/*
+ *  LDForge: LDraw parts authoring CAD
+ *  Copyright (C) 2013, 2014 Teemu Piippo
+ *
+ *  This program is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+#include "main.h"
+
+void RotateObjects (const int l, const int m, const int n,
+	double angle, LDObjectList const& objects);
--- a/src/mainWindow.cc	Sun Aug 31 14:38:53 2014 +0300
+++ b/src/mainWindow.cc	Sun Aug 31 20:39:30 2014 +0300
@@ -150,6 +150,7 @@
 	// Update the list item of the current file - we may need to draw an icon
 	// now that marks it as having unsaved changes.
 	updateDocumentListItem (CurrentDocument());
+	refresh();
 }
 
 // =============================================================================

mercurial