Example #1
0
  void NeighborList::initOneTwo()
  {
    unsigned int numAtoms = m_atoms.size();
    if (!numAtoms)
      return;

    m_oneTwo.resize(m_atoms.size());
    m_oneThree.resize(m_atoms.size());

    if (m_atoms.isEmpty())
      return;

    Molecule *molecule = m_atoms.first()->molecule();
    if (!molecule) {
      qDebug() << "Error, null molecule returned in NeighborList::initOneTwo()";
      return;
    }

    foreach (Atom *atom, m_atoms) {
      foreach (unsigned long id1, atom->neighbors()) {
        Atom *nbr1 = molecule->atomById(id1);
        m_oneTwo[atom->index()].push_back(nbr1->index());
        m_oneTwo[nbr1->index()].push_back(atom->index());

        foreach (unsigned long id2, nbr1->neighbors()) {
          Atom *nbr2 = molecule->atomById(id2);
          if (atom->index() == nbr2->index())
            continue;

          m_oneThree[atom->index()].push_back(nbr2->index());
          m_oneThree[nbr2->index()].push_back(atom->index());
        }
      }
    }
Example #2
0
  bool RingEngine::renderRing(const QList<unsigned long> &ring, PainterDevice *pd)
  {
    // We need to get rid of the constness in order to get the atoms
    Molecule *mol = const_cast<Molecule *>(pd->molecule());

    // Calculate an appropriate normal and use it for all the triangles in the
    // ring - this will give consistent lighting.
    Eigen::Vector3d v1, v2, norm;
    v1 = *mol->atomById(ring[1])->pos() - *mol->atomById(ring[0])->pos();
    v2 = *mol->atomById(ring[2])->pos() - *mol->atomById(ring[1])->pos();
    norm = v1.cross(v2);
    if (norm.dot(pd->camera()->backTransformedZAxis()) > 0) norm *= -1;

    // Disable face culling for ring structures.
    glDisable(GL_CULL_FACE);

    // Optimize for smaller ring structures
    switch (ring.size()) {
      case 3:
        // Single triangle - easy
        pd->painter()->setColor(ringColors[0][0], ringColors[0][1],
                                ringColors[0][2], m_alpha);
        pd->painter()->drawTriangle(*mol->atomById(ring[0])->pos(),
                                    *mol->atomById(ring[1])->pos(),
                                    *mol->atomById(ring[2])->pos(),
                                    norm);
        break;
      case 4:
        // Two triangles
        pd->painter()->setColor(ringColors[1][0], ringColors[1][1],
                                ringColors[1][2], m_alpha);
        pd->painter()->drawTriangle(*mol->atomById(ring[0])->pos(),
                                    *mol->atomById(ring[1])->pos(),
                                    *mol->atomById(ring[2])->pos(),
                                    norm);
        pd->painter()->drawTriangle(*mol->atomById(ring[0])->pos(),
                                    *mol->atomById(ring[2])->pos(),
                                    *mol->atomById(ring[3])->pos(),
                                    norm);
        break;
      case 5:
        // Three triangles
        pd->painter()->setColor(ringColors[2][0], ringColors[2][1],
                                ringColors[2][2], m_alpha);
        pd->painter()->drawTriangle(*mol->atomById(ring[0])->pos(),
                                    *mol->atomById(ring[1])->pos(),
                                    *mol->atomById(ring[2])->pos(),
                                    norm);
        pd->painter()->drawTriangle(*mol->atomById(ring[0])->pos(),
                                    *mol->atomById(ring[2])->pos(),
                                    *mol->atomById(ring[3])->pos(),
                                    norm);
        pd->painter()->drawTriangle(*mol->atomById(ring[0])->pos(),
                                    *mol->atomById(ring[3])->pos(),
                                    *mol->atomById(ring[4])->pos(),
                                    norm);
        break;
      case 6:
        // Four triangles
        pd->painter()->setColor(ringColors[3][0], ringColors[3][1],
                                ringColors[3][2], m_alpha);
        pd->painter()->drawTriangle(*mol->atomById(ring[0])->pos(),
                                    *mol->atomById(ring[1])->pos(),
                                    *mol->atomById(ring[2])->pos(),
                                    norm);
        pd->painter()->drawTriangle(*mol->atomById(ring[2])->pos(),
                                    *mol->atomById(ring[3])->pos(),
                                    *mol->atomById(ring[4])->pos(),
                                    norm);
        pd->painter()->drawTriangle(*mol->atomById(ring[4])->pos(),
                                    *mol->atomById(ring[5])->pos(),
                                    *mol->atomById(ring[0])->pos(),
                                    norm);
        pd->painter()->drawTriangle(*mol->atomById(ring[0])->pos(),
                                    *mol->atomById(ring[2])->pos(),
                                    *mol->atomById(ring[4])->pos(),
                                    norm);
        break;
      default:
        // The generic case - find the centre of the ring and draw a triangle fan
        pd->painter()->setColor(ringColors[4][0], ringColors[4][1],
                                ringColors[4][2], m_alpha);
        Vector3d center;
        for (int i = 0; i < ring.size(); i++)
          center += *mol->atomById(ring[i])->pos();
        center /= ring.size();
        for (int i = 0; i < ring.size()-1; i++)
          pd->painter()->drawTriangle(center,
                                      *mol->atomById(ring[i])->pos(),
                                      *mol->atomById(ring[i+1])->pos(),
                                      norm);
        pd->painter()->drawTriangle(center,
                                    *mol->atomById(ring[ring.size()-1])->pos(),
                                    *mol->atomById(ring[0])->pos(),
                                    norm);

    }
    return true;
  }