diff --git a/avogadro/qtplugins/crystal/crystalscene.cpp b/avogadro/qtplugins/crystal/crystalscene.cpp index 9eebe5732e..4c9530f5c1 100644 --- a/avogadro/qtplugins/crystal/crystalscene.cpp +++ b/avogadro/qtplugins/crystal/crystalscene.cpp @@ -14,6 +14,7 @@ #include #include +#include #include #include #include @@ -28,8 +29,11 @@ using Rendering::GeometryNode; using Rendering::GroupNode; using Rendering::LineStripGeometry; -CrystalScene::CrystalScene(QObject* p) - : ScenePlugin(p), m_setupWidget(nullptr) +const Vector3ub red = { 255, 0, 0 }; +const Vector3ub green = { 0, 255, 0 }; +const Vector3ub blue = { 0, 0, 255 }; + +CrystalScene::CrystalScene(QObject* p) : ScenePlugin(p), m_setupWidget(nullptr) { m_layerManager = QtGui::PluginLayerManager(m_name); @@ -41,6 +45,8 @@ CrystalScene::CrystalScene(QObject* p) m_color[0] = static_cast(color.red()); m_color[1] = static_cast(color.green()); m_color[2] = static_cast(color.blue()); + + m_multiColor = settings.value("crystal/multiColor", true).toBool(); } CrystalScene::~CrystalScene() {} @@ -52,8 +58,8 @@ void CrystalScene::process(const QtGui::Molecule& molecule, GroupNode& node) node.addChild(geometry); auto* lines = new LineStripGeometry; geometry->addDrawable(lines); - lines->setColor(m_color); + auto color = m_color; float width = m_lineWidth; Vector3f a = cell->aVector().cast(); @@ -63,24 +69,50 @@ void CrystalScene::process(const QtGui::Molecule& molecule, GroupNode& node) Vector3f vertex(Vector3f::Zero()); Array strip; + // draw the a axis strip.reserve(5); strip.push_back(vertex); - strip.push_back(vertex += a); - strip.push_back(vertex += b); - strip.push_back(vertex -= a); - strip.push_back(vertex -= b); + strip.push_back(vertex + a); + if (!m_multiColor) + lines->addLineStrip(strip, color, width); + else // a axis is R-G-B + lines->addLineStrip(strip, red, width); + + // now the b-axis + strip.clear(); + strip.push_back(vertex); + strip.push_back(vertex + b); + if (!m_multiColor) + lines->addLineStrip(strip, color, width); + else // b axis is R-G-B + lines->addLineStrip(strip, green, width); + + // now the rest of the ab plane + strip.clear(); + strip.push_back(vertex + a); + strip.push_back(vertex + a + b); + strip.push_back(vertex + b); lines->addLineStrip(strip, width); - for (auto & it : strip) { - it += c; - } + // now the ab plane "up" by axis c + strip.clear(); + strip.push_back(vertex + c); + strip.push_back(vertex + a + c); + strip.push_back(vertex + a + b + c); + strip.push_back(vertex + b + c); + strip.push_back(vertex + c); lines->addLineStrip(strip, width); + // now the c axis strip.resize(2); strip[0] = Vector3f::Zero(); strip[1] = c; - lines->addLineStrip(strip, width); + if (!m_multiColor) + lines->addLineStrip(strip, color, width); + else // c axis is R-G-B + lines->addLineStrip(strip, blue, width); + // now the remaining "struts" from ab plane along c axis strip[0] += a; strip[1] += a; lines->addLineStrip(strip, width); @@ -116,6 +148,15 @@ void CrystalScene::setColor(const QColor& color) settings.setValue("crystal/color", color); } +void CrystalScene::setMultiColor(bool multiColor) +{ + m_multiColor = multiColor; + emit drawablesChanged(); + + QSettings settings; + settings.setValue("crystal/multiColor", multiColor); +} + QWidget* CrystalScene::setupWidget() { if (!m_setupWidget) { @@ -132,6 +173,11 @@ QWidget* CrystalScene::setupWidget() auto* form = new QFormLayout; form->addRow(tr("Line width:"), spin); + auto* multiColor = new QCheckBox; + multiColor->setChecked(m_multiColor); + form->addRow(tr("Color axes:"), multiColor); + connect(multiColor, SIGNAL(toggled(bool)), SLOT(setMultiColor(bool))); + auto* color = new QtGui::ColorButton; connect(color, SIGNAL(colorChanged(const QColor&)), SLOT(setColor(const QColor&))); @@ -145,4 +191,4 @@ QWidget* CrystalScene::setupWidget() return m_setupWidget; } -} // namespace Avogadro +} // namespace Avogadro::QtPlugins diff --git a/avogadro/qtplugins/crystal/crystalscene.h b/avogadro/qtplugins/crystal/crystalscene.h index e3b1ba88a1..85898e22c8 100644 --- a/avogadro/qtplugins/crystal/crystalscene.h +++ b/avogadro/qtplugins/crystal/crystalscene.h @@ -9,7 +9,7 @@ #include #include -#include +#include namespace Avogadro { namespace QtPlugins { @@ -38,8 +38,9 @@ class CrystalScene : public QtGui::ScenePlugin QWidget* setupWidget() override; private slots: - void setColor(const QColor &color); + void setColor(const QColor& color); void setLineWidth(double width); + void setMultiColor(bool multiColor); private: std::string m_name = "Crystal Lattice"; @@ -47,6 +48,7 @@ private slots: QWidget* m_setupWidget; float m_lineWidth; Vector3ub m_color; + bool m_multiColor; }; } // end namespace QtPlugins diff --git a/avogadro/rendering/linestripgeometry.cpp b/avogadro/rendering/linestripgeometry.cpp index 0ebaa880e8..fdb0de31b5 100644 --- a/avogadro/rendering/linestripgeometry.cpp +++ b/avogadro/rendering/linestripgeometry.cpp @@ -22,12 +22,12 @@ namespace { #include "linestrip_fs.h" #include "linestrip_vs.h" -} +} // namespace -using Avogadro::Core::Array; using Avogadro::Vector3f; using Avogadro::Vector3ub; using Avogadro::Vector4ub; +using Avogadro::Core::Array; using std::cout; using std::endl; @@ -231,6 +231,29 @@ size_t LineStripGeometry::addLineStrip(const Core::Array& vertices, return result; } +size_t LineStripGeometry::addLineStrip(const Core::Array& vertices, + const Vector3ub& rgb, float lineWidth) +{ + if (vertices.empty()) + return InvalidIndex; + + size_t result = m_lineStarts.size(); + m_lineStarts.push_back(static_cast(m_vertices.size())); + m_lineWidths.push_back(lineWidth); + + auto vertIter(vertices.begin()); + auto vertEnd(vertices.end()); + + m_vertices.reserve(m_vertices.size() + vertices.size()); + Vector4ub tmpColor(rgb[0], rgb[1], rgb[2], m_opacity); + while (vertIter != vertEnd) { + m_vertices.push_back(PackedVertex(*(vertIter++), tmpColor)); + } + + m_dirty = true; + return result; +} + size_t LineStripGeometry::addLineStrip(const Core::Array& vertices, float lineWidth) { @@ -253,4 +276,4 @@ size_t LineStripGeometry::addLineStrip(const Core::Array& vertices, return result; } -} // End namespace Avogadro +} // namespace Avogadro::Rendering diff --git a/avogadro/rendering/linestripgeometry.h b/avogadro/rendering/linestripgeometry.h index 542b756008..dbf0145807 100644 --- a/avogadro/rendering/linestripgeometry.h +++ b/avogadro/rendering/linestripgeometry.h @@ -27,10 +27,7 @@ class AVOGADRORENDERING_EXPORT LineStripGeometry : public Drawable Vector3f vertex; // 12 bytes Vector4ub color; // 4 bytes - PackedVertex(const Vector3f& v, const Vector4ub& c) - : vertex(v) - , color(c) - {} + PackedVertex(const Vector3f& v, const Vector4ub& c) : vertex(v), color(c) {} static int vertexOffset() { return 0; } static int colorOffset() { return static_cast(sizeof(Vector3f)); } }; @@ -76,6 +73,8 @@ class AVOGADRORENDERING_EXPORT LineStripGeometry : public Drawable const Core::Array& color, float lineWidth); size_t addLineStrip(const Core::Array& vertices, const Core::Array& color, float lineWidth); + size_t addLineStrip(const Core::Array& vertices, + const Vector3ub& color, float lineWidth); size_t addLineStrip(const Core::Array& vertices, float lineWidth); /** @} */