Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
Scientific Software
Takin
mag-core
Commits
03d57416
Verified
Commit
03d57416
authored
Aug 13, 2020
by
Tobias WEBER
Browse files
continued with dynamics tool
parent
9c8f1af3
Changes
3
Hide whitespace changes
Inline
Side-by-side
tools/moldyn/CMakeLists.txt
View file @
03d57416
...
...
@@ -7,8 +7,9 @@
# mingw64-cmake -DCMAKE_BUILD_TYPE=Release ..
#
cmake_minimum_required
(
VERSION 3.0
)
project
(
moldyn
)
cmake_minimum_required
(
VERSION 3.0
)
list
(
APPEND CMAKE_MODULE_PATH
"
${
PROJECT_SOURCE_DIR
}
"
"
${
PROJECT_SOURCE_DIR
}
/../../tlibs2/cmake"
)
set
(
CMAKE_VERBOSE_MAKEFILE TRUE
)
...
...
@@ -16,6 +17,7 @@ set(CMAKE_VERBOSE_MAKEFILE TRUE)
#find_package(Boost REQUIRED COMPONENTS system REQUIRED)
find_package
(
Boost REQUIRED
)
find_package
(
Qt5 REQUIRED COMPONENTS Core Gui Widgets OpenGL
)
find_package
(
Qhull REQUIRED
)
set
(
CMAKE_AUTOUIC TRUE
)
...
...
@@ -26,11 +28,12 @@ add_definitions(-std=c++20)
add_definitions
(
${
Boost_CXX_FLAGS
}
)
add_definitions
(
-DBOOST_SYSTEM_NO_DEPRECATED -DBOOST_ERROR_CODE_HEADER_ONLY
)
add_definitions
(
-D_GL_MAJ_VER=3 -D_GL_MIN_VER=2
)
add_definitions
(
-DUSE_QHULL
)
include_directories
(
"
${
PROJECT_SOURCE_DIR
}
"
"
${
Boost_INCLUD
E_DIR
S
}
/.."
"../.."
"ext"
"
${
PROJECT_SOURCE_DIR
}
"
"
${
PROJECT_SOURC
E_DIR
}
/.."
"
${
PROJECT_SOURCE_DIR
}
/
../.."
"
${
Boost_INCLUDE_DIRS
}
/.."
"
${
Qhull_INCLUDE_DIRS
}
"
"ext"
)
...
...
@@ -38,5 +41,5 @@ add_executable(moldyn
moldyn.cpp moldyn.h
../../libs/glplot.cpp ../../libs/glplot.h
)
target_link_libraries
(
moldyn
${
Boost_LIBRARIES
}
)
target_link_libraries
(
moldyn
${
Qhull_LIBRARIES
}
${
Boost_LIBRARIES
}
)
qt5_use_modules
(
moldyn Core Gui Widgets OpenGL
)
tools/moldyn/moldyn.cpp
View file @
03d57416
/**
* atom dynamics
* atom dynamics
tool
* @author Tobias Weber <tweber@ill.fr>
* @date Dec-2019
* @license GPLv3, see 'LICENSE' file
...
...
@@ -150,14 +150,18 @@ MolDynDlg::MolDynDlg(QWidget* pParent) : QMainWindow{pParent},
auto
acCalcDist
=
new
QAction
(
"Distance Between Selected Atoms..."
,
menuEdit
);
auto
acCalcPos
=
new
QAction
(
"Positions Of Selected Atoms..."
,
menuEdit
);
auto
acCalcDeltaDist
=
new
QAction
(
"Distances to Initial Position of Selected Atoms..."
,
menuEdit
);
auto
acCalcHull
=
new
QAction
(
"Convex Hull of Selected Atoms"
,
menuEdit
);
menuCalc
->
addAction
(
acCalcDist
);
menuCalc
->
addAction
(
acCalcPos
);
menuCalc
->
addAction
(
acCalcDeltaDist
);
menuCalc
->
addSeparator
();
menuCalc
->
addAction
(
acCalcHull
);
connect
(
acCalcDist
,
&
QAction
::
triggered
,
this
,
&
MolDynDlg
::
CalculateDistanceBetweenAtoms
);
connect
(
acCalcPos
,
&
QAction
::
triggered
,
this
,
&
MolDynDlg
::
CalculatePositionsOfAtoms
);
connect
(
acCalcDeltaDist
,
&
QAction
::
triggered
,
this
,
&
MolDynDlg
::
CalculateDeltaDistancesOfAtoms
);
connect
(
acCalcHull
,
&
QAction
::
triggered
,
this
,
&
MolDynDlg
::
CalculateConvexHullOfAtoms
);
// Help
...
...
@@ -256,15 +260,15 @@ MolDynDlg::MolDynDlg(QWidget* pParent) : QMainWindow{pParent},
m_spinScale
->
setValue
(
0.4
);
m_spinScale
->
setFocusPolicy
(
Qt
::
StrongFocus
);
m_slider
=
new
QSlider
(
Qt
::
Horizontal
,
this
);
m_slider
->
setSizePolicy
(
QSizePolicy
{
QSizePolicy
::
Expanding
,
QSizePolicy
::
Minimum
});
m_slider
->
setMinimum
(
0
);
m_slider
->
setSingleStep
(
1
);
m_slider
->
setPageStep
(
10
);
m_slider
->
setTracking
(
1
);
m_slider
->
setFocusPolicy
(
Qt
::
StrongFocus
);
m_slider
Frame
=
new
QSlider
(
Qt
::
Horizontal
,
this
);
m_slider
Frame
->
setSizePolicy
(
QSizePolicy
{
QSizePolicy
::
Expanding
,
QSizePolicy
::
Minimum
});
m_slider
Frame
->
setMinimum
(
0
);
m_slider
Frame
->
setSingleStep
(
1
);
m_slider
Frame
->
setPageStep
(
10
);
m_slider
Frame
->
setTracking
(
1
);
m_slider
Frame
->
setFocusPolicy
(
Qt
::
StrongFocus
);
connect
(
m_slider
,
&
QSlider
::
valueChanged
,
this
,
&
MolDynDlg
::
SliderValueChanged
);
connect
(
m_slider
Frame
,
&
QSlider
::
valueChanged
,
this
,
&
MolDynDlg
::
SliderValueChanged
);
connect
(
comboCoordSys
,
static_cast
<
void
(
QComboBox
::*
)(
int
)
>
(
&
QComboBox
::
currentIndexChanged
),
this
,
[
this
](
int
val
)
{
if
(
this
->
m_plot
)
...
...
@@ -275,7 +279,7 @@ MolDynDlg::MolDynDlg(QWidget* pParent) : QMainWindow{pParent},
if
(
!
this
->
m_plot
)
return
;
// hack to trigger update
SliderValueChanged
(
m_slider
->
value
());
SliderValueChanged
(
m_slider
Frame
->
value
());
});
pMainGrid
->
addWidget
(
labCoordSys
,
1
,
0
,
1
,
1
);
...
...
@@ -283,7 +287,7 @@ MolDynDlg::MolDynDlg(QWidget* pParent) : QMainWindow{pParent},
pMainGrid
->
addWidget
(
labScale
,
1
,
2
,
1
,
1
);
pMainGrid
->
addWidget
(
m_spinScale
,
1
,
3
,
1
,
1
);
pMainGrid
->
addWidget
(
labFrames
,
1
,
4
,
1
,
1
);
pMainGrid
->
addWidget
(
m_slider
,
1
,
5
,
1
,
4
);
pMainGrid
->
addWidget
(
m_slider
Frame
,
1
,
5
,
1
,
4
);
}
...
...
@@ -340,6 +344,35 @@ void MolDynDlg::Change3DItem(std::size_t obj, const t_vec *vec, const t_vec *col
// ----------------------------------------------------------------------------
std
::
vector
<
std
::
tuple
<
std
::
size_t
,
std
::
size_t
>>
MolDynDlg
::
GetSelectedAtoms
()
{
// get selected atoms
std
::
vector
<
std
::
tuple
<
std
::
size_t
,
std
::
size_t
>>
objs
;
for
(
const
auto
&
obj
:
m_sphereHandles
)
{
// continue if object isn't selected
if
(
!
m_plot
->
GetImpl
()
->
GetObjectHighlight
(
obj
))
continue
;
//const auto [typelabel, _atomSubTypeIdx] = SplitDataString(m_plot->GetImpl()->GetObjectDataString(obj));
// get indices for selected atoms
const
auto
[
bOk
,
atomTypeIdx
,
atomSubTypeIdx
,
sphereIdx
]
=
GetAtomIndexFromHandle
(
obj
);
if
(
!
bOk
/*|| _atomSubTypeIdx != atomSubTypeIdx*/
)
{
QMessageBox
::
critical
(
this
,
PROG_NAME
,
"Atom handle not found, data is corrupted."
);
return
std
::
vector
<
std
::
tuple
<
std
::
size_t
,
std
::
size_t
>>
{};
}
objs
.
emplace_back
(
std
::
make_tuple
(
atomTypeIdx
,
atomSubTypeIdx
));
}
return
objs
;
}
/**
* calculate the distance between selected atoms
*/
...
...
@@ -348,24 +381,7 @@ void MolDynDlg::CalculateDistanceBetweenAtoms()
try
{
// get selected atoms
std
::
vector
<
std
::
tuple
<
std
::
size_t
,
std
::
size_t
>>
objs
;
for
(
const
auto
&
obj
:
m_sphereHandles
)
{
// continue if object isn't selected
if
(
!
m_plot
->
GetImpl
()
->
GetObjectHighlight
(
obj
))
continue
;
// get indices for selected atoms
const
auto
[
bOk
,
atomTypeIdx
,
atomSubTypeIdx
,
sphereIdx
]
=
GetAtomIndexFromHandle
(
obj
);
if
(
!
bOk
)
{
QMessageBox
::
critical
(
this
,
PROG_NAME
,
"Atom handle not found, data is corrupted."
);
return
;
}
objs
.
push_back
(
std
::
make_tuple
(
atomTypeIdx
,
atomSubTypeIdx
));
}
std
::
vector
<
std
::
tuple
<
std
::
size_t
,
std
::
size_t
>>
objs
=
GetSelectedAtoms
();
if
(
objs
.
size
()
<=
1
)
{
...
...
@@ -447,7 +463,6 @@ void MolDynDlg::CalculateDistanceBetweenAtoms()
}
/**
* calculate positions of selected atoms
*/
...
...
@@ -456,24 +471,7 @@ void MolDynDlg::CalculatePositionsOfAtoms()
try
{
// get selected atoms
std
::
vector
<
std
::
tuple
<
std
::
size_t
,
std
::
size_t
>>
objs
;
for
(
const
auto
&
obj
:
m_sphereHandles
)
{
// continue if object isn't selected
if
(
!
m_plot
->
GetImpl
()
->
GetObjectHighlight
(
obj
))
continue
;
// get indices for selected atoms
const
auto
[
bOk
,
atomTypeIdx
,
atomSubTypeIdx
,
sphereIdx
]
=
GetAtomIndexFromHandle
(
obj
);
if
(
!
bOk
)
{
QMessageBox
::
critical
(
this
,
PROG_NAME
,
"Atom handle not found, data is corrupted."
);
return
;
}
objs
.
push_back
(
std
::
make_tuple
(
atomTypeIdx
,
atomSubTypeIdx
));
}
std
::
vector
<
std
::
tuple
<
std
::
size_t
,
std
::
size_t
>>
objs
=
GetSelectedAtoms
();
if
(
objs
.
size
()
<=
0
)
{
...
...
@@ -553,7 +551,6 @@ void MolDynDlg::CalculatePositionsOfAtoms()
}
/**
* calculate distance to initial positions of selected atoms
*/
...
...
@@ -562,26 +559,7 @@ void MolDynDlg::CalculateDeltaDistancesOfAtoms()
try
{
// get selected atoms
std
::
vector
<
std
::
tuple
<
std
::
size_t
,
std
::
size_t
>>
objs
;
for
(
const
auto
&
obj
:
m_sphereHandles
)
{
// continue if object isn't selected
if
(
!
m_plot
->
GetImpl
()
->
GetObjectHighlight
(
obj
))
continue
;
//const auto [typelabel, _atomSubTypeIdx] = SplitDataString(m_plot->GetImpl()->GetObjectDataString(obj));
// get indices for selected atoms
const
auto
[
bOk
,
atomTypeIdx
,
atomSubTypeIdx
,
sphereIdx
]
=
GetAtomIndexFromHandle
(
obj
);
if
(
!
bOk
/*|| _atomSubTypeIdx != atomSubTypeIdx*/
)
{
QMessageBox
::
critical
(
this
,
PROG_NAME
,
"Atom handle not found, data is corrupted."
);
return
;
}
objs
.
push_back
(
std
::
make_tuple
(
atomTypeIdx
,
atomSubTypeIdx
));
}
std
::
vector
<
std
::
tuple
<
std
::
size_t
,
std
::
size_t
>>
objs
=
GetSelectedAtoms
();
if
(
objs
.
size
()
<=
0
)
{
...
...
@@ -659,10 +637,63 @@ void MolDynDlg::CalculateDeltaDistancesOfAtoms()
QMessageBox
::
critical
(
this
,
PROG_NAME
,
ex
.
what
());
}
}
/**
* calculate the convex hull of selected atoms
*/
void
MolDynDlg
::
CalculateConvexHullOfAtoms
()
{
// get selected atoms
HullIndices
hull
;
hull
.
vertices
=
GetSelectedAtoms
();
if
(
hull
.
vertices
.
size
()
<=
3
)
{
QMessageBox
::
critical
(
this
,
PROG_NAME
,
"At least four atoms have to be selected."
);
return
;
}
// mark indices for hull calculation
m_hulls
.
emplace_back
(
std
::
move
(
hull
));
CalculateConvexHulls
();
}
/**
* calculate all convex hulls for the atom indices given in m_hulls
*/
void
MolDynDlg
::
CalculateConvexHulls
()
{
std
::
size_t
frameidx
=
m_sliderFrame
->
value
();
for
(
const
auto
&
hull
:
m_hulls
)
{
std
::
vector
<
t_vec
>
vertices
;
for
(
const
auto
[
objTypeIdx
,
objSubTypeIdx
]
:
hull
.
vertices
)
{
const
t_vec
&
coords
=
m_mol
.
GetAtomCoords
(
objTypeIdx
,
objSubTypeIdx
,
frameidx
);
vertices
.
push_back
(
coords
);
}
auto
polys
=
tl2_qh
::
get_convexhull
(
vertices
);
for
(
const
auto
&
poly
:
polys
)
{
std
::
cout
<<
"hull polygon:
\n
"
;
for
(
const
auto
&
vert
:
poly
)
std
::
cout
<<
"
\t
vertex: "
<<
vert
<<
std
::
endl
;
}
// TODO
}
}
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
void
MolDynDlg
::
New
()
{
...
...
@@ -672,7 +703,7 @@ void MolDynDlg::New()
m_plot
->
GetImpl
()
->
RemoveObject
(
obj
);
m_sphereHandles
.
clear
();
m_slider
->
setValue
(
0
);
m_slider
Frame
->
setValue
(
0
);
m_plot
->
update
();
}
...
...
@@ -723,7 +754,7 @@ void MolDynDlg::Load()
m_mol
.
UnsubscribeFromLoadProgress
(
&
progressHandler
);
m_slider
->
setMaximum
(
m_mol
.
GetFrameCount
()
-
1
);
m_slider
Frame
->
setMaximum
(
m_mol
.
GetFrameCount
()
-
1
);
// crystal A and B matrices
...
...
@@ -885,7 +916,7 @@ void MolDynDlg::SetStatusMsg(const std::string& msg)
void
MolDynDlg
::
UpdateAtomsStatusMsg
()
{
if
(
!
m_statusAtoms
||
!
m_slider
)
return
;
if
(
!
m_statusAtoms
||
!
m_slider
Frame
)
return
;
// Atoms
std
::
string
numAtoms
=
std
::
to_string
(
m_mol
.
GetNumAtomsTotal
())
+
" atoms."
;
...
...
@@ -905,7 +936,7 @@ void MolDynDlg::UpdateAtomsStatusMsg()
}
// Frames
numAtoms
+=
" Frame "
+
std
::
to_string
(
m_slider
->
value
()
+
1
)
+
" of "
+
std
::
to_string
(
m_mol
.
GetFrameCount
())
+
"."
;
numAtoms
+=
" Frame "
+
std
::
to_string
(
m_slider
Frame
->
value
()
+
1
)
+
" of "
+
std
::
to_string
(
m_mol
.
GetFrameCount
())
+
"."
;
m_statusAtoms
->
setText
(
numAtoms
.
c_str
());
}
...
...
@@ -1344,17 +1375,17 @@ void MolDynDlg::closeEvent(QCloseEvent *evt)
void
MolDynDlg
::
keyPressEvent
(
QKeyEvent
*
evt
)
{
if
(
evt
->
key
()
==
Qt
::
Key_Left
||
evt
->
key
()
==
Qt
::
Key_Down
)
m_slider
->
setValue
(
m_slider
->
value
()
-
m_slider
->
singleStep
());
m_slider
Frame
->
setValue
(
m_slider
Frame
->
value
()
-
m_slider
Frame
->
singleStep
());
else
if
(
evt
->
key
()
==
Qt
::
Key_Right
||
evt
->
key
()
==
Qt
::
Key_Up
)
m_slider
->
setValue
(
m_slider
->
value
()
+
m_slider
->
singleStep
());
m_slider
Frame
->
setValue
(
m_slider
Frame
->
value
()
+
m_slider
Frame
->
singleStep
());
else
if
(
evt
->
key
()
==
Qt
::
Key_PageUp
)
m_slider
->
setValue
(
m_slider
->
value
()
+
m_slider
->
pageStep
());
m_slider
Frame
->
setValue
(
m_slider
Frame
->
value
()
+
m_slider
Frame
->
pageStep
());
else
if
(
evt
->
key
()
==
Qt
::
Key_PageDown
)
m_slider
->
setValue
(
m_slider
->
value
()
-
m_slider
->
pageStep
());
m_slider
Frame
->
setValue
(
m_slider
Frame
->
value
()
-
m_slider
Frame
->
pageStep
());
else
if
(
evt
->
key
()
==
Qt
::
Key_Home
)
m_slider
->
setValue
(
m_slider
->
minimum
());
m_slider
Frame
->
setValue
(
m_slider
Frame
->
minimum
());
else
if
(
evt
->
key
()
==
Qt
::
Key_End
)
m_slider
->
setValue
(
m_slider
->
maximum
());
m_slider
Frame
->
setValue
(
m_slider
Frame
->
maximum
());
QMainWindow
::
keyPressEvent
(
evt
);
}
...
...
tools/moldyn/moldyn.h
View file @
03d57416
...
...
@@ -31,6 +31,15 @@ using t_vec = tl2::vec<t_real, std::vector>;
using
t_mat
=
tl2
::
mat
<
t_real
,
std
::
vector
>
;
/**
* atom indices for convex hull calculation
*/
struct
HullIndices
{
std
::
vector
<
std
::
tuple
<
std
::
size_t
,
std
::
size_t
>>
vertices
;
};
class
MolDynDlg
:
public
QMainWindow
{
public:
...
...
@@ -62,12 +71,17 @@ protected:
void
CalculateDistanceBetweenAtoms
();
void
CalculatePositionsOfAtoms
();
void
CalculateDeltaDistancesOfAtoms
();
void
CalculateConvexHullOfAtoms
();
void
CalculateConvexHulls
();
void
SliderValueChanged
(
int
val
);
void
SelectAll
();
void
SelectNone
();
std
::
vector
<
std
::
tuple
<
std
::
size_t
,
std
::
size_t
>>
GetSelectedAtoms
();
void
DeleteSelectedAtoms
();
void
OnlyKeepSelectedAtoms
();
void
SelectAtomsOfSameType
();
...
...
@@ -91,7 +105,7 @@ protected:
QLabel
*
m_statusCurAtom
=
nullptr
;
QLabel
*
m_statusAtoms
=
nullptr
;
QSlider
*
m_slider
=
nullptr
;
QSlider
*
m_slider
Frame
=
nullptr
;
QDoubleSpinBox
*
m_spinScale
=
nullptr
;
QMenu
*
m_atomContextMenu
=
nullptr
;
...
...
@@ -99,6 +113,8 @@ protected:
std
::
size_t
m_sphere
=
0
;
std
::
vector
<
std
::
size_t
>
m_sphereHandles
;
std
::
vector
<
HullIndices
>
m_hulls
;
private:
long
m_curPickedObj
=
-
1
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment