Added the radial type, this one sure has been on my wishlist for a while. :)

Tue, 16 Apr 2013 02:13:11 +0300

author
Santeri Piippo <crimsondusk64@gmail.com>
date
Tue, 16 Apr 2013 02:13:11 +0300
changeset 111
125e8031dbf1
parent 110
a62ab18d1b80
child 112
fa2f00081357

Added the radial type, this one sure has been on my wishlist for a while. :)

gldraw.cpp file | annotate | diff | comparison | revisions
gui.cpp file | annotate | diff | comparison | revisions
gui_actions.cpp file | annotate | diff | comparison | revisions
icons/add-radial.png file | annotate | diff | comparison | revisions
icons/corner-verts.png file | annotate | diff | comparison | revisions
icons/radial.png file | annotate | diff | comparison | revisions
icons/select-all.png file | annotate | diff | comparison | revisions
icons/select-color.png file | annotate | diff | comparison | revisions
icons/select-type.png file | annotate | diff | comparison | revisions
ldtypes.cpp file | annotate | diff | comparison | revisions
ldtypes.h file | annotate | diff | comparison | revisions
zz_addObjectDialog.cpp file | annotate | diff | comparison | revisions
zz_addObjectDialog.h file | annotate | diff | comparison | revisions
--- a/gldraw.cpp	Mon Apr 15 18:07:29 2013 +0300
+++ b/gldraw.cpp	Tue Apr 16 02:13:11 2013 +0300
@@ -347,8 +347,19 @@
 	case OBJ_Subfile:
 		{
 			LDSubfile* ref = static_cast<LDSubfile*> (obj);
+			vector<LDObject*> objs = ref->inlineContents (true, true);
 			
-			vector<LDObject*> objs = ref->inlineContents (true, true);
+			for (LDObject* obj : objs) {
+				compileOneObject (obj);
+				delete obj;
+			}
+		}
+		break;
+	
+	case OBJ_Radial:
+		{
+			LDRadial* pRadial = static_cast<LDRadial*> (obj);
+			std::vector<LDObject*> objs = pRadial->decompose (true);
 			
 			for (LDObject* obj : objs) {
 				compileOneObject (obj);
--- a/gui.cpp	Mon Apr 15 18:07:29 2013 +0300
+++ b/gui.cpp	Tue Apr 16 02:13:11 2013 +0300
@@ -54,6 +54,7 @@
 EXTERN_ACTION (newQuad)
 EXTERN_ACTION (newVertex)
 EXTERN_ACTION (newComment)
+EXTERN_ACTION (newRadial)
 EXTERN_ACTION (help)
 EXTERN_ACTION (about)
 EXTERN_ACTION (aboutQt)
@@ -71,6 +72,7 @@
 
 #ifndef RELEASE
 EXTERN_ACTION (addTestQuad)
+EXTERN_ACTION (addTestRadial)
 #endif // RELEASE
 
 vector<actionmeta> g_ActionMeta;
@@ -180,6 +182,7 @@
 	qInsertMenu->addAction (ACTION_NAME (newCondLine));		// New Conditional Line
 	qInsertMenu->addAction (ACTION_NAME (newComment));		// New Comment
 	qInsertMenu->addAction (ACTION_NAME (newVertex));		// New Vertex
+	qInsertMenu->addAction (ACTION_NAME (newRadial));		// New Radial
 	
 	// Edit menu
 	qEditMenu = menuBar ()->addMenu (tr ("&Edit"));
@@ -222,6 +225,7 @@
 	// Debug menu
 	qDebugMenu = menuBar ()->addMenu (tr ("&Debug"));
 	qDebugMenu->addAction (ACTION_NAME (addTestQuad));		// Add Test Quad
+	qDebugMenu->addAction (ACTION_NAME (addTestRadial));	// Add Test Radial
 #endif // RELEASE
 	
 	// Help menu
@@ -283,6 +287,7 @@
 	ADD_TOOLBAR_ITEM (newCondLine)
 	ADD_TOOLBAR_ITEM (newComment)
 	ADD_TOOLBAR_ITEM (newVertex)
+	ADD_TOOLBAR_ITEM (newRadial)
 	
 	initSingleToolBar ("Edit");
 	ADD_TOOLBAR_ITEM (undo)
--- a/gui_actions.cpp	Mon Apr 15 18:07:29 2013 +0300
+++ b/gui_actions.cpp	Tue Apr 16 02:13:11 2013 +0300
@@ -119,10 +119,15 @@
 ACTION (newComment, "New Comment", "add-comment", "Creates a new comment.", 0) {
 	AddObjectDialog::staticDialog (OBJ_Comment, g_ForgeWindow);
 }
+
 ACTION (newVertex, "New Vertex", "add-vertex", "Creates a new vertex.", 0) {
 	AddObjectDialog::staticDialog (OBJ_Vertex, g_ForgeWindow);
 }
 
+ACTION (newRadial, "New Radial", "add-radial", "Creates a new radial.", 0) {
+	AddObjectDialog::staticDialog (OBJ_Radial, g_ForgeWindow);
+}
+
 ACTION (help, "Help", "help", "Shows the " APPNAME_DISPLAY " help manual.", KEY (F1)) {
 	
 }
@@ -200,9 +205,9 @@
 // =============================================================================
 // Debug things
 #ifndef RELEASE
-ACTION (addTestQuad, "Add Test Quad", "add-quad", "Adds a test quad.", CTRL_SHIFT (Q)) {
+ACTION (addTestQuad, "Add Test Quad", "add-quad", "Adds a test quad.", (0)) {
 	LDQuad* pQuad = new LDQuad;
-	pQuad->dColor = rand () % 16;
+	pQuad->dColor = rand () % 24;
 	pQuad->vaCoords[0] = { 1.0f, 0.0f,  1.0f};
 	pQuad->vaCoords[1] = {-1.0f, 0.0f,  1.0f};
 	pQuad->vaCoords[2] = {-1.0f, 0.0f, -1.0f};
@@ -212,4 +217,20 @@
 	History::addEntry (new AddHistory ({(ulong)pQuad->getIndex (g_CurrentFile)}, {pQuad->clone ()}));
 	g_ForgeWindow->refresh ();
 }
+
+ACTION (addTestRadial, "Add Test Radial", "add-radial", "Adds a test radial.", (0)) {
+	LDRadial* pRad = new LDRadial;
+	pRad->eRadialType = LDRadial::Cone;
+	pRad->mMatrix = g_mIdentity;
+	pRad->vPosition = vertex (0, 0, 0);
+	pRad->dColor = rand () % 24;
+	pRad->dDivisions = 16;
+	pRad->dRingNum = 2;
+	pRad->dSegments = 16;
+	
+	g_CurrentFile->addObject (pRad);
+	History::addEntry (new AddHistory ({(ulong)pRad->getIndex (g_CurrentFile)}, {pRad->clone ()}));
+	g_ForgeWindow->refresh ();
+}
+
 #endif // RELEASE
\ No newline at end of file
Binary file icons/add-radial.png has changed
Binary file icons/corner-verts.png has changed
Binary file icons/radial.png has changed
Binary file icons/select-all.png has changed
Binary file icons/select-color.png has changed
Binary file icons/select-type.png has changed
--- a/ldtypes.cpp	Mon Apr 15 18:07:29 2013 +0300
+++ b/ldtypes.cpp	Tue Apr 16 02:13:11 2013 +0300
@@ -24,6 +24,7 @@
 
 char const* g_saObjTypeNames[] = {
 	"subfile",
+	"radial",
 	"quadrilateral",
 	"triangle",
 	"line",
@@ -39,6 +40,7 @@
 // Should probably get rid of this array sometime
 char const* g_saObjTypeIcons[] = {
 	"subfile",
+	"radial",
 	"quad",
 	"triangle",
 	"line",
@@ -56,16 +58,14 @@
 // =============================================================================
 // LDObject constructors
 LDObject::LDObject () {
-	commonInit ();
-}
-
-void LDObject::commonInit () {
 	qObjListEntry = null;
 	parent = null;
 }
 
+void LDObject::commonInit () {
+}
+
 LDGibberish::LDGibberish () {
-	commonInit ();
 	dColor = -1;
 }
 
@@ -73,46 +73,42 @@
 	zContents = _zContent;
 	zReason = _zReason;
 	dColor = -1;
-	
-	commonInit ();
 }
 
 LDEmpty::LDEmpty () {
-	commonInit ();
 	dColor = -1;
 }
 
 LDComment::LDComment () {
-	commonInit ();
 	dColor = -1;
 }
 
 LDSubfile::LDSubfile () {
-	commonInit ();
+	
 }
 
 LDLine::LDLine () {
-	commonInit ();
+	
 }
 
 LDTriangle::LDTriangle () {
-	commonInit ();
+	
 }
 
 LDQuad::LDQuad () {
-	commonInit ();
+	
 }
 
 LDCondLine::LDCondLine () {
-	commonInit ();
+	
 }
 
 LDVertex::LDVertex () {
-	commonInit ();
+	
 }
 
 LDBFC::LDBFC () {
-	commonInit ();
+	
 }
 
 // =============================================================================
@@ -273,6 +269,7 @@
 LDTriangle::~LDTriangle () {}
 LDVertex::~LDVertex () {}
 LDBFC::~LDBFC () {}
+LDRadial::~LDRadial () {}
 
 // =============================================================================
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
@@ -474,7 +471,7 @@
 }
 
 // =============================================================================
-LDSubfile* LDObject::topLevelParent () {
+LDObject* LDObject::topLevelParent () {
 	if (!parent)
 		return null;
 	
@@ -483,7 +480,7 @@
 	while (it->parent)
 		it = it->parent;
 	
-	return static_cast<LDSubfile*> (it);
+	return it;
 }
 
 
@@ -504,6 +501,10 @@
 	vPosition += vVector;
 }
 
+void LDRadial::move (vertex vVector) {
+	vPosition += vVector;
+}
+
 void LDLine::move (vertex vVector) {
 	for (short i = 0; i < 2; ++i)
 		vaCoords[i] += vVector;
@@ -522,4 +523,152 @@
 void LDCondLine::move (vertex vVector) {
 	for (short i = 0; i < 4; ++i)
 		vaCoords[i] += vVector;
+}
+
+// ===========================================f==================================
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+// =============================================================================
+LDRadial::LDRadial () {
+	
+}
+
+const char* g_saRadialTypeNames[] = {
+	"Circle",
+	"Cylinder",
+	"Disc",
+	"Disc Negative",
+	"Ring",
+	"Cone",
+	null
+};
+
+std::vector<LDObject*> LDRadial::decompose (bool bTransform) {
+	std::vector<LDObject*> paObjects;
+	
+	for (short i = 0; i < dSegments; ++i) {
+		double x0 = cos ((i * 2 * pi) / dDivisions),
+			x1 = cos (((i + 1) * 2 * pi) / dDivisions),
+			z0 = sin ((i * 2 * pi) / dDivisions),
+			z1 = sin (((i + 1) * 2 * pi) / dDivisions);
+		
+		switch (eRadialType) {
+		case LDRadial::Circle:
+			{
+				vertex v0 (x0, 0.0f, z0),
+					v1 (x1, 0.0f, z1);
+				
+				if (bTransform) {
+					v0.transform (mMatrix, vPosition);
+					v1.transform (mMatrix, vPosition);
+				}
+				
+				LDLine* pLine = new LDLine;
+				pLine->vaCoords[0] = v0;
+				pLine->vaCoords[1] = v1;
+				pLine->dColor = dEdgeColor;
+				pLine->parent = this;
+				
+				paObjects.push_back (pLine);
+			}
+			break;
+		
+		case LDRadial::Cylinder:
+		case LDRadial::Ring:
+		case LDRadial::Cone:
+			{
+				double x2, x3, z2, z3;
+				double y0, y1, y2, y3;
+				
+				if (eRadialType == LDRadial::Cylinder) {
+					x2 = x1;
+					x3 = x0;
+					z2 = z1;
+					z3 = z0;
+					
+					y0 = y1 = 0.0f;
+					y2 = y3 = 1.0f;
+				} else {
+					x2 = x1 * (dRingNum + 1);
+					x3 = x0 * (dRingNum + 1);
+					z2 = z1 * (dRingNum + 1);
+					z3 = z0 * (dRingNum + 1);
+					
+					x0 *= dRingNum;
+					x1 *= dRingNum;
+					z0 *= dRingNum;
+					z1 *= dRingNum;
+					
+					if (eRadialType == LDRadial::Ring) {
+						y0 = y1 = y2 = y3 = 0.0f;
+					} else {
+						y0 = y1 = 1.0f;
+						y2 = y3 = 0.0f;
+					} 
+				}
+				
+				vertex v0 (x0, y0, z0),
+					v1 (x1, y1, z1),
+					v2 (x2, y2, z2),
+					v3 (x3, y3, z3);
+				
+				if (bTransform) {
+					v0.transform (mMatrix, vPosition);
+					v1.transform (mMatrix, vPosition);
+					v2.transform (mMatrix, vPosition);
+					v3.transform (mMatrix, vPosition);
+				}
+				
+				LDQuad* pQuad = new LDQuad;
+				pQuad->vaCoords[0] = v0;
+				pQuad->vaCoords[1] = v1;
+				pQuad->vaCoords[2] = v2;
+				pQuad->vaCoords[3] = v3;
+				pQuad->dColor = dColor;
+				pQuad->parent = this;
+				
+				paObjects.push_back (pQuad);
+			}
+			break;
+		
+		case LDRadial::Disc:
+		case LDRadial::DiscNeg:
+			{
+				double x2, z2;
+				
+				if (eRadialType == LDRadial::Disc) {
+					x2 = z2 = 0.0f;
+				} else {
+					x2 = (x0 >= 0.0f) ? 1.0f : -1.0f;
+					z2 = (z0 >= 0.0f) ? 1.0f : -1.0f;
+				}
+				
+				vertex v0 (x0, 0.0f, z0),
+					v1 (x1, 0.0f, z1),
+					v2 (x2, 0.0f, z2);
+				
+				if (bTransform) {
+					v0.transform (mMatrix, vPosition);
+					v1.transform (mMatrix, vPosition);
+					v2.transform (mMatrix, vPosition);
+				}
+				
+				LDTriangle* pSeg = new LDTriangle;
+				pSeg->vaCoords[0] = v0;
+				pSeg->vaCoords[1] = v1;
+				pSeg->vaCoords[2] = v2;
+				pSeg->dColor = dColor;
+				pSeg->parent = this;
+				
+				paObjects.push_back (pSeg);
+			}
+			break;
+		}
+	}
+	
+	return paObjects;
+}
+
+str LDRadial::getContents () {
+	// TODO
+	return "0 !LDFORGE RADIAL";
 }
\ No newline at end of file
--- a/ldtypes.h	Mon Apr 15 18:07:29 2013 +0300
+++ b/ldtypes.h	Tue Apr 16 02:13:11 2013 +0300
@@ -44,6 +44,7 @@
 // =============================================================================
 enum LDObjectType_e {
 	OBJ_Subfile,		// Object represents a sub-file reference
+	OBJ_Radial,			// Object represents a generic radial
 	OBJ_Quad,			// Object represents a quadrilateral
 	OBJ_Triangle,		// Object represents a triangle
 	OBJ_Line,			// Object represents a line
@@ -81,7 +82,7 @@
 	uint uGLList, uGLPickList;
 	
 	// Object this object was referenced from, if any
-	LDSubfile* parent;
+	LDObject* parent;
 	
 	// Type enumerator of this object
 	virtual LDObjectType_e getType () const {
@@ -111,8 +112,8 @@
 	// Moves this object using the given vertex as a movement vector
 	virtual void move (vertex vVector);
 	
-	// What subfile in the current file ultimately references this?
-	LDSubfile* topLevelParent ();
+	// What object in the current file ultimately references this?
+	LDObject* topLevelParent ();
 	
 	static void moveObjects (std::vector<LDObject*> objs, const bool bUp);
 	static str objectListContents (std::vector<LDObject*>& objs);
@@ -281,7 +282,7 @@
 // =============================================================================
 // LDVertex
 // 
-// The vertex is another LDForce-specific extension. It represents a single
+// The vertex is an LDForce-specific extension which represents a single
 // vertex which can be used as a parameter to tools or to store coordinates
 // with. Vertices are a part authoring tool and they should not appear in
 // finished parts.
@@ -294,6 +295,44 @@
 };
 
 // =============================================================================
+// LDRadial
+// 
+// The generic radial primitive (radial for short) is another LDforge-specific
+// extension which represents an arbitrary circular primitive. Radials can appear
+// as circles, cylinders, rings, cones, discs and disc negatives; the point is to
+// allow part authors to add radial primitives to parts without much hassle about
+// non-existant primitive parts.
+// =============================================================================
+class LDRadial : public LDObject {
+public:
+	enum Type {
+		Circle,
+		Cylinder,
+		Disc,
+		DiscNeg,
+		Ring,
+		Cone,
+		NumTypes
+	};
+	
+	IMPLEMENT_LDTYPE (Radial)
+	
+	LDRadial::Type eRadialType;
+	vertex vPosition;
+	matrix mMatrix;
+	short dDivisions, dSegments, dRingNum;
+	
+	LDRadial (LDRadial::Type eRadialType, vertex vPosition, matrix mMatrix,
+		short dDivisions, short dSegments, short dRingNum) :
+		eRadialType (eRadialType), vPosition (vPosition), mMatrix (mMatrix),
+		dDivisions (dDivisions), dSegments (dSegments), dRingNum (dRingNum) {}
+	
+	std::vector<LDObject*> decompose (bool bTransform);
+};
+
+extern const char* g_saRadialTypeNames[];
+
+// =============================================================================
 // Object type names. Pass the return value of getType as the index to get a
 // string representation of the object's type.
 extern const char* g_saObjTypeNames[];
--- a/zz_addObjectDialog.cpp	Mon Apr 15 18:07:29 2013 +0300
+++ b/zz_addObjectDialog.cpp	Tue Apr 16 02:13:11 2013 +0300
@@ -47,18 +47,48 @@
 	case OBJ_Comment:
 		qCommentLine = new QLineEdit;
 		break;
+	
 	case OBJ_Line:
 		dCoordCount = 6;
 		break;
+	
 	case OBJ_Triangle:
 		dCoordCount = 9;
 		break;
+	
 	case OBJ_Quad:
 	case OBJ_CondLine:
 		dCoordCount = 12;
 		break;
+	
 	case OBJ_Vertex:
 		dCoordCount = 3;
+	
+	case OBJ_Radial:
+		dCoordCount = 3;
+		
+		qRadialTypeLabel = new QLabel ("Type:");
+		qRadialResolutionLabel = new QLabel ("Resolution:");
+		qRadialSegmentsLabel = new QLabel ("Segments:");
+		qRadialRingNumLabel = new QLabel ("Ring number:");
+		
+		qRadialType = new QComboBox;
+		
+		for (int i = 0; i < LDRadial::NumTypes; ++i)
+			qRadialType->addItem (g_saRadialTypeNames[i]);
+		
+		connect (qRadialType, SIGNAL (currentIndexChanged (int)), this, SLOT (slot_radialTypeChanged (int)));
+		
+		qRadialResolution = new QComboBox;
+		qRadialResolution->addItems ({"Normal (16)", "Hi-Res (48)"});
+		
+		qRadialSegments = new QSpinBox;
+		qRadialSegments->setMinimum (1);
+		
+		qRadialRingNum = new QSpinBox;
+		qRadialRingNum->setEnabled (false);
+		break;
+	
 	default:
 		break;
 	}
@@ -72,6 +102,7 @@
 	case OBJ_Triangle:
 	case OBJ_Vertex:
 	case OBJ_Subfile:
+	case OBJ_Radial:
 		bUsesColor = true;
 		break;
 	default:
@@ -102,6 +133,18 @@
 	case OBJ_Comment:
 		qLayout->addWidget (qCommentLine, 0, 1);
 		break;
+	
+	case OBJ_Radial:
+		qLayout->addWidget (qRadialTypeLabel, 1, 1);
+		qLayout->addWidget (qRadialType, 1, 2);
+		qLayout->addWidget (qRadialResolutionLabel, 2, 1);
+		qLayout->addWidget (qRadialResolution, 2, 2);
+		qLayout->addWidget (qRadialSegmentsLabel, 3, 1);
+		qLayout->addWidget (qRadialSegments, 3, 2);
+		qLayout->addWidget (qRadialRingNumLabel, 4, 1);
+		qLayout->addWidget (qRadialRingNum, 4, 2);
+		break;
+	
 	default:
 		break;
 	}
@@ -115,10 +158,10 @@
 		for (short i = 0; i < dCoordCount; ++i)
 			qCoordLayout->addWidget (qaCoordinates[i], (i / 3), (i % 3));
 		
-		qLayout->addLayout (qCoordLayout, 0, 1, 2, 1);
+		qLayout->addLayout (qCoordLayout, 0, 1, 2, 2);
 	}
 	
-	qLayout->addWidget (qButtons, 2, 1);
+	qLayout->addWidget (qButtons, 5, 1);
 	setLayout (qLayout);
 	setWindowTitle (str::mkfmt (APPNAME_DISPLAY " - new %s",
 		g_saObjTypeNames[type]).chars());
@@ -148,6 +191,14 @@
 // =============================================================================
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 // =============================================================================
+void AddObjectDialog::slot_radialTypeChanged (int dType) {
+	LDRadial::Type eType = (LDRadial::Type) dType;
+	qRadialRingNum->setEnabled (eType == LDRadial::Ring || eType == LDRadial::Cone);
+}
+
+// =============================================================================
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+// =============================================================================
 void AddObjectDialog::staticDialog (const LDObjectType_e type, ForgeWindow* window) {
 	AddObjectDialog dlg (type, window);
 	LDObject* obj = null;
@@ -205,6 +256,23 @@
 			}
 			break;
 		
+		case OBJ_Radial:
+			{
+				LDRadial* pRad = new LDRadial;
+				pRad->dColor = dlg.dColor;
+				pRad->vPosition.x = dlg.qaCoordinates[0]->value ();
+				pRad->vPosition.y = dlg.qaCoordinates[1]->value ();
+				pRad->vPosition.z = dlg.qaCoordinates[2]->value ();
+				pRad->dDivisions = (dlg.qRadialResolution->currentIndex () == 0) ? 16 : 48;
+				pRad->dSegments = min<short> (dlg.qRadialSegments->value (), pRad->dDivisions);
+				pRad->eRadialType = (LDRadial::Type) dlg.qRadialType->currentIndex ();
+				pRad->dRingNum = dlg.qRadialRingNum->value ();
+				pRad->mMatrix = g_mIdentity;
+				
+				obj = pRad;
+			}
+			break;
+		
 		default:
 			break;
 		}
--- a/zz_addObjectDialog.h	Mon Apr 15 18:07:29 2013 +0300
+++ b/zz_addObjectDialog.h	Tue Apr 16 02:13:11 2013 +0300
@@ -26,6 +26,7 @@
 #include <qlabel.h>
 #include <qspinbox.h>
 #include <qpushbutton.h>
+#include <qcombobox.h>
 
 class AddObjectDialog : public QDialog {
 	Q_OBJECT
@@ -45,6 +46,12 @@
 	// Color selection dialog button
 	QPushButton* qColorButton;
 	
+	// Radial stuff
+	QComboBox* qRadialType, *qRadialResolution;
+	QSpinBox* qRadialSegments, *qRadialRingNum;
+	QLabel* qRadialTypeLabel, *qRadialResolutionLabel, *qRadialSegmentsLabel,
+		*qRadialRingNumLabel;
+	
 	QDialogButtonBox* qButtons;
 	
 private:
@@ -54,6 +61,7 @@
 	
 private slots:
 	void slot_colorButtonClicked ();
+	void slot_radialTypeChanged (int dType);
 };
 
 #endif // __ZZ_ADDOBJECTDIALOG_H__
\ No newline at end of file

mercurial