From 83e22825235c583b8ecc98379771929c5060d587 Mon Sep 17 00:00:00 2001 From: Peter Spackman Date: Tue, 10 Sep 2024 09:14:38 +0800 Subject: [PATCH] Initial selection of aggregate objects --- src/crystal/crystalstructure.cpp | 38 +++------------------- src/graphics/chemicalstructurerenderer.cpp | 8 ++++- src/graphics/chemicalstructurerenderer.h | 7 ++++ src/graphics/frameworkrenderer.cpp | 2 +- src/graphics/renderselection.h | 1 + src/graphics/scene.cpp | 34 +++++++++++++++++-- 6 files changed, 52 insertions(+), 38 deletions(-) diff --git a/src/crystal/crystalstructure.cpp b/src/crystal/crystalstructure.cpp index f1cf8c8..1cc20d6 100644 --- a/src/crystal/crystalstructure.cpp +++ b/src/crystal/crystalstructure.cpp @@ -270,7 +270,6 @@ void CrystalStructure::setOccCrystal(const OccCrystal &crystal) { m_unitCellAtomFragments.clear(); for (const auto &mol : m_crystal.unit_cell_molecules()) { FragmentIndex idx{mol.unit_cell_molecule_idx(), 0, 0, 0}; - qDebug() << "Unit cell mol: " << idx; auto frag = makeFragmentFromOccMolecule(mol); frag.asymmetricFragmentIndex = @@ -281,16 +280,12 @@ void CrystalStructure::setOccCrystal(const OccCrystal &crystal) { getTransformation(asymFrag.atomIndices, frag.atomIndices, frag.asymmetricFragmentTransform); m_unitCellFragments.insert({idx, frag}); - qDebug() << "Inserting unit cell fragment:" << frag.index; for (const auto &atomIndex : frag.atomIndices) { - qDebug() << "AtomIndex: " << atomIndex; FragmentIndex thisIndex = idx; thisIndex.h = -atomIndex.x; thisIndex.k = -atomIndex.y; thisIndex.l = -atomIndex.z; m_unitCellAtomFragments[atomIndex.unique] = thisIndex; - qDebug() << "Fragment for unit cell index" << atomIndex.unique - << thisIndex; } } @@ -598,10 +593,6 @@ void CrystalStructure::completeFragmentContaining(GenericAtomIndex index) { const Fragment frag = makeFragmentFromFragmentIndex(fragmentIndex); - for (const auto &idx : frag.atomIndices) { - qDebug() << idx; - } - addAtomsByCrystalIndex(frag.atomIndices, AtomFlag::NoFlag); if (haveContactAtoms) { @@ -877,11 +868,7 @@ void CrystalStructure::buildSlab(SlabGenerationOptions options) { center[1] >= lower.k && center[1] < upper.k + 1 && center[2] >= lower.l && center[2] < upper.l + 1) { - qDebug() << "Center in bounds:" << center[0] << center[1] - << center[2]; FragmentIndex unitCellIndex{i, 0, 0, 0}; - qDebug() << "FragmentIndex:" << unitCellIndex.u << unitCellIndex.h - << unitCellIndex.k << unitCellIndex.l; const auto &ucFrag = m_unitCellFragments.at(unitCellIndex); for (auto &atomIndex : ucFrag.atomIndices) { @@ -895,7 +882,6 @@ void CrystalStructure::buildSlab(SlabGenerationOptions options) { } } - qDebug() << "Total indices added:" << indices.size(); }; const auto &uc_mols = m_crystal.unit_cell_molecules(); @@ -1167,7 +1153,7 @@ CrystalStructure::findUnitCellFragment(const Fragment &frag) const { return offset; } } - qDebug() << "No Matching unit cell fragment!"; + qWarning() << "No Matching unit cell fragment!"; return FragmentIndex{-1, 0, 0, 0}; } @@ -1260,7 +1246,7 @@ CrystalStructure::getAtomIndicesUnderTransformation( if (closestAtomIndex != -1) { if (minDistance > 1e-3) - qDebug() << "Match has large distance: " << closestAtomIndex + qWarning() << "Match has large distance: " << closestAtomIndex << minDistance; result.emplace_back(GenericAtomIndex{static_cast(closestAtomIndex), cellOffset(0), cellOffset(1), @@ -1299,7 +1285,6 @@ void CrystalStructure::setPairInteractionsFromDimerAtoms( std::vector idxsToAdd(idxs.begin(), idxs.end()); - qDebug() << "Adding" << idxsToAdd.size() << "atoms"; addAtomsByCrystalIndex(idxsToAdd); updateBondGraph(); @@ -1328,19 +1313,13 @@ void CrystalStructure::setPairInteractionsFromDimerAtoms( const Fragment uFragA = makeFragmentFromFragmentIndex(uniquePairIndex.a); const Fragment uFragB = makeFragmentFromFragmentIndex(uniquePairIndex.b); FragmentDimer ud(uFragA, uFragB); - qDebug() << "Fragment dimer" << d.index; - qDebug() << "Unique dimer" << ud.index << ud.nearestAtomDistance; if (added.find(unique) != added.end()) { - qDebug() << "Should only import unique dimers:" + qWarning() << "Should only import unique dimers:" << FragmentIndexPair::fromDimerIndex(unique); continue; } - for (const auto &related : dimerMap.symmetry_related_dimers(idx)) { - qDebug() << "Related:" << FragmentIndexPair::fromDimerIndex(related); - } - added.insert(unique); pair_energy::Parameters params; @@ -1453,6 +1432,7 @@ CrystalStructure::atomicDisplacementParameters(GenericAtomIndex idx) const { } void CrystalStructure::buildDimerMappingTable(double maxRadius) { + // TODO extend dimer calculationg on the fly when people have dimers with higher than current max radius m_unitCellDimers = m_crystal.unit_cell_dimers(maxRadius); qDebug() << "Building dimer mapping table"; qDebug() << "Unit cell molecules" << m_unitCellFragments.size(); @@ -1512,12 +1492,6 @@ CrystalStructure::findFragmentPairs(FragmentPairSettings settings) const { DimerIndex canonicalIndex = dimerTable.canonical_dimer_index(dimerIndex); DimerIndex symmetryUniqueDimer = dimerTable.symmetry_unique_dimer(canonicalIndex); - qDebug() << "distance" << d.centroidDistance; - qDebug() << "Dimer" << FragmentIndexPair::fromDimerIndex(dimerIndex); - qDebug() << "Canonical" - << FragmentIndexPair::fromDimerIndex(canonicalIndex); - qDebug() << "symmetryUnique" - << FragmentIndexPair::fromDimerIndex(symmetryUniqueDimer); symmetryUniqueMap.insert({dimerIndex, symmetryUniqueDimer}); symmetryUniquePairs.insert(symmetryUniqueDimer); @@ -1531,10 +1505,6 @@ CrystalStructure::findFragmentPairs(FragmentPairSettings settings) const { auto a = makeFragmentFromFragmentIndex(ab.a); auto b = makeFragmentFromFragmentIndex(ab.b); FragmentDimer d(a, b); - qDebug() << "UNIQUE" << d.index << d.nearestAtomDistance - << d.centroidDistance; - qDebug() << "a" << a; - qDebug() << "b" << b; result.uniquePairs.push_back(d); } diff --git a/src/graphics/chemicalstructurerenderer.cpp b/src/graphics/chemicalstructurerenderer.cpp index 97370ee..976327d 100644 --- a/src/graphics/chemicalstructurerenderer.cpp +++ b/src/graphics/chemicalstructurerenderer.cpp @@ -340,6 +340,10 @@ void ChemicalStructureRenderer::handleCellsUpdate() { m_cellsNeedsUpdate = false; } +AggregateIndex ChemicalStructureRenderer::getAggregateIndex(size_t index) const { + if(index < m_aggregateIndices.size()) return m_aggregateIndices[index]; + return AggregateIndex{}; +} void ChemicalStructureRenderer::addAggregateRepresentations() { if(!(m_drawingStyle == DrawingStyle::Centroid || m_drawingStyle == DrawingStyle::CenterOfMass)) return; @@ -349,7 +353,8 @@ void ChemicalStructureRenderer::addAggregateRepresentations() { m_selectionHandler->clear(SelectionType::Aggregate); } - std::vector fragments = m_structure->completedFragments(); + m_aggregateIndices.clear(); + const auto &fragments = m_structure->completedFragments(); const auto &fragmentMap = m_structure->getFragments(); int i = 0; @@ -366,6 +371,7 @@ void ChemicalStructureRenderer::addAggregateRepresentations() { selectionIdColor = m_selectionHandler->getColorFromId(selectionId); } + m_aggregateIndices.push_back(AggregateIndex{frag, pos}); cx::graphics::addSphereToEllipsoidRenderer(m_ellipsoidRenderer, pos, color, 0.4, selectionIdColor, selected); i++; } diff --git a/src/graphics/chemicalstructurerenderer.h b/src/graphics/chemicalstructurerenderer.h index 9b0df93..9262593 100644 --- a/src/graphics/chemicalstructurerenderer.h +++ b/src/graphics/chemicalstructurerenderer.h @@ -23,6 +23,11 @@ struct TextLabel { QVector3D position; }; +struct AggregateIndex { + FragmentIndex fragment; + QVector3D position; +}; + class ChemicalStructureRenderer : public QObject { Q_OBJECT public: @@ -63,6 +68,7 @@ class ChemicalStructureRenderer : public QObject { [[nodiscard]] DrawingStyle drawingStyle() const; [[nodiscard]] AtomDrawingStyle atomStyle() const; [[nodiscard]] BondDrawingStyle bondStyle() const; + [[nodiscard]] AggregateIndex getAggregateIndex(size_t index) const; [[nodiscard]] float bondThickness() const; @@ -155,6 +161,7 @@ public slots: RendererUniforms m_uniforms; FrameworkOptions m_frameworkOptions; + std::vector m_aggregateIndices; }; } // namespace cx::graphics diff --git a/src/graphics/frameworkrenderer.cpp b/src/graphics/frameworkrenderer.cpp index 4fcf100..3efe008 100644 --- a/src/graphics/frameworkrenderer.cpp +++ b/src/graphics/frameworkrenderer.cpp @@ -176,7 +176,7 @@ void FrameworkRenderer::handleInteractionsUpdate() { } } auto [color, energy] = energies[uniqueIndex]; - if (std::abs(energy) <= m_options.cutoff) + if ((m_options.cutoff != 0.0) && (std::abs(energy) <= m_options.cutoff)) continue; double scale = -energy * thickness(); if (std::abs(scale) < 1e-4) diff --git a/src/graphics/renderselection.h b/src/graphics/renderselection.h index 90667ab..8869627 100644 --- a/src/graphics/renderselection.h +++ b/src/graphics/renderselection.h @@ -3,6 +3,7 @@ #include #include #include +#include "fragment.h" #include namespace cx::graphics { diff --git a/src/graphics/scene.cpp b/src/graphics/scene.cpp index bd9ee5e..be1ab9b 100644 --- a/src/graphics/scene.cpp +++ b/src/graphics/scene.cpp @@ -134,11 +134,13 @@ bool Scene::hasMeasurements() const { return !m_measurementList.isEmpty(); } void Scene::setSelectionColor(const QColor &color) { m_selectionColor = color; } AtomDrawingStyle Scene::atomStyle() const { - if(m_structureRenderer) return m_structureRenderer->atomStyle(); + if (m_structureRenderer) + return m_structureRenderer->atomStyle(); return atomStyleForDrawingStyle(m_drawingStyle); } BondDrawingStyle Scene::bondStyle() const { - if(m_structureRenderer) return m_structureRenderer->bondStyle(); + if (m_structureRenderer) + return m_structureRenderer->bondStyle(); return bondStyleForDrawingStyle(m_drawingStyle); } @@ -426,6 +428,19 @@ bool Scene::processSelectionSingleClick(const QColor &color) { return true; break; } + case SelectionType::Aggregate: { + auto agg = m_structureRenderer->getAggregateIndex(m_selection.index); + const auto &fragments = m_structure->getFragments(); + const auto kv = fragments.find(agg.fragment); + if(kv == fragments.end()) break; + const auto &frag = kv->second; + for(const auto &atom: frag.atomIndices) { + m_structure->toggleAtomFlag(atom, AtomFlag::Selected); + } + emit atomSelectionChanged(); + return true; + break; + } default: { break; } @@ -548,6 +563,21 @@ MeasurementObject Scene::processMeasurementSingleClick(const QColor &color, break; } + case SelectionType::Aggregate: { + auto agg = m_structureRenderer->getAggregateIndex(m_selection.index); + const auto &fragments = m_structure->getFragments(); + const auto kv = fragments.find(agg.fragment); + if(kv == fragments.end()) break; + const auto &frag = kv->second; + result.position = agg.position; + result.selectionType = SelectionType::Aggregate; + result.index = m_selection.index; + for(const auto &atom: frag.atomIndices) { + m_structure->toggleAtomFlag(atom, AtomFlag::Selected); + } + emit atomSelectionChanged(); + break; + } default: break; }