You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
483 lines
14 KiB
C
483 lines
14 KiB
C
3 weeks ago
|
/*=========================================================================
|
||
|
|
||
|
Program: Visualization Toolkit
|
||
|
Module: vtkMolecule.h
|
||
|
|
||
|
Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
|
||
|
All rights reserved.
|
||
|
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
|
||
|
|
||
|
This software is distributed WITHOUT ANY WARRANTY; without even
|
||
|
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||
|
PURPOSE. See the above copyright notice for more information.
|
||
|
|
||
|
=========================================================================*/
|
||
|
/**
|
||
|
* @class vtkMolecule
|
||
|
* @brief class describing a molecule
|
||
|
*
|
||
|
*
|
||
|
*
|
||
|
* vtkMolecule and the convenience classes vtkAtom and vtkBond
|
||
|
* describe the geometry and connectivity of a molecule. The molecule
|
||
|
* can be constructed using the AppendAtom() and AppendBond() methods in one
|
||
|
* of two ways; either by fully specifying the atom/bond in a single
|
||
|
* call, or by incrementally setting the various attributes using the
|
||
|
* convenience vtkAtom and vtkBond classes:
|
||
|
*
|
||
|
* Single call:
|
||
|
* \code
|
||
|
* vtkMolecule *mol = vtkMolecule::New();
|
||
|
* vtkAtom h1 = mol->AppendAtom(1, 0.0, 0.0, -0.5);
|
||
|
* vtkAtom h2 = mol->AppendAtom(1, 0.0, 0.0, 0.5);
|
||
|
* vtkBond b = mol->AppendBond(h1, h2, 1);
|
||
|
* \endcode
|
||
|
*
|
||
|
* Incremental:
|
||
|
* \code
|
||
|
* vtkMolecule *mol = vtkMolecule::New();
|
||
|
*
|
||
|
* vtkAtom h1 = mol->AppendAtom();
|
||
|
* h1.SetAtomicNumber(1);
|
||
|
* h1.SetPosition(0.0, 0.0, -0.5);
|
||
|
*
|
||
|
* vtkAtom h2 = mol->AppendAtom();
|
||
|
* h2.SetAtomicNumber(1);
|
||
|
* vtkVector3d displacement (0.0, 0.0, 1.0);
|
||
|
* h2.SetPosition(h1.GetPositionAsVector3d() + displacement);
|
||
|
*
|
||
|
* vtkBond b = mol->AppendBond(h1, h2, 1);
|
||
|
* \endcode
|
||
|
*
|
||
|
* Both of the above methods will produce the same molecule, two
|
||
|
* hydrogens connected with a 1.0 Angstrom single bond, aligned to the
|
||
|
* z-axis. The second example also demonstrates the use of VTK's
|
||
|
* vtkVector class, which is fully supported by the Chemistry kit.
|
||
|
*
|
||
|
* The vtkMolecule object is intended to be used with the
|
||
|
* vtkMoleculeMapper class for visualizing molecular structure using
|
||
|
* common rendering techniques.
|
||
|
*
|
||
|
* \warning While direct use of the underlying vtkUndirectedGraph
|
||
|
* structure is possible due to vtkMolecule's public inheritance, this
|
||
|
* should not be relied upon and may change in the future.
|
||
|
*
|
||
|
* @sa
|
||
|
* vtkAtom vtkBond vtkMoleculeMapper vtkPeriodicTable
|
||
|
*/
|
||
|
|
||
|
#ifndef vtkMolecule_h
|
||
|
#define vtkMolecule_h
|
||
|
|
||
|
#include "vtkCommonDataModelModule.h" // For export macro
|
||
|
#include "vtkSmartPointer.h" // For vtkSmartPointer
|
||
|
#include "vtkUndirectedGraph.h"
|
||
|
|
||
|
#include "vtkAtom.h" // Simple proxy class dependent on vtkMolecule
|
||
|
#include "vtkBond.h" // Simple proxy class dependent on vtkMolecule
|
||
|
|
||
|
#include "vtkVector.h" // Small templated vector convenience class
|
||
|
|
||
|
class vtkAbstractElectronicData;
|
||
|
class vtkDataArray;
|
||
|
class vtkInformation;
|
||
|
class vtkInformationVector;
|
||
|
class vtkMatrix3x3;
|
||
|
class vtkPlane;
|
||
|
class vtkPoints;
|
||
|
class vtkUnsignedCharArray;
|
||
|
class vtkUnsignedShortArray;
|
||
|
|
||
|
class VTKCOMMONDATAMODEL_EXPORT vtkMolecule : public vtkUndirectedGraph
|
||
|
{
|
||
|
public:
|
||
|
static vtkMolecule* New();
|
||
|
vtkTypeMacro(vtkMolecule, vtkUndirectedGraph);
|
||
|
void PrintSelf(ostream& os, vtkIndent indent) override;
|
||
|
void Initialize() override;
|
||
|
|
||
|
/**
|
||
|
* Return what type of dataset this is.
|
||
|
*/
|
||
|
int GetDataObjectType() override { return VTK_MOLECULE; }
|
||
|
|
||
|
/**
|
||
|
* Add new atom with atomic number 0 (dummy atom) at origin. Return
|
||
|
* a vtkAtom that refers to the new atom.
|
||
|
*/
|
||
|
vtkAtom AppendAtom() { return this->AppendAtom(0, 0., 0., 0.); }
|
||
|
|
||
|
//@{
|
||
|
/**
|
||
|
* Add new atom with the specified atomic number and position. Return a
|
||
|
* vtkAtom that refers to the new atom.
|
||
|
*/
|
||
|
vtkAtom AppendAtom(unsigned short atomicNumber, double x, double y, double z);
|
||
|
vtkAtom AppendAtom(unsigned short atomicNumber, const vtkVector3f& pos)
|
||
|
{
|
||
|
return this->AppendAtom(atomicNumber, pos[0], pos[1], pos[2]);
|
||
|
}
|
||
|
|
||
|
vtkAtom AppendAtom(unsigned short atomicNumber, double pos[3])
|
||
|
{
|
||
|
return this->AppendAtom(atomicNumber, pos[0], pos[1], pos[2]);
|
||
|
}
|
||
|
//@}
|
||
|
|
||
|
/**
|
||
|
* Return a vtkAtom that refers to the atom with the specified id.
|
||
|
*/
|
||
|
vtkAtom GetAtom(vtkIdType atomId);
|
||
|
|
||
|
/**
|
||
|
* Return the number of atoms in the molecule.
|
||
|
*/
|
||
|
vtkIdType GetNumberOfAtoms();
|
||
|
|
||
|
//@{
|
||
|
/**
|
||
|
* Add a bond between the specified atoms, optionally setting the
|
||
|
* bond order (default: 1). Return a vtkBond object referring to the
|
||
|
* new bond.
|
||
|
*/
|
||
|
vtkBond AppendBond(vtkIdType atom1, vtkIdType atom2, unsigned short order = 1);
|
||
|
vtkBond AppendBond(const vtkAtom& atom1, const vtkAtom& atom2, unsigned short order = 1)
|
||
|
{
|
||
|
return this->AppendBond(atom1.Id, atom2.Id, order);
|
||
|
}
|
||
|
//@}
|
||
|
|
||
|
/**
|
||
|
* Return a vtkAtom that refers to the bond with the specified id.
|
||
|
*/
|
||
|
vtkBond GetBond(vtkIdType bondId);
|
||
|
|
||
|
/**
|
||
|
* Return the number of bonds in the molecule.
|
||
|
*/
|
||
|
vtkIdType GetNumberOfBonds();
|
||
|
|
||
|
/**
|
||
|
* Return the atomic number of the atom with the specified id.
|
||
|
*/
|
||
|
unsigned short GetAtomAtomicNumber(vtkIdType atomId);
|
||
|
|
||
|
/**
|
||
|
* Set the atomic number of the atom with the specified id.
|
||
|
*/
|
||
|
void SetAtomAtomicNumber(vtkIdType atomId, unsigned short atomicNum);
|
||
|
|
||
|
//@{
|
||
|
/**
|
||
|
* Set the position of the atom with the specified id.
|
||
|
*/
|
||
|
void SetAtomPosition(vtkIdType atomId, const vtkVector3f& pos);
|
||
|
void SetAtomPosition(vtkIdType atomId, double x, double y, double z);
|
||
|
void SetAtomPosition(vtkIdType atomId, double pos[3])
|
||
|
{
|
||
|
this->SetAtomPosition(atomId, pos[0], pos[1], pos[2]);
|
||
|
}
|
||
|
//@}
|
||
|
|
||
|
//@{
|
||
|
/**
|
||
|
* Get the position of the atom with the specified id.
|
||
|
*/
|
||
|
vtkVector3f GetAtomPosition(vtkIdType atomId);
|
||
|
void GetAtomPosition(vtkIdType atomId, float pos[3]);
|
||
|
void GetAtomPosition(vtkIdType atomId, double pos[3]);
|
||
|
//@}
|
||
|
|
||
|
//@{
|
||
|
/**
|
||
|
* Get/Set the bond order of the bond with the specified id
|
||
|
*/
|
||
|
void SetBondOrder(vtkIdType bondId, unsigned short order);
|
||
|
unsigned short GetBondOrder(vtkIdType bondId);
|
||
|
//@}
|
||
|
|
||
|
/**
|
||
|
* Get the bond length of the bond with the specified id
|
||
|
|
||
|
* \note If the associated vtkBond object is already available,
|
||
|
* vtkBond::GetBondLength is potentially much faster than this
|
||
|
* function, as a list of all bonds may need to be constructed to
|
||
|
* locate the appropriate bond.
|
||
|
* \sa UpdateBondList()
|
||
|
*/
|
||
|
double GetBondLength(vtkIdType bondId);
|
||
|
|
||
|
//@{
|
||
|
/**
|
||
|
* Access the raw arrays used in this vtkMolecule instance
|
||
|
*/
|
||
|
vtkPoints* GetAtomicPositionArray();
|
||
|
vtkUnsignedShortArray* GetAtomicNumberArray();
|
||
|
vtkUnsignedShortArray* GetBondOrdersArray();
|
||
|
//@}
|
||
|
|
||
|
//@{
|
||
|
/**
|
||
|
* Set/Get the AbstractElectronicData-subclassed object for this molecule.
|
||
|
*/
|
||
|
vtkGetObjectMacro(ElectronicData, vtkAbstractElectronicData);
|
||
|
virtual void SetElectronicData(vtkAbstractElectronicData*);
|
||
|
//@}
|
||
|
|
||
|
/**
|
||
|
* Performs the same operation as ShallowCopy(),
|
||
|
* but instead of reporting an error for an incompatible graph,
|
||
|
* returns false.
|
||
|
*/
|
||
|
bool CheckedShallowCopy(vtkGraph* g) override;
|
||
|
|
||
|
/**
|
||
|
* Performs the same operation as DeepCopy(),
|
||
|
* but instead of reporting an error for an incompatible graph,
|
||
|
* returns false.
|
||
|
*/
|
||
|
bool CheckedDeepCopy(vtkGraph* g) override;
|
||
|
|
||
|
/**
|
||
|
* Shallow copies the data object into this molecule.
|
||
|
*/
|
||
|
void ShallowCopy(vtkDataObject* obj) override;
|
||
|
|
||
|
/**
|
||
|
* Deep copies the data object into this molecule.
|
||
|
*/
|
||
|
void DeepCopy(vtkDataObject* obj) override;
|
||
|
|
||
|
/**
|
||
|
* Shallow copies the atoms and bonds from @a m into @a this.
|
||
|
*/
|
||
|
virtual void ShallowCopyStructure(vtkMolecule* m);
|
||
|
|
||
|
/**
|
||
|
* Deep copies the atoms and bonds from @a m into @a this.
|
||
|
*/
|
||
|
virtual void DeepCopyStructure(vtkMolecule* m);
|
||
|
|
||
|
/**
|
||
|
* Shallow copies attributes (i.e. everything besides atoms and bonds) from
|
||
|
* @a m into @a this.
|
||
|
*/
|
||
|
virtual void ShallowCopyAttributes(vtkMolecule* m);
|
||
|
|
||
|
/**
|
||
|
* Deep copies attributes (i.e. everything besides atoms and bonds) from
|
||
|
* @a m into @a this.
|
||
|
*/
|
||
|
virtual void DeepCopyAttributes(vtkMolecule* m);
|
||
|
|
||
|
//@{
|
||
|
/**
|
||
|
* Obtain the plane that passes through the indicated bond with the given
|
||
|
* normal. If the plane is set successfully, the function returns true.
|
||
|
|
||
|
* If the normal is not orthogonal to the bond, a new normal will be
|
||
|
* constructed in such a way that the plane will be orthogonal to
|
||
|
* the plane spanned by the bond vector and the input normal vector.
|
||
|
|
||
|
* This ensures that the plane passes through the bond, and the
|
||
|
* normal is more of a "hint" indicating the orientation of the plane.
|
||
|
|
||
|
* The new normal (n) is defined as the input normal vector (n_i) minus
|
||
|
* the projection of itself (proj[n_i]_v) onto the bond vector (v):
|
||
|
|
||
|
* @verbatim
|
||
|
* v ^
|
||
|
* | n = (n_i - proj[n_j]_v)
|
||
|
* proj[n_i]_v ^ |----x
|
||
|
* | | /
|
||
|
* | | / n_i
|
||
|
* | | /
|
||
|
* | |/
|
||
|
* @endverbatim
|
||
|
|
||
|
* If n_i is parallel to v, a warning will be printed and no plane will be
|
||
|
* added. Obviously, n_i must not be parallel to v.
|
||
|
*/
|
||
|
static bool GetPlaneFromBond(const vtkBond& bond, const vtkVector3f& normal, vtkPlane* plane);
|
||
|
static bool GetPlaneFromBond(
|
||
|
const vtkAtom& atom1, const vtkAtom& atom2, const vtkVector3f& normal, vtkPlane* plane);
|
||
|
//@}
|
||
|
|
||
|
/**
|
||
|
* Return true if a unit cell lattice is defined.
|
||
|
*/
|
||
|
bool HasLattice();
|
||
|
|
||
|
/**
|
||
|
* Remove any unit cell lattice information from the molecule.
|
||
|
*/
|
||
|
void ClearLattice();
|
||
|
|
||
|
//@{
|
||
|
/**
|
||
|
* The unit cell vectors. The matrix is stored using a row-major layout, with
|
||
|
* the vectors encoded as columns.
|
||
|
*/
|
||
|
void SetLattice(vtkMatrix3x3* matrix);
|
||
|
void SetLattice(const vtkVector3d& a, const vtkVector3d& b, const vtkVector3d& c);
|
||
|
//@}
|
||
|
|
||
|
/**
|
||
|
* Get the unit cell lattice vectors. The matrix is stored using a row-major
|
||
|
* layout, with the vectors encoded as columns. Will return nullptr if no
|
||
|
* unit cell information is available.
|
||
|
* @sa GetLatticeOrigin
|
||
|
*/
|
||
|
vtkMatrix3x3* GetLattice();
|
||
|
|
||
|
//@{
|
||
|
/**
|
||
|
* Get the unit cell lattice vectors, and optionally, the origin.
|
||
|
*/
|
||
|
void GetLattice(vtkVector3d& a, vtkVector3d& b, vtkVector3d& c);
|
||
|
void GetLattice(vtkVector3d& a, vtkVector3d& b, vtkVector3d& c, vtkVector3d& origin);
|
||
|
//@}
|
||
|
|
||
|
//@{
|
||
|
/**
|
||
|
* Get the unit cell origin (for rendering purposes).
|
||
|
*/
|
||
|
vtkGetMacro(LatticeOrigin, vtkVector3d);
|
||
|
vtkSetMacro(LatticeOrigin, vtkVector3d);
|
||
|
//@}
|
||
|
|
||
|
/**
|
||
|
* Get the array that defines the ghost type of each atom.
|
||
|
*/
|
||
|
vtkUnsignedCharArray* GetAtomGhostArray();
|
||
|
|
||
|
/**
|
||
|
* Allocate ghost array for atoms.
|
||
|
*/
|
||
|
void AllocateAtomGhostArray();
|
||
|
|
||
|
/**
|
||
|
* Get the array that defines the ghost type of each bond.
|
||
|
*/
|
||
|
vtkUnsignedCharArray* GetBondGhostArray();
|
||
|
|
||
|
/**
|
||
|
* Allocate ghost array for bonds.
|
||
|
*/
|
||
|
void AllocateBondGhostArray();
|
||
|
|
||
|
/**
|
||
|
* Initialize a molecule with an atom per input point.
|
||
|
* Parameters atomPositions and atomicNumberArray should have the same size.
|
||
|
*/
|
||
|
int Initialize(
|
||
|
vtkPoints* atomPositions, vtkDataArray* atomicNumberArray, vtkDataSetAttributes* atomData);
|
||
|
|
||
|
/**
|
||
|
* Overloads Initialize method.
|
||
|
*/
|
||
|
int Initialize(vtkPoints* atomPositions, vtkDataSetAttributes* atomData)
|
||
|
{
|
||
|
return this->Initialize(atomPositions, nullptr, atomData);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Use input molecule points, atomic number and atomic data to initialize the new molecule.
|
||
|
*/
|
||
|
int Initialize(vtkMolecule* molecule);
|
||
|
|
||
|
//@{
|
||
|
/**
|
||
|
* Retrieve a molecule from an information vector.
|
||
|
*/
|
||
|
static vtkMolecule* GetData(vtkInformation* info);
|
||
|
static vtkMolecule* GetData(vtkInformationVector* v, int i = 0);
|
||
|
//@}
|
||
|
|
||
|
/**
|
||
|
* Return the VertexData of the underlying graph
|
||
|
*/
|
||
|
vtkDataSetAttributes* GetAtomData() { return this->GetVertexData(); }
|
||
|
|
||
|
/**
|
||
|
* Return the EdgeData of the underlying graph
|
||
|
*/
|
||
|
vtkDataSetAttributes* GetBondData() { return this->GetEdgeData(); }
|
||
|
|
||
|
/**
|
||
|
* Return the edge id from the underlying graph.
|
||
|
*/
|
||
|
vtkIdType GetBondId(vtkIdType a, vtkIdType b) { return this->GetEdgeId(a, b); }
|
||
|
|
||
|
//@{
|
||
|
/**
|
||
|
* Get/Set the atomic number array name.
|
||
|
*/
|
||
|
vtkSetStringMacro(AtomicNumberArrayName);
|
||
|
vtkGetStringMacro(AtomicNumberArrayName);
|
||
|
//@}
|
||
|
|
||
|
//@{
|
||
|
/**
|
||
|
* Get/Set the bond orders array name.
|
||
|
*/
|
||
|
vtkSetStringMacro(BondOrdersArrayName);
|
||
|
vtkGetStringMacro(BondOrdersArrayName);
|
||
|
//@}
|
||
|
|
||
|
/**
|
||
|
* Return the actual size of the data in kibibytes (1024 bytes). This number
|
||
|
* is valid only after the pipeline has updated. The memory size
|
||
|
* returned is guaranteed to be greater than or equal to the
|
||
|
* memory required to represent the data (e.g., extra space in
|
||
|
* arrays, etc. are not included in the return value).
|
||
|
*/
|
||
|
unsigned long GetActualMemorySize() override;
|
||
|
|
||
|
protected:
|
||
|
vtkMolecule();
|
||
|
~vtkMolecule() override;
|
||
|
|
||
|
/**
|
||
|
* Copy bonds and atoms.
|
||
|
*/
|
||
|
virtual void CopyStructureInternal(vtkMolecule* m, bool deep);
|
||
|
|
||
|
/**
|
||
|
* Copy everything but bonds and atoms.
|
||
|
*/
|
||
|
virtual void CopyAttributesInternal(vtkMolecule* m, bool deep);
|
||
|
|
||
|
//@{
|
||
|
/**
|
||
|
* The graph superclass does not provide fast random access to the
|
||
|
* edge (bond) data. All random access is performed using a lookup
|
||
|
* table that must be rebuilt periodically. These allow for lazy
|
||
|
* building of the lookup table
|
||
|
*/
|
||
|
bool BondListIsDirty;
|
||
|
void SetBondListDirty() { this->BondListIsDirty = true; }
|
||
|
void UpdateBondList();
|
||
|
vtkIdTypeArray* GetBondList();
|
||
|
//@}
|
||
|
|
||
|
friend class vtkAtom;
|
||
|
friend class vtkBond;
|
||
|
|
||
|
vtkAbstractElectronicData* ElectronicData;
|
||
|
vtkSmartPointer<vtkMatrix3x3> Lattice;
|
||
|
vtkVector3d LatticeOrigin;
|
||
|
|
||
|
vtkUnsignedCharArray* AtomGhostArray;
|
||
|
vtkUnsignedCharArray* BondGhostArray;
|
||
|
|
||
|
char* AtomicNumberArrayName;
|
||
|
char* BondOrdersArrayName;
|
||
|
|
||
|
private:
|
||
|
vtkMolecule(const vtkMolecule&) = delete;
|
||
|
void operator=(const vtkMolecule&) = delete;
|
||
|
};
|
||
|
|
||
|
#endif
|