Begin converting the radial type into a primitive generator

Mon, 01 Jul 2013 23:07:35 +0300

author
Santeri Piippo <crimsondusk64@gmail.com>
date
Mon, 01 Jul 2013 23:07:35 +0300
changeset 310
c62edce5668c
parent 309
11ec6aa1f1fb
child 311
c6e38e5e4f33

Begin converting the radial type into a primitive generator

src/file.cpp file | annotate | diff | comparison | revisions
src/file.h file | annotate | diff | comparison | revisions
src/gui.cpp file | annotate | diff | comparison | revisions
src/gui.h file | annotate | diff | comparison | revisions
src/gui_actions.cpp file | annotate | diff | comparison | revisions
src/ldtypes.cpp file | annotate | diff | comparison | revisions
src/primitives.cpp file | annotate | diff | comparison | revisions
src/primitives.h file | annotate | diff | comparison | revisions
src/types.cpp file | annotate | diff | comparison | revisions
--- a/src/file.cpp	Mon Jul 01 19:48:29 2013 +0300
+++ b/src/file.cpp	Mon Jul 01 23:07:35 2013 +0300
@@ -965,4 +965,12 @@
 		return null;
 	
 	return m_objs[pos];
+}
+
+LDOpenFile& LDOpenFile::operator<<( vector<LDObject*> objs )
+{
+	for( LDObject* obj : objs )
+		m_objs << obj;
+	
+	return *this;
 }
\ No newline at end of file
--- a/src/file.h	Mon Jul 01 19:48:29 2013 +0300
+++ b/src/file.h	Mon Jul 01 23:07:35 2013 +0300
@@ -86,6 +86,8 @@
 		return *this;
 	}
 	
+	LDOpenFile& operator<<( vector<LDObject*> objs );
+	
 	it begin () { return PROP_NAME (objs).begin (); }
 	c_it begin () const { return PROP_NAME (objs).begin (); }
 	it end () { return PROP_NAME (objs).end (); }
--- a/src/gui.cpp	Mon Jul 01 19:48:29 2013 +0300
+++ b/src/gui.cpp	Mon Jul 01 23:07:35 2013 +0300
@@ -30,6 +30,8 @@
 #include <QToolBar>
 #include <QProgressBar>
 #include <QLabel>
+#include <QFileDialog>
+#include <QPushButton>
 #include <QCoreApplication>
 #include <QTimer>
 
@@ -212,7 +214,6 @@
 	addMenuAction ("newComment");
 	addMenuAction ("newBFC");
 	addMenuAction ("newVertex");
-	addMenuAction ("newRadial");
 	
 	// Edit menu
 	initMenu ("&Edit");
@@ -241,7 +242,7 @@
 	addMenuAction ("invert");
 	addMenuAction ("inlineContents");
 	addMenuAction ("deepInline");
-	addMenuAction ("radialConvert");
+	addMenuAction ("makePrimitive");
 	menu->addSeparator ();
 	addMenuAction ("splitQuads");
 	addMenuAction ("setContents");
@@ -287,10 +288,10 @@
 	
 	// Help menu
 	initMenu ("&Help");
-	addMenuAction ("help");				// Help
-	menu->addSeparator ();					// -----
-	addMenuAction ("about");				// About
-	addMenuAction ("aboutQt");				// About Qt
+	addMenuAction ("help");
+	menu->addSeparator ();
+	addMenuAction ("about");
+	addMenuAction ("aboutQt");
 }
 
 // =============================================================================
@@ -349,7 +350,6 @@
 	addToolBarAction ("newComment");
 	addToolBarAction ("newBFC");
 	addToolBarAction ("newVertex");
-	addToolBarAction ("newRadial");
 	
 	// ==========================================
 	initSingleToolBar ("Edit");
@@ -413,7 +413,7 @@
 	addToolBarAction ("invert");
 	addToolBarAction ("inlineContents");
 	addToolBarAction ("deepInline");
-	addToolBarAction ("radialConvert");
+	addToolBarAction ("makePrimitive");
 	addToolBarAction ("splitQuads");
 	addToolBarAction ("setContents");
 	addToolBarAction ("makeBorders");
@@ -661,18 +661,6 @@
 			descr = LDBFC::statements[static_cast<LDBFC*> (obj)->type];
 		break;
 		
-		case LDObject::Radial:
-			{
-				LDRadial* rad = static_cast<LDRadial*> (obj);
-				descr = fmt ("%1 / %2 %3", rad->segments (), rad->divisions (), rad->radialTypeName ());
-				
-				if (rad->type () == LDRadial::Ring || rad->type () == LDRadial::Cone)
-					descr += fmt (" %1", rad->number ());
-				
-				descr += " " + rad->position ().stringRep (true);
-			}
-			break;
-		
 		default:
 			descr = g_saObjTypeNames[obj->getType ()];
 			break;
@@ -1023,6 +1011,53 @@
 	m_primLoaderBar->setFormat ("Done");
 }
 
+// =============================================================================
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+// =============================================================================
+void ForgeWindow::save( LDOpenFile* f, bool saveAs )
+{
+	str path = f->name ();
+	
+	if (path.length () == 0 || saveAs) {
+		path = QFileDialog::getSaveFileName (g_win, "Save As",
+			g_curfile->name (), "LDraw files (*.dat *.ldr)");
+		
+		if (path.length () == 0) {
+			// User didn't give a file name. This happens if the user cancelled
+			// saving in the save file dialog. Abort.
+			return;
+		}
+	}
+	
+	if( f->save( path ))
+	{
+		f->setName (path);
+		
+		if( f == g_curfile )
+			g_win->updateTitle ();
+	}
+	else
+	{
+		setlocale( LC_ALL, "C" );
+		
+		str message = fmt ("Failed to save to %1\nReason: %2", path, strerror (errno));
+		
+		// Tell the user the save failed, and give the option for saving as with it.
+		QMessageBox dlg( QMessageBox::Critical, "Save Failure", message,
+			QMessageBox::Close, g_win );
+		
+		// Add a save-as button
+		QPushButton* saveAsBtn = new QPushButton( "Save As" );
+		saveAsBtn->setIcon( getIcon( "file-save-as" ));
+		dlg.addButton( saveAsBtn, QMessageBox::ActionRole );
+		dlg.setDefaultButton( QMessageBox::Close );
+		dlg.exec();
+		
+		if( dlg.clickedButton () == saveAsBtn )
+			save (f, true); // yay recursion!
+	}
+}
+
 // ============================================================================
 void ObjectList::contextMenuEvent (QContextMenuEvent* ev) {
 	g_win->spawnContextMenu (ev->globalPos ());
--- a/src/gui.h	Mon Jul 01 19:48:29 2013 +0300
+++ b/src/gui.h	Mon Jul 01 23:07:35 2013 +0300
@@ -122,6 +122,7 @@
 	void deleteObjVector (vector< LDObject* > objs);
 	void deleteSelection ();
 	void deleteByColor (const short int colnum);
+	void save( LDOpenFile* f, bool saveAs );
 	GLRenderer* R () { return m_renderer; }
 	vector<LDObject*>& sel () { return m_sel; }
 	void setQuickColorMeta (vector<quickColor>& quickColorMeta) {
--- a/src/gui_actions.cpp	Mon Jul 01 19:48:29 2013 +0300
+++ b/src/gui_actions.cpp	Mon Jul 01 23:07:35 2013 +0300
@@ -66,54 +66,17 @@
 // =============================================================================
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 // =============================================================================
-void doSave (bool saveAs) {
-	str path = g_curfile->name ();
-	
-	if (path.length () == 0 || saveAs) {
-		path = QFileDialog::getSaveFileName (g_win, "Save As",
-			g_curfile->name (), "LDraw files (*.dat *.ldr)");
-		
-		if (path.length () == 0) {
-			// User didn't give a file name. This happens if the user cancelled
-			// saving in the save file dialog. Abort.
-			return;
-		}
-	}
-	
-	if (g_curfile->save (path)) {
-		g_curfile->setName (path);
-		g_win->updateTitle ();
-	} else {
-		setlocale (LC_ALL, "C");
-		
-		// Tell the user the save failed, and give the option for saving as with it.
-		QMessageBox dlg (QMessageBox::Critical, "Save Failure",
-			fmt ("Failed to save to %1\nReason: %2", path, strerror (errno)),
-			QMessageBox::Close, g_win);
-		
-		QPushButton* saveAsBtn = new QPushButton ("Save As");
-		saveAsBtn->setIcon (getIcon ("file-save-as"));
-		dlg.addButton (saveAsBtn, QMessageBox::ActionRole);
-		dlg.setDefaultButton (QMessageBox::Close);
-		dlg.exec ();
-		
-		if (dlg.clickedButton () == saveAsBtn)
-			doSave (true); // yay recursion!
-	}
+MAKE_ACTION( save, "&Save", "file-save", "Save the part model.", CTRL( S ))
+{
+	g_win->save( g_curfile, false );
 }
 
 // =============================================================================
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 // =============================================================================
-MAKE_ACTION (save, "&Save", "file-save", "Save the part model.", CTRL (S)) {
-	doSave (false);
-}
-
-// =============================================================================
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-// =============================================================================
-MAKE_ACTION (saveAs, "Save &As", "file-save-as", "Save the part model to a specific file.", CTRL_SHIFT (S)) {
-	doSave (true);
+MAKE_ACTION( saveAs, "Save &As", "file-save-as", "Save the part model to a specific file.", CTRL_SHIFT( S ))
+{
+	g_win->save( g_curfile, true );
 }
 
 // =============================================================================
@@ -170,8 +133,9 @@
 	AddObjectDialog::staticDialog (LDObject::Vertex, null);
 }
 
-MAKE_ACTION (newRadial, "New Radial", "add-radial", "Creates a new radial.", 0) {
-	AddObjectDialog::staticDialog (LDObject::Radial, null);
+MAKE_ACTION( makePrimitive, "Make a Primitive", "radial", "Generate a new circular primitive.", 0 )
+{
+	generatePrimitive();
 }
 
 MAKE_ACTION (editObject, "Edit Object", "edit-object", "Edits this object.", 0) {
--- a/src/ldtypes.cpp	Mon Jul 01 19:48:29 2013 +0300
+++ b/src/ldtypes.cpp	Mon Jul 01 23:07:35 2013 +0300
@@ -522,141 +522,9 @@
 	return g_saRadialTypeNames[typeval];
 }
 
-// =============================================================================
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-// =============================================================================
-vector<LDObject*> LDRadial::decompose (bool applyTransform) {
-	vector<LDObject*> objs;
-	
-	for (short i = 0; i < segments (); ++i) {
-		double x0 = cos ((i * 2 * pi) / divisions ()),
-			x1 = cos (((i + 1) * 2 * pi) / divisions ()),
-			z0 = sin ((i * 2 * pi) / divisions ()),
-			z1 = sin (((i + 1) * 2 * pi) / divisions ());
-		
-		LDObject* obj = null;
-		
-		switch (type ()) {
-		case LDRadial::Circle:
-			{
-				vertex v0 (x0, 0.0f, z0),
-					v1 (x1, 0.0f, z1);
-				
-				LDLine* line = new LDLine;
-				line->setVertex (0, v0);
-				line->setVertex (1, v1);
-				line->setColor (edgecolor);
-				line->setParent (this);
-				
-				obj = line;
-			}
-			break;
-		
-		case LDRadial::Cylinder:
-		case LDRadial::Ring:
-		case LDRadial::Cone:
-			{
-				double x2, x3, z2, z3;
-				double y0, y1, y2, y3;
-				
-				if (type () == LDRadial::Cylinder) {
-					x2 = x1;
-					x3 = x0;
-					z2 = z1;
-					z3 = z0;
-					
-					y0 = y1 = 0.0f;
-					y2 = y3 = 1.0f;
-				} else {
-					x2 = x1 * (number () + 1);
-					x3 = x0 * (number () + 1);
-					z2 = z1 * (number () + 1);
-					z3 = z0 * (number () + 1);
-					
-					x0 *= number ();
-					x1 *= number ();
-					z0 *= number ();
-					z1 *= number ();
-					
-					if (type () == 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);
-				
-				LDQuad* quad = new LDQuad;
-				quad->setVertex (0, v0);
-				quad->setVertex (1, v1);
-				quad->setVertex (2, v2);
-				quad->setVertex (3, v3);
-				
-				quad->setColor (color ());
-				quad->setParent (this);
-				
-				obj = quad;
-			}
-			break;
-		
-		case LDRadial::Disc:
-		case LDRadial::DiscNeg:
-			{
-				double x2, z2;
-				
-				if (type () == 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);
-				
-				LDTriangle* seg = new LDTriangle;
-				seg->setVertex (0, v0);
-				seg->setVertex (1, v1);
-				seg->setVertex (2, v2);
-				seg->setColor (color ());
-				seg->setParent (this);
-				
-				if (applyTransform) {
-					for (int i = 0; i < 3; ++i) {
-						vertex v = seg->getVertex (i);
-						v.transform (transform (), position ());
-						seg->setVertex (i, v);
-					}
-				}
-				
-				obj = seg;
-			}
-			break;
-		
-		default:
-			break;
-		}
-		
-		if (obj) {
-			if (applyTransform) {
-				for (int i = 0; i < obj->vertices (); ++i) {
-					vertex v = obj->getVertex (i);
-					v.transform (transform (), position ());
-					obj->setVertex (i, v);
-				}
-			}
-			
-			objs << obj;
-		}
-	}
-	
-	return objs;
+vector<LDObject*> LDRadial::decompose( bool applyTransform )
+{
+	return vector<LDObject*>();
 }
 
 // =============================================================================
--- a/src/primitives.cpp	Mon Jul 01 19:48:29 2013 +0300
+++ b/src/primitives.cpp	Mon Jul 01 23:07:35 2013 +0300
@@ -19,9 +19,11 @@
 #include <QDir>
 #include <QThread>
 #include <QRegExp>
+#include <QFileDialog>
 #include "file.h"
 #include "gui.h"
 #include "primitives.h"
+#include "ui_makeprim.h"
 
 vector<PrimitiveCategory> g_PrimitiveCategories;
 static PrimitiveLister* g_activePrimLister = null;
@@ -269,6 +271,180 @@
 	g_PrimitiveCategories << cat;
 }
 
-bool primitiveLoaderBusy() {
+// =============================================================================
+bool primitiveLoaderBusy()
+{
 	return g_primListerMutex;
+}
+
+vector<LDObject*> makePrimitive( PrimitiveType type, int segs, int divs, int num )
+{
+	vector<LDObject*> objs;
+	
+	for( int i = 0; i < segs; ++i )
+	{
+		double x0 = cos(( i * 2 * pi ) / divs ),
+			x1 = cos((( i + 1 ) * 2 * pi) / divs ),
+			z0 = sin(( i * 2 * pi ) / divs ),
+			z1 = sin((( i + 1 ) * 2 * pi ) / divs );
+		
+		LDObject* obj = null;
+		
+		switch( type )
+		{
+		case Circle:
+			{
+				vertex v0( x0, 0.0f, z0 ),
+					v1( x1, 0.0f, z1 );
+				
+				LDLine* line = new LDLine;
+				line->setVertex( 0, v0 );
+				line->setVertex( 1, v1 );
+				line->setColor( edgecolor );
+				obj = line;
+			}
+			break;
+		
+		case Cylinder:
+		case Ring:
+		case Cone:
+			{
+				double x2, x3, z2, z3;
+				double y0, y1, y2, y3;
+				
+				if( type == Cylinder )
+				{
+					x2 = x1;
+					x3 = x0;
+					z2 = z1;
+					z3 = z0;
+					
+					y0 = y1 = 0.0f;
+					y2 = y3 = 1.0f;
+				} else {
+					x2 = x1 * (num + 1);
+					x3 = x0 * (num + 1);
+					z2 = z1 * (num + 1);
+					z3 = z0 * (num + 1);
+					
+					x0 *= num;
+					x1 *= num;
+					z0 *= num;
+					z1 *= num;
+					
+					if( type == 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 );
+				
+				LDQuad* quad = new LDQuad;
+				quad->setColor( maincolor );
+				quad->setVertex( 0, v0 );
+				quad->setVertex( 1, v1 );
+				quad->setVertex( 2, v2 );
+				quad->setVertex( 3, v3 );
+				obj = quad;
+			}
+			break;
+		
+		case Disc:
+		case DiscNeg:
+			{
+				double x2, z2;
+				
+				if( type == 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 );
+				
+				LDTriangle* seg = new LDTriangle;
+				seg->setColor( maincolor );
+				seg->setVertex( 0, v0 );
+				seg->setVertex( 1, v1 );
+				seg->setVertex( 2, v2 );
+				obj = seg;
+			}
+			break;
+		
+		default:
+			break;
+		}
+		
+		if( obj )
+			objs << obj;
+	}
+	
+	return objs;
+}
+
+str primitiveTypeName( PrimitiveType type )
+{
+	return type == Circle   ? "Circle" :
+	       type == Cylinder ? "Cylinder" :
+	       type == Disc     ? "Disc" :
+	       type == DiscNeg  ? "Disc Negative" :
+	       type == Ring     ? "Ring" :
+	                          "Cone";
+}
+
+// =============================================================================
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+// =============================================================================
+void generatePrimitive()
+{
+	QDialog* dlg = new QDialog( g_win );
+	Ui::MakePrimUI ui;
+	ui.setupUi( dlg );
+	
+exec:
+	if( !dlg->exec() )
+		return;
+	
+	int segs = ui.sb_segs->value();
+	int divs = ui.cb_hires->isChecked() ? hires : lores;
+	int num = ui.sb_ringnum->value();
+	PrimitiveType type =
+		ui.rb_circle->isChecked()   ? Circle :
+		ui.rb_cylinder->isChecked() ? Cylinder :
+		ui.rb_disc->isChecked()     ? Disc :
+		ui.rb_ndisc->isChecked()    ? DiscNeg :
+		ui.rb_ring->isChecked()     ? Ring :
+		                              Cone;
+	
+	// Make the description
+	str descr = fmt ("%1 / %2 %3", segs, divs, primitiveTypeName( type ));
+	
+	if (type == Ring || type == Cone)
+		descr += fmt (" %1", num);
+	
+	LDOpenFile* f = new LDOpenFile;
+	
+	*f << new LDComment( descr );
+	*f << new LDComment( fmt( "Name: ???.dat" ));
+	*f << new LDComment( fmt( "Author: LDForge" ));
+	*f << new LDComment( fmt( "!LDRAW_ORG Unofficial_%1Primitive", divs == hires ? "48_" : "" ));
+	*f << new LDComment( "Redistributable under CCAL version 2.0 : see CAreadme.txt" );
+	*f << new LDEmpty;
+	*f << new LDBFC( LDBFC::CertifyCCW );
+	*f << new LDEmpty;
+	*f << makePrimitive( type, segs, divs, num );
+	
+	g_win->save( f, true );
+	delete f;
 }
\ No newline at end of file
--- a/src/primitives.h	Mon Jul 01 19:48:29 2013 +0300
+++ b/src/primitives.h	Mon Jul 01 23:07:35 2013 +0300
@@ -82,4 +82,17 @@
 void loadPrimitives ();
 bool primitiveLoaderBusy ();
 
+enum PrimitiveType
+{
+	Circle,
+	Cylinder,
+	Disc,
+	DiscNeg,
+	Ring,
+	Cone,
+};
+
+// =============================================================================
+void generatePrimitive();
+
 #endif // PRIMITIVES_H
\ No newline at end of file
--- a/src/types.cpp	Mon Jul 01 19:48:29 2013 +0300
+++ b/src/types.cpp	Mon Jul 01 23:07:35 2013 +0300
@@ -188,7 +188,7 @@
 		val += ftoa (m_vals[i]);
 	}
 	
-	return val;	
+	return val;
 }
 
 // =============================================================================

mercurial