|
AvogadroLibs 2.1.0-20261111
|
Find the part of a molecule that one end of an internal coordinate can move independently of the rest, and move it. More...
#include <avogadro/qtgui/fragmenttools.h>
Public Types | |
| enum class | CoordinateEditResult { Ok , InvalidAtoms , InvalidValue , Ring , NotRigid , Degenerate } |
Static Public Member Functions | |
| static Core::Array< Index > | fragmentUniqueIds (RWMolecule &molecule, const RWBond &bond, const RWAtom &startAtom) |
| static Core::Array< Index > | fragmentUniqueIds (RWMolecule &molecule, Index anchorAtom, Index movingAtom) |
| static void | transformAtoms (RWMolecule &molecule, const Core::Array< Index > &uniqueIds, const Eigen::Affine3d &transform) |
| static void | transformAtoms (RWMolecule &molecule, const Core::Array< Index > &uniqueIds, const Eigen::Affine3d &transform, const QString &undoText) |
| static bool | setDistance (RWMolecule &molecule, Index atom, Index a, Real length) |
| static bool | setAngle (RWMolecule &molecule, Index atom, Index a, Index b, Real degrees) |
| static bool | setTorsion (RWMolecule &molecule, Index atom, Index a, Index b, Index c, Real degrees) |
| static bool | setDistance (RWMolecule &molecule, Index atom, Index a, Real length, const Core::Array< Index > &fragment) |
| static bool | setAngle (RWMolecule &molecule, Index atom, Index a, Index b, Real degrees, const Core::Array< Index > &fragment) |
| static bool | setTorsion (RWMolecule &molecule, Index atom, Index a, Index b, Index c, Real degrees, const Core::Array< Index > &fragment) |
| static CoordinateEditResult | setChainDistance (RWMolecule &molecule, const std::array< Index, 2 > &uniqueIds, Real length) |
| static CoordinateEditResult | setChainAngle (RWMolecule &molecule, const std::array< Index, 3 > &uniqueIds, Real degrees) |
| static CoordinateEditResult | setChainTorsion (RWMolecule &molecule, const std::array< Index, 4 > &uniqueIds, Real degrees) |
Static Public Attributes | |
| static constexpr Real | minimumChainDistance = 0.5 |
| static constexpr Real | maximumChainDistance = 1000.0 |
Editing a bond length, angle or torsion means moving everything on one side of it and leaving the other side alone, so that the rest of the molecule – and where the molecule sits in the view – stays put. These collect that side and apply a transform to it.
Atoms are named by unique id rather than index, so a fragment stays valid across the edits made while moving it.
|
strong |
The outcome of a chain edit (setChainDistance(), setChainAngle(), setChainTorsion()).
Ok is the only outcome that changed anything. The others each name a distinct reason the edit could not be carried out, so a caller such as the Measure tool can explain the refusal rather than just reporting failure:
|
static |
The atoms that move with startAtom when bond is manipulated, as unique ids, including startAtom itself.
For an ordinary bond that is everything on startAtom's side of it. When bond lies in a ring there is no such side, since every ring atom is reachable from both ends without crossing the bond; the ring itself then stays rigid, but whatever hangs off startAtom and is held by nothing else – its hydrogens and other substituents – still comes along.
| molecule | The molecule to walk. |
| bond | The bond whose two sides are being separated. |
| startAtom | The end of bond whose side is wanted. |
|
static |
The atoms that move when movingAtom is moved relative to anchorAtom, as unique ids.
An internal coordinate may be measured against any two atoms, not only bonded ones, so this covers three cases:
movingAtom's side of that bond.anchorAtom's side holding movingAtom in place, so the whole of movingAtom's molecule is the fragment. This is what lets editing one atom of a water dimer's second molecule move that whole molecule rigidly.movingAtom itself moves.
|
static |
Apply transform to every atom named in uniqueIds.
The moves are pushed individually, so a caller that wants them to undo as one step is responsible for the surrounding merge scope. Use this from a caller that already holds one – an interactive drag, say, whose whole gesture should undo at once.
|
static |
Apply transform to every atom named in uniqueIds, as a single undo command titled undoText.
|
static |
Set one internal coordinate, moving atom and the fragment attached to it and leaving everything else – including where the molecule sits in the view – alone.
The arguments are in the order a z-matrix row names them, and it is the first atom, the one the row places, that moves.
|
static |
Set one internal coordinate, moving atom and the fragment attached to it and leaving everything else – including where the molecule sits in the view – alone.
The arguments are in the order a z-matrix row names them, and it is the first atom, the one the row places, that moves.
|
static |
Set one internal coordinate, moving atom and the fragment attached to it and leaving everything else – including where the molecule sits in the view – alone.
The arguments are in the order a z-matrix row names them, and it is the first atom, the one the row places, that moves.
|
static |
Set one internal coordinate, moving exactly fragment.
The geometry these reach is the same as the overloads above – the same distance, angle or torsion, measured the same way round – but the caller says what moves to get there. Which part of the molecule should move is a question about the edit, not about the coordinate: placing a z-matrix row moves only the atom that row places, while twisting a torsion in a table rotates the whole side of the central bond so the geometry around it stays rigid.
Pass a fragment from fragmentUniqueIds().
fragment does not contain the atom actually named to move – the ring case above, where a bond has no side of its own. It also refuses if fragment contains a reference atom the transform would move regardless of the fragment: a for setDistance() (a translation moves everything given to it), b for setAngle() (the rotation only leaves the pivot a fixed) and c for setTorsion() (the rotation only leaves the a-b axis fixed). The pivot and axis atoms themselves may be in fragment – the property table's angle fragment always contains the vertex – only the other reference atom may not. Without this a fragment that happens to carry its own reference point along would turn the edit into a silent no-op.
|
static |
Set one internal coordinate, moving exactly fragment.
The geometry these reach is the same as the overloads above – the same distance, angle or torsion, measured the same way round – but the caller says what moves to get there. Which part of the molecule should move is a question about the edit, not about the coordinate: placing a z-matrix row moves only the atom that row places, while twisting a torsion in a table rotates the whole side of the central bond so the geometry around it stays rigid.
Pass a fragment from fragmentUniqueIds().
fragment does not contain the atom actually named to move – the ring case above, where a bond has no side of its own. It also refuses if fragment contains a reference atom the transform would move regardless of the fragment: a for setDistance() (a translation moves everything given to it), b for setAngle() (the rotation only leaves the pivot a fixed) and c for setTorsion() (the rotation only leaves the a-b axis fixed). The pivot and axis atoms themselves may be in fragment – the property table's angle fragment always contains the vertex – only the other reference atom may not. Without this a fragment that happens to carry its own reference point along would turn the edit into a silent no-op.
|
static |
Set one internal coordinate, moving exactly fragment.
The geometry these reach is the same as the overloads above – the same distance, angle or torsion, measured the same way round – but the caller says what moves to get there. Which part of the molecule should move is a question about the edit, not about the coordinate: placing a z-matrix row moves only the atom that row places, while twisting a torsion in a table rotates the whole side of the central bond so the geometry around it stays rigid.
Pass a fragment from fragmentUniqueIds().
fragment does not contain the atom actually named to move – the ring case above, where a bond has no side of its own. It also refuses if fragment contains a reference atom the transform would move regardless of the fragment: a for setDistance() (a translation moves everything given to it), b for setAngle() (the rotation only leaves the pivot a fixed) and c for setTorsion() (the rotation only leaves the a-b axis fixed). The pivot and axis atoms themselves may be in fragment – the property table's angle fragment always contains the vertex – only the other reference atom may not. Without this a fragment that happens to carry its own reference point along would turn the edit into a silent no-op.
|
static |
Set one internal coordinate along a click-ordered chain of atoms, named by unique id: the first atom is fixed and the last one moves, matching how the Measure tool collects its atoms.
Unlike the fragment-free overloads above – which always move only the first-named atom, the z-matrix convention – these choose a moving fragment the way the property tables do: as much of the molecule as can rotate or translate rigidly with the moving end. Preference order, from the design notes:
setChainDistance() only accepts a finite length from minimumChainDistance to maximumChainDistance inclusive; anything else returns InvalidValue and leaves the molecule untouched. setChainAngle() likewise returns InvalidValue, before anything else, for an angle outside 0 to 180 degrees, and for one that would fold the moving end atom to within minimumChainDistance of the fixed end atom while bringing them closer. Only that pair is checked, not the whole moving fragment against the rest of the molecule. Torsions wrap, so have no range.
|
static |
Set one internal coordinate along a click-ordered chain of atoms, named by unique id: the first atom is fixed and the last one moves, matching how the Measure tool collects its atoms.
Unlike the fragment-free overloads above – which always move only the first-named atom, the z-matrix convention – these choose a moving fragment the way the property tables do: as much of the molecule as can rotate or translate rigidly with the moving end. Preference order, from the design notes:
setChainDistance() only accepts a finite length from minimumChainDistance to maximumChainDistance inclusive; anything else returns InvalidValue and leaves the molecule untouched. setChainAngle() likewise returns InvalidValue, before anything else, for an angle outside 0 to 180 degrees, and for one that would fold the moving end atom to within minimumChainDistance of the fixed end atom while bringing them closer. Only that pair is checked, not the whole moving fragment against the rest of the molecule. Torsions wrap, so have no range.
|
static |
Set one internal coordinate along a click-ordered chain of atoms, named by unique id: the first atom is fixed and the last one moves, matching how the Measure tool collects its atoms.
Unlike the fragment-free overloads above – which always move only the first-named atom, the z-matrix convention – these choose a moving fragment the way the property tables do: as much of the molecule as can rotate or translate rigidly with the moving end. Preference order, from the design notes:
setChainDistance() only accepts a finite length from minimumChainDistance to maximumChainDistance inclusive; anything else returns InvalidValue and leaves the molecule untouched. setChainAngle() likewise returns InvalidValue, before anything else, for an angle outside 0 to 180 degrees, and for one that would fold the moving end atom to within minimumChainDistance of the fixed end atom while bringing them closer. Only that pair is checked, not the whole moving fragment against the rest of the molecule. Torsions wrap, so have no range.
|
staticconstexpr |
The shortest distance, in Angstroms, that setDistance() and setChainDistance() will set. A little shorter than an H-H bond; anything below it stacks atoms on top of each other.
|
staticconstexpr |
The longest distance, in Angstroms, that setDistance() and setChainDistance() will set. Large enough for any supercell edge, small enough that a typo cannot fling atoms out to where the coordinates overflow.