diff --git a/modules/geom/src/transform.cc b/modules/geom/src/transform.cc index b40a3229d4a0966b1e1f0b772c8f17c020b30a5d..c620410fb0332233bd047e39b2cf60b7f3da7e86 100644 --- a/modules/geom/src/transform.cc +++ b/modules/geom/src/transform.cc @@ -40,6 +40,13 @@ void Transform::SetMatrix(const Mat4& m) { tm_=m; ttm_ = Transpose(tm_); + try { + itm_ = Invert(tm_); + } catch (GeomException& e) { + std::cerr << "caught GeomException in Transform::SetMatrix: " << e.what() << std::endl; + std::cerr << m << std::endl; + itm_=geom::Mat4(); + } update_components(); } @@ -151,6 +158,18 @@ Vec4 Transform::Apply(const Vec4& v) const return nrvo; } +Vec3 Transform::ApplyInverse(const Vec3& v) const +{ + Vec3 nrvo(itm_*Vec4(v)); + return nrvo; +} + +Vec4 Transform::ApplyInverse(const Vec4& v) const +{ + Vec4 nrvo=itm_*v; + return nrvo; +} + geom::AlignedCuboid Transform::Apply(const geom::AlignedCuboid& c) const { geom::Vec3 cmin=c.GetMin(); @@ -196,14 +215,14 @@ void Transform::update_tm() { tm_ = Mat4(1.0,0.0,0.0,trans_[0], - 0.0,1.0,0.0,trans_[1], - 0.0,0.0,1.0,trans_[2], - 0.0,0.0,0.0,1.0) * + 0.0,1.0,0.0,trans_[1], + 0.0,0.0,1.0,trans_[2], + 0.0,0.0,0.0,1.0) * Mat4(rot_) * Mat4(1.0,0.0,0.0,-cen_[0], - 0.0,1.0,0.0,-cen_[1], - 0.0,0.0,1.0,-cen_[2], - 0.0,0.0,0.0,1.0); + 0.0,1.0,0.0,-cen_[1], + 0.0,0.0,1.0,-cen_[2], + 0.0,0.0,0.0,1.0); ttm_ = Transpose(tm_); // TODO: calculate from rot, cen and trans try { diff --git a/modules/geom/src/transform.hh b/modules/geom/src/transform.hh index ac6a87d0bed5478b08b2ad26feeb14bd51ac3296..6965c48437dd5b4c041aabf46eb705ec87bd9ec4 100644 --- a/modules/geom/src/transform.hh +++ b/modules/geom/src/transform.hh @@ -39,7 +39,10 @@ namespace geom { class DLLEXPORT_OST_GEOM Transform { public: Transform(); - + + /// \brief reset to identity + void Reset() {*this=Transform();} + /// \brief retrieve transformation matrix Mat4 GetMatrix() const {return tm_;} /// \brief retrieve transposed transformation matrix @@ -78,9 +81,16 @@ public: void SetTrans(const Vec3& t); Vec3 GetTrans() const; //@} - + + // apply to a vec3 and return result Vec3 Apply(const Vec3& v) const; + // apply to a vec4 and return result Vec4 Apply(const Vec4& v) const; + // apply inverse to a vec3 and return result + Vec3 ApplyInverse(const Vec3& v) const; + // apply inverse to a vec4 and return result + Vec4 ApplyInverse(const Vec4& v) const; + // apply to an aligned cuboid and return result AlignedCuboid Apply(const AlignedCuboid& c) const; Transform Apply(const Transform& tf) const; diff --git a/modules/geom/src/vec3.hh b/modules/geom/src/vec3.hh index 7b4bb5b33fd33cccfe285f6d602bfa8d968bb687..c1cde046c0174c7571701ca6ee82e9645ccc41c8 100644 --- a/modules/geom/src/vec3.hh +++ b/modules/geom/src/vec3.hh @@ -239,11 +239,15 @@ namespace geom { inline Vec3::Vec3(const Vec4& v): x(v.x), y(v.y), z(v.z) { if (std::fabs(v.w)<1e-10) { - throw DivideByZeroException(); + // it is better to ignore very small w and to simply assume + // that this is not a homogeneous coordinate rather than + // throwing an exception + //throw DivideByZeroException(); + } else { + x/=v.w; + y/=v.w; + z/=v.w; } - x/=v.w; - y/=v.w; - z/=v.w; } } // namespace geom diff --git a/modules/geom/tests/test_vec3.cc b/modules/geom/tests/test_vec3.cc index 9e3e4d9485c379293b59bf454d0befce87181737..3964daf007ade2efcb4db4b0d97547761135fbd5 100644 --- a/modules/geom/tests/test_vec3.cc +++ b/modules/geom/tests/test_vec3.cc @@ -58,8 +58,8 @@ BOOST_AUTO_TEST_CASE(init_vec3) // conversion from vec4 Vec3 v6(Vec4(0.4,1.2,4.0,2.0)); BOOST_CHECK(match(v6,0.2,0.6,2.0)); - BOOST_CHECK_THROW( Vec3(Vec4(1.0,1.0,1.0,0.0)), DivideByZeroException); + BOOST_CHECK(match(Vec3(Vec4(2.0,1.0,3.0,0.0)),2.0,1.0,3.0)); } BOOST_AUTO_TEST_CASE(access_vec3) diff --git a/modules/io/src/mol/pdb_writer.cc b/modules/io/src/mol/pdb_writer.cc index d06a5228c5890f593c40c86ac9ceb4617f6ee379..28c18cd36732b6296d52b108b4f670f74f34639e 100644 --- a/modules/io/src/mol/pdb_writer.cc +++ b/modules/io/src/mol/pdb_writer.cc @@ -154,8 +154,10 @@ void write_atom(std::ostream& ostr, FormattedLine& line, } else { for (std::vector<String>::const_iterator i=names.begin(), e=names.end(); i!=e; ++i) { - geom::Mat4 tf=atom.GetEntity().GetTransformationMatrix(); - p=geom::Vec3(tf*geom::Vec4(atom.GetAltPos(*i))); + // GetAltPos always return orig pos, i.e. does not honor + // transformations like GetPos does - so apply it here + // seems like a FIXME... + p=atom.GetEntity().GetTransform().Apply(atom.GetAltPos(*i)); line(30, 50).Clear(); if (i->size()>1) { diff --git a/modules/mol/base/pymod/export_editors.cc b/modules/mol/base/pymod/export_editors.cc index c9d7873982ee0b33a51403090dfb8b758fe9922f..aae903f7d276721545a60af51cd1ed0dff227263 100644 --- a/modules/mol/base/pymod/export_editors.cc +++ b/modules/mol/base/pymod/export_editors.cc @@ -216,6 +216,7 @@ void export_Editors() import_array(); #endif + class_<EditorBase>("EditorBase", no_init) .def("InsertChain", insert_chain_a) .def("InsertChain", insert_chain_b,(arg("chain_name"),arg("chain"), arg("deep")=false)) @@ -250,12 +251,19 @@ void export_Editors() .def("RenumberAllResidues",&EditorBase::RenumberAllResidues) ; + void (XCSEditor::*apply_transform1)(const geom::Mat4&) = &XCSEditor::ApplyTransform; + void (XCSEditor::*apply_transform2)(const geom::Transform&) = &XCSEditor::ApplyTransform; + void (XCSEditor::*set_transform1)(const geom::Mat4&) = &XCSEditor::SetTransform; + void (XCSEditor::*set_transform2)(const geom::Transform&) = &XCSEditor::SetTransform; + class_<XCSEditor, bases<EditorBase> >("XCSEditor", no_init) .def("SetAtomPos", set_t_pos) .def("SetAtomTransformedPos", set_t_pos) .def("SetAtomOriginalPos", set_o_pos) - .def("ApplyTransform", &XCSEditor::ApplyTransform) - .def("SetTransform", &XCSEditor::SetTransform) + .def("ApplyTransform", apply_transform1) + .def("ApplyTransform", apply_transform2) + .def("SetTransform", set_transform1) + .def("SetTransform", set_transform2) .def("UpdateICS", &XCSEditor::UpdateICS) .def("__exit__", &XCSEditor::UpdateICS) ; diff --git a/modules/mol/base/pymod/export_entity.cc b/modules/mol/base/pymod/export_entity.cc index adf2c83b7621420f1000aafa96439f90d34a203f..d01cd047290d7e8e88f9b454d68fd57082afc09d 100644 --- a/modules/mol/base/pymod/export_entity.cc +++ b/modules/mol/base/pymod/export_entity.cc @@ -100,7 +100,15 @@ PyObject* get_pos1(EntityHandle& entity) return get_pos2(entity,true); } +geom::Mat4 depr_get_transformation_matrix(const EntityHandle& eh) +{ + return eh.GetTransformationMatrix(); +} +bool depr_is_transformation_identity(const EntityHandle& eh) +{ + return eh.IsTransformationIdentity(); +} #endif } // ns @@ -181,17 +189,17 @@ void export_Entity() .add_property("bonds", &EntityHandle::GetBondList) .def("GetBounds", &EntityHandle::GetBounds) .add_property("bounds", &EntityHandle::GetBounds) - .def("GetTransformationMatrix", &EntityHandle::GetTransformationMatrix, - return_value_policy<copy_const_reference>()) - .add_property("transform", - make_function(&EntityHandle::GetTransformationMatrix, - return_value_policy<copy_const_reference>())) - + .def("GetTransformationMatrix", depr_get_transformation_matrix) + .def("IsTransformationIdentity",depr_is_transformation_identity) + .def("GetTransform",&EntityHandle::GetTransform) + .def("SetTransform",&EntityHandle::SetTransform) + .add_property("transform",&EntityHandle::GetTransform,&EntityHandle::SetTransform) + .def("HasTransform",&EntityHandle::HasTransform) + .def("ClearTransform",&EntityHandle::ClearTransform) .def("EditXCS", &EntityHandle::EditXCS, arg("mode")=UNBUFFERED_EDIT) .def("EditICS", &EntityHandle::EditICS, arg("mode")=UNBUFFERED_EDIT) .def("RequestXCSEditor", &depr_request_xcs_editor, arg("mode")=UNBUFFERED_EDIT) .def("RequestICSEditor", &depr_request_ics_editor, arg("mode")=UNBUFFERED_EDIT) - .def("IsTransformationIdentity",&EntityHandle::IsTransformationIdentity) .def(self==self) .def(self!=self) #if OST_NUMPY_SUPPORT_ENABLED diff --git a/modules/mol/base/src/entity_handle.cc b/modules/mol/base/src/entity_handle.cc index 0abad5ede1b3241f05300b5768cf0b7c332f4c12..e34e11d2e233ab4a60da62e20c3e085c4ece1f58 100644 --- a/modules/mol/base/src/entity_handle.cc +++ b/modules/mol/base/src/entity_handle.cc @@ -17,6 +17,8 @@ // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA //------------------------------------------------------------------------------ +#include <ost/log.hh> + #include "impl/entity_impl.hh" #include "bond_handle.hh" #include "torsion_handle.hh" @@ -235,24 +237,62 @@ Real EntityHandle::GetAngle(const AtomView& a1, const AtomView& a2, return GetAngle(a1.GetHandle(), a2.GetHandle(), a3.GetHandle()); } -const geom::Mat4& EntityHandle::GetTransformationMatrix() const - +geom::Mat4 EntityHandle::GetTransformationMatrix() const { + static bool warn=true; + if(warn) { + LOG_WARNING("Entity::GetTransformationMatrix is deprecated, use GetTransform instead"); + warn=false; + } this->CheckValidity(); - return Impl()->GetTransfMatrix(); + return Impl()->GetTransform().GetMatrix(); } -const geom::Mat4& EntityHandle::GetInvTransformationMatrix() const +geom::Mat4 EntityHandle::GetInvTransformationMatrix() const { + static bool warn=true; + if(warn) { + LOG_WARNING("Entity::GetInvTransformationMatrix is deprecated, use GetTransform instead"); + warn=false; + } this->CheckValidity(); - return Impl()->GetInvTransfMatrix(); + return Impl()->GetTransform().GetInvertedMatrix(); } bool EntityHandle::IsTransformationIdentity() const +{ + static bool warn=true; + if(warn) { + LOG_WARNING("Entity::IsTransformationIdentity is deprecated, use HasTransform instead"); + warn=false; + } + this->CheckValidity(); + return !Impl()->HasTransform(); +} + +geom::Transform EntityHandle::GetTransform() const +{ + this->CheckValidity(); + return Impl()->GetTransform(); +} + +void EntityHandle::SetTransform(const geom::Transform& tf) +{ + this->CheckValidity(); + Impl()->SetTransform(tf); +} + +bool EntityHandle::HasTransform() const +{ + this->CheckValidity(); + return Impl()->HasTransform(); +} + +void EntityHandle::ClearTransform() { this->CheckValidity(); - return Impl()->IsTransfIdentity(); + Impl()->ClearTransform(); } ResidueHandle EntityHandle::FindResidue(const String& chain_name, diff --git a/modules/mol/base/src/entity_handle.hh b/modules/mol/base/src/entity_handle.hh index 2783b404b75b11a1e31127017d8461b740752cf5..fe2a439135306d6f2a7c080ed91f1e15604faea0 100644 --- a/modules/mol/base/src/entity_handle.hh +++ b/modules/mol/base/src/entity_handle.hh @@ -264,13 +264,22 @@ public: Real GetAngle(const AtomView& a1, const AtomView& a2, const AtomView& a3) const; - const geom::Mat4& GetTransformationMatrix() const; - - - const geom::Mat4& GetInvTransformationMatrix() const; - + /// \brief DEPRECATED + geom::Mat4 GetTransformationMatrix() const; + /// \brief DEPRECATED + geom::Mat4 GetInvTransformationMatrix() const; + /// \brief DEPRECATED bool IsTransformationIdentity() const; + /// \brief retrieve transformation of this entity + geom::Transform GetTransform() const; + /// \brief set transformation that will affect this entity + void SetTransform(const geom::Transform& t); + /// \brief checks whether a transform has been set + bool HasTransform() const; + /// \brief remove transform + void ClearTransform(); + /// \brief get complete list of residues /// \sa #ResiduesBegin, #ResiduesEnd ResidueHandleList GetResidueList() const; diff --git a/modules/mol/base/src/impl/atom_impl.cc b/modules/mol/base/src/impl/atom_impl.cc index 4f7f059b818eda692de6447a9b3d2b5d547037e7..3a2b4d013f2c14e82f345e55241aa911d0809ffe 100644 --- a/modules/mol/base/src/impl/atom_impl.cc +++ b/modules/mol/base/src/impl/atom_impl.cc @@ -56,10 +56,8 @@ AtomImpl::AtomImpl(const EntityImplPtr& e, state_(0), index_(index) { - EntityHandle ent = this->GetEntity(); - geom::Mat4 transf_matrix = ent.GetTransformationMatrix(); - geom::Vec3 transf_pos = geom::Vec3(transf_matrix*geom::Vec4(p)); - tf_pos_ = transf_pos; + EntityImplPtr eip = GetEntity(); + tf_pos_ = eip->HasTransform() ? eip->GetTransform().Apply(p) : p; prop_=AtomProp::GetDefaultProps(element_); } diff --git a/modules/mol/base/src/impl/chain_impl.cc b/modules/mol/base/src/impl/chain_impl.cc index 91261db8e74cd0b9bbd5358c0dfb7892f5a68aa3..8b3cbe271eef0e860d78ea5039ac7f00a35e191e 100644 --- a/modules/mol/base/src/impl/chain_impl.cc +++ b/modules/mol/base/src/impl/chain_impl.cc @@ -530,5 +530,12 @@ void ChainImpl::SetInSequence(const int index) this->UpdateShifts(); } } + +void ChainImpl::UpdateTransformedPos() +{ + for (ResidueImplList::iterator rit=residue_list_.begin(); rit!=residue_list_.end(); ++rit) { + (*rit)->UpdateTransformedPos(); + } +} }}} // ns diff --git a/modules/mol/base/src/impl/chain_impl.hh b/modules/mol/base/src/impl/chain_impl.hh index 446c74052937d6947f6a6a4a4b04f0a733730cf7..018c3b9e1b76c8666f3593f2843fa9f63933ff9e 100644 --- a/modules/mol/base/src/impl/chain_impl.hh +++ b/modules/mol/base/src/impl/chain_impl.hh @@ -182,6 +182,8 @@ public: /// property and updates it accordingly void SetInSequence(int index); + void UpdateTransformedPos(); + private: int GetIndexForResNumInSequence(const ResNum& number) const; void UpdateShifts(); diff --git a/modules/mol/base/src/impl/entity_impl.cc b/modules/mol/base/src/impl/entity_impl.cc index 6bdbd835c01b12f48930f2c89ce448a618a0328b..8b81293fbc01d47c81fa32af970b7d83c2075dcb 100644 --- a/modules/mol/base/src/impl/entity_impl.cc +++ b/modules/mol/base/src/impl/entity_impl.cc @@ -67,9 +67,8 @@ EntityImpl::EntityImpl(): chain_list_(), connector_map_(), torsion_map_(), - transformation_matrix_(), - inverse_transformation_matrix_(), - identity_transf_(true), + transform_(), + has_transform_(false), atom_organizer_(5.0), fragment_list_(), observer_map_(), @@ -251,21 +250,6 @@ int EntityImpl::GetChainCount() const return static_cast<int>(chain_list_.size()); } -const geom::Mat4& EntityImpl::GetTransfMatrix() const -{ - return transformation_matrix_; -} - -const geom::Mat4& EntityImpl::GetInvTransfMatrix() const -{ - return inverse_transformation_matrix_; -} - -bool EntityImpl::IsTransfIdentity() const -{ - return identity_transf_; -} - EntityImpl::~EntityImpl() { // notify all observers of pending destruct @@ -329,23 +313,18 @@ Real EntityImpl::GetMass() const { AtomImplPtr EntityImpl::CreateAtom(const ResidueImplPtr& rp, const String& name, - const geom::Vec3& pos, + const geom::Vec3& pos2, const String& ele) { #if MAKE_SHARED_AVAILABLE AtomImplPtr ap=boost::make_shared<AtomImpl>(shared_from_this(), rp, name, - pos, ele,next_index_++); + pos2, ele,next_index_++); #else - AtomImplPtr ap(new AtomImpl(shared_from_this(), rp, name, pos, ele, next_index_++)); + AtomImplPtr ap(new AtomImpl(shared_from_this(), rp, name, pos2, ele, next_index_++)); #endif - if (!identity_transf_) { - geom::Vec3 transformed_pos = geom::Vec3(transformation_matrix_*geom::Vec4(pos)); - ap->TransformedPos()=transformed_pos; - atom_organizer_.Add(ap,transformed_pos); - } else { - ap->TransformedPos()=pos; - atom_organizer_.Add(ap,pos); - } + geom::Vec3 pos = has_transform_ ? transform_.Apply(pos2) : pos2; + ap->TransformedPos()=pos; + atom_organizer_.Add(ap,pos); atom_map_.insert(AtomImplMap::value_type(ap.get(),ap)); return ap; } @@ -767,21 +746,25 @@ void EntityImpl::Apply(EntityVisitor& v) v.OnExit(); } -void EntityImpl::ApplyTransform(const geom::Mat4 transfmat) +void EntityImpl::ApplyTransform(const geom::Transform& tf) { - geom::Mat4 updated_transformation_matrix=transfmat*transformation_matrix_; - this->SetTransform(updated_transformation_matrix); + SetTransform(transform_.Apply(tf)); } -void EntityImpl::SetTransform(const geom::Mat4 transfmat) +void EntityImpl::SetTransform(const geom::Transform& tf) { - transformation_matrix_=transfmat; - inverse_transformation_matrix_=Invert(transformation_matrix_); - identity_transf_ = (transformation_matrix_==geom::Mat4()); + transform_=tf; + has_transform_=true; this->UpdateTransformedPos(); this->MarkOrganizerDirty(); } +void EntityImpl::ClearTransform() +{ + has_transform_=false; + SetTransform(geom::Transform()); +} + void EntityImpl::AttachObserver(const EntityObserverPtr& o) { observer_map_.insert(EntityObserverMap::value_type(o.get(),o)); @@ -805,7 +788,8 @@ void EntityImpl::Swap(EntityImpl& impl) chain_list_.swap(impl.chain_list_); connector_map_.swap(impl.connector_map_); torsion_map_.swap(impl.torsion_map_); - std::swap(transformation_matrix_,impl.transformation_matrix_); + std::swap(transform_,impl.transform_); + std::swap(has_transform_,impl.has_transform_); atom_organizer_.Swap(impl.atom_organizer_); fragment_list_.swap(impl.fragment_list_); observer_map_.swap(impl.observer_map_); @@ -1201,7 +1185,10 @@ void EntityImpl::RenameChain(ChainImplPtr chain, const String& new_name) void EntityImpl::UpdateTransformedPos(){ for(AtomImplMap::iterator it = atom_map_.begin();it!=atom_map_.end();++it) { - it->second->TransformedPos()=geom::Vec3(transformation_matrix_*geom::Vec4(it->second->OriginalPos())); + it->second->TransformedPos()=has_transform_ ? transform_.Apply(it->second->OriginalPos()) : it->second->OriginalPos(); + } + for(ChainImplList::iterator cit=chain_list_.begin();cit!=chain_list_.end();++cit) { + (*cit)->UpdateTransformedPos(); } } diff --git a/modules/mol/base/src/impl/entity_impl.hh b/modules/mol/base/src/impl/entity_impl.hh index 209858644faa69c8fd61628cd90d04803f899f8e..a5f5cd805cde4e67fb2ad33b4c376d65c4b2253a 100644 --- a/modules/mol/base/src/impl/entity_impl.hh +++ b/modules/mol/base/src/impl/entity_impl.hh @@ -143,9 +143,12 @@ public: void UpdateFromXCS(); void Apply(EntityVisitor& v); - void ApplyTransform(const geom::Mat4 transfmat); + void ApplyTransform(const geom::Transform& t); - void SetTransform(const geom::Mat4 transfmat); + void SetTransform(const geom::Transform& t); + const geom::Transform& GetTransform() const {return transform_;} + bool HasTransform() const {return has_transform_;} + void ClearTransform(); void AttachObserver(const EntityObserverPtr& o); void DetachObserver(const EntityObserverPtr& o); @@ -198,14 +201,6 @@ public: //! Get number of chains int GetChainCount() const; - //! Get transformation matrix - const geom::Mat4& GetTransfMatrix() const; - - //! Get inverse transformation matrix - const geom::Mat4& GetInvTransfMatrix() const; - - bool IsTransfIdentity() const; - const ChainImplList& GetChainList() const { return chain_list_; } ChainImplList& GetChainList() { return chain_list_; } @@ -266,10 +261,8 @@ private: ConnectorImplMap connector_map_; TorsionImplMap torsion_map_; - geom::Mat4 transformation_matrix_; - geom::Mat4 inverse_transformation_matrix_; - bool identity_transf_; - + geom::Transform transform_; + bool has_transform_; SpatialAtomOrganizer atom_organizer_; FragmentImplList fragment_list_; diff --git a/modules/mol/base/src/impl/residue_impl.cc b/modules/mol/base/src/impl/residue_impl.cc index 1e0fa1d461662e1895f6d8dd5bbeb7d8a58479f6..fd2c7762b3193caafa68d2b86af177243ceafe5d 100644 --- a/modules/mol/base/src/impl/residue_impl.cc +++ b/modules/mol/base/src/impl/residue_impl.cc @@ -118,9 +118,16 @@ geom::Vec3 ResidueImpl::GetAltAtomPos(const AtomImplPtr& atom, throw Error("No alt atom group '"+group+"'"); } const AtomGroup& g=i->second; + EntityImplPtr eip=GetEntity(); for (AtomGroupEntryList::const_iterator j=g.atoms.begin(), e=g.atoms.end(); j!=e; ++j) { if (atom==j->atom.lock()) { + // the alternate entry positions are stored as original, and + // are returned as original as well ?! at least that is what + // the unit test seems to require + // also, the PDB writer currently expects this behavior, so + // if it is changed here, it must be changed there as well + //return eip->HasTransform() ? eip->GetTransform().Apply(j->pos) : j->pos; return j->pos; } } @@ -626,14 +633,11 @@ bool ResidueImpl::SwitchAtomPos(const String& group) { AtomGroup& agr=i->second; AtomGroupEntryList::iterator j=agr.atoms.begin(); for (; j!=agr.atoms.end(); ++j) { - AtomGroupEntry& entry=*j; assert(!entry.atom.expired()); entry.atom.lock()->OriginalPos()=entry.pos; - EntityHandle ent = entry.atom.lock()->GetEntity(); - geom::Mat4 transf_matrix = ent.GetTransformationMatrix(); - geom::Vec3 transf_pos = geom::Vec3(transf_matrix*geom::Vec4(entry.pos)); - entry.atom.lock()->TransformedPos()=transf_pos; + EntityImplPtr eip = entry.atom.lock()->GetEntity(); + entry.atom.lock()->TransformedPos() = eip->GetTransform().Apply(entry.pos); entry.atom.lock()->SetBFactor(j->b_factor); entry.atom.lock()->SetOccupancy(j->occ); } @@ -671,4 +675,25 @@ String ResidueImpl::GetStringProperty(Prop::ID prop_id) const } } +void ResidueImpl::UpdateTransformedPos() +{ + /* + the alt atom positions always store the original pos; hence the below code + is not necessary; however, it isn't clear (at least to me (AP)) if the + AtomImplPtr in the alt group is supposed to be modified here, or if this is + already taken care of in EntityImpl::UpdateTransformedPos() + */ +#if 0 + geom::Transform tf = GetEntity()->GetTransform(); + for(AtomEntryGroups::iterator git=alt_groups_.begin(); git!=alt_groups_.end();++git) { + for(AtomGroupEntryList::iterator lit=git->second.atoms.begin(); lit!=git->second.atoms.end();++lit) { + AtomImplPtr atom=lit->atom.lock().get(); + geom::Vec3 tpos=tf.Apply(atom->OriginalPos()); + atom->TransformedPos()=tpos; + lit->pos=atom->tpos; + } + } +#endif +} + }}} // ns diff --git a/modules/mol/base/src/impl/residue_impl.hh b/modules/mol/base/src/impl/residue_impl.hh index 24f829c6922bdbfdcc0ee8645cbec80e4ff49f88..91b6843e78ab8de6ab7034302aea3708595487a0 100644 --- a/modules/mol/base/src/impl/residue_impl.hh +++ b/modules/mol/base/src/impl/residue_impl.hh @@ -223,6 +223,9 @@ public: bool IsLigand() const { return ligand_; } void SetIsLigand(bool flag) { ligand_=flag; } + + void UpdateTransformedPos(); + private: void AddAltAtom(const String& group, const AtomImplPtr& atom, const geom::Vec3& position, Real occ, Real b_factor); diff --git a/modules/mol/base/src/xcs_editor.cc b/modules/mol/base/src/xcs_editor.cc index 0c2454b187c8d29902b8380e4caf3b7969db3fe5..5596e3962d1479921f2c5b8ae5108d0c92ee9b38 100644 --- a/modules/mol/base/src/xcs_editor.cc +++ b/modules/mol/base/src/xcs_editor.cc @@ -74,14 +74,11 @@ void XCSEditor::SetAtomTransformedPos(const AtomHandle& atom, const geom::Vec3& position) { CheckHandleValidity(atom); + impl::EntityImplPtr eip=ent_.Impl(); atom.Impl()->TransformedPos()=position; - if(ent_.Impl()->IsTransfIdentity()) { - atom.Impl()->OriginalPos()=position; - } else { - atom.Impl()->OriginalPos() = geom::Vec3(ent_.Impl()->GetInvTransfMatrix()*geom::Vec4(position)); - } - ent_.Impl()->MarkICSDirty(); - ent_.Impl()->MarkOrganizerDirty(); + atom.Impl()->OriginalPos() = eip->HasTransform() ? eip->GetTransform().ApplyInverse(position) : position; + eip->MarkICSDirty(); + eip->MarkOrganizerDirty(); this->Update(); } @@ -89,17 +86,14 @@ namespace { template<typename T> void set_transformed_pos(impl::EntityImpl* ent, const AtomHandleList& alist, T *positions) { - bool has_tf=ent->IsTransfIdentity(); + bool has_tf=ent->HasTransform(); for(AtomHandleList::const_iterator ait=alist.begin();ait!=alist.end();++ait) { if(ait->IsValid()) { - ait->Impl()->TransformedPos()[0]=static_cast<Real>(positions[0]); - ait->Impl()->TransformedPos()[1]=static_cast<Real>(positions[1]); - ait->Impl()->TransformedPos()[2]=static_cast<Real>(positions[2]); - if(has_tf) { - ait->Impl()->OriginalPos()=ait->Impl()->TransformedPos(); - } else { - ait->Impl()->OriginalPos() = geom::Vec3(ent->GetInvTransfMatrix()*geom::Vec4(ait->Impl()->TransformedPos())); - } + geom::Vec3& tpos=ait->Impl()->TransformedPos(); + tpos[0]=static_cast<Real>(positions[0]); + tpos[1]=static_cast<Real>(positions[1]); + tpos[2]=static_cast<Real>(positions[2]); + ait->Impl()->OriginalPos()=has_tf ? ent->GetTransform().ApplyInverse(tpos) : tpos; } positions+=3; } @@ -124,14 +118,11 @@ void XCSEditor::SetAtomOriginalPos(const AtomHandle& atom, const geom::Vec3& position) { CheckHandleValidity(atom); + impl::EntityImplPtr eip=ent_.Impl(); atom.Impl()->OriginalPos()=position; - if(ent_.Impl()->IsTransfIdentity()) { - atom.Impl()->TransformedPos()=position; - } else { - atom.Impl()->TransformedPos() = geom::Vec3(ent_.Impl()->GetTransfMatrix()*geom::Vec4(position)); - } - ent_.Impl()->MarkICSDirty(); - ent_.Impl()->MarkOrganizerDirty(); + atom.Impl()->TransformedPos() = eip->HasTransform() ? eip->GetTransform().Apply(position) : position; + eip->MarkICSDirty(); + eip->MarkOrganizerDirty(); this->Update(); } @@ -139,17 +130,14 @@ namespace { template<typename T> void set_original_pos(impl::EntityImpl* ent, const AtomHandleList& alist, T *positions) { - bool has_tf=ent->IsTransfIdentity(); + bool has_tf=ent->HasTransform(); for(AtomHandleList::const_iterator ait=alist.begin();ait!=alist.end();++ait) { if(ait->IsValid()) { - ait->Impl()->OriginalPos()[0]=static_cast<Real>(positions[0]); - ait->Impl()->OriginalPos()[1]=static_cast<Real>(positions[1]); - ait->Impl()->OriginalPos()[2]=static_cast<Real>(positions[2]); - if(has_tf) { - ait->Impl()->TransformedPos()=ait->Impl()->OriginalPos(); - } else { - ait->Impl()->TransformedPos() = geom::Vec3(ent->GetTransfMatrix()*geom::Vec4(ait->Impl()->OriginalPos())); - } + geom::Vec3& opos=ait->Impl()->OriginalPos(); + opos[0]=static_cast<Real>(positions[0]); + opos[1]=static_cast<Real>(positions[1]); + opos[2]=static_cast<Real>(positions[2]); + ait->Impl()->TransformedPos()= has_tf ? ent->GetTransform().Apply(opos) : opos; } positions+=3; } @@ -186,6 +174,13 @@ void XCSEditor::SetAtomPos(const AtomHandleList& alist, double *positions) } void XCSEditor::ApplyTransform(const geom::Mat4& transform) +{ + geom::Transform tf; + tf.SetMatrix(transform); + this->ApplyTransform(tf); +} + +void XCSEditor::ApplyTransform(const geom::Transform& transform) { ent_.Impl()->ApplyTransform(transform); ent_.Impl()->UpdateTransformedPos(); @@ -194,8 +189,14 @@ void XCSEditor::ApplyTransform(const geom::Mat4& transform) this->Update(); } - void XCSEditor::SetTransform(const geom::Mat4& transform) +{ + geom::Transform tf; + tf.SetMatrix(transform); + this->SetTransform(tf); +} + +void XCSEditor::SetTransform(const geom::Transform& transform) { ent_.Impl()->SetTransform(transform); ent_.Impl()->UpdateTransformedPos(); @@ -204,7 +205,6 @@ void XCSEditor::SetTransform(const geom::Mat4& transform) this->Update(); } - void XCSEditor::Update() { if (GetMode()==UNBUFFERED_EDIT) { diff --git a/modules/mol/base/src/xcs_editor.hh b/modules/mol/base/src/xcs_editor.hh index 73d96a652829932c469a6a0382093de7fd53b5f4..a7cc317b2e5273b62211b03a8d04559de97f0fff 100644 --- a/modules/mol/base/src/xcs_editor.hh +++ b/modules/mol/base/src/xcs_editor.hh @@ -98,10 +98,11 @@ public: /// This transformation is applied \em after the transformation /// already stored in the entity void ApplyTransform(const geom::Mat4& transform); + void ApplyTransform(const geom::Transform& transform); /// \brief apply a new transformation to all atoms - void SetTransform(const geom::Mat4& transform); + void SetTransform(const geom::Transform& transform); /// \brief immediately update internal coordinate system void UpdateICS(); diff --git a/modules/mol/base/tests/test_entity.cc b/modules/mol/base/tests/test_entity.cc index d8ecd8f3b9a9007e84549d6b4a20e302a1a5fe67..47ffcbd73c2a32e749ae40b049a59a58178c6c0e 100644 --- a/modules/mol/base/tests/test_entity.cc +++ b/modules/mol/base/tests/test_entity.cc @@ -179,14 +179,12 @@ BOOST_AUTO_TEST_CASE(transformation) BOOST_CHECK(within_list1[0]==atom1); BOOST_CHECK(within_list1[1]==atom2); - BOOST_CHECK(eh.IsTransformationIdentity()==true); + BOOST_CHECK(eh.HasTransform()==false); geom::Transform trans; trans.ApplyZAxisRotation(90.0); - geom::Mat4 mat = trans.GetMatrix(); - - e.ApplyTransform(mat); - BOOST_CHECK(eh.IsTransformationIdentity()==false); + e.ApplyTransform(trans); + BOOST_CHECK(eh.HasTransform()==true); geom::Vec3 orig_atom1=geom::Vec3(1.0,0.0,0.0); geom::Vec3 orig_atom2=geom::Vec3(0.0,2.0,0.0); @@ -205,11 +203,9 @@ BOOST_AUTO_TEST_CASE(transformation) geom::Transform trans2; trans2.ApplyXAxisTranslation(3.5); - geom::Mat4 mat2 = trans2.GetMatrix(); - - e.ApplyTransform(mat2); + e.ApplyTransform(trans2); - BOOST_CHECK(eh.IsTransformationIdentity()==false); + BOOST_CHECK(eh.HasTransform()==true); tr_atom1=geom::Vec3(3.5,-1.0,0.0); tr_atom2=geom::Vec3(5.5,0.0,0.0); @@ -253,7 +249,7 @@ BOOST_AUTO_TEST_CASE(transformation) geom::Mat4 identity; e.SetTransform(identity); - BOOST_CHECK(eh.IsTransformationIdentity()==true); + //BOOST_CHECK(eh.HasTransform()==false); BondHandle bond1 = e.Connect(atom1,atom2); BondHandle bond2 = e.Connect(atom1,atom3); @@ -261,9 +257,9 @@ BOOST_AUTO_TEST_CASE(transformation) BOOST_CHECK(bond1.GetLength()==1.5); BOOST_CHECK(bond2.GetLength()==2.0); - e.SetTransform(mat); - - BOOST_CHECK(eh.IsTransformationIdentity()==false); + e.SetTransform(trans); + + //BOOST_CHECK(eh.HasTransform()==true); BOOST_CHECK(bond1.GetLength()==1.5); BOOST_CHECK(bond2.GetLength()==2.0);