Cryos,
Just go ahead and add the engine if you want. You dont’ need to send
patches. It’s not going to get in the way and if it gets removed it’s
no biggy. Engines / Tools are kinda brainstorming directories, if there
are some junk tools it’s not a bad thing; they will get naturally
cleaned up as they evolve an others replace them.
–
Donald
(Fri, May 11, 2007 at 09:16:19AM +0100) “Marcus D. Hanwell” marcus@cryos.org:
Hi,
Got back from holiday early and spent some time coding yesterday. I saw
Geoff’s atom manipulation stuff in the select/rotate tool but wanted to see
if I could make a tool that manipulated atoms in the same way that the
navigate tool manipulates the view.
Right now left button translates the atom in x and y and the middle button
zooms the atom into and out of the display. One thing I thought may feel more
natural than the current zoom behaviour is if I computed a vector from the
camera centre through the atom center used that instead of the camera z axis.
With groups you would just use the group centre instead of the atom centre.
After talking with Benoit I have refined it a little but it is still only
working with single atoms under the mouse. With Geoff’s additions to glwidget
it will not take much to extend it though. The thought occurred to me whether
it was better to have these actions as a subsidiary function of a tool or as
the primary function of a tool, i.e. in the select/rotate tool or in its own
tool file.
Either way the actions in this patch and the new actions Geoff has added to
the select/rotate tool should be merged into the same tool at some point
really soon. I think clicking on a tool and being in manipulation mode would
feel most natural but I can also see how selecting atoms/residues and then
manipulating them also goes together very well.
There is also the other question that has been raised about keeping the
movements consistent across tools, i.e. navigate and selectrotate right now.
Another thing in my mind was adding some shortcuts, I would like to be able
to switch between tools with a few key strokes. Is this a good idea?
I see a possible workflow where I draw a molecule (draw tool), manipulate the
view (navigate tool), adjust some atoms positions (manipulate tool), draw
another group onto the molecule (draw tool), select a portion of the molecule
(selectrotate) and then move that group to where I want it (manipulate tool).
After that I would probably want to optimise the structure.
That is a lot of switching and once you use avo a fair bit shortcuts would be
extremely useful with a few tools specialising in specific areas. You guys
may have different ideas though and so I would appreciate any of your
thoughts on how this may be different.
Thanks,
Marcus
PS I was blown away by the number of changes in the last few days - need to
save some stuff for my Google Summer of Code project )
Index: libavogadro/src/tools/manipulate.qrc
— libavogadro/src/tools/manipulate.qrc (revision 0)
+++ libavogadro/src/tools/manipulate.qrc (revision 0)
@@ -0,0 +1,5 @@
+
+
\ No newline at end of file
Index: libavogadro/src/tools/manipulatetool.h
— libavogadro/src/tools/manipulatetool.h (revision 0)
+++ libavogadro/src/tools/manipulatetool.h (revision 0)
@@ -0,0 +1,111 @@
+/**********************************************************************
- ManipulateTool - Manipulation Tool for Avogadro
- Copyright (C) 2007 by Marcus D. Hanwell
- Copyright (C) 2007 by Benoit Jacob
- This file is part of the Avogadro molecular editor project.
- For more information, see http://avogadro.sourceforge.net/
- Some code is based on Open Babel
- For more information, see http://openbabel.sourceforge.net/
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation version 2 of the License.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- ***********************************************************************/
+#ifndef __MANIPULATETOOL_H
+#define __MANIPULATETOOL_H
+
+#include <avogadro/glwidget.h>
+#include <avogadro/tool.h>
+
+#include <openbabel/mol.h>
+
+#include
+#include
+#include
+#include
+#include
+
+namespace Avogadro {
+
- /**
-
-
- @brief Manipulate the position of atoms
-
- @author Marcus D. Hanwell
-
-
- This tool enables the manipulation of the position of
-
- */
- class ManipulateTool : public Tool
- {
- Q_OBJECT
- public:
-
//! Constructor
-
ManipulateTool(QObject *parent = 0);
-
//! Deconstructor
-
virtual ~ManipulateTool();
-
//! \name Description methods
-
//@{
-
//! Tool Name (ie Draw)
-
virtual QString name() const { return(tr("Manipulate")); }
-
//! Tool Description (ie. Draws atoms and bonds)
-
virtual QString description() const { return(tr("Manipulation Tool")); }
-
//@}
-
//! \name Tool Methods
-
//@{
-
//! \brief Callback methods for ui.actions on the canvas.
-
/*!
-
*/
-
virtual QUndoCommand* mousePress(GLWidget *widget, const QMouseEvent *event);
-
virtual QUndoCommand* mouseRelease(GLWidget *widget, const QMouseEvent *event);
-
virtual QUndoCommand* mouseMove(GLWidget *widget, const QMouseEvent *event);
-
virtual QUndoCommand* wheel(GLWidget *widget, const QWheelEvent *event);
-
virtual int usefulness() const;
-
virtual bool paint(GLWidget *widget);
- protected:
-
GLWidget * m_glwidget;
-
bool m_leftButtonPressed; // rotation
-
bool m_rightButtonPressed; // translation
-
bool m_midButtonPressed; // scale / zoom
-
Atom * m_clickedAtom;
-
//! Temporary var for adding selection box
-
GLuint m_selectionDL;
-
QPoint m_lastDraggingPosition;
-
void drawSphere(GLWidget *widget, const Eigen::Vector3d ¢er, double radius, float alpha);
-
void computeClickedAtom(const QPoint& p);
-
void zoom( const Eigen::Vector3d &goal, double delta ) const;
-
void translate( const Eigen::Vector3d &what, const QPoint &from, const QPoint &to ) const;
-
void rotate( const Eigen::Vector3d ¢er, double deltaX, double deltaY ) const;
-
void tilt( const Eigen::Vector3d ¢er, double delta ) const;
- };
- class ManipulateToolFactory : public QObject, public ToolFactory
- {
-
Q_OBJECT;
-
Q_INTERFACES(Avogadro::ToolFactory);
-
public:
-
Tool *createInstance(QObject *parent = 0) { return new ManipulateTool(); }
- };
+} // end namespace Avogadro
+
+#endif
Index: libavogadro/src/tools/CMakeLists.txt
— libavogadro/src/tools/CMakeLists.txt (revision 357)
+++ libavogadro/src/tools/CMakeLists.txt (working copy)
@@ -65,3 +65,15 @@
)
INSTALL(TARGETS navigatetool DESTINATION ${DESTINATION_DIR})
+### manipulatetool
+set(manipulatetool_SRCS manipulatetool.cpp)
+qt4_add_resources(manipulatetool_RC_SRCS manipulate.qrc)
+qt4_automoc({manipulatetool_SRCS})
+ADD_LIBRARY(manipulatetool SHARED {manipulatetool_SRCS} ${manipulatetool_RC_SRCS})
+TARGET_LINK_LIBRARIES(manipulatetool
- ${OPENBABEL2_LIBRARIES}
- ${QT_LIBRARIES}
- ${OPENGL_LIBRARIES}
- avogadro-lib
+)
+INSTALL(TARGETS manipulatetool DESTINATION ${DESTINATION_DIR})
Index: libavogadro/src/tools/manipulatetool.cpp
===================================================================
— libavogadro/src/tools/manipulatetool.cpp (revision 0)
+++ libavogadro/src/tools/manipulatetool.cpp (revision 0)
@@ -0,0 +1,243 @@
+/**********************************************************************
- ManipulateTool - Manipulation Tool for Avogadro
- Copyright (C) 2007 by Marcus D. Hanwell
- Copyright (C) 2007 by Benoit Jacob
- This file is part of the Avogadro molecular editor project.
- For more information, see http://avogadro.sourceforge.net/
- Some code is based on Open Babel
- For more information, see http://openbabel.sourceforge.net/
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation version 2 of the License.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- ***********************************************************************/
+#include “manipulatetool.h”
+#include <avogadro/primitive.h>
+#include <avogadro/color.h>
+#include <avogadro/glwidget.h>
+#include <avogadro/camera.h>
+
+#include <openbabel/obiter.h>
+#include <openbabel/mol.h>
+
+#include
+
+using namespace std;
+using namespace OpenBabel;
+using namespace Avogadro;
+using namespace Eigen;
+
+ManipulateTool::ManipulateTool(QObject *parent) : Tool(parent), m_clickedAtom(0), m_leftButtonPressed(false), m_midButtonPressed(false), m_rightButtonPressed(false)
+{
- QAction *action = activateAction();
- action->setIcon(QIcon(QString::fromUtf8(“:/navigate/navigate.png”)));
- action->setToolTip(tr(“Manipulation Tool\n\n”
-
"Left Mouse: Click and drag to move atoms and bonds\n"
-
"Middle Mouse: Click and drag to move atoms further away or closer\n"
-
"Right Mouse: Click and drag to rotate atoms and bonds"));
+}
+
+ManipulateTool::~ManipulateTool()
+{
+}
+
+int ManipulateTool::usefulness() const
+{
+void ManipulateTool::computeClickedAtom(const QPoint& p)
+{
- QList hits;
- m_clickedAtom = 0;
- // Perform a OpenGL selection and retrieve the list of hits.
- hits = m_glwidget->hits(p.x()-SEL_BOX_HALF_SIZE,
-
p.y()-SEL_BOX_HALF_SIZE,
-
SEL_BOX_SIZE, SEL_BOX_SIZE);
- // Find the first atom (if any) in hits - this will be the closest
- foreach( GLHit hit, hits )
- {
- if(hit.type() == Primitive::AtomType)
- {
-
m_clickedAtom = static_cast<Atom *>( m_glwidget->molecule()->GetAtom(hit.name()) );
-
return;
- }
- }
+}
+void ManipulateTool::zoom( const Eigen::Vector3d &goal, double delta ) const
+{
- Vector3d transformedGoal = m_glwidget->camera()->modelview() * goal;
- double distanceToGoal = transformedGoal.norm();
- double t = ZOOM_SPEED * delta;
- const double minDistanceToGoal = 2.0 * CAMERA_NEAR_DISTANCE;
- double u = minDistanceToGoal / distanceToGoal - 1.0;
- if( fabs(t) > fabs(u) ) {
- t = u;
- }
- MatrixP3d atomTranslation;
- atomTranslation.loadTranslation(m_glwidget->camera()->backTransformedZAxis() * t);
- if (m_clickedAtom)
- m_clickedAtom->setPos(atomTranslation * m_clickedAtom->pos());
+}
+void ManipulateTool::translate( const Eigen::Vector3d &what, const QPoint &from, const QPoint &to ) const
+{
- Vector3d fromPos = m_glwidget->camera()->unProject(from, what);
- Vector3d toPos = m_glwidget->camera()->unProject(to, what);
- MatrixP3d atomTranslation;
- atomTranslation.loadTranslation(toPos - fromPos);
- if (m_clickedAtom)
- m_clickedAtom->setPos(atomTranslation * m_clickedAtom->pos());
+}
+void ManipulateTool::rotate( const Eigen::Vector3d ¢er, double deltaX, double deltaY ) const
+{
+
+}
+
+void ManipulateTool::tilt( const Eigen::Vector3d ¢er, double delta ) const
+{
+
+}
+
+QUndoCommand* ManipulateTool::mousePress(GLWidget *widget, const QMouseEvent *event)
+{
- m_glwidget = widget;
- m_lastDraggingPosition = event->pos();
- m_leftButtonPressed = ( event->buttons() & Qt::LeftButton );
- m_midButtonPressed = ( event->buttons() & Qt::MidButton );
- m_rightButtonPressed = ( event->buttons() & Qt::RightButton );
- computeClickedAtom(event->pos());
- widget->update();
- return 0;
+}
+QUndoCommand* ManipulateTool::mouseRelease(GLWidget *widget, const QMouseEvent *event)
+{
- m_glwidget = widget;
- m_leftButtonPressed = false;
- m_midButtonPressed = false;
- m_rightButtonPressed = false;
- m_clickedAtom = 0;
- widget->update();
- return 0;
+}
+QUndoCommand* ManipulateTool::mouseMove(GLWidget *widget, const QMouseEvent *event)
+{
- m_glwidget = widget;
- if(!m_glwidget->molecule()) {
- return 0;
- }
- QPoint deltaDragging = event->pos() - m_lastDraggingPosition;
- // Manipulation can be performed in two ways - centred on an individual atom
- if( m_clickedAtom )
- {
- if ( event->buttons() & Qt::LeftButton )
- {
-
// translate the molecule following mouse movement
-
translate( m_clickedAtom->pos(), m_lastDraggingPosition, event->pos() );
- }
- else if ( event->buttons() & Qt::MidButton )
- {
-
// Perform the rotation
+// tilt( m_clickedAtom->pos(), deltaDragging.x() );
+
-
// Perform the zoom toward clicked atom
-
zoom( m_clickedAtom->pos(), deltaDragging.y() );
- }
- else if ( event->buttons() & Qt::RightButton )
- {
-
// Atom centred rotation
-
rotate( m_clickedAtom->pos(), deltaDragging.x(), deltaDragging.y() );
- }
- }
- else // Nothing clicked on
- {
- if( event->buttons() & Qt::RightButton )
- {
-
// rotation around the center of the molecule
-
rotate( m_glwidget->center(), deltaDragging.x(), deltaDragging.y() );
- }
- else if ( event->buttons() & Qt::MidButton )
- {
-
// Perform the rotation
-
tilt( m_glwidget->center(), deltaDragging.x() );
-
// Perform the zoom toward molecule center
-
zoom( m_glwidget->center(), deltaDragging.y() );
- }
- else if ( event->buttons() & Qt::LeftButton )
- {
-
// translate the molecule following mouse movement
-
translate( m_glwidget->center(), m_lastDraggingPosition, event->pos() );
- }
- }
- m_lastDraggingPosition = event->pos();
- m_glwidget->update();
- return 0;
+}
+QUndoCommand* ManipulateTool::wheel(GLWidget *widget, const QWheelEvent *event )
+{
+bool ManipulateTool::paint(GLWidget *widget)
+{
- if(m_leftButtonPressed || m_midButtonPressed || m_rightButtonPressed) {
- if(m_clickedAtom) {
-
double renderRadius = 0.0;
-
foreach(Engine *engine, widget->engines())
-
{
-
if(engine->isEnabled())
-
{
-
double engineRadius = engine->radius(m_clickedAtom);
-
if(engineRadius > renderRadius) {
-
renderRadius = engineRadius;
-
}
-
}
-
}
-
renderRadius += 0.10;
-
drawSphere(widget, m_clickedAtom->GetVector().AsArray(), renderRadius, 0.7);
- }
- }
- return true;
+}
+void ManipulateTool::drawSphere(GLWidget *widget, const Eigen::Vector3d &position, double radius, float alpha )
+{
- Color( 1.0, 0.3, 0.3, alpha ).applyAsMaterials();
- glEnable( GL_BLEND );
- widget->painter()->drawSphere(position, radius);
- glDisable( GL_BLEND );
+}
+#include “manipulatetool.moc”
+
+Q_EXPORT_PLUGIN2(manipulatetool, ManipulateToolFactory)
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
Avogadro-devel mailing list
Avogadro-devel@lists.sourceforge.net
avogadro-devel List Signup and Options