diff --git a/modules/mol/base/src/coord_group.cc b/modules/mol/base/src/coord_group.cc index bd56a4e004159ee76f30cbf8e4d5051a0967fae3..4fe6677ee7da3981ee2bc3f9b48f2c26599820e4 100644 --- a/modules/mol/base/src/coord_group.cc +++ b/modules/mol/base/src/coord_group.cc @@ -254,6 +254,15 @@ CoordGroupHandle CoordGroupHandle::Filter(const EntityView& selected, int first, } return filtered_cg; } - + +void CoordGroupHandle::ApplyTransform(const mol::Transform& tf) +{ + this->CheckValidity(); + if (source_->IsMutable()) { + source_->ApplyTransform(tf); + } else { + throw IntegrityError("Cannot apply transform, CoordGroup is immutable"); + } +} }} // ns diff --git a/modules/mol/base/src/coord_group.hh b/modules/mol/base/src/coord_group.hh index bf049aadd049b4a3803c8fe1bc35f954f72d142b..74fffcb6c45d47f2e0f0e3c469e5174a07a31cab 100644 --- a/modules/mol/base/src/coord_group.hh +++ b/modules/mol/base/src/coord_group.hh @@ -30,6 +30,8 @@ namespace ost { namespace mol { +class Transform; + /// \brief coordinate group, for trajectories and such class DLLEXPORT_OST_MOL CoordGroupHandle { public: @@ -105,7 +107,9 @@ public: /// \brief return a filtered coord group, containing only the atoms in the /// view CoordGroupHandle Filter(const EntityView& selected,int first=0,int last=-1) const; - + + /// \brief apply in-place transform to each coordinate in each frame + void ApplyTransform(const Transform& tf); private: diff --git a/modules/mol/base/src/coord_source.cc b/modules/mol/base/src/coord_source.cc index 335117423068e6bae62392a60bbaf87f2658ae96..06b7864b7a831fa2fe8d0e144765b6bff2094b9e 100644 --- a/modules/mol/base/src/coord_source.cc +++ b/modules/mol/base/src/coord_source.cc @@ -21,13 +21,12 @@ Author: Marco Biasini */ #include <ost/log.hh> -#include <ost/mol/atom_handle.hh> -#include <ost/mol/xcs_editor.hh> -#include <ost/mol/in_mem_coord_source.hh> - +#include "atom_handle.hh" +#include "xcs_editor.hh" +#include "in_mem_coord_source.hh" +#include "transform.hh" #include "coord_source.hh" - namespace ost { namespace mol { @@ -166,4 +165,16 @@ geom::Vec3 CoordSource::GetAtomPos(uint frame, AtomHandle atom) const return geom::Vec3(); } +void CoordSource::ApplyTransform(const Transform& tf) +{ + if(!mutable_) return; + size_t frame_count=GetFrameCount(); + for(size_t n=0;n<frame_count;++n) { + CoordFramePtr cfp=GetFrame(n); + for(CoordFrame::iterator it=cfp->begin();it!=cfp->end();++it) { + *it=tf.Apply(*it); + } + } +} + }} // ns diff --git a/modules/mol/base/src/coord_source.hh b/modules/mol/base/src/coord_source.hh index a50f256a15ee81b62d969ef92be0a64cb7cb5bbb..a33162abc4e14a95a94e1414aa90401cb47bd0af 100644 --- a/modules/mol/base/src/coord_source.hh +++ b/modules/mol/base/src/coord_source.hh @@ -31,6 +31,7 @@ namespace ost { namespace mol { class CoordSource; +class Transform; typedef boost::shared_ptr<CoordSource> CoordSourcePtr; @@ -80,6 +81,9 @@ public: virtual void AddFrame(const std::vector<geom::Vec3>& coords) = 0; virtual void AddFrame(const std::vector<geom::Vec3>& coords,const geom::Vec3& cell_size,const geom::Vec3& cell_angles) = 0; virtual void InsertFrame(int pos, const std::vector<geom::Vec3>& coords) = 0; + + void ApplyTransform(const Transform& tf); + protected: void SetMutable(bool flag); private: diff --git a/modules/mol/base/src/transform.cc b/modules/mol/base/src/transform.cc index cb76e719655a8f9023daabcaa4824f934f3a87a4..ba1e59258299ca1f6011ddc1ebe1582aafba222b 100644 --- a/modules/mol/base/src/transform.cc +++ b/modules/mol/base/src/transform.cc @@ -122,7 +122,7 @@ void Transform::ApplyZAxisRotation(float delta) void Transform::ApplyAxisRotation(float delta, const Vec3& axis) { - rot_=rot_*AxisRotation(rot_*axis, delta*P_180); + rot_=rot_*AxisRotation(axis, delta*P_180); update_tm(); } diff --git a/modules/mol/base/tests/test_coord_group.cc b/modules/mol/base/tests/test_coord_group.cc index 7e3d385982636a346a6b88ea6b143b410352d64d..3c0cdc18fbe5fe139c930d0e7f54ad26cb5941ea 100644 --- a/modules/mol/base/tests/test_coord_group.cc +++ b/modules/mol/base/tests/test_coord_group.cc @@ -80,6 +80,18 @@ BOOST_AUTO_TEST_CASE(coord_group) BOOST_CHECK(ab.GetPos()==geom::Vec3(-14,-15,-16)); BOOST_CHECK(ac.GetPos()==geom::Vec3(-17,-18,-19)); BOOST_CHECK(ad.GetPos()==geom::Vec3(9,10,11)); + + Transform tf; + tf.ApplyXAxisRotation(17.0); + tf.ApplyYAxisRotation(-135.0); + tf.ApplyZAxisRotation(234.0); + tf.SetCenter(geom::Vec3(-7.3,1.2,5.5)); + tf.SetTrans(geom::Vec3(14.5,-87.1,22.2)); + + cg.ApplyTransform(tf); + for(size_t i=0;i<3;++i) { + BOOST_CHECK_CLOSE(geom::Distance(cg.GetAtomPos(1,alist[i]),tf.Apply(clist[i])),Real(0),1e-6); + } } BOOST_AUTO_TEST_SUITE_END();