Commit b15ad7ec authored by Tobias WEBER's avatar Tobias WEBER
Browse files

started with moldyn gui

parent 8f1533c2
#
# @author Tobias Weber
# @date dec-2019
# @license GPLv3, see 'LICENSE' file
#
cmake_minimum_required(VERSION 3.0)
project(moldyn)
set(CMAKE_VERBOSE_MAKEFILE TRUE)
find_package(Boost REQUIRED)
find_package(Qt5 REQUIRED COMPONENTS Core Gui Widgets OpenGL)
set(CMAKE_AUTOUIC TRUE)
set(CMAKE_AUTOMOC TRUE)
set(CMAKE_CXX_STANDARD 20)
add_definitions(-std=c++2a -fconcepts)
add_definitions(${Boost_CXX_FLAGS})
include_directories(
"${PROJECT_SOURCE_DIR}" "${Boost_INCLUDE_DIRS}/.." "../.."
"ext"
)
add_executable(moldyn
moldyn.cpp moldyn.h
../../libs/_cxx20/glplot.cpp ../../libs/_cxx20/glplot.h)
target_link_libraries(moldyn ${Boost_LIBRARIES})
qt5_use_modules(moldyn Core Gui Widgets OpenGL)
/**
* loads atom dynamics file
* @author Tobias Weber <tweber@ill.fr>
* @date Dec-2019
* @license GPLv3, see 'LICENSE' file
*/
#ifndef __MOLDYN_H__
#define __MOLDYN_H__
#include <fstream>
#include <iostream>
#include <vector>
#include <string>
#include "libs/str.h"
template<class t_real, class t_vec>
class MolFrame
{
public:
MolFrame()
{
m_config.reserve(128);
}
void AddAtomConfig(std::vector<t_vec>&& config)
{
m_config.emplace_back(std::move(config));
}
void AddAtomConfig(const std::vector<t_vec>& config)
{
m_config.push_back(config);
}
private:
// atoms -> coordinates
std::vector<std::vector<t_vec>> m_config;
};
template<class t_real, class t_vec>
class MolDyn
{
public:
MolDyn() : m_baseA(3), m_baseB(3), m_baseC(3)
{
m_frames.reserve(16384);
}
void SetBaseA(t_real x, t_real y, t_real z)
{
m_baseA[0] = x;
m_baseA[1] = y;
m_baseA[2] = z;
}
void SetBaseB(t_real x, t_real y, t_real z)
{
m_baseB[0] = x;
m_baseB[1] = y;
m_baseB[2] = z;
}
void SetBaseC(t_real x, t_real y, t_real z)
{
m_baseC[0] = x;
m_baseC[1] = y;
m_baseC[2] = z;
}
void AddAtomType(const std::string& name, unsigned int number)
{
m_vecAtoms.push_back(name);
m_vecAtomNums.push_back(number);
}
void AddFrame(MolFrame<t_real, t_vec>&& frame)
{
m_frames.emplace_back(std::move(frame));
}
void AddFrame(const MolFrame<t_real, t_vec>& frame)
{
m_frames.push_back(frame);
}
bool LoadFile(const std::string& filename, unsigned int frameskip = 0)
{
const std::string strDelim{" \t"};
std::ifstream ifstr{filename};
if(!ifstr)
{
std::cerr << "Cannot open \"" << filename << "\".";
return 0;
}
std::string strSys;
std::getline(ifstr, strSys);
tl2::trim(strSys);
std::cout << "System: " << strSys << std::endl;
std::string strScale;
std::getline(ifstr, strScale);
t_real scale = tl2::str_to_var<t_real>(strScale);
std::cout << "scale: " << scale << std::endl;
std::string strVecs1;
std::string strVecs2;
std::string strVecs3;
std::getline(ifstr, strVecs1);
std::getline(ifstr, strVecs2);
std::getline(ifstr, strVecs3);
std::vector<t_real> _vecBase1, _vecBase2, _vecBase3;
tl2::get_tokens<t_real>(strVecs1, strDelim, _vecBase1);
tl2::get_tokens<t_real>(strVecs2, strDelim, _vecBase2);
tl2::get_tokens<t_real>(strVecs3, strDelim, _vecBase3);
if(_vecBase1.size()!=3 || _vecBase2.size()!=3 || _vecBase3.size()!=3)
{
std::cerr << "Invalid base vectors." << std::endl;
return 0;
}
SetBaseA(_vecBase1[0]*scale, _vecBase2[0]*scale, _vecBase3[0]*scale);
SetBaseB(_vecBase1[1]*scale, _vecBase2[1]*scale, _vecBase3[1]*scale);
SetBaseC(_vecBase1[2]*scale, _vecBase2[2]*scale, _vecBase3[2]*scale);
std::string strAtoms;
std::string strAtomNums;
std::getline(ifstr, strAtoms);
std::getline(ifstr, strAtomNums);
tl2::get_tokens<std::string>(strAtoms, strDelim, m_vecAtoms);
tl2::get_tokens<unsigned int>(strAtomNums, strDelim, m_vecAtomNums);
if(m_vecAtoms.size() != m_vecAtomNums.size())
{
std::cerr << "Atom size mismatch." << std::endl;
return 0;
}
for(std::size_t i=0; i<m_vecAtoms.size(); ++i)
{
std::cout << m_vecAtomNums[i] << " " << m_vecAtoms[i] << " atoms." << std::endl;
}
std::size_t iNumConfigs = 0;
while(true)
{
std::string strConfig;
std::getline(ifstr, strConfig);
tl2::trim(strConfig);
if(ifstr.eof())
break;
if(frameskip || iNumConfigs % 100)
{
std::cout << "\rReading " << strConfig << "..." << " ";
std::cout.flush();
}
MolFrame<t_real, t_vec> frame;
for(std::size_t iAtomType=0; iAtomType<m_vecAtoms.size(); ++iAtomType)
{
std::vector<t_vec> atomconf;
for(std::size_t iAtom=0; iAtom<m_vecAtomNums[iAtomType]; ++iAtom)
{
std::string strCoords;
std::getline(ifstr, strCoords);
t_vec vecCoords;
vecCoords.reserve(3);
tl2::get_tokens<t_real>(strCoords, strDelim, vecCoords);
if(vecCoords.size() != 3)
{
std::cerr << "Invalid coordinate." << std::endl;
return 0;
}
atomconf.emplace_back(std::move(vecCoords));
}
frame.AddAtomConfig(std::move(atomconf));
}
AddFrame(std::move(frame));
++iNumConfigs;
// skip frames
for(unsigned int skipped=0; skipped<frameskip; ++skipped)
{
std::string strTmp;
std::getline(ifstr, strTmp);
//std::cout << "Skipping " << strTmp << "..." << " ";
for(std::size_t iAtomType=0; iAtomType<m_vecAtoms.size(); ++iAtomType)
{
for(std::size_t iAtom=0; iAtom<m_vecAtomNums[iAtomType]; ++iAtom)
std::getline(ifstr, strTmp);
}
}
}
std::cout << "\rRead " << iNumConfigs << " configurations." << " " << std::endl;
return 1;
}
private:
t_vec m_baseA;
t_vec m_baseB;
t_vec m_baseC;
std::vector<std::string> m_vecAtoms;
std::vector<unsigned int> m_vecAtomNums;
std::vector<MolFrame<t_real, t_vec>> m_frames;
};
#endif
/**
* loads atom dynamics file
* @author Tobias Weber <tweber@ill.fr>
* @date Dec-2019
* @license GPLv3, see 'LICENSE' file
*
* g++ -std=c++17 -I ../../tlibs2 -o moldyn-test moldyn-test.cpp
*/
#include "moldyn-loader.h"
using t_real = double;
using t_vec = std::vector<t_real>;
int main(int argc, char** argv)
{
if(argc <= 1)
return -1;
MolDyn<t_real, t_vec> mol;
mol.LoadFile(argv[1], 100);
return 0;
}
/**
* loads atom dynamics file
* atom dynamics
* @author Tobias Weber <tweber@ill.fr>
* @date Dec-2019
* @license GPLv3, see 'LICENSE' file
*
* g++ -std=c++17 -I ../../tlibs2 -o moldyn moldyn.cpp
*/
#include "moldyn.h"
#include <QtWidgets/QApplication>
#include <QtWidgets/QGridLayout>
#include <QtWidgets/QLabel>
#include <QtWidgets/QFileDialog>
#include <QtWidgets/QMessageBox>
using t_real = double;
using t_vec = std::vector<t_real>;
#include <iostream>
#include <tuple>
#include "libs/algos.h"
#include "libs/helper.h"
using namespace m_ops;
constexpr t_real g_eps = 1e-6;
constexpr int g_prec = 6;
// ----------------------------------------------------------------------------
MolDynDlg::MolDynDlg(QWidget* pParent) : QMainWindow{pParent},
m_sett{new QSettings{"tobis_stuff", "moldyn"}}
{
setWindowTitle("Molecular Dynamics");
this->setObjectName("moldyn");
m_status = new QStatusBar(this);
this->setStatusBar(m_status);
// menu bar
{
m_menu = new QMenuBar(this);
m_menu->setNativeMenuBar(m_sett ? m_sett->value("native_gui", false).toBool() : false);
auto menuFile = new QMenu("File", m_menu);
auto acNew = new QAction("New", menuFile);
auto acLoad = new QAction("Load...", menuFile);
auto acSave = new QAction("Save...", menuFile);
auto acExit = new QAction("Exit", menuFile);
menuFile->addAction(acNew);
menuFile->addSeparator();
menuFile->addAction(acLoad);
menuFile->addAction(acSave);
menuFile->addSeparator();
menuFile->addAction(acExit);
connect(acNew, &QAction::triggered, this, &MolDynDlg::New);
connect(acLoad, &QAction::triggered, this, &MolDynDlg::Load);
connect(acSave, &QAction::triggered, this, &MolDynDlg::Save);
connect(acExit, &QAction::triggered, this, &QDialog::close);
m_menu->addMenu(menuFile);
this->setMenuBar(m_menu);
}
// plot widget
{
m_plot = new GlPlot(this);
m_plot->setSizePolicy(QSizePolicy{QSizePolicy::Expanding, QSizePolicy::Expanding});
m_plot->GetImpl()->SetLight(0, m::create<t_vec3_gl>({ 5, 5, 5 }));
m_plot->GetImpl()->SetLight(1, m::create<t_vec3_gl>({ -5, -5, -5 }));
m_plot->GetImpl()->SetCoordMax(1.);
m_plot->GetImpl()->SetCamBase(m::create<t_mat_gl>({1,0,0,0, 0,0,1,0, 0,-1,0,-1.5, 0,0,0,1}),
m::create<t_vec_gl>({1,0,0,0}), m::create<t_vec_gl>({0,0,1,0}));
connect(m_plot, &GlPlot::AfterGLInitialisation, this, &MolDynDlg::AfterGLInitialisation);
connect(m_plot->GetImpl(), &GlPlot_impl::PickerIntersection, this, &MolDynDlg::PickerIntersection);
connect(m_plot, &GlPlot::MouseDown, this, &MolDynDlg::PlotMouseDown);
connect(m_plot, &GlPlot::MouseUp, this, &MolDynDlg::PlotMouseUp);
this->setCentralWidget(m_plot);
}
// restore window size and position
if(m_sett && m_sett->contains("geo"))
restoreGeometry(m_sett->value("geo").toByteArray());
else
resize(600, 500);
m_ignoreChanges = 0;
}
// ----------------------------------------------------------------------------
/**
* add 3d object
*/
void MolDynDlg::Add3DItem(int row)
{
if(!m_plot) return;
// add all items
if(row < 0)
{
//for(int row=0; row<m_nuclei->rowCount(); ++row)
// Add3DItem(row);
return;
}
qreal r=1, g=1, b=1;
QColor col;
col.getRgbF(&r, &g, &b);
//auto obj = m_plot->GetImpl()->AddLinkedObject(m_sphere, 0,0,0, r,g,b,1);
//auto obj = m_plot->GetImpl()->AddSphere(0.05, 0,0,0, r,g,b,1);
//m_plot->GetImpl()->SetObjectMatrix(obj, m::hom_translation<t_mat_gl>(posx, posy, posz)*m::hom_scaling<t_mat_gl>(scale,scale,scale));
//m_plot->GetImpl()->SetObjectLabel(obj, itemName->text().toStdString());
//m_plot->update();
}
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
void MolDynDlg::New()
{
}
void MolDynDlg::Load()
{
}
void MolDynDlg::Save()
{
}
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
/**
* mouse hovers over 3d object
*/
void MolDynDlg::PickerIntersection(const t_vec3_gl* pos, std::size_t objIdx, const t_vec3_gl* posSphere)
{
if(pos)
m_curPickedObj = long(objIdx);
else
m_curPickedObj = -1;
if(m_curPickedObj > 0)
{
}
else
{
Set3DStatusMsg("");
}
}
/**
* set status label text in 3d dialog
*/
void MolDynDlg::Set3DStatusMsg(const std::string& msg)
{
if(!m_status) return;
m_status->showMessage(msg.c_str());
}
/**
* mouse button pressed
*/
void MolDynDlg::PlotMouseDown(bool left, bool mid, bool right)
{
if(left && m_curPickedObj > 0)
{
}
}
/**
* mouse button released
*/
void MolDynDlg::PlotMouseUp(bool left, bool mid, bool right)
{
}
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
void MolDynDlg::AfterGLInitialisation()
{
if(!m_plot) return;
// reference sphere for linked objects
m_sphere = m_plot->GetImpl()->AddSphere(0.05, 0.,0.,0., 1.,1.,1.,1.);
m_plot->GetImpl()->SetObjectVisible(m_sphere, false);
// add all 3d objects
Add3DItem(-1);
// GL device info
auto [strGlVer, strGlShaderVer, strGlVendor, strGlRenderer]
= m_plot->GetImpl()->GetGlDescr();
std::cout << "GL Version: " << strGlVer << ", Shader Version: " << strGlShaderVer << "." << std::endl;
std::cout << "GL Device: " << strGlRenderer << ", " << strGlVendor << "." << std::endl;
}
void MolDynDlg::closeEvent(QCloseEvent *evt)
{
if(m_sett)
{
m_sett->setValue("geo", saveGeometry());
}
}
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
int main(int argc, char** argv)
{
if(argc <= 1)
return -1;
set_gl_format(1, _GL_MAJ_VER, _GL_MIN_VER, 8);
tl2::set_locales();
MolDyn<t_real, t_vec> mol;
mol.LoadFile(argv[1], 100);
auto app = std::make_unique<QApplication>(argc, argv);
auto dlg = std::make_unique<MolDynDlg>(nullptr);
dlg->show();
return 0;
return app->exec();
}
// ----------------------------------------------------------------------------
/**
* loads atom dynamics file
* atom dynamics
* @author Tobias Weber <tweber@ill.fr>
* @date Dec-2019
* @license GPLv3, see 'LICENSE' file
*/
#ifndef __MOLDYN_H__
#define __MOLDYN_H__
#ifndef __MOLDYN_GUI_H__
#define __MOLDYN_GUI_H__
#include <QtWidgets/QMainWindow>
#include <QtWidgets/QDialog>
#include <QtWidgets/QMenuBar>
#include <QtWidgets/QStatusBar>
#include <QtWidgets/QMenu>
#include <QtWidgets/QLabel>
#include <QtCore/QSettings>
#include <fstream>
#include <iostream>
#include <vector>
#include <string>
#include <sstream>
#include "libs/str.h"
#include "libs/_cxx20/glplot.h"
#include "libs/_cxx20/math_algos.h"
template<class t_real, class t_vec>
class MolFrame
{
public:
MolFrame()
{
m_config.reserve(128);
}
void AddAtomConfig(std::vector<t_vec>&& config)
{
m_config.emplace_back(std::move(config));
}
void AddAtomConfig(const std::vector<t_vec>& config)
{
m_config.push_back(config);