Mon, 01 Jul 2013 23:07:35 +0300
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