diff --git a/src/childpropertycontroller.cpp b/src/childpropertycontroller.cpp index 18a0bbb..05b3115 100644 --- a/src/childpropertycontroller.cpp +++ b/src/childpropertycontroller.cpp @@ -117,7 +117,7 @@ void ChildPropertyController::setup() { connect(modelComboBox, &QComboBox::currentIndexChanged, [this]() { updatePairInteractionComponents(); }); - connect(frameworkTubeSizeSpinBox, &QSpinBox::valueChanged, + connect(frameworkTubeSizeSpinBox, &QDoubleSpinBox::valueChanged, [this]() { emitFrameworkOptions(); }); connect(frameworkCutoffSpinBox, &QDoubleSpinBox::valueChanged, diff --git a/src/childpropertycontroller.ui b/src/childpropertycontroller.ui index 065d3b2..719b835 100644 --- a/src/childpropertycontroller.ui +++ b/src/childpropertycontroller.ui @@ -38,7 +38,7 @@ - 0 + 4 @@ -858,22 +858,6 @@ - - - - Å mol / J - - - 1 - - - 1000 - - - 10 - - - @@ -961,6 +945,13 @@ + + + + 10.000000000000000 + + + diff --git a/src/core/chemicalstructure.cpp b/src/core/chemicalstructure.cpp index 198ccc8..8281920 100644 --- a/src/core/chemicalstructure.cpp +++ b/src/core/chemicalstructure.cpp @@ -114,7 +114,8 @@ void ChemicalStructure::guessBondsBasedOnDistances() { }; for (const auto &[k, v] : m_bondOverrides) { - if(v != BondMethod::Bond) continue; + if (v != BondMethod::Bond) + continue; size_t l = genericIndexToIndex(k.a); size_t r = genericIndexToIndex(k.b); double d = (m_atomicPositions.col(r) - m_atomicPositions.col(l)).norm(); @@ -150,8 +151,6 @@ void ChemicalStructure::guessBondsBasedOnDistances() { results.clear(); } - - m_bondsNeedUpdate = false; m_fragments.clear(); m_symmetryUniqueFragments.clear(); @@ -909,6 +908,23 @@ ChemicalStructure::getAtomIndicesUnderTransformation( return result; } +QString ChemicalStructure::getTransformationString( + const Eigen::Isometry3d &transform) const { + + Eigen::AngleAxisd aa(transform.rotation()); + const auto &axis = aa.axis(); + float angle = aa.angle(); + const auto &t = transform.translation(); + + std::string desc{""}; + if (angle > 1e-3) + desc += fmt::format(" Rot {:.3f}° @ [{:.3f},{:.3f},{:.3f}]", + angle * 180 / M_PI, axis(0), axis(1), axis(2)); + desc += fmt::format(" + [{:.3f},{:.3f},{:.3f}]", t(0), t(1), t(2)); + + return QString::fromStdString(desc); +} + bool ChemicalStructure::getTransformation( const std::vector &from_orig, const std::vector &to_orig, diff --git a/src/core/chemicalstructure.h b/src/core/chemicalstructure.h index c6f0dff..3c1cf92 100644 --- a/src/core/chemicalstructure.h +++ b/src/core/chemicalstructure.h @@ -136,6 +136,9 @@ class ChemicalStructure : public QObject { const std::vector &to, Eigen::Isometry3d &result) const; + virtual QString + getTransformationString(const Eigen::Isometry3d &) const; + virtual std::vector getAtomIndicesUnderTransformation(const std::vector &idxs, const Eigen::Isometry3d &result) const; diff --git a/src/core/meshinstance.cpp b/src/core/meshinstance.cpp index 44ed311..21ff474 100644 --- a/src/core/meshinstance.cpp +++ b/src/core/meshinstance.cpp @@ -95,8 +95,7 @@ void MeshInstance::setTransparent(bool transparent) { emit transparencyChanged(); } -void MeshInstance::setTransparency(float transparency) -{ +void MeshInstance::setTransparency(float transparency) { if (transparency == m_transparency) return; m_transparency = transparency; @@ -156,18 +155,11 @@ MeshInstance *MeshInstance::newInstanceFromSelectedAtoms( return nullptr; if (mesh->haveChildMatchingTransform(transform)) return nullptr; - Eigen::AngleAxisd aa(transform.rotation()); auto instance = new MeshInstance(mesh, transform); - const auto &axis = aa.axis(); - float angle = aa.angle(); - const auto &t = transform.translation(); - std::string desc{""}; - if (angle > 1e-3) - desc += fmt::format(" Rot {:.3f}° @ [{:.3f},{:.3f},{:.3f}]", - angle * 180 / M_PI, axis(0), axis(1), axis(2)); - desc += fmt::format(" + [{:.3f},{:.3f},{:.3f}]", t(0), t(1), t(2)); - - instance->setObjectName(QString::fromStdString(desc)); + auto fragment = structure->makeFragment(atoms); + QString fragmentLabel = fragment.name; + + instance->setObjectName(fragmentLabel); return instance; } @@ -231,13 +223,14 @@ MeshInstance::nearestPoint(const MeshInstance *other) const { return result; } - void MeshInstance::populateSurroundingAtoms() { ChemicalStructure *structure = qobject_cast(m_mesh->parent()); - if(structure) { - m_atomsInside = structure->getAtomIndicesUnderTransformation(m_mesh->atomsInside(), m_transform); - m_atomsOutside = structure->getAtomIndicesUnderTransformation(m_mesh->atomsOutside(), m_transform); + if (structure) { + m_atomsInside = structure->getAtomIndicesUnderTransformation( + m_mesh->atomsInside(), m_transform); + m_atomsOutside = structure->getAtomIndicesUnderTransformation( + m_mesh->atomsOutside(), m_transform); qDebug() << "m_atomsOutside" << m_atomsOutside.size(); } } diff --git a/src/crystal/crystalstructure.cpp b/src/crystal/crystalstructure.cpp index 170cfa7..ce42791 100644 --- a/src/crystal/crystalstructure.cpp +++ b/src/crystal/crystalstructure.cpp @@ -1229,7 +1229,7 @@ Fragment CrystalStructure::makeFragment( result.asymmetricFragmentTransform *= t; result.name = ucFrag.name; if (result.index != ucIndex) { - result.name = result.name.left(result.name.lastIndexOf(' ')) + + result.name = result.name.left(result.name.lastIndexOf(' ')) + " " + getTransformationString(result.asymmetricFragmentTransform); } } else { diff --git a/src/crystal/crystalstructure.h b/src/crystal/crystalstructure.h index 891c705..7789a3b 100644 --- a/src/crystal/crystalstructure.h +++ b/src/crystal/crystalstructure.h @@ -127,7 +127,7 @@ class CrystalStructure : public ChemicalStructure { atomicDisplacementParameters(GenericAtomIndex) const override; [[nodiscard]] QString - getTransformationString(const Eigen::Isometry3d &result) const; + getTransformationString(const Eigen::Isometry3d &) const override; [[nodiscard]] nlohmann::json toJson() const override; bool fromJson(const nlohmann::json &) override; diff --git a/src/graphics/meshinstancerenderer.cpp b/src/graphics/meshinstancerenderer.cpp index 68e3438..4080fbd 100644 --- a/src/graphics/meshinstancerenderer.cpp +++ b/src/graphics/meshinstancerenderer.cpp @@ -164,7 +164,7 @@ void MeshInstanceRenderer::setMesh(Mesh *mesh) { for (size_t i = 0; i < vals.rows(); i++) { QColor color = cmap(vals(i)); int sign = vertexMask(i) ? 1 : -1; - propertyData.push_back(sign * color.redF()); + propertyData.push_back(sign * (color.redF() + 0.000001f)); propertyData.push_back(color.greenF()); propertyData.push_back(color.blueF()); propertyData.push_back(color.alphaF()); diff --git a/src/occ/crystal/dimer_mapping_table.cpp b/src/occ/crystal/dimer_mapping_table.cpp index 5cbedb9..54bcb54 100644 --- a/src/occ/crystal/dimer_mapping_table.cpp +++ b/src/occ/crystal/dimer_mapping_table.cpp @@ -1,3 +1,4 @@ +#include #include #include @@ -188,24 +189,19 @@ DimerMappingTable::create_atomic_pair_table(const Crystal &crystal, const auto &vdw_radii = crystal.asymmetric_unit().vdw_radii(); double max_vdw = vdw_radii.maxCoeff(); double max_dist = (max_vdw * 2 + 0.6) * (max_vdw * 2 + 0.6); + occ::core::KDTree tree(s.cart_pos.rows(), s.cart_pos, + occ::core::max_leaf); + tree.index->buildIndex(); + + core::KdResultSet idxs_dists; + core::KdRadiusResultSet results(max_dist, idxs_dists); - // For each atom in the unit cell for (int i = 0; i < uc_atoms.size(); i++) { Vec3 pos_i = uc_atoms.frac_pos.col(i); - Vec3 cart_pos_i = uc_atoms.cart_pos.col(i); - - // Look through expanded slab for possible bonds - for (int j = 0; j < s.frac_pos.cols(); j++) { - if (j % uc_atoms.size() <= i) - continue; // avoid duplicates - // Then in the pair loop: - Vec3 cart_pos_j = s.cart_pos.col(j); - Vec3 pos_diff = cart_pos_j - cart_pos_i; - if (pos_diff.squaredNorm() > max_dist) - continue; // Skip pairs too far apart - + const double *q = s.cart_pos.col(i).data(); + tree.index->findNeighbors(results, q, nanoflann::SearchParams()); + for (const auto &[j, dist2] : results.m_indices_dists) { Vec3 pos_j = s.frac_pos.col(j); - int uc_idx_j = s.uc_idx(j); HKL cell_offset{s.hkl(0, j), s.hkl(1, j), s.hkl(2, j)}; @@ -245,9 +241,10 @@ DimerMappingTable::create_atomic_pair_table(const Crystal &crystal, table.m_symmetry_unique_dimer_map[norm_ab] = table.m_symmetry_unique_dimer_map[canonical_ab]; } + + results.clear(); } - // Populate unique dimers as before for (const auto &dimer : table.m_unique_dimers) { if (table.m_symmetry_unique_dimer_map[dimer] == dimer) { table.m_symmetry_unique_dimers.push_back(dimer);