00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00019
00027
00028
00029
00031
00032
00033 #include <algorithm>
00034
00035
00036 #include <qfiledialog.h>
00037 #include <qinputdialog.h>
00038 #include <qmessagebox.h>
00039
00040 #include <qradiobutton.h>
00041 #include <qstringlist.h>
00042 #include <qtimer.h>
00043 #include <qvalidator.h>
00044
00045
00046 #include "atomset.h"
00047 #include "coordinateswidget.h"
00048 #include "densitybase.h"
00049 #include "glmoleculeview.h"
00050 #include "isosurface.h"
00051 #include "newatombase.h"
00052 #include "point3d.h"
00053 #include "quaternion.h"
00054 #include "vector3d.h"
00055
00059
00061 GLMoleculeView::GLMoleculeView(AtomSet* atomset, QWidget* parent, const char* name) : GLSimpleMoleculeView(atomset, parent, name),
00062 atoms(atomset),
00063 densityDialog(NULL),
00064 newAtomDialog(NULL),
00065 manipulateSelection(false)
00067 {
00068 isoSurface = new IsoSurface();
00069 }
00070
00072 GLMoleculeView::~GLMoleculeView()
00074 {
00075 makeCurrent();
00076 for(unsigned int i = 0; i < glSurfaces.size(); i++)
00077 glDeleteLists(glSurfaces[i], 1);
00078 delete isoSurface;
00079 }
00080
00084
00086 void GLMoleculeView::alterCartesian()
00090 {
00091 if(selectionList.size() == 0)
00092 return;
00093
00095 CoordinatesWidget* coords = new CoordinatesWidget(this, 0, true);
00096 QDoubleValidator* v = new QDoubleValidator(-9999.0,9999.,12,this);
00097 coords->LineEditX->setValidator(v);
00098 coords->LineEditY->setValidator(v);
00099 coords->LineEditZ->setValidator(v);
00100 v = 0;
00101 if(selectionList.size() == 1)
00102 {
00103
00104 unsigned int atom = *selectionList.begin();
00105 coords->LineEditX->setText(QString::number(atoms->x(atom), 'f', 8));
00106 coords->LineEditY->setText(QString::number(atoms->y(atom), 'f', 8));
00107 coords->LineEditZ->setText(QString::number(atoms->z(atom), 'f', 8));
00108 }
00109 else
00110 {
00111
00112 coords->RadioButtonAbsolute->setEnabled(false);
00113 coords->RadioButtonRelative->setChecked(true);
00114 coords->LineEditX->setText("0.0");
00115 coords->LineEditY->setText("0.0");
00116 coords->LineEditZ->setText("0.0");
00117 }
00118
00120 if(coords->exec() == QDialog::Accepted)
00121 {
00122 if(coords->RadioButtonAbsolute->isChecked())
00123 {
00124
00125 unsigned int atom = *selectionList.begin();
00126 bool ok;
00127 double newx = coords->LineEditX->text().toDouble(&ok);
00128 if(ok)
00129 atoms->setX(atom, newx);
00130 double newy = coords->LineEditY->text().toDouble(&ok);
00131 if(ok)
00132 atoms->setY(atom, newy);
00133 double newz = coords->LineEditZ->text().toDouble(&ok);
00134 if(ok)
00135 atoms->setZ(atom, newz);
00136 }
00137 else
00138 {
00139
00140 bool ok;
00141 double deltax = coords->LineEditX->text().toDouble(&ok);
00142 if(!ok)
00143 deltax = 0.0;
00144 double deltay = coords->LineEditY->text().toDouble(&ok);
00145 if(!ok)
00146 deltay = 0.0;
00147 double deltaz = coords->LineEditZ->text().toDouble(&ok);
00148 if(!ok)
00149 deltaz = 0.0;
00150 std::list<unsigned int>::iterator it = selectionList.begin();
00151 while(it != selectionList.end())
00152 {
00153 atoms->setX(*it, atoms->x(*it) + deltax);
00154 atoms->setY(*it, atoms->y(*it) + deltay);
00155 atoms->setZ(*it, atoms->z(*it) + deltaz);
00156 it++;
00157 }
00158 }
00159 }
00160 delete coords;
00161 setModified();
00162 updateAtomSet();
00163 }
00164
00166 void GLMoleculeView::alterInternal()
00170 {
00171 switch(selectionType)
00172 {
00173 case SELECTION_BOND:
00174 {
00175 std::list<unsigned int>::iterator it = selectionList.begin();
00176 unsigned int atom1 = *it++;
00177 unsigned int atom2 = *it;
00179
00180 Vector3D<double> bond(atoms->x(atom2), atoms->y(atom2), atoms->z(atom2), atoms->x(atom1), atoms->y(atom1), atoms->z(atom1));
00181 double bondLength = bond.length();
00182
00183 bool ok;
00184 double newLength = QInputDialog::getDouble("Xbrabo", tr("Change the distance between atoms ")+QString::number(atom1+1)+" and "+QString::number(atom2+1), bondLength, -1000.0, 1000.0, 4, &ok, this);
00185 if(ok && fabs(newLength - bondLength) > 0.00001)
00186 atoms->changeBond(newLength - bondLength, atom1, atom2, true);
00187 else
00188 return;
00189 break;
00190 }
00191
00192 case SELECTION_ANGLE:
00193 {
00194 std::list<unsigned int>::iterator it = selectionList.begin();
00195 unsigned int atom1 = *it++;
00196 unsigned int atom2 = *it++;
00197 unsigned int atom3 = *it;
00199 Vector3D<double> bond1(atoms->x(atom2), atoms->y(atom2), atoms->z(atom2), atoms->x(atom1), atoms->y(atom1), atoms->z(atom1));
00200 Vector3D<double> bond2(atoms->x(atom2), atoms->y(atom2), atoms->z(atom2), atoms->x(atom3), atoms->y(atom3), atoms->z(atom3));
00201 double angle = bond1.angle(bond2);
00202 bool ok;
00203 double newAngle = QInputDialog::getDouble("Xbrabo", tr("Change the angle ")+QString::number(atom1+1)+"-"+QString::number(atom2+1)+"-"+QString::number(atom3+1), angle, -1000.0, 1000.0, 2, &ok, this);
00204 if(ok && fabs(newAngle - angle) > 0.001)
00205 atoms->changeAngle(newAngle - angle, atom1, atom2, atom3, true);
00206 else
00207 return;
00208 break;
00209 }
00210
00211 case SELECTION_TORSION:
00212 {
00213 std::list<unsigned int>::iterator it = selectionList.begin();
00214 unsigned int atom1 = *it++;
00215 unsigned int atom2 = *it++;
00216 unsigned int atom3 = *it++;
00217 unsigned int atom4 = *it;
00219 Vector3D<double> bond1(atoms->x(atom2), atoms->y(atom2), atoms->z(atom2), atoms->x(atom1), atoms->y(atom1), atoms->z(atom1));
00220 Vector3D<double> centralbond(atoms->x(atom2), atoms->y(atom2), atoms->z(atom2), atoms->x(atom3), atoms->y(atom3), atoms->z(atom3));
00221 Vector3D<double> bond2(atoms->x(atom3), atoms->y(atom3), atoms->z(atom3), atoms->x(atom4), atoms->y(atom4), atoms->z(atom4));
00222 double torsion = bond1.torsion(bond2, centralbond);
00223 bool ok;
00224 double newTorsion = QInputDialog::getDouble("Xbrabo", tr("Change the torsion angle ")+QString::number(atom1+1)+"-"+QString::number(atom2+1)+"-"+QString::number(atom3+1)+"-"+QString::number(atom4+1), torsion, -1000.0, 1000.0, 2, &ok, this);
00225 if(ok && fabs(newTorsion - torsion) > 0.001)
00226 atoms->changeTorsion(torsion - newTorsion, atom1, atom2, atom3, atom4, true);
00227 else
00228 return;
00229 break;
00230 }
00231 default: return;
00232 }
00233 setModified();
00234 updateAtomSet();
00235 }
00236
00238 void GLMoleculeView::showDensity()
00240 {
00241 if(densityDialog == NULL)
00242 {
00243 densityDialog = new DensityBase(isoSurface, this);
00244 connect(densityDialog, SIGNAL(newSurface(const unsigned int)), this, SLOT(addGLSurface(const unsigned int)));
00245 connect(densityDialog, SIGNAL(updatedSurface(const unsigned int)), this, SLOT(updateGLSurface(const unsigned int)));
00246 connect(densityDialog, SIGNAL(deletedSurface(const unsigned int)), this, SLOT(deleteGLSurface(const unsigned int)));
00247 connect(densityDialog, SIGNAL(redrawScene()), this, SLOT(updateGL()));
00248 }
00249 densityDialog->show();
00250 if(!isoSurface->densityPresent())
00251 densityDialog->loadDensityA();
00252 }
00253
00255 void GLMoleculeView::addAtoms()
00257 {
00258 if(newAtomDialog == NULL)
00259 {
00260 newAtomDialog = new NewAtomBase(atoms, this);
00261 connect(newAtomDialog, SIGNAL(atomAdded()), this, SLOT(updateAtomSet()));
00262 connect(newAtomDialog, SIGNAL(atomAdded()), this, SLOT(setModified()));
00263 connect(newAtomDialog, SIGNAL(atomAdded()), this, SIGNAL(atomsetChanged()));
00264 }
00265 newAtomDialog->show();
00266 }
00267
00269 void GLMoleculeView::deleteSelectedAtoms()
00271 {
00272 if(selectionList.empty())
00273 return;
00274
00276
00277 std::vector<unsigned int> sortedList;
00278 sortedList.reserve(selectionList.size());
00279 sortedList.assign(selectionList.begin(), selectionList.end());
00280
00281 std::sort(sortedList.begin(), sortedList.end(), std::greater<unsigned int>());
00282
00283 for(unsigned int i = 0; i < sortedList.size(); i++)
00284 atoms->removeAtom(sortedList[i]);
00285
00286 unselectAll();
00287 if(newAtomDialog != 0)
00288 newAtomDialog->updateAtomLimits();
00289 updateAtomSet();
00290 setModified();
00291 emit atomsetChanged();
00292 }
00293
00295 void GLMoleculeView::toggleSelection()
00297 {
00298 manipulateSelection = !manipulateSelection;
00299 }
00300
00304
00306 float GLMoleculeView::boundingSphereRadius()
00310 {
00311 float radius = GLSimpleMoleculeView::boundingSphereRadius();
00312
00313 if(atoms->count() == 0 && isoSurface->densityPresent())
00314 {
00316 Point3D<float> origin = isoSurface->getOrigin();
00317 Point3D<float> delta = isoSurface->getDelta();
00318 Point3D<unsigned int> numPoints = isoSurface->getNumPoints();
00319 float x, y, z;
00320 std::vector<float> squaredR;
00321
00322 squaredR.push_back(static_cast<float>(radius*radius));
00323
00324 x = origin.x() - centerX;
00325 y = origin.y() - centerY;
00326 z = origin.z() - centerZ;
00327 squaredR.push_back(x*x + y*y + z*z);
00328
00329 x = origin.x() + delta.x() * (numPoints.x() - 1) - centerX;
00330 y = origin.y() - centerY;
00331 z = origin.z() - centerZ;
00332 squaredR.push_back(x*x + y*y + z*z);
00333
00334 x = origin.x() - centerX;
00335 y = origin.y() + delta.y() * (numPoints.y() - 1) - centerY;
00336 z = origin.z() - centerZ;
00337 squaredR.push_back(x*x + y*y + z*z);
00338
00339 x = origin.x() - centerX;
00340 y = origin.y() - centerY;
00341 z = origin.z() + delta.z() * (numPoints.z() - 1) - centerZ;
00342 squaredR.push_back(x*x + y*y + z*z);
00343
00344 x = origin.x() + delta.x() * (numPoints.x() - 1) - centerX;
00345 y = origin.y() + delta.y() * (numPoints.y() - 1) - centerY;
00346 z = origin.z() - centerZ;
00347 squaredR.push_back(x*x + y*y + z*z);
00348
00349 x = origin.x() + delta.x() * (numPoints.x() - 1) - centerX;
00350 y = origin.y() - centerY;
00351 z = origin.z() + delta.z() * (numPoints.z() - 1) - centerZ;
00352 squaredR.push_back(x*x + y*y + z*z);
00353
00354 x = origin.x() - centerX;
00355 y = origin.y() + delta.y() * (numPoints.y() - 1) - centerY;
00356 z = origin.z() + delta.z() * (numPoints.z() - 1) - centerZ;
00357 squaredR.push_back(x*x + y*y + z*z);
00358
00359 x = origin.x() + delta.x() * (numPoints.x() - 1) - centerX;
00360 y = origin.y() + delta.y() * (numPoints.y() - 1) - centerY;
00361 z = origin.z() + delta.z() * (numPoints.z() - 1) - centerZ;
00362 squaredR.push_back(x*x + y*y + z*z);
00363
00364 float boxradius = sqrt(*(std::max_element(squaredR.begin(), squaredR.end())));
00365 qDebug("GLMoleculeView::boundingSphereRadius: boxradius = %f, radius = %f",boxradius, radius);
00366 if(boxradius > radius)
00367 radius = boxradius;
00368 }
00369 return radius;
00370 }
00371
00373 void GLMoleculeView::mouseMoveEvent(QMouseEvent* e)
00376 {
00377 QPoint newPosition = e->pos();
00378 if(selectionType != SELECTION_NONE && e->state() & Qt::LeftButton && (manipulateSelection || e->state() & Qt::AltButton) && !(e->state() & Qt::ShiftButton && e->state() & Qt::ControlButton))
00379 {
00381 if(e->state() & Qt::ShiftButton)
00382 {
00385 if(abs(newPosition.y() - mousePosition.y()) > abs(newPosition.x() - mousePosition.x()))
00386 translateSelection(0, 0, newPosition.y() - mousePosition.y());
00387 else if(newPosition.x() != mousePosition.x())
00388 rotateSelection(0.0, 0.0, 180.0 * static_cast<double>(newPosition.x() - mousePosition.x()) / static_cast<double>(width()));
00389 }
00390 else if(e->state() & Qt::ControlButton)
00393 translateSelection(newPosition.x() - mousePosition.x(), newPosition.y() - mousePosition.y(), 0);
00394 else
00397 rotateSelection(-180.0 * static_cast<double>(newPosition.y() - mousePosition.y()) / static_cast<double>(height()),
00398 -180.0 * static_cast<double>(newPosition.x() - mousePosition.x()) / static_cast<double>(width()), 0.0);
00399 }
00400 else if(selectionType >= SELECTION_BOND && selectionType <= SELECTION_TORSION && e->state() & Qt::LeftButton && e->state() & Qt::ShiftButton && e->state() & Qt::ControlButton)
00402 changeSelectedIC(e->pos().x() - mousePosition.x());
00403 else
00404 GLView::mouseMoveEvent(e);
00405
00406 mousePosition = newPosition;
00407 }
00408
00410 void GLMoleculeView::keyPressEvent(QKeyEvent* e)
00413 {
00414 if(selectionType != SELECTION_NONE && (manipulateSelection || e->state() & Qt::AltButton) && !(e->state() & Qt::ShiftButton && e->state() & Qt::ControlButton))
00415 {
00416 switch(e->key())
00417 {
00418 case Qt::Key_Left : if(e->state() & Qt::ShiftButton)
00419 rotateSelection(0.0, 0.0, -5.0);
00420 else if(e->state() & Qt::ControlButton)
00421 translateSelection(-5, 0, 0);
00422 else
00423 rotateSelection(0.0, 5.0, 0.0);
00424 break;
00425
00426 case Qt::Key_Up : if(e->state() & Qt::ShiftButton)
00427 translateSelection(0, 0, -5);
00428 else if(e->state() & Qt::ControlButton)
00429 translateSelection(0, -5, 0);
00430 else
00431 rotateSelection(5.0, 0.0, 0.0);
00432 break;
00433
00434 case Qt::Key_Right: if(e->state() & Qt::ShiftButton)
00435 rotateSelection(0.0, 0.0, 5.0);
00436 else if(e->state() & Qt::ControlButton)
00437 translateSelection(5, 0, 0);
00438 else
00439 rotateSelection(0.0, -5.0, 0.0);
00440 break;
00441
00442 case Qt::Key_Down : if(e->state() & Qt::ShiftButton)
00443 translateSelection(0, 0, 5);
00444 else if(e->state() & Qt::ControlButton)
00445 translateSelection(0, 5, 0);
00446 else
00447 rotateSelection(-5.0, 0.0, 0.0);
00448 break;
00449
00450
00451
00452 }
00453 }
00454 else if(selectionType >= SELECTION_BOND && selectionType <= SELECTION_TORSION && e->state() & Qt::ShiftButton && e->state() & Qt::ControlButton)
00455 {
00456 switch(e->key())
00457 {
00458 case Qt::Key_Left : changeSelectedIC(-1);
00459 break;
00460 case Qt::Key_Right: changeSelectedIC(1);
00461 break;
00462
00463
00464 }
00465 }
00466 else
00467 GLSimpleMoleculeView::keyPressEvent(e);
00468 }
00469
00471 void GLMoleculeView::updateShapes()
00474 {
00475 GLSimpleMoleculeView::updateShapes();
00476
00477 ShapeProperties prop;
00478
00480 for(unsigned int i = 0; i < isoSurface->numSurfaces(); i++)
00481 {
00482 prop.id = i;
00483 if(densityDialog->surfaceType(i) == 0)
00484 prop.opacity = densityDialog->surfaceOpacity(i);
00485 else
00486 prop.opacity = 100;
00487 prop.type = SHAPE_SURFACE;
00488 shapes.push_back(prop);
00489 }
00490 }
00491
00495
00497 void GLMoleculeView::addGLSurface(const unsigned int index)
00499 {
00501 makeCurrent();
00502 GLuint newList = glGenLists(1);
00503 glSurfaces.push_back(newList);
00504
00506 if(glSurfaces.size() == 1 && atoms->count() == 0)
00507 zoomFit(false);
00508
00509 qDebug("creating surface %d", index);
00511 updateGLSurface(index);
00512 }
00513
00515 void GLMoleculeView::updateGLSurface(const unsigned int index)
00517 {
00518 makeCurrent();
00519 QColor surfaceColor = densityDialog->surfaceColor(index);
00520 unsigned int surfaceOpacity = densityDialog->surfaceOpacity(index);
00521 Point3D<float> point1, point2, point3, normal1, normal2, normal3;
00522
00523 qDebug("updating surface %d", index);
00524 qDebug(" which consists of %d vertices and %d triangles",isoSurface->numVertices(index),isoSurface->numTriangles(index));
00525 qDebug(" with color %d, %d, %d and opacity %d", surfaceColor.red(), surfaceColor.green(), surfaceColor.blue(), surfaceOpacity);
00526 glNewList(glSurfaces[index], GL_COMPILE);
00527 switch(densityDialog->surfaceType(index))
00528 {
00529 case 0:
00530 glBegin(GL_TRIANGLES);
00531 glColor4d(surfaceColor.red()/255.0, surfaceColor.green()/255.0, surfaceColor.blue()/255, surfaceOpacity/100.0);
00532 for(unsigned int i = 0; i < isoSurface->numTriangles(index); i++)
00533 {
00534 isoSurface->getTriangle(index, i, point1, point2, point3, normal1, normal2, normal3);
00535 glNormal3f(normal1.x(), normal1.y(), normal1.z());
00536 glVertex3f(point1.x(), point1.y(), point1.z());
00537 glNormal3f(normal2.x(), normal2.y(), normal2.z());
00538 glVertex3f(point2.x(), point2.y(), point2.z());
00539 glNormal3f(normal3.x(), normal3.y(), normal3.z());
00540 glVertex3f(point3.x(), point3.y(), point3.z());
00541 }
00542 glEnd();
00543 break;
00544 case 1:
00545
00546 {
00547 double lw, ps;
00548 glGetDoublev(GL_LINE_WIDTH, &lw);
00549 glGetDoublev(GL_POINT_SIZE, &ps);
00550 qDebug("linewidth and pointsize used for generating: %f and %f", lw, ps);
00551 }
00552 glBegin(GL_LINES);
00553 glColor3d(surfaceColor.red()/255.0, surfaceColor.green()/255.0, surfaceColor.blue()/255.0);
00554 for(unsigned int i = 0; i < isoSurface->numTriangles(index); i++)
00555 {
00556 isoSurface->getTriangle(index, i, point1, point2, point3, normal1, normal2, normal3);
00557 glVertex3f(point1.x(), point1.y(), point1.z());
00558 glVertex3f(point2.x(), point2.y(), point2.z());
00559 glVertex3f(point1.x(), point1.y(), point1.z());
00560 glVertex3f(point3.x(), point3.y(), point3.z());
00561 glVertex3f(point2.x(), point2.y(), point2.z());
00562 glVertex3f(point3.x(), point3.y(), point3.z());
00563 }
00564 glEnd();
00565 break;
00566 case 2:
00567 glPointSize(1.0);
00568 glBegin(GL_POINTS);
00569 glColor3d(surfaceColor.red()/255.0, surfaceColor.green()/255.0, surfaceColor.blue()/255.0);
00570 for(unsigned int i = 0; i < isoSurface->numVertices(index); i++)
00571 {
00572 point1 = isoSurface->getPoint(index, i);
00573 glVertex3f(point1.x(), point1.y(), point1.z());
00574 }
00575 glEnd();
00576 }
00577 glEndList();
00578 reorderShapes();
00579 }
00580
00582 void GLMoleculeView::deleteGLSurface(const unsigned int index)
00584 {
00585 makeCurrent();
00586 glDeleteLists(glSurfaces[index], 1);
00587 std::vector<GLuint>::iterator it = glSurfaces.begin();
00588 it += index;
00589 glSurfaces.erase(it);
00590 reorderShapes();
00591 }
00592
00596
00598 void GLMoleculeView::translateSelection(const int xRange, const int yRange, const int zRange)
00600 {
00601 if(selectionList.empty())
00602 return;
00603
00604 makeCurrent();
00605
00606 GLdouble modelview[16];
00607 GLdouble projection[16];
00608 GLint viewport[4];
00609
00610
00611 Vector3D<float> axis;
00612 float angle;
00613 orientationQuaternion->getAxisAngle(axis, angle);
00614 glPushMatrix();
00615 glTranslatef(xPos, yPos, 0.0f);
00616 glRotatef(angle, axis.x(), axis.y(), axis.z());
00617 glGetDoublev(GL_MODELVIEW_MATRIX, modelview);
00618 glPopMatrix();
00619
00620
00621 glGetDoublev(GL_PROJECTION_MATRIX, projection);
00622 glGetIntegerv(GL_VIEWPORT, viewport);
00623
00625 GLdouble x, y, z, xwin, ywin, zwin;
00626 std::list<unsigned int>::iterator it = selectionList.begin();
00627
00628
00629 x = atoms->x(*it);
00630 y = atoms->y(*it);
00631 z = atoms->z(*it);
00632
00633
00634 if(gluProject(x, y, z, modelview, projection, viewport, &xwin, &ywin, &zwin) == GL_FALSE)
00635 return;
00636
00637
00638 xwin += static_cast<double>(xRange);
00639 ywin -= static_cast<double>(yRange);
00640 if(baseParameters.perspectiveProjection)
00641 zwin += static_cast<double>(zRange)/10000.0;
00642 else
00643 zwin += static_cast<double>(zRange)/100.0;
00644
00645
00646
00647 if(gluUnProject(xwin, ywin, zwin, modelview, projection, viewport, &x, &y, &z) == GL_FALSE)
00648 return;
00649
00650
00651 const double dx = x - atoms->x(*it);
00652 const double dy = y - atoms->y(*it);
00653 const double dz = z - atoms->z(*it);
00654
00655
00656 while(it != selectionList.end())
00657 {
00658 atoms->setX(*it, atoms->x(*it) + dx);
00659 atoms->setY(*it, atoms->y(*it) + dy);
00660 atoms->setZ(*it, atoms->z(*it) + dz);
00661 it++;
00662 }
00663
00664 updateAtomSet();
00665 setModified();
00666 }
00667
00669 void GLMoleculeView::rotateSelection(const double angleX, const double angleY, const double angleZ)
00671 {
00672 if(selectionList.empty())
00673 return;
00674
00679
00680 Vector3D<double> axis;
00681 double angle;
00682 Quaternion<double> q(angleX, angleY, angleZ);
00683 q.getAxisAngle(axis, angle);
00684 Vector3D<float> axis2;
00685 float angle2;
00686 orientationQuaternion->getAxisAngle(axis2, angle2);
00687 double backAngle = - angle2;
00688 Vector3D<double> backAxis(axis2.x(), axis2.y(), axis2.z());
00689
00690
00691
00692
00693
00694
00695
00696
00697
00698
00699
00700
00701
00702 if(fabs(angle) < Point3D<double>::TOLERANCE)
00703 return;
00704
00706 Point3D<double> centerOfMass(0.0, 0.0, 0.0);
00707 std::list<unsigned int>::iterator it = selectionList.begin();
00708 while(it != selectionList.end())
00709 centerOfMass.add(atoms->coordinates(*it++));
00710 centerOfMass.setValues(centerOfMass.x()/selectionList.size(), centerOfMass.y()/selectionList.size(), centerOfMass.z()/selectionList.size());
00711
00712
00714 it = selectionList.begin();
00715 while(it != selectionList.end())
00716 {
00717 Vector3D<double> v(centerOfMass, atoms->coordinates(*it));
00718
00719 v.rotate(backAxis, backAngle);
00720 v.rotate(axis, angle);
00721 v.rotate(backAxis, -backAngle);
00722 atoms->setX(*it, centerOfMass.x() + v.x());
00723 atoms->setY(*it, centerOfMass.y() + v.y());
00724 atoms->setZ(*it, centerOfMass.z() + v.z());
00725 it++;
00726 }
00727 updateAtomSet();
00728 setModified();
00729 }
00730
00732 void GLMoleculeView::changeSelectedIC(const int range)
00735 {
00736 if(range == 0)
00737 return;
00738
00739 unsigned int atom1, atom2, atom3, atom4;
00740 std::list<unsigned int>::iterator it = selectionList.begin();
00741 switch(selectionType)
00742 {
00743 case SELECTION_BOND: atom1 = *it++;
00744 atom2 = *it;
00745 atoms->changeBond(static_cast<double>(range) * 0.1, atom1, atom2, true);
00746 break;
00747
00748 case SELECTION_ANGLE: atom1 = *it++;
00749 atom2 = *it++;
00750 atom3 = *it;
00751 atoms->changeAngle(180.0 * static_cast<double>(range) / static_cast<double>(width()), atom1, atom2, atom3, true);
00752 break;
00753 case SELECTION_TORSION: atom1 = *it++;
00754 atom2 = *it++;
00755 atom3 = *it++;
00756 atom4 = *it;
00757 atoms->changeTorsion(-180.0 * static_cast<double>(range) / static_cast<double>(width()), atom1, atom2, atom3, atom4, true);
00758 break;
00759 }
00760 updateAtomSet();
00761 setModified();
00762 }
00763
00765 void GLMoleculeView::drawItem(const unsigned int index)
00767 {
00768 if(shapes[index].type != SHAPE_SURFACE)
00769 return;
00770
00771 const unsigned int currentSurface = shapes[index].id;
00772 if(currentSurface >= isoSurface->numSurfaces())
00773 return;
00774
00775 if(densityDialog->surfaceVisible(currentSurface))
00776 {
00777 if(densityDialog->surfaceType(currentSurface) == 0)
00778 {
00779 glCallList(glSurfaces[currentSurface]);
00780 }
00781 else
00782 {
00783 glDisable(GL_LIGHTING);
00784 glCallList(glSurfaces[currentSurface]);
00785 glEnable(GL_LIGHTING);
00786 }
00787 }
00788 }
00789