[kboincspy-cvs] SF.net SVN: kboincspy: [738] trunk/kboincspy
Status: Beta
Brought to you by:
rvirga
From: <rv...@us...> - 2006-04-07 02:20:08
|
Revision: 738 Author: rvirga Date: 2006-04-06 19:19:45 -0700 (Thu, 06 Apr 2006) ViewCVS: http://svn.sourceforge.net/kboincspy/?rev=738&view=rev Log Message: ----------- removed COMPILE_GL_SOURCES, in favor of a more fine-grained approach. KBoincSpy has been tested to compile both with the default configuration and with --without-gl. Modified Paths: -------------- trunk/kboincspy/configure.in.in trunk/kboincspy/kboincspy.kdevelop trunk/kboincspy/src/monitors/common/molbio/Makefile.am trunk/kboincspy/src/monitors/common/molbio/kbsmoleculelog.h trunk/kboincspy/src/monitors/common/molbio/kbsmoleculeview.cpp trunk/kboincspy/src/monitors/common/molbio/kbsmoleculeview.h trunk/kboincspy/src/monitors/common/molbio/kbsmoleculewindow.cpp trunk/kboincspy/src/panels/lhc/Makefile.am trunk/kboincspy/src/panels/lhc/tracking/kbslhcparticleview.cpp trunk/kboincspy/src/panels/lhc/tracking/kbslhcparticleview.h trunk/kboincspy/src/panels/lhc/tracking/kbslhctrackingdetailswindow.cpp trunk/kboincspy/src/panels/lhc/tracking/kbslhctrackingdetailswindow.h trunk/kboincspy/src/panels/lhc/tracking/kbslhctrackingpanelnode.cpp trunk/kboincspy/src/panels/lhc/tracking/kbslhctrackingpanelnode.h trunk/kboincspy/src/panels/predictor/folding/kbscharmmfoldingpanelnode.h Added Paths: ----------- trunk/kboincspy/src/monitors/common/molbio/kbsmoleculemodel.cpp trunk/kboincspy/src/monitors/common/molbio/kbsmoleculemodel.h Modified: trunk/kboincspy/configure.in.in =================================================================== --- trunk/kboincspy/configure.in.in 2006-04-06 17:55:22 UTC (rev 737) +++ trunk/kboincspy/configure.in.in 2006-04-07 02:19:45 UTC (rev 738) @@ -5,8 +5,7 @@ AC_C_BIGENDIAN AC_CHECK_KDEMAXPATHLEN -AC_HAVE_GL(have_gl=yes, have_gl=no) -AM_CONDITIONAL(COMPILE_GL_SOURCES, test x$have_gl = xyes) +AC_HAVE_GL dnl KBoincSpy headers and libraries AC_SUBST(KBSCORE_INCLUDES, '-I$(top_srcdir)/src/kbscore -I$(top_builddir)/src/kbscore') Modified: trunk/kboincspy/kboincspy.kdevelop =================================================================== --- trunk/kboincspy/kboincspy.kdevelop 2006-04-06 17:55:22 UTC (rev 737) +++ trunk/kboincspy/kboincspy.kdevelop 2006-04-07 02:19:45 UTC (rev 738) @@ -14,7 +14,7 @@ </keywords> <projectdirectory>.</projectdirectory> <absoluteprojectpath>false</absoluteprojectpath> - <description/> + <description></description> <ignoreparts> <part>kdevabbrev</part> <part>kdevbookmarks</part> @@ -37,12 +37,12 @@ <part>kdevvalgrind</part> </ignoreparts> <secondaryLanguages/> - <versioncontrol>kdevcvsservice</versioncontrol> + <versioncontrol>kdevsubversion</versioncontrol> </general> <kdevautoproject> <general> <activetarget>src/monitors/predictor/libkbspredictormonitor.la</activetarget> - <useconfiguration>optimized</useconfiguration> + <useconfiguration>debug</useconfiguration> </general> <run> <mainprogram>src/kboincspy</mainprogram> @@ -187,15 +187,15 @@ <kdevdebugger> <general> <dbgshell>libtool</dbgshell> - <programargs/> - <gdbpath/> + <programargs></programargs> + <gdbpath></gdbpath> <breakonloadinglibs>true</breakonloadinglibs> <separatetty>false</separatetty> <floatingtoolbar>false</floatingtoolbar> <runappinappdirectory>true</runappinappdirectory> - <configGdbScript/> - <runShellScript/> - <runGdbScript/> + <configGdbScript></configGdbScript> + <runShellScript></runShellScript> + <runGdbScript></runGdbScript> </general> <display> <staticmembers>false</staticmembers> @@ -269,7 +269,7 @@ <headerCompletionDelay>250</headerCompletionDelay> </codecompletion> <creategettersetter> - <prefixGet/> + <prefixGet></prefixGet> <prefixSet>set</prefixSet> <prefixVariable>m_,_</prefixVariable> <parameterName>theValue</parameterName> Modified: trunk/kboincspy/src/monitors/common/molbio/Makefile.am =================================================================== --- trunk/kboincspy/src/monitors/common/molbio/Makefile.am 2006-04-06 17:55:22 UTC (rev 737) +++ trunk/kboincspy/src/monitors/common/molbio/Makefile.am 2006-04-07 02:19:45 UTC (rev 738) @@ -6,9 +6,9 @@ libkbsmolbio_la_LIBADD = $(LIB_KDECORE) $(LIB_KBSCORE) $(GLLIB) libkbsmolbio_la_SOURCES = kbsmolbiodata.cpp kbsmoleculelog.cpp \ - kbsmoleculeview.cpp kbsmoleculewindow.cpp + kbsmoleculemodel.cpp kbsmoleculeview.cpp kbsmoleculewindow.cpp include_HEADERS = kbsmolbiodata.h kbsmoleculelog.h \ - kbsmoleculeview.h kbsmoleculewindow.h + kbsmoleculemodel.h kbsmoleculeview.h kbsmoleculewindow.h METASOURCES = AUTO Modified: trunk/kboincspy/src/monitors/common/molbio/kbsmoleculelog.h =================================================================== --- trunk/kboincspy/src/monitors/common/molbio/kbsmoleculelog.h 2006-04-06 17:55:22 UTC (rev 737) +++ trunk/kboincspy/src/monitors/common/molbio/kbsmoleculelog.h 2006-04-07 02:19:45 UTC (rev 738) @@ -23,7 +23,7 @@ #include <kurl.h> -#include <kbsmoleculeview.h> +#include <kbsmoleculemodel.h> class KBSMoleculeLog { Added: trunk/kboincspy/src/monitors/common/molbio/kbsmoleculemodel.cpp =================================================================== --- trunk/kboincspy/src/monitors/common/molbio/kbsmoleculemodel.cpp (rev 0) +++ trunk/kboincspy/src/monitors/common/molbio/kbsmoleculemodel.cpp 2006-04-07 02:19:45 UTC (rev 738) @@ -0,0 +1,1085 @@ +/*************************************************************************** + * Copyright (C) 2006 by Roberto Virga * + * rv...@us... * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Library General Public License as * + * published by the Free Software Foundation; either version 2 of the * + * License, or (at your option) any later version. * + * * + * 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. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#include <math.h> + +#include <qdom.h> +#include <qfile.h> +#include <qfont.h> +#include <qfontmetrics.h> +#include <qimage.h> +#include <qmap.h> +#include <qpainter.h> +#include <qpixmap.h> +#include <qtextstream.h> + +#include <kaboutdata.h> +#include <kfilterdev.h> +#include <kglobal.h> +#include <kinstance.h> + +#include "kbsmoleculemodel.h" + +using namespace KBSMolBio; + +QColor progressColor(double progress) +{ + double r, g, b; + if(progress <= 0.25) { + r = 0.0; + g = progress / 0.25; + b = 1.0; + } else if(progress <= 0.50) { + r = 0.0; + g = 1.0; + b = 1.0 - (progress - 0.25) / 0.25; + } else if(progress <= 0.75) { + r = (progress - 0.50) / 0.25; + g = 1.0; + b = 0.0; + } else { + r = 1.0; + g = 1.0 - (progress - 0.75) / 0.25; + b = 0.0; + } + + return QColor(int(r * 255), int(g * 255), int(b * 255)); +} + +const unsigned KBSAminoAcidColor[AminoAcids+1] = + {0xEBEBEB, 0xC8C8C8, 0xFA9600, 0xE6E600, 0x0F820F, 0xFA9600, 0x0F820F, + 0xDC9682, 0xE6E600, 0xE60A0A, 0x00DCDC, 0x0F820F, 0x145AFF, 0xE60A0A, + 0x00DCDC, 0x145AFF, 0x8282D2, 0x3232AA, 0x3232AA, 0xB45AB4, 0xBEA06E}; + +QColor shapelyColor(KBSAminoAcid aa) +{ + return QColor(KBSAminoAcidColor[aa]); +} + +const unsigned KBSElementColor[Elements+1] = + {0xFFFFFF, 0xFFC0CB, 0xB22222, 0x00FF00, 0xC8C8C8, 0x8F8FFF, 0xF00000, + 0xDAA520, 0xFF1493, 0x0000FF, 0x228B22, 0x808090, 0xDAA520, 0xFFA500, + 0xFFC832, 0x00FF00, 0xFF1493, 0xFF1493, 0x808090, 0x808090, 0x808090, + 0x808090, 0xFFA500, 0xA52A2A, 0xA52A2A, 0xA52A2A, 0xFF1493, 0xFF1493, + 0xFF1493, 0xA52A2A, 0xFF1493, 0xFF1493, 0x808090, 0xFF1493, 0xFF1493, + 0xFF1493, 0xFF1493, 0xA020F0, 0xFF1493, 0xFFA500, 0xFF1493, 0xDAA520, + 0xFF1493, 0xFF1493, 0xFF1493, 0xFF1493, 0xFF1493}; + +QColor cpkColor(KBSElement element) +{ + return QColor(KBSElementColor[element]); +} + +const unsigned KBSFeatureColor[Features+1] = + {0xF00080, 0xFFFF00, 0x6080FF, 0xFFFFFF}; + +QColor structureColor(KBSFeature feature) +{ + return QColor(KBSFeatureColor[feature]); +} + +QColor monochromeColor() +{ + return Qt::lightGray; +} + +double dotProduct(double *v1, double *v2) +{ + return v1[0] * v2[0] + v1[1] * v2[1] + v1[2] * v2[2]; +} + +void crossProduct(double *v1, double *v2, double *v3) +{ + v3[0] = v1[1] * v2[2] - v1[2] * v2[1]; + v3[1] = v1[2] * v2[0] - v1[0] * v2[2]; + v3[2] = v1[0] * v2[1] - v2[1] * v1[0]; +} + +double norm(double *v) +{ + return sqrt(dotProduct(v, v)); +} + +void normalize(double *v) +{ + double n = norm(v); + v[0] /= n; v[1] /= n; v[2] /= n; +} + +double distance(double *v1, double *v2) +{ + double v[] = { + v1[0] - v2[0], + v1[1] - v2[1], + v1[2] - v2[2] + }; + + return norm(v); +} + +KBSVRMLRenderer::KBSVRMLRenderer(const QString &fileName) + : KBSMoleculeRenderer(), m_color("0 0 0"), m_open(false) +{ + QIODevice *device = KFilterDev::deviceForFile(fileName, "application/x-gzip", true); + + if(device->open(IO_WriteOnly)) + { + m_text.setDevice(device); + + const KAboutData *aboutData = KGlobal::instance()->aboutData(); + QString comment = i18n("Generated by %1 %2").arg(aboutData->programName()) + .arg(aboutData->version()); + m_text << QString("#VRML V2.0 utf8 %1\n").arg(comment); + + m_text << "NavigationInfo { type \"EXAMINE\" }\n"; + m_text << "Group { children [\n"; + + m_open = true; + } + else + delete device; +} + +KBSVRMLRenderer::~ KBSVRMLRenderer() +{ + close(); +} + +bool KBSVRMLRenderer::isOpen() const +{ + return m_open; +} + +void KBSVRMLRenderer::close() +{ + if(!m_open) return; + + if(!m_lineCoords.isEmpty()) + { + m_text << "Shape {\n"; + m_text << "geometry IndexedLineSet {\n"; + + QString indices; + for(unsigned i = 0; i < m_lineCoords.count(); i+=2) + indices += QString("%1 %2 -1 ").arg(i).arg(i+1); + + m_text << "coord Coordinate { point [ " << m_lineCoords.join(", ") << " ] }\n"; + m_text << "coordIndex [ " << indices << "]\n"; + m_text << "color Color { color [ " << m_lineColors.join(", ") << " ] }\n"; + m_text << "colorIndex [ " << indices << "]\n"; + + m_text << "}\n"; // IndexedLineSet + m_text << "}\n"; // Shape + } + + if(!m_faceCoords.isEmpty()) + { + m_text << "Shape {\n"; + m_text << "geometry IndexedFaceSet {"; + + QString indices; + for(unsigned i = 0; i < m_lineCoords.count(); i+=4) + indices += QString("%1 %2 %3 -1 %4 %5 %6 -1 ").arg(i).arg(i+1).arg(i+2) + .arg(i+1).arg(i+2).arg(i+3); + + m_text << "coord Coordinate { point [ " << m_lineCoords.join(", ") << " ] }\n"; + m_text << "color Color { color [ " << m_lineColors.join(", ") << " ] }\n"; + m_text << "coordIndex [ " << indices << "]\n"; + m_text << "colorIndex [ " << indices << "]\n"; + + m_text << "}\n"; // IndexedFaceSet + m_text << "}\n"; // Shape + } + + m_text << "]\n"; // children + m_text << "}\n"; // Group + + QIODevice *device = m_text.device(); + device->close(); + delete device; + + m_open = false; +} + +void KBSVRMLRenderer::setColor(QColor color) +{ + m_color = QString("%1 %2 %3").arg(double(color.red()) / 255) + .arg(double(color.green()) / 255) + .arg(double(color.blue()) / 255); +} + +void KBSVRMLRenderer::drawBall(double *v, double radius) +{ + if(!m_open || radius <= 0) return; + + m_text << "Transform {\n"; + + m_text << QString("translation %1 %2 %3\n").arg(v[0]).arg(v[1]).arg(v[2]); + + m_text << "children "; + + m_text << "Shape {\n"; + + m_text << QString("geometry Sphere { radius %1 }\n").arg(radius * 0.09); + + m_text << "appearance Appearance {\n"; + + m_text << "material Material { diffuseColor " << m_color << " }\n"; + + m_text << "}\n"; // Appearance + + m_text << "}\n"; // Shape + + m_text << "}\n"; // Transform +} + +void KBSVRMLRenderer::drawLine(double *v1, double *v2, double thickness) +{ + if(!m_open) return; + + if(thickness > 0) + { + const double radius = thickness * 0.03; + + { + m_text << "Transform {\n"; + + m_text << QString("translation %1 %2 %3\n").arg(v1[0]).arg(v1[1]).arg(v1[2]); + + m_text << "children Shape {\n"; + + m_text << QString("geometry Sphere { radius %1 }\n").arg(radius); + + m_text << "appearance Appearance {\n"; + + m_text << "material Material { diffuseColor " << m_color << " }\n"; + + m_text << "}\n"; // Appearance + + m_text << "}\n"; // Shape + + m_text << "}\n"; // Transform + } + + { + m_text << "Transform {\n"; + + m_text << QString("translation %1 %2 %3\n").arg(v2[0]).arg(v2[1]).arg(v2[2]); + + m_text << "children Shape {\n"; + + m_text << QString("geometry Sphere { radius %1 }\n").arg(radius); + + m_text << "appearance Appearance {\n"; + + m_text << "material Material { diffuseColor " << m_color << " }\n"; + + m_text << "}\n"; // Appearance + + m_text << "}\n"; // Shape + + m_text << "}\n"; // Transform + } + + { + double v[] = { + (v1[0] + v2[0]) / 2, + (v1[1] + v2[1]) / 2, + (v1[2] + v2[2]) / 2 + }; + + const double dx = v1[0] - v2[0], + dy = v1[1] - v2[1], + dz = v1[2] - v2[2]; + + const double height = sqrt(dx * dx + dy * dy + dz * dz), + alpha = acos(dy / height); + + m_text << "Transform {\n"; + + m_text << QString("translation %1 %2 %3\n").arg(v[0]).arg(v[1]).arg(v[2]); + + m_text << QString("rotation %1 0 %2 %3").arg(dz).arg(-dx).arg(alpha); + + m_text << "children Shape {\n"; + + m_text << "geometry Cylinder {\n"; + + m_text << QString("radius %1 height %2\n").arg(radius).arg(height); + + m_text << "}\n"; // Cylinder + + m_text << "appearance Appearance {\n"; + + m_text << "material Material { diffuseColor " << m_color << " }\n"; + + m_text << "}\n"; // Appearance + + m_text << "}\n"; // Shape + + m_text << "}\n"; // Transform + } + } + else + { + m_lineCoords << QString("%1 %2 %3").arg(v1[0]).arg(v1[1]).arg(v1[2]); + m_lineCoords << QString("%1 %2 %3").arg(v2[0]).arg(v2[1]).arg(v2[2]); + m_lineColors << m_color << m_color; + } +} + +void KBSVRMLRenderer::drawQuadrangle(double *v1, double *v2, double *v3, double *v4) +{ + if(!m_open) return; + + m_faceCoords << QString("%1 %2 %3").arg(v1[0]).arg(v1[1]).arg(v1[2]); + m_faceCoords << QString("%1 %2 %3").arg(v2[0]).arg(v2[1]).arg(v2[2]); + m_faceCoords << QString("%1 %2 %3").arg(v3[0]).arg(v3[1]).arg(v3[2]); + m_faceCoords << QString("%1 %2 %3").arg(v4[0]).arg(v4[1]).arg(v4[2]); + m_faceColors << m_color << m_color << m_color << m_color; +} + +KBSX3DRenderer::KBSX3DRenderer(const QString &fileName) + : KBSMoleculeRenderer(), m_color("0 0 0"), m_open(false) +{ + QIODevice *device = KFilterDev::deviceForFile(fileName, "application/x-gzip", true); + + if(device->open(IO_WriteOnly)) + { + m_text.setDevice(device); + + m_text << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"; + + QDomDocumentType docType = QDomImplementation().createDocumentType( + "X3D", + "ISO//Web3D//DTD X3D 3.0//EN", + "http://www.web3d.org/specifications/x3d-3.0.dtd" + ); + + m_doc = QDomDocument(docType); + + QDomElement x3d = m_doc.createElement("X3D"); + x3d.setAttribute("profile", "Immersive"); + m_doc.appendChild(x3d); + + QDomElement scene = m_doc.createElement("Scene"); + x3d.appendChild(scene); + + QDomElement navigationInfo = m_doc.createElement("NavigationInfo"); + navigationInfo.setAttribute("type", "EXAMINE"); + scene.appendChild(navigationInfo); + + m_group = m_doc.createElement("Group"); + scene.appendChild(m_group); + + m_open = true; + } + else + delete device; +} + +KBSX3DRenderer::~ KBSX3DRenderer() +{ + close(); +} + +bool KBSX3DRenderer::isOpen() const +{ + return m_open; +} + +void KBSX3DRenderer::close() +{ + if(!m_open) return; + + if(!m_lineCoords.isEmpty()) + { + QDomElement shape = m_doc.createElement("Shape"); + m_group.appendChild(shape); + + QString indices; + for(unsigned i = 0; i < m_lineCoords.count(); i+=2) + indices += QString("%1 %2 -1 ").arg(i).arg(i+1); + + QDomElement indexedLineSet = m_doc.createElement("IndexedLineSet"); + indexedLineSet.setAttribute("coordIndex", indices); + indexedLineSet.setAttribute("colorIndex", indices); + shape.appendChild(indexedLineSet); + + QDomElement coordinate = m_doc.createElement("Coordinate"); + coordinate.setAttribute("point", m_lineCoords.join(", ")); + indexedLineSet.appendChild(coordinate); + + QDomElement color = m_doc.createElement("Color"); + color.setAttribute("color", m_lineColors.join(", ")); + indexedLineSet.appendChild(color); + } + + if(!m_faceCoords.isEmpty()) + { + QDomElement shape = m_doc.createElement("Shape"); + m_group.appendChild(shape); + + QString indices; + for(unsigned i = 0; i < m_faceCoords.count(); i+=4) + indices += QString("%1 %2 %3 -1 %4 %5 %6 -1 ").arg(i).arg(i+1).arg(i+2) + .arg(i+1).arg(i+2).arg(i+3); + + QDomElement indexedFaceSet = m_doc.createElement("IndexedFaceSet"); + indexedFaceSet.setAttribute("coordIndex", indices); + indexedFaceSet.setAttribute("colorIndex", indices); + shape.appendChild(indexedFaceSet); + + QDomElement coordinate = m_doc.createElement("Coordinate"); + coordinate.setAttribute("point", m_faceCoords.join(", ")); + indexedFaceSet.appendChild(coordinate); + + QDomElement color = m_doc.createElement("Color"); + color.setAttribute("color", m_faceColors.join(", ")); + indexedFaceSet.appendChild(color); + } + + m_text << m_doc.toString(); + + QIODevice *device = m_text.device(); + device->close(); + delete device; + + m_open = false; +} + +void KBSX3DRenderer::setColor(QColor color) +{ + m_color = QString("%1 %2 %3").arg(double(color.red()) / 255) + .arg(double(color.green()) / 255) + .arg(double(color.blue()) / 255); +} + +void KBSX3DRenderer::drawBall(double *v, double radius) +{ + if(!m_open || radius <= 0) return; + + const QString coord = QString("%1 %2 %3").arg(v[0]).arg(v[1]).arg(v[2]); + + QDomElement transform = m_doc.createElement("Transform"); + transform.setAttribute("translation", coord); + m_group.appendChild(transform); + + QDomElement shape = m_doc.createElement("Shape"); + transform.appendChild(shape); + + QDomElement sphere = m_doc.createElement("Sphere"); + sphere.setAttribute("radius", radius * 0.1); + shape.appendChild(sphere); + + QDomElement appearance = m_doc.createElement("Appearance"); + shape.appendChild(appearance); + + QDomElement material = m_doc.createElement("Material"); + material.setAttribute("diffuseColor", m_color); + appearance.appendChild(material); +} + +void KBSX3DRenderer::drawLine(double *v1, double *v2, double thickness) +{ + if(!m_open) return; + + if(thickness > 0.0) + { + const double radius = thickness * 0.03; + + { + const QString coord = QString("%1 %2 %3").arg(v1[0]).arg(v1[1]).arg(v1[2]); + + QDomElement transform = m_doc.createElement("Transform"); + transform.setAttribute("translation", coord); + m_group.appendChild(transform); + + QDomElement shape = m_doc.createElement("Shape"); + transform.appendChild(shape); + + QDomElement sphere = m_doc.createElement("Sphere"); + sphere.setAttribute("radius", radius); + shape.appendChild(sphere); + + QDomElement appearance = m_doc.createElement("Appearance"); + shape.appendChild(appearance); + + QDomElement material = m_doc.createElement("Material"); + material.setAttribute("diffuseColor", m_color); + appearance.appendChild(material); + } + + { + const QString coord = QString("%1 %2 %3").arg(v2[0]).arg(v2[1]).arg(v2[2]); + + QDomElement transform = m_doc.createElement("Transform"); + transform.setAttribute("translation", coord); + m_group.appendChild(transform); + + QDomElement shape = m_doc.createElement("Shape"); + transform.appendChild(shape); + + QDomElement sphere = m_doc.createElement("Sphere"); + sphere.setAttribute("radius", radius); + shape.appendChild(sphere); + + QDomElement appearance = m_doc.createElement("Appearance"); + shape.appendChild(appearance); + + QDomElement material = m_doc.createElement("Material"); + material.setAttribute("diffuseColor", m_color); + appearance.appendChild(material); + } + + { + double v[] = { + (v1[0] + v2[0]) / 2, + (v1[1] + v2[1]) / 2, + (v1[2] + v2[2]) / 2 + }; + + const double dx = v1[0] - v2[0], + dy = v1[1] - v2[1], + dz = v1[2] - v2[2]; + + const double height = sqrt(dx * dx + dy * dy + dz * dz), + alpha = acos(dy / height); + + const QString coord = QString("%1 %2 %3").arg(v[0]).arg(v[1]).arg(v[2]), + rot = QString("%1 0 %2 %3").arg(dz).arg(-dx).arg(alpha); + + QDomElement transform = m_doc.createElement("Transform"); + transform.setAttribute("translation", coord); + transform.setAttribute("rotation", rot); + m_group.appendChild(transform); + + QDomElement shape = m_doc.createElement("Shape"); + transform.appendChild(shape); + + QDomElement cylinder = m_doc.createElement("Cylinder"); + cylinder.setAttribute("radius", radius); + cylinder.setAttribute("height", height); + shape.appendChild(cylinder); + + QDomElement appearance = m_doc.createElement("Appearance"); + shape.appendChild(appearance); + + QDomElement material = m_doc.createElement("Material"); + material.setAttribute("diffuseColor", m_color); + appearance.appendChild(material); + } + } + else + { + m_lineCoords << QString("%1 %2 %3").arg(v1[0]).arg(v1[1]).arg(v1[2]); + m_lineCoords << QString("%1 %2 %3").arg(v2[0]).arg(v2[1]).arg(v2[2]); + m_lineColors << m_color << m_color; + } +} + +void KBSX3DRenderer::drawQuadrangle(double *v1, double *v2, double *v3, double *v4) +{ + if(!m_open) return; + + m_faceCoords << QString("%1 %2 %3").arg(v1[0]).arg(v1[1]).arg(v1[2]); + m_faceCoords << QString("%1 %2 %3").arg(v2[0]).arg(v2[1]).arg(v2[2]); + m_faceCoords << QString("%1 %2 %3").arg(v3[0]).arg(v3[1]).arg(v3[2]); + m_faceCoords << QString("%1 %2 %3").arg(v4[0]).arg(v4[1]).arg(v4[2]); + m_faceColors << m_color << m_color << m_color << m_color; +} + +const unsigned KBSMoleculeModel::s_divisions = 10; + +KBSMoleculeModel::KBSMoleculeModel(QObject *parent, char *name) + : QObject(parent, name), + m_backboneCoords(NULL), m_atomCoords(NULL), + m_style(Backbone), m_coloring(Group) +{ +} + +KBSMoleculeModel::~KBSMoleculeModel() +{ + if(NULL != m_backboneCoords) delete m_backboneCoords; + if(NULL != m_atomCoords) delete m_atomCoords; +} + +KBSMoleculeModel::Style KBSMoleculeModel::style() const +{ + return m_style; +} + +void KBSMoleculeModel::setStyle(Style style) +{ + if(m_style == style) return; + + m_style = style; + + if(!isSupportedColoring(m_coloring)) m_coloring = Monochrome; + + emit styleChanged(); +} + +bool KBSMoleculeModel::isSupportedStyle(Style style) const +{ + if(style <= Spline) + { + if(m_group.isEmpty()) return false; + for(QValueList<unsigned>::const_iterator group = m_group.begin(); group != m_group.end(); ++group) + if(*group <= 1) return false; + } + + if(style >= Wireframe && m_atom.isEmpty()) return false; + + return true; +} + +KBSMoleculeModel::Coloring KBSMoleculeModel::coloring() const +{ + return m_coloring; +} + +void KBSMoleculeModel::setColoring(Coloring coloring) +{ + if(m_coloring == coloring) return; + + m_coloring = coloring; + + emit coloringChanged(); +} + +bool KBSMoleculeModel::isSupportedColoring(Coloring coloring) const +{ + switch(coloring) { + case CPK: + return(m_style >= Wireframe && !m_atom.isEmpty()); + default: + return true; + } +} + +void KBSMoleculeModel::setChain(const KBSProteinChain &chain) +{ + const unsigned groups = chain.atom.count() >= 2 ? chain.atom.count() - 2 : 0; + + m_maxSeq = groups; + m_group.clear(); m_group << groups; + + if(m_sequence.count() != groups) + m_sequence.clear(); + + m_atom.clear(); + + if(NULL != m_backboneCoords) { + delete m_backboneCoords; + m_backboneCoords = NULL; + } + + if(NULL != m_atomCoords) { + delete m_atomCoords; + m_atomCoords = NULL; + } + + if(0 == groups) return; + + const unsigned points = groups + s_divisions * (groups - 1); + m_backboneCoords = new double[3 * points]; + + unsigned g = 0; + for(QValueList<KBSProteinAtom>::const_iterator atom = chain.atom.at(1); g < groups; ++g, ++atom) + { + const unsigned p = g * (s_divisions + 1); + + m_backboneCoords[3*p + 0] = 0.1 * ((*atom).x - 50.0); + m_backboneCoords[3*p + 1] = 0.1 * ((*atom).y - 50.0); + m_backboneCoords[3*p + 2] = 0.1 * ((*atom).z - 50.0); + } + + interpolateBackbone(); + + emit dataChanged(); +} + +void KBSMoleculeModel::setFASTA(const KBSProteinFASTA &fasta) +{ + m_sequence = fasta.sequence; + + emit dataChanged(); +} + +void KBSMoleculeModel::setPDB(const KBSProteinPDB &pdb) +{ + m_maxSeq = pdb.maxSeq; + m_group = pdb.group; + m_atom = pdb.atom; + + const unsigned groups = pdb.groups(), + atoms = pdb.atom.count(); + + if(NULL != m_atomCoords) { delete m_atomCoords; m_atomCoords = NULL; } + if(atoms > 0) m_atomCoords = new double[3 * atoms]; + + if(NULL != m_backboneCoords) { delete m_backboneCoords; m_backboneCoords = NULL; } + if(groups > 0) { + const unsigned points = groups + s_divisions * (groups - 1); + m_backboneCoords = new double[3 * points]; + } + + m_sequence.clear(); + unsigned a = 0, g = 0; + for(QValueList<KBSAtomPDB>::const_iterator atom = m_atom.begin(); atom != m_atom.end(); ++a, ++atom) + { + m_atomCoords[3*a + 0] = 0.1 * (*atom).x; + m_atomCoords[3*a + 1] = 0.1 * (*atom).y; + m_atomCoords[3*a + 2] = 0.1 * (*atom).z; + + if((*atom).name.iupac == "CA") + { + const unsigned p = g++ * (s_divisions + 1); + + m_backboneCoords[3*p + 0] = 0.1 * (*atom).x; + m_backboneCoords[3*p + 1] = 0.1 * (*atom).y; + m_backboneCoords[3*p + 2] = 0.1 * (*atom).z; + + m_sequence << (*atom).resName; + } + } + + interpolateBackbone(); + + emit dataChanged(); +} + +void KBSMoleculeModel::rotateData(int dx, int dy) +{ + const double alpha = 1e-2 * dx, beta = 1e-2 * dy; + + const double sinAlpha = sin(alpha), cosAlpha = cos(alpha), + sinBeta = sin(beta), cosBeta = cos(beta); + + if(NULL != m_backboneCoords) + { + unsigned groups = 0; + for(QValueList<unsigned>::const_iterator it = m_group.begin(); it != m_group.end(); ++it) + groups += *it; + + const unsigned points = groups + s_divisions * (groups - 1); + + for(unsigned p = 0; p < points; ++p) + { + const double x = m_backboneCoords[3*p + 0], + y = m_backboneCoords[3*p + 1], + z = m_backboneCoords[3*p + 2]; + + const double tx = x * cosAlpha + z * sinAlpha, + ty = x * sinAlpha * sinBeta + y * cosBeta - z * cosAlpha * sinBeta, + tz = -x * sinAlpha * cosBeta + y * sinBeta + z * cosAlpha * cosBeta; + + m_backboneCoords[3*p + 0] = tx; + m_backboneCoords[3*p + 1] = ty; + m_backboneCoords[3*p + 2] = tz; + } + } + + if(NULL != m_atomCoords) + { + const unsigned atoms = m_atom.count(); + + for(unsigned a = 0; a < atoms; ++a) + { + const double x = m_atomCoords[3*a + 0], + y = m_atomCoords[3*a + 1], + z = m_atomCoords[3*a + 2]; + + const double tx = x * cosAlpha + z * sinAlpha, + ty = x * sinAlpha * sinBeta + y * cosBeta - z * cosAlpha * sinBeta, + tz = -x * sinAlpha * cosBeta + y * sinBeta + z * cosAlpha * cosBeta; + + m_atomCoords[3*a + 0] = tx; + m_atomCoords[3*a + 1] = ty; + m_atomCoords[3*a + 2] = tz; + } + } + + emit dataChanged(); +} + +bool KBSMoleculeModel::exportVRML(const QString &fileName) const +{ + KBSVRMLRenderer renderer(fileName); + if(!renderer.isOpen()) return false; + + render(&renderer); + renderer.close(); + + return true; +} + +bool KBSMoleculeModel::exportX3D(const QString &fileName) const +{ + KBSX3DRenderer renderer(fileName); + if(!renderer.isOpen()) return false; + + render(&renderer); + renderer.close(); + + return true; +} + +void KBSMoleculeModel::render(KBSMoleculeRenderer *renderer) const +{ + if(Backbone == m_style) + { + unsigned groups = 0; + + for(QValueList<unsigned>::const_iterator group = m_group.begin(); + group != m_group.end(); groups += *(group++)) + for(unsigned g1 = 0; g1 < (*group - 1); ++g1) + { + QColor c1; + switch(m_coloring) { + case Group: + c1 = progressColor(double(g1) / (*group - 1)); + break; + case Shapely: + c1 = shapelyColor(groups + g1 < m_sequence.count() ? m_sequence[groups + g1] : AminoAcids); + break; + default: + c1 = monochromeColor(); + break; + } + + const unsigned g2 = g1 + 1; + + QColor c2; + switch(m_coloring) { + case Group: + c2 = progressColor(double(g2) / (*group - 1)); + break; + case Shapely: + c2 = shapelyColor(groups + g2 < m_sequence.count() ? m_sequence[groups + g2] : AminoAcids); + break; + default: + c2 = monochromeColor(); + break; + } + + const unsigned p1 = (g1 + groups) * (s_divisions + 1), + p2 = p1 + (s_divisions + 1); + + if(c1 != c2) + { + double v[] = { + (m_backboneCoords[3*p1 + 0] + m_backboneCoords[3*p2 + 0]) / 2, + (m_backboneCoords[3*p1 + 1] + m_backboneCoords[3*p2 + 1]) / 2, + (m_backboneCoords[3*p1 + 2] + m_backboneCoords[3*p2 + 2]) / 2 + }; + + renderer->setColor(c1); + renderer->drawLine(m_backboneCoords + 3*p1, v, 1); + renderer->setColor(c2); + renderer->drawLine(v, m_backboneCoords + 3*p2, 1); + } + else + { + renderer->setColor(c1); + renderer->drawLine(m_backboneCoords + 3*p1, m_backboneCoords + 3*p2, 1); + } + } + } + else if(Spline >= m_style) + { + unsigned groups = 0, points = 0, p1 = 0; + + for(QValueList<unsigned>::const_iterator group = m_group.begin(); group != m_group.end(); ++group) + { + points += *group + s_divisions * (*group - 1); + + for( ; p1 < points-1; ++p1) + { + const unsigned g = unsigned(double(p1) / (s_divisions + 1) + 0.5) - groups; + + QColor c; + switch(m_coloring) { + case Group: + c = progressColor(double(g) / (*group - 1)); + break; + case Shapely: + c = shapelyColor(groups + g < m_sequence.count() ? m_sequence[groups + g] : AminoAcids); + break; + default: + c = monochromeColor(); + break; + } + + renderer->setColor(c); + + const unsigned p2 = p1 + 1; + + renderer->drawLine(m_backboneCoords + 3*p1, m_backboneCoords + 3*p2); + } + + groups += *group; + p1 += s_divisions; + } + } + else + { + const double radius = (BallAndStick == m_style) ? 0.3 + : (Spacefill == m_style) ? 1.0 + : 0.0; + + const double thickness = (BallAndStick == m_style) ? 0.4 + : (Sticks == m_style) ? 1.0 + : 0.0; + + unsigned pa = 0; + for(QValueList<KBSAtomPDB>::const_iterator atom = m_atom.begin(); + atom != m_atom.end(); ++atom, ++pa) + { + QColor ca; + + switch(m_coloring) { + case Group: + ca = progressColor(m_maxSeq > 1 ? double((*atom).resSeq - 1) / (m_maxSeq - 1) : 0); + break; + case Shapely: + ca = shapelyColor((*atom).resName); + break; + case CPK: + ca = cpkColor((*atom).element); + break; + default: + ca = monochromeColor(); + break; + } + + renderer->setColor(ca); + + if(Spacefill == m_style || BallAndStick == m_style) + renderer->drawBall(m_atomCoords + 3*pa, radius * atomRadius((*atom).element)); + + if(Spacefill == m_style) continue; + + unsigned pp = 0; + for(QValueList<KBSAtomPDB>::const_iterator parent = m_atom.begin(); + parent != atom; ++parent, ++pp) + { + if(!(*atom).covalentBond(*parent)) continue; + + QColor cp; + + switch(m_coloring) { + case Group: + cp = progressColor(m_maxSeq > 1 ? double((*parent).resSeq - 1) / (m_maxSeq - 1) : 0); + break; + case Shapely: + cp = shapelyColor((*parent).resName); + break; + case CPK: + cp = cpkColor((*parent).element); + break; + default: + cp = monochromeColor(); + break; + } + + if(cp != ca) + { + double v[] = { + (m_atomCoords[3*pp + 0] + m_atomCoords[3*pa + 0]) / 2, + (m_atomCoords[3*pp + 1] + m_atomCoords[3*pa + 1]) / 2, + (m_atomCoords[3*pp + 2] + m_atomCoords[3*pa + 2]) / 2 + }; + + renderer->drawLine(v, m_atomCoords + 3*pa, thickness); + renderer->setColor(cp); + renderer->drawLine(m_atomCoords + 3*pp, v, thickness); + renderer->setColor(ca); + } + else + renderer->drawLine(m_atomCoords + 3*pp, m_atomCoords + 3*pa, thickness); + } + } + } +} + +void KBSMoleculeModel::interpolateBackbone() +{ + if(NULL == m_backboneCoords) return; + + unsigned groups = 0; + for(QValueList<unsigned>::const_iterator it = m_group.begin(); it != m_group.end(); ++it) + groups += *it; + + if(0 == groups) return; + + for(unsigned g = 0; g < groups - 1; ++g) + { + const unsigned p1 = g * (s_divisions + 1), + p2 = p1 + (s_divisions + 1); + + const double d12 = distance(m_backboneCoords + 3*p1, m_backboneCoords + 3*p2); + + double a1[3], a2[3]; + for(unsigned i = 0; i < 3; ++i) { + if(g > 0) { + const unsigned p0 = p1 - (s_divisions + 1); + + a1[i] = (m_backboneCoords[3*p2 + i] - m_backboneCoords[3*p0 + i]); + a1[i] *= d12 / distance(m_backboneCoords + 3*p2, m_backboneCoords + 3*p0); + } else + a1[i] = m_backboneCoords[3*p2 + i] - m_backboneCoords[3*p1 + i]; + + a1[i] *= 0.4; + a1[i] += m_backboneCoords[3*p1 + i]; + + if(g < groups-2) { + const unsigned p3 = p2 + (s_divisions + 1); + + a2[i] = (m_backboneCoords[3*p3 + i] - m_backboneCoords[3*p1 + i]); + a2[i] *= d12 / distance(m_backboneCoords + 3*p3, m_backboneCoords + 3*p1); + } + else + a2[i] = m_backboneCoords[3*p2 + i] - m_backboneCoords[3*p1 + i]; + + a2[i] *= -0.4; + a2[i] += m_backboneCoords[3*p2 + i]; + } + + for(unsigned p = p1 + 1; p < p2; ++p) + { + const double t = double(p - p1) / (s_divisions + 1), + t1 = 1 - t; + + double cp1 = t1 * t1 * t1, + ca1 = 3 * cp1 * t / t1, + ca2 = ca1 * t / t1, + cp2 = (ca2 / 3) * t / t1; + + for(unsigned i = 0; i < 3; ++i) + m_backboneCoords[3*p + i] = cp1 * m_backboneCoords[3*p1 + i] + + ca1 * a1[i] + ca2 * a2[i] + + cp2 * m_backboneCoords[3*p2 + i]; + } + } +} + +#include "kbsmoleculemodel.moc" Added: trunk/kboincspy/src/monitors/common/molbio/kbsmoleculemodel.h =================================================================== --- trunk/kboincspy/src/monitors/common/molbio/kbsmoleculemodel.h (rev 0) +++ trunk/kboincspy/src/monitors/common/molbio/kbsmoleculemodel.h 2006-04-07 02:19:45 UTC (rev 738) @@ -0,0 +1,150 @@ +/*************************************************************************** + * Copyright (C) 2006 by Roberto Virga * + * rv...@us... * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Library General Public License as * + * published by the Free Software Foundation; either version 2 of the * + * License, or (at your option) any later version. * + * * + * 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. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#ifndef KBSMOLECULEMODEL_H +#define KBSMOLECULEMODEL_H + +#include <qdom.h> +#include <qmap.h> +#include <qobject.h> +#include <qstringlist.h> +#include <qtextstream.h> + +#include <kbsmolbiodata.h> + +class KBSMoleculeRenderer +{ + public: + virtual ~KBSMoleculeRenderer() {} + + virtual void setColor(QColor color) = 0; + virtual void drawBall(double *v, double radius) = 0; + virtual void drawLine(double *v1, double *v2, double thickness=0.0) = 0; + virtual void drawQuadrangle(double *v1, double *v2, double *v3, double *v4) = 0; + + protected: + KBSMoleculeRenderer() {}; +}; + +class KBSVRMLRenderer : public KBSMoleculeRenderer +{ + public: + KBSVRMLRenderer(const QString &fileName); + virtual ~KBSVRMLRenderer(); + + virtual bool isOpen() const; + virtual void close(); + + virtual void setColor(QColor color); + virtual void drawBall(double *v, double radius); + virtual void drawLine(double *v1, double *v2, double thickness=0.0); + virtual void drawQuadrangle(double *v1, double *v2, double *v3, double *v4); + + protected: + QString m_color; + QStringList m_lineCoords, m_lineColors, m_faceCoords, m_faceColors; + QTextStream m_text; + + private: + bool m_open; +}; + +class KBSX3DRenderer : public KBSMoleculeRenderer +{ + public: + KBSX3DRenderer(const QString &fileName); + virtual ~KBSX3DRenderer(); + + virtual bool isOpen() const; + virtual void close(); + + virtual void setColor(QColor color); + virtual void drawBall(double *v, double radius); + virtual void drawLine(double *v1, double *v2, double thickness=0.0); + virtual void drawQuadrangle(double *v1, double *v2, double *v3, double *v4); + + protected: + QString m_color; + QStringList m_lineCoords, m_lineColors, m_faceCoords, m_faceColors; + QDomDocument m_doc; + QDomElement m_group; + QTextStream m_text; + + private: + bool m_open; +}; + +class KBSMoleculeModel : public QObject +{ + Q_OBJECT + public: + KBSMoleculeModel(QObject *parent=0, char *name=0); + virtual ~KBSMoleculeModel(); + + enum Style { Backbone, Spline, + Wireframe, Sticks, Spacefill, BallAndStick }; + virtual Style style() const; + virtual void setStyle(Style style); + virtual bool isSupportedStyle(Style style) const; + + enum Coloring { Monochrome, Group, Shapely, CPK, Structure }; + virtual Coloring coloring() const; + virtual void setColoring(Coloring coloring); + virtual bool isSupportedColoring(Coloring coloring) const; + + virtual void setChain(const KBSProteinChain &chain); + virtual void setFASTA(const KBSProteinFASTA &fasta); + virtual void setPDB(const KBSProteinPDB &pdb); + + virtual void rotateData(int dx, int dy); + + virtual bool exportVRML(const QString &fileName) const; + virtual bool exportX3D(const QString &fileName) const; + + friend class KBSMoleculeView; + + signals: + void styleChanged(); + void coloringChanged(); + void dataChanged(); + + protected: + virtual void render(KBSMoleculeRenderer *renderer) const; + + private: + void interpolateBackbone(); + + protected: + unsigned m_maxSeq; + QValueList<unsigned> m_group; + QValueList<KBSProteinAtom> m_backbone; + QValueList<KBSAminoAcid> m_sequence; + QValueList<KBSAtomPDB> m_atom; + + double *m_backboneCoords, *m_atomCoords; + + static const unsigned s_divisions; + + private: + Style m_style; + Coloring m_coloring; +}; + +#endif Modified: trunk/kboincspy/src/monitors/common/molbio/kbsmoleculeview.cpp =================================================================== --- trunk/kboincspy/src/monitors/common/molbio/kbsmoleculeview.cpp 2006-04-06 17:55:22 UTC (rev 737) +++ trunk/kboincspy/src/monitors/common/molbio/kbsmoleculeview.cpp 2006-04-07 02:19:45 UTC (rev 738) @@ -37,1053 +37,10 @@ #include "kbsmoleculeview.h" -using namespace KBSMolBio; - -QColor progressColor(double progress) -{ - double r, g, b; - if(progress <= 0.25) { - r = 0.0; - g = progress / 0.25; - b = 1.0; - } else if(progress <= 0.50) { - r = 0.0; - g = 1.0; - b = 1.0 - (progress - 0.25) / 0.25; - } else if(progress <= 0.75) { - r = (progress - 0.50) / 0.25; - g = 1.0; - b = 0.0; - } else { - r = 1.0; - g = 1.0 - (progress - 0.75) / 0.25; - b = 0.0; - } - - return QColor(int(r * 255), int(g * 255), int(b * 255)); -} - -const unsigned KBSAminoAcidColor[AminoAcids+1] = - {0xEBEBEB, 0xC8C8C8, 0xFA9600, 0xE6E600, 0x0F820F, 0xFA9600, 0x0F820F, - 0xDC9682, 0xE6E600, 0xE60A0A, 0x00DCDC, 0x0F820F, 0x145AFF, 0xE60A0A, - 0x00DCDC, 0x145AFF, 0x8282D2, 0x3232AA, 0x3232AA, 0xB45AB4, 0xBEA06E}; - -QColor shapelyColor(KBSAminoAcid aa) -{ - return QColor(KBSAminoAcidColor[aa]); -} - -const unsigned KBSElementColor[Elements+1] = - {0xFFFFFF, 0xFFC0CB, 0xB22222, 0x00FF00, 0xC8C8C8, 0x8F8FFF, 0xF00000, - 0xDAA520, 0xFF1493, 0x0000FF, 0x228B22, 0x808090, 0xDAA520, 0xFFA500, - 0xFFC832, 0x00FF00, 0xFF1493, 0xFF1493, 0x808090, 0x808090, 0x808090, - 0x808090, 0xFFA500, 0xA52A2A, 0xA52A2A, 0xA52A2A, 0xFF1493, 0xFF1493, - 0xFF1493, 0xA52A2A, 0xFF1493, 0xFF1493, 0x808090, 0xFF1493, 0xFF1493, - 0xFF1493, 0xFF1493, 0xA020F0, 0xFF1493, 0xFFA500, 0xFF1493, 0xDAA520, - 0xFF1493, 0xFF1493, 0xFF1493, 0xFF1493, 0xFF1493}; - -QColor cpkColor(KBSElement element) -{ - return QColor(KBSElementColor[element]); -} - -const unsigned KBSFeatureColor[Features+1] = - {0xF00080, 0xFFFF00, 0x6080FF, 0xFFFFFF}; - -QColor structureColor(KBSFeature feature) -{ - return QColor(KBSFeatureColor[feature]); -} - -QColor monochromeColor() -{ - return Qt::lightGray; -} - -double dotProduct(double *v1, double *v2) -{ - return v1[0] * v2[0] + v1[1] * v2[1] + v1[2] * v2[2]; -} - -void crossProduct(double *v1, double *v2, double *v3) -{ - v3[0] = v1[1] * v2[2] - v1[2] * v2[1]; - v3[1] = v1[2] * v2[0] - v1[0] * v2[2]; - v3[2] = v1[0] * v2[1] - v2[1] * v1[0]; -} - -double norm(double *v) -{ - return sqrt(dotProduct(v, v)); -} - -void normalize(double *v) -{ - double n = norm(v); - v[0] /= n; v[1] /= n; v[2] /= n; -} - -double distance(double *v1, double *v2) -{ - double v[] = { - v1[0] - v2[0], - v1[1] - v2[1], - v1[2] - v2[2] - }; - - return norm(v); -} - -KBSVRMLRenderer::KBSVRMLRenderer(const QString &fileName) - : KBSMoleculeRenderer(), m_color("0 0 0"), m_open(false) -{ - QIODevice *device = KFilterDev::deviceForFile(fileName, "application/x-gzip", true); - - if(device->open(IO_WriteOnly)) - { - m_text.setDevice(device); - - const KAboutData *aboutData = KGlobal::instance()->aboutData(); - QString comment = i18n("Generated by %1 %2").arg(aboutData->programName()) - .arg(aboutData->version()); - m_text << QString("#VRML V2.0 utf8 %1\n").arg(comment); - - m_text << "NavigationInfo { type \"EXAMINE\" }\n"; - m_text << "Group { children [\n"; - - m_open = true; - } - else - delete device; -} - -KBSVRMLRenderer::~ KBSVRMLRenderer() -{ - close(); -} - -bool KBSVRMLRenderer::isOpen() const -{ - return m_open; -} - -void KBSVRMLRenderer::close() -{ - if(!m_open) return; - - if(!m_lineCoords.isEmpty()) - { - m_text << "Shape {\n"; - m_text << "geometry IndexedLineSet {\n"; - - QString indices; - for(unsigned i = 0; i < m_lineCoords.count(); i+=2) - indices += QString("%1 %2 -1 ").arg(i).arg(i+1); - - m_text << "coord Coordinate { point [ " << m_lineCoords.join(", ") << " ] }\n"; - m_text << "coordIndex [ " << indices << "]\n"; - m_text << "color Color { color [ " << m_lineColors.join(", ") << " ] }\n"; - m_text << "colorIndex [ " << indices << "]\n"; - - m_text << "}\n"; // IndexedLineSet - m_text << "}\n"; // Shape - } - - if(!m_faceCoords.isEmpty()) - { - m_text << "Shape {\n"; - m_text << "geometry IndexedFaceSet {"; - - QString indices; - for(unsigned i = 0; i < m_lineCoords.count(); i+=4) - indices += QString("%1 %2 %3 -1 %4 %5 %6 -1 ").arg(i).arg(i+1).arg(i+2) - .arg(i+1).arg(i+2).arg(i+3); - - m_text << "coord Coordinate { point [ " << m_lineCoords.join(", ") << " ] }\n"; - m_text << "color Color { color [ " << m_lineColors.join(", ") << " ] }\n"; - m_text << "coordIndex [ " << indices << "]\n"; - m_text << "colorIndex [ " << indices << "]\n"; - - m_text << "}\n"; // IndexedFaceSet - m_text << "}\n"; // Shape - } - - m_text << "]\n"; // children - m_text << "}\n"; // Group - - QIODevice *device = m_text.device(); - device->close(); - delete device; - - m_open = false; -} - -void KBSVRMLRenderer::setColor(QColor color) -{ - m_color = QString("%1 %2 %3").arg(double(color.red()) / 255) - .arg(double(color.green()) / 255) - .arg(double(color.blue()) / 255); -} - -void KBSVRMLRenderer::drawBall(double *v, double radius) -{ - if(!m_open || radius <= 0) return; - - m_text << "Transform {\n"; - - m_text << QString("translation %1 %2 %3\n").arg(v[0]).arg(v[1]).arg(v[2]); - - m_text << "children "; - - m_text << "Shape {\n"; - - m_text << QString("geometry Sphere { radius %1 }\n").arg(radius * 0.09); - - m_text << "appearance Appearance {\n"; - - m_text << "material Material { diffuseColor " << m_color << " }\n"; - - m_text << "}\n"; // Appearance - - m_text << "}\n"; // Shape - - m_text << "}\n"; // Transform -} - -void KBSVRMLRenderer::drawLine(double *v1, double *v2, double thickness) -{ - if(!m_open) return; - - if(thickness > 0) - { - const double radius = thickness * 0.03; - - { - m_text << "Transform {\n"; - - m_text << QString("translation %1 %2 %3\n").arg(v1[0]).arg(v1[1]).arg(v1[2]); - - m_text << "children Shape {\n"; - - m_text << QString("geometry Sphere { radius %1 }\n").arg(radius); - - m_text << "appearance Appearance {\n"; - - m_text << "material Material { diffuseColor " << m_color << " }\n"; - - m_text << "}\n"; // Appearance - - m_text << "}\n"; // Shape - - m_text << "}\n"; // Transform - } - - { - m_text << "Transform {\n"; - - m_text << QString("translation %1 %2 %3\n").arg(v2[0]).arg(v2[1]).arg(v2[2]); - - m_text << "children Shape {\n"; - - m_text << QString("geometry Sphere { radius %1 }\n").arg(radius); - - m_text << "appearance Appearance {\n"; - - m_text << "material Material { diffuseColor " << m_color << " }\n"; - - m_text << "}\n"; // Appearance - - m_text << "}\n"; // Shape - - m_text << "}\n"; // Transform - } - - { - double v[] = { - (v1[0] + v2[0]) / 2, - (v1[1] + v2[1]) / 2, - (v1[2] + v2[2]) / 2 - }; - - const double dx = v1[0] - v2[0], - dy = v1[1] - v2[1], - dz = v1[2] - v2[2]; - - const double height = sqrt(dx * dx + dy * dy + dz * dz), - alpha = acos(dy / height); - - m_text << "Transform {\n"; - - m_text << QString("translation %1 %2 %3\n").arg(v[0]).arg(v[1]).arg(v[2]); - - m_text << QString("rotation %1 0 %2 %3").arg(dz).arg(-dx).arg(alpha); - - m_text << "children Shape {\n"; - - m_text << "geometry Cylinder {\n"; - - m_text << QString("radius %1 height %2\n").arg(radius).arg(height); - - m_text << "}\n"; // Cylinder - - m_text << "appearance Appearance {\n"; - - m_text << "material Material { diffuseColor " << m_color << " }\n"; - - m_text << "}\n"; // Appearance - - m_text << "}\n"; // Shape - - m_text << "}\n"; // Transform - } - } - else - { - m_lineCoords << QString("%1 %2 %3").arg(v1[0]).arg(v1[1]).arg(v1[2]); - m_lineCoords << QString("%1 %2 %3").arg(v2[0]).arg(v2[1]).arg(v2[2]); - m_lineColors << m_color << m_color; - } -} - -void KBSVRMLRenderer::drawQuadrangle(double *v1, double *v2, double *v3, double *v4) -{ - if(!m_open) return; - - m_faceCoords << QString("%1 %2 %3").arg(v1[0]).arg(v1[1]).arg(v1[2]); - m_faceCoords << QString("%1 %2 %3").arg(v2[0]).arg(v2[1]).arg(v2[2]); - m_faceCoords << QString("%1 %2 %3").arg(v3[0]).arg(v3[1]).arg(v3[2]); - m_faceCoords << QString("%1 %2 %3").arg(v4[0]).arg(v4[1]).arg(v4[2]); - m_faceColors << m_color << m_color << m_color << m_color; -} - -KBSX3DRenderer::KBSX3DRenderer(const QString &fileName) - : KBSMoleculeRenderer(), m_color("0 0 0"), m_open(false) -{ - QIODevice *device = KFilterDev::deviceForFile(fileName, "application/x-gzip", true); - - if(device->open(IO_WriteOnly)) - { - m_text.setDevice(device); - - m_text << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"; - - QDomDocumentType docType = QDomImplementation().createDocumentType( - "X3D", - "ISO//Web3D//DTD X3D 3.0//EN", - "http://www.web3d.org/specifications/x3d-3.0.dtd" - ); - - m_doc = QDomDocument(docType); - - QDomElement x3d = m_doc.createElement("X3D"); - x3d.setAttribute("profile", "Immersive"); - m_doc.appendChild(x3d); - - QDomElement scene = m_doc.createElement("Scene"); - x3d.appendChild(scene); - - QDomElement navigationInfo = m_doc.createElement("NavigationInfo"); - navigationInfo.setAttribute("type", "EXAMINE"); - scene.appendChild(navigationInfo); - - m_group = m_doc.createElement("Group"); - scene.appendChild(m_group); - - m_open = true; - } - else - delete device; -} - -KBSX3DRenderer::~ KBSX3DRenderer() -{ - close(); -} - -bool KBSX3DRenderer::isOpen() const -{ - return m_open; -} - -void KBSX3DRenderer::close() -{ - if(!m_open) return; - - if(!m_lineCoords.isEmpty()) - { - QDomElement shape = m_doc.createElement("Shape"); - m_group.appendChild(shape); - - QString indices; - for(unsigned i = 0; i < m_lineCoords.count(); i+=2) - indices += QString("%1 %2 -1 ").arg(i).arg(i+1); - - QDomElement indexedLineSet = m_doc.createElement("IndexedLineSet"); - indexedLineSet.setAttribute("coordIndex", indices); - indexedLineSet.setAttribute("colorIndex", indices); - shape.appendChild(indexedLineSet); - - QDomElement coordinate = m_doc.createElement("Coordinate"); - coordinate.setAttribute("point", m_lineCoords.join(", ")); - indexedLineSet.appendChild(coordinate); - - QDomElement color = m_doc.createElement("Color"); - color.setAttribute("color", m_lineColors.join(", ")); - indexedLineSet.appendChild(color); - } - - if(!m_faceCoords.isEmpty()) - { - QDomElement shape = m_doc.createElement("Shape"); - m_group.appendChild(shape); - - QString indices; - for(unsigned i = 0; i < m_faceCoords.count(); i+=4) - indices += QString("%1 %2 %3 -1 %4 %5 %6 -1 ").arg(i).arg(i+1).arg(i+2) - .arg(i+1).arg(i+2).arg(i+3); - - QDomElement indexedFaceSet = m_doc.createElement("IndexedFaceSet"); - indexedFaceSet.setAttribute("coordIndex", indices); - indexedFaceSet.setAttribute("colorIndex", indices); - shape.appendChild(indexedFaceSet); - - QDomElement coordinate = m_doc.createElement("Coordinate"); - coordinate.setAttribute("point", m_faceCoords.join(", ")); - indexedFaceSet.appendChild(coordinate); - - QDomElement color = m_doc.createElement("Color"); - color.setAttribute("color", m_faceColors.join(", ")); - indexedFaceSet.appendChild(color); - } - - m_text << m_doc.toString(); - - QIODevice *device = m_text.device(); - device->close(); - delete device; - - m_open = false; -} - -void KBSX3DRenderer::setColor(QColor color) -{ - m_color = QString("%1 %2 %3").arg(double(color.red()) / 255) - .arg(double(color.green()) / 255) - .arg(double(color.blue()) / 255); -} - -void KBSX3DRenderer::drawBall(double *v, double radius) -{ - if(!m_open || radius <= 0) return; - - const QString coord = QString("%1 %2 %3").arg(v[0]).arg(v[1]).arg(v[2]); - - QDomElement transform = m_doc.createElement("Transform"); - transform.setAttribute("translation", coord); - m_group.appendChild(transform); - - QDomElement shape = m_doc.createElement("Shape"); - transform.appendChild(shape); - - QDomElement sphere = m_doc.createElement("Sphere"); - sphere.setAttribute("radius", radius * 0.1); - shape.appendChild(sphere); - - QDomElement appearance = m_doc.createElement("Appearance"); - shape.appendChild(appearance); - - QDomElement material = m_doc.createElement("Material"); - material.setAttribute("diffuseColor", m_color); - appearance.appendChild(material); -} - -void KBSX3DRenderer::drawLine(double *v1, double *v2, double thickness) -{ - if(!m_open) return; - - if(thickness > 0.0) - { - const double radius = thickness * 0.03; - - { - const QString coord = QString("%1 %2 %3").arg(v1[0]).arg(v1[1]).arg(v1[2]); - - QDomElement transform = m_doc.createElement("Transform"); - transform.setAttribute("translation", coord); - m_group.appendChild(transform); - - QDomElement shape = m_doc.createElement("Shape"); - transform.appendChild(shape); - - QDomElement sphere = m_doc.createElement("Sphere"); - sphere.setAttribute("radius", radius); - shape.appendChild(sphere); - - QDomElement appearance = m_doc.createElement("Appearance"); - shape.appendChild(appearance); - - QDomElement material = m_doc.createElement("Material"); - material.setAttribute("diffuseColor", m_color); - appearance.appendChild(material); - } - - { - const QString coord = QString("%1 %2 %3").arg(v2[0]).arg(v2[1]).arg(v2[2]); - - QDomElement transform = m_doc.createElement("Transform"); - transform.setAttribute("translation", coord); - m_group.appendChild(transform); - - QDomElement shape = m_doc.createElement("Shape"); - transform.appendChild(shape); - - QDomElement sphere = m_doc.createElement("Sphere"); - sphere.setAttribute("radius", radius); - shape.appendChild(sphere); - - QDomElement appearance = m_doc.createElement("Appearance"); - shape.appendChild(appearance); - - QDomElement material = m_doc.createElement("Material"); - material.setAttribute("diffuseColor", m_color); - appearance.appendChild(material); - } - - { - double v[] = { - (v1[0] + v2[0]) / 2, - (v1[1] + v2[1]) / 2, - (v1[2] + v2[2]) / 2 - }; - - const double dx = v1[0] - v2[0], - dy = v1[1] - v2[1], - dz = v1[2] - v2[2]; - - const double height = sqrt(dx * dx + dy * dy + dz * dz), - alpha = acos(dy / height); - - const QString coord = QString("%1 %2 %3").arg(v[0]).arg(v[1]).arg(v[2]), - rot = QString("%1 0 %2 %3").arg(dz).arg(-dx).arg(alpha); - - QDomElement transform = m_doc.createElement("Transform"); - transform.setAttribute("translation", coord); - transform.setAttribute("rotation", rot); - m_group.appendChild(transform); - - QDomElement shape = m_doc.createElement("Shape"); - transform.appendChild(shape); - - QDomElement cylinder = m_doc.createElement("Cylinder"); - cylinder.setAttribute("radius", radius); - cylinder.setAttribute("height", height); - shape.appendChild(cylinder); - - QDomElement appearance = m_doc.createElement("Appearance"); - shape.appendChild(appearance); - - QDomElement material = m_doc.createElement("Material"); - material.setAttribute("diffuseColor", m_color); - appearance.appendChild(material); - } - } - else - { - m_lineCoords << QString("%1 %2 %3").arg(v1[0]).arg(v1[1]).arg(v1[2]); - m_lineCoords... [truncated message content] |