1 #pragma once 2 3 #include <cstddef> 4 #include <vector> 5 6 struct AtomInfoType; 7 struct ObjectMolecule; 8 9 /* 10 * Ring finder subroutine 11 */ 12 class AbstractRingFinder 13 { 14 ObjectMolecule* m_obj = nullptr; 15 std::vector<int> m_indices; 16 17 void recursion(int atm, int depth); 18 19 protected: 20 AbstractRingFinder() = delete; AbstractRingFinder(unsigned maxringsize)21 AbstractRingFinder(unsigned maxringsize) 22 : m_indices(maxringsize) 23 { 24 } 25 26 /** 27 * Optional object preparation. Note that `ObjectMoleculeUpdateNeighbors` is 28 * always called. 29 */ prepareObject(ObjectMolecule * obj)30 virtual void prepareObject(ObjectMolecule* obj) {} 31 32 /** 33 * Optional atom filter. 34 * @return True to exclude an atom, false to include it. 35 */ atomIsExcluded(const AtomInfoType &)36 virtual bool atomIsExcluded(const AtomInfoType&) const { return false; } 37 38 /** 39 * Is called when a ring is found. 40 * 41 * @param obj Molecule object 42 * @param indices Ring atom indices 43 * @param size Ring size 44 */ 45 virtual void onRingFound( 46 ObjectMolecule* obj, const int* indices, size_t size) = 0; 47 48 public: 49 /* 50 * Does a depth-first search for all paths of length in 51 * range [3, maxringsize], which lead back to `atm` and 52 * don't visit any atom twice. 53 */ 54 void apply(ObjectMolecule* obj, int atm); 55 }; 56