diff --git a/tools/lammps-gui/TODO.md b/tools/lammps-gui/TODO.md index 53f020a401..c54550fbfd 100644 --- a/tools/lammps-gui/TODO.md +++ b/tools/lammps-gui/TODO.md @@ -2,9 +2,6 @@ LAMMPS-GUI TODO list: # Short term goals -- add option to image viewer to select a group and rerender, similar for the two rotate options with +/- buttons and +/- zoom buttons. - add checkbutton for HQ rendering (i.e. SSAO) - also move the image setting preferences there and remove scrollwheel zoom support. - use qgetenv, qputenv for portability - use QFile/QDir/QFileInto for portable file and directory operations. - write LAMMPS GUI Howto showing/explaining options -> simplify docs and readme diff --git a/tools/lammps-gui/imageviewer.cpp b/tools/lammps-gui/imageviewer.cpp index 6551d3e1d7..74bd1dfad4 100644 --- a/tools/lammps-gui/imageviewer.cpp +++ b/tools/lammps-gui/imageviewer.cpp @@ -36,9 +36,11 @@ #include #include +static const QString blank(" "); + ImageViewer::ImageViewer(const QString &fileName, LammpsWrapper *_lammps, QWidget *parent) : QDialog(parent), imageLabel(new QLabel), scrollArea(new QScrollArea), menuBar(new QMenuBar), - lammps(_lammps), group("all") + lammps(_lammps), group("all"), filename(fileName) { imageLabel->setBackgroundRole(QPalette::Base); imageLabel->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored); @@ -55,40 +57,56 @@ ImageViewer::ImageViewer(const QString &fileName, LammpsWrapper *_lammps, QWidge connect(buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject); QVBoxLayout *mainLayout = new QVBoxLayout; + + auto *zoomin = new QPushButton("Zoom In"); + auto *zoomout = new QPushButton("Zoom Out"); + auto *rotleft = new QPushButton("Rotate Left"); + auto *rotright = new QPushButton("Rotate Right"); + auto *rotup = new QPushButton("Rotate Up"); + auto *rotdown = new QPushButton("Rotate Down"); + auto *combo = new QComboBox; + combo->setObjectName("group"); + int ngroup = lammps->id_count("group"); + char gname[64]; + for (int i = 0; i < ngroup; ++i) { + lammps->id_name("group", i, gname, 64); + combo->addItem(gname); + } + QHBoxLayout *menuLayout = new QHBoxLayout; menuLayout->addWidget(menuBar); - menuLayout->addWidget(new QPushButton("Zoom Out")); - menuLayout->addWidget(new QPushButton("Zoom In")); - menuLayout->addWidget(new QPushButton("Rotate Left")); - menuLayout->addWidget(new QPushButton("Rotate Right")); - menuLayout->addWidget(new QPushButton("Rotate Up")); - menuLayout->addWidget(new QPushButton("Rotate Down")); - menuLayout->addWidget(new QComboBox); + menuLayout->addWidget(zoomin); + menuLayout->addWidget(zoomout); + menuLayout->addWidget(rotleft); + menuLayout->addWidget(rotright); + menuLayout->addWidget(rotup); + menuLayout->addWidget(rotdown); + menuLayout->addWidget(new QLabel(" Group: ")); + menuLayout->addWidget(combo); + + connect(zoomin, &QPushButton::released, this, &ImageViewer::do_zoom_in); + connect(zoomout, &QPushButton::released, this, &ImageViewer::do_zoom_out); + connect(rotleft, &QPushButton::released, this, &ImageViewer::do_rot_left); + connect(rotright, &QPushButton::released, this, &ImageViewer::do_rot_right); + connect(rotup, &QPushButton::released, this, &ImageViewer::do_rot_up); + connect(rotdown, &QPushButton::released, this, &ImageViewer::do_rot_down); + connect(combo, SIGNAL(currentIndexChanged(int)), this, SLOT(change_group(int))); mainLayout->addLayout(menuLayout); mainLayout->addWidget(scrollArea); mainLayout->addWidget(buttonBox); setWindowTitle(QString("Image Viewer: ") + QFileInfo(fileName).completeBaseName()); - createActions(); - - QImageReader reader(fileName); - reader.setAutoTransform(true); - const QImage newImage = reader.read(); - - if (newImage.isNull()) { - QMessageBox::warning(this, QGuiApplication::applicationDisplayName(), - tr("Cannot load %1: %2").arg(fileName, reader.errorString())); - return; - } QSettings settings; settings.beginGroup("snapshot"); - int xsize = settings.value("xsize", 800).toInt(); - int ysize = settings.value("ysize", 600).toInt(); + zoom = settings.value("zoom", 1.0).toDouble(); + hrot = settings.value("hrot", 60).toInt(); + vrot = settings.value("vrot", 30).toInt(); settings.endGroup(); - // scale back to achieve antialiasing - image = newImage.scaled(xsize, ysize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation); - imageLabel->setPixmap(QPixmap::fromImage(image)); + + createActions(); + createImage(); + scaleFactor = 1.0; resize(image.width() + 20, image.height() + 50); @@ -99,6 +117,102 @@ ImageViewer::ImageViewer(const QString &fileName, LammpsWrapper *_lammps, QWidge setLayout(mainLayout); } +void ImageViewer::do_zoom_in() +{ + zoom = zoom * 1.1; + if (zoom > 5.0) zoom = 5.0; + createImage(); +} + +void ImageViewer::do_zoom_out() +{ + zoom = zoom / 1.1; + if (zoom < 0.5) zoom = 0.5; + createImage(); +} + +void ImageViewer::do_rot_right() +{ + vrot -= 15; + if (vrot < 0) vrot += 360; + createImage(); +} + +void ImageViewer::do_rot_left() +{ + vrot += 15; + if (vrot > 360) vrot -= 360; + createImage(); +} + +void ImageViewer::do_rot_down() +{ + hrot -= 15; + if (hrot < 0) hrot += 360; + createImage(); +} + +void ImageViewer::do_rot_up() +{ + hrot += 15; + if (hrot > 360) hrot -= 360; + createImage(); +} + +void ImageViewer::change_group(int idx) +{ + QComboBox *box = findChild("group"); + if (box) group = box->currentText(); + createImage(); +} + +void ImageViewer::createImage() +{ + QSettings settings; + QString dumpcmd = QString("write_dump ") + group + " image "; + QDir dumpdir = settings.value("tempdir").toString(); + QFile dumpfile(dumpdir.absoluteFilePath(filename + ".ppm")); + dumpcmd += dumpfile.fileName(); + + settings.beginGroup("snapshot"); + int aa = settings.value("antialias", 0).toInt() + 1; + int xsize = settings.value("xsize", 800).toInt() * aa; + int ysize = settings.value("ysize", 600).toInt() * aa; + + dumpcmd += blank + settings.value("color", "type").toString(); + dumpcmd += blank + settings.value("diameter", "type").toString(); + dumpcmd += QString(" size ") + QString::number(xsize) + blank + QString::number(ysize); + dumpcmd += QString(" zoom ") + QString::number(zoom); + lammps->command(dumpcmd.toLocal8Bit()); + if (lammps->extract_setting("dimension") == 3) { + dumpcmd += QString(" view ") + QString::number(hrot) + blank + QString::number(vrot); + } + if (settings.value("ssao", false).toBool()) dumpcmd += QString(" ssao yes 453983 0.6"); + settings.endGroup(); + + lammps->command(dumpcmd.toLocal8Bit()); + + QImageReader reader(dumpfile.fileName()); + reader.setAutoTransform(true); + const QImage newImage = reader.read(); + + if (newImage.isNull()) { + QMessageBox::warning( + this, QGuiApplication::applicationDisplayName(), + tr("Cannot load %1: %2").arg(dumpfile.fileName(), reader.errorString())); + return; + } + dumpfile.remove(); + + settings.beginGroup("snapshot"); + xsize = settings.value("xsize", 800).toInt(); + ysize = settings.value("ysize", 600).toInt(); + settings.endGroup(); + // scale back to achieve antialiasing + image = newImage.scaled(xsize, ysize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation); + imageLabel->setPixmap(QPixmap::fromImage(image)); +} + void ImageViewer::saveAs() { QString fileName = QFileDialog::getSaveFileName(this, "Save Image File As", QString(), diff --git a/tools/lammps-gui/imageviewer.h b/tools/lammps-gui/imageviewer.h index 630d72944c..9aee1cf957 100644 --- a/tools/lammps-gui/imageviewer.h +++ b/tools/lammps-gui/imageviewer.h @@ -45,8 +45,17 @@ private slots: void normalSize(); void fitToWindow(); + void do_zoom_in(); + void do_zoom_out(); + void do_rot_left(); + void do_rot_right(); + void do_rot_up(); + void do_rot_down(); + void change_group(int); + private: void createActions(); + void createImage(); void updateActions(); void saveFile(const QString &fileName); void scaleImage(double factor); @@ -69,6 +78,9 @@ private: LammpsWrapper *lammps; QString group; + QString filename; + int hrot, vrot; + double zoom; }; #endif diff --git a/tools/lammps-gui/lammpsgui.cpp b/tools/lammps-gui/lammpsgui.cpp index 72f332c1d3..5546173a44 100644 --- a/tools/lammps-gui/lammpsgui.cpp +++ b/tools/lammps-gui/lammpsgui.cpp @@ -230,7 +230,6 @@ LammpsGui::LammpsGui(QWidget *parent, const char *filename) : // none of the plugin paths could load, remove key settings.remove("plugin_path"); QMessageBox::critical(this, "Error", "Cannot open LAMMPS shared library file"); - // QCoreApplication::quit(); exit(1); } #endif @@ -715,38 +714,7 @@ void LammpsGui::view_image() "Cannot create snapshot image without a system box"); return; } - - QSettings settings; - QString dumpcmd = "write_dump all image "; - QString dumpfile = settings.value("tempdir").toString(); -#if defined(_WIN32) - dumpfile += '\\'; -#else - dumpfile += '/'; -#endif - dumpfile += current_file + ".ppm"; - dumpcmd += dumpfile; - - settings.beginGroup("snapshot"); - int aa = settings.value("antialias", 0).toInt() + 1; - int xsize = settings.value("xsize", 800).toInt() * aa; - int ysize = settings.value("ysize", 800).toInt() * aa; - - dumpcmd += blank + settings.value("color", "type").toString(); - dumpcmd += blank + settings.value("diameter", "type").toString(); - dumpcmd += QString(" size ") + QString::number(xsize) + blank + QString::number(ysize); - dumpcmd += QString(" zoom ") + settings.value("zoom", "1.0").toString(); - if (settings.value("ssao", false).toBool()) dumpcmd += QString(" ssao yes 453983 0.6"); - settings.endGroup(); - - dirstatus->setText(" Rendering Snapshot Image... "); - status->repaint(); - lammps.command(dumpcmd.toLocal8Bit()); - dirstatus->setText(QString(" Directory: ") + current_dir); - status->repaint(); - - imagewindow = new ImageViewer(dumpfile, &lammps); - QFile::remove(dumpfile); + imagewindow = new ImageViewer(current_file, &lammps); } else { QMessageBox::warning(this, "ImageViewer Error", "Cannot create snapshot image while LAMMPS is running"); diff --git a/tools/lammps-gui/lammpswrapper.cpp b/tools/lammps-gui/lammpswrapper.cpp index 7d5b54a634..de66f82f6e 100644 --- a/tools/lammps-gui/lammpswrapper.cpp +++ b/tools/lammps-gui/lammpswrapper.cpp @@ -45,6 +45,33 @@ int LammpsWrapper::extract_setting(const char *keyword) return val; } +int LammpsWrapper::id_count(const char *keyword) +{ + int val = 0; + if (lammps_handle) { +#if defined(LAMMPS_GUI_USE_PLUGIN) + val = ((liblammpsplugin_t *)plugin_handle)->id_count(lammps_handle, keyword); +#else + val = lammps_id_count(lammps_handle, keyword); +#endif + } + return val; +} + +int LammpsWrapper::id_name(const char *keyword, int idx, char *buf, int buflen) +{ + int val = 0; + if (lammps_handle) { +#if defined(LAMMPS_GUI_USE_PLUGIN) + val = + ((liblammpsplugin_t *)plugin_handle)->id_name(lammps_handle, keyword, idx, buf, buflen); +#else + val = lammps_id_name(lammps_handle, keyword, idx, buf, buflen); +#endif + } + return val; +} + double LammpsWrapper::get_thermo(const char *keyword) { double val = 0.0; diff --git a/tools/lammps-gui/lammpswrapper.h b/tools/lammps-gui/lammpswrapper.h index 9aa75b2b54..064e784981 100644 --- a/tools/lammps-gui/lammpswrapper.h +++ b/tools/lammps-gui/lammpswrapper.h @@ -29,6 +29,9 @@ public: void force_timeout(); int extract_setting(const char *keyword); + int id_count(const char *idtype); + int id_name(const char *idtype, int idx, char *buf, int buflen); + double get_thermo(const char *keyword); void *last_thermo(const char *keyword, int idx); bool is_open() const { return lammps_handle != nullptr; }