Warning, file /office/calligra/libs/odf/Ko3dScene.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001 /* This file is part of the KDE project 0002 * 0003 * Copyright (C) 2012 Inge Wallin <inge@lysator.liu.se> 0004 * 0005 * This library is free software; you can redistribute it and/or 0006 * modify it under the terms of the GNU Library General Public 0007 * License as published by the Free Software Foundation; either 0008 * version 2 of the License, or (at your option) any later version. 0009 * 0010 * This library is distributed in the hope that it will be useful, 0011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 0012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0013 * Library General Public License for more details. 0014 * 0015 * You should have received a copy of the GNU Library General Public License 0016 * along with this library; see the file COPYING.LIB. If not, write to 0017 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 0018 * Boston, MA 02110-1301, USA. 0019 */ 0020 0021 // Own 0022 #include "Ko3dScene.h" 0023 0024 #include "OdfDebug.h" 0025 0026 // Calligra 0027 #include <KoXmlReader.h> 0028 #include <KoXmlNS.h> 0029 #include <KoXmlWriter.h> 0030 0031 0032 static QVector3D odfToVector3D(const QString &string); 0033 0034 0035 0036 // ---------------------------------------------------------------- 0037 // Ko3dScene::Private 0038 0039 0040 class Q_DECL_HIDDEN Ko3dScene::Private 0041 { 0042 public: 0043 Private() {}; 0044 ~Private() {}; 0045 0046 // Camera attributes 0047 QVector3D vrp; // Camera origin 0048 QVector3D vpn; // Camera direction 0049 QVector3D vup; // Up direction 0050 Projection projection; 0051 QString distance; 0052 QString focalLength; 0053 QString shadowSlant; 0054 0055 // Rendering attributes 0056 Shademode shadeMode; 0057 QColor ambientColor; 0058 bool lightingMode; // True: enable lights, false: disable lights 0059 QString transform; 0060 0061 // Lightsources (these are children of the element, not attributes) 0062 QVector<Lightsource> lights; 0063 }; 0064 0065 0066 // ---------------------------------------------------------------- 0067 // Lightsource 0068 0069 0070 Ko3dScene::Lightsource::Lightsource() 0071 { 0072 } 0073 0074 Ko3dScene::Lightsource::~Lightsource() 0075 { 0076 } 0077 0078 0079 // getters 0080 QColor Ko3dScene::Lightsource::diffuseColor() const { return m_diffuseColor; } 0081 QVector3D Ko3dScene::Lightsource::direction() const { return m_direction; } 0082 bool Ko3dScene::Lightsource::enabled() const { return m_enabled; } 0083 bool Ko3dScene::Lightsource::specular() const { return m_specular; } 0084 0085 // setters 0086 void 0087 Ko3dScene::Lightsource::setDiffuseColor(const QColor &color) 0088 { 0089 m_diffuseColor = color; 0090 } 0091 0092 void 0093 Ko3dScene::Lightsource::setDirection(const QVector3D &direction) 0094 { 0095 m_direction = direction; 0096 } 0097 0098 void 0099 Ko3dScene::Lightsource::setEnabled(const bool enabled) 0100 { 0101 m_enabled = enabled; 0102 } 0103 0104 void 0105 Ko3dScene::Lightsource::setSpecular(const bool specular) 0106 { 0107 m_specular = specular; 0108 } 0109 0110 0111 bool Ko3dScene::Lightsource::loadOdf(const KoXmlElement &lightElement) 0112 { 0113 m_diffuseColor = QColor(lightElement.attributeNS(KoXmlNS::dr3d, "diffuse-color", "#ffffff")); 0114 QString direction = lightElement.attributeNS(KoXmlNS::dr3d, "direction"); 0115 m_direction = odfToVector3D(direction); 0116 m_enabled = (lightElement.attributeNS(KoXmlNS::dr3d, "enabled") == "true"); 0117 m_specular = (lightElement.attributeNS(KoXmlNS::dr3d, "specular") == "true"); 0118 0119 return true; 0120 } 0121 0122 void Ko3dScene::Lightsource::saveOdf(KoXmlWriter &writer) const 0123 { 0124 writer.startElement("dr3d:light"); 0125 0126 writer.addAttribute("dr3d:diffuse-color", m_diffuseColor.name()); 0127 writer.addAttribute("dr3d:direction", (QString("(%1 %2 %3)") 0128 .arg(m_direction.x(), 0, 'f', 11) 0129 .arg(m_direction.y(), 0, 'f', 11) 0130 .arg(m_direction.z(), 0, 'f', 11))); 0131 writer.addAttribute("dr3d:enabled", m_enabled); 0132 writer.addAttribute("dr3d:specular", m_specular); 0133 0134 writer.endElement(); // dr3d:light 0135 } 0136 0137 0138 // ---------------------------------------------------------------- 0139 // Ko3dScene 0140 0141 0142 Ko3dScene::Ko3dScene() 0143 : d(new Private()) 0144 { 0145 } 0146 0147 Ko3dScene::~Ko3dScene() 0148 { 0149 delete d; 0150 } 0151 0152 0153 // getters 0154 QVector3D Ko3dScene::vrp() const { return d->vrp; } 0155 QVector3D Ko3dScene::vpn() const { return d->vpn; } 0156 QVector3D Ko3dScene::vup() const { return d->vup; } 0157 Ko3dScene::Projection Ko3dScene::projection() const { return d->projection; } 0158 QString Ko3dScene::distance() const { return d->distance; } 0159 QString Ko3dScene::focalLength() const { return d->focalLength; } 0160 QString Ko3dScene::shadowSlant() const { return d->shadowSlant; } 0161 Ko3dScene::Shademode Ko3dScene::shadeMode() const { return d->shadeMode; } 0162 QColor Ko3dScene::ambientColor() const { return d->ambientColor; } 0163 bool Ko3dScene::lightingMode() const { return d->lightingMode; } 0164 QString Ko3dScene::transform() const { return d->transform; } 0165 0166 // setters 0167 void Ko3dScene::setVrp(const QVector3D &vrp) { d->vrp = vrp; } 0168 void Ko3dScene::setVpn(const QVector3D &vpn) { d->vpn = vpn; } 0169 void Ko3dScene::setVup(const QVector3D &vup) { d->vup = vup; } 0170 void Ko3dScene::setProjection(Projection projection) { d->projection = projection; } 0171 void Ko3dScene::setDistance(const QString &distance) { d->distance = distance; } 0172 void Ko3dScene::setFocalLength(const QString &focalLength) { d->focalLength = focalLength; } 0173 void Ko3dScene::setShadowSlant(const QString &shadowSlant) { d->shadowSlant = shadowSlant; } 0174 void Ko3dScene::setShadeMode(Shademode shadeMode) { d->shadeMode = shadeMode; } 0175 void Ko3dScene::setAmbientColor(const QColor &ambientColor) { d->ambientColor = ambientColor; } 0176 void Ko3dScene::setLightingMode(bool lightingMode) { d->lightingMode = lightingMode; } 0177 void Ko3dScene::setTransform(const QString &transform) { d->transform = transform; } 0178 0179 0180 bool Ko3dScene::loadOdf(const KoXmlElement &sceneElement) 0181 { 0182 QString dummy; 0183 0184 // Check if there is a 3d scene at all in this element. We 0185 // approximate that by checking if there are any camera parameters. 0186 if (!sceneElement.hasAttributeNS(KoXmlNS::dr3d, "vrp") 0187 && !sceneElement.hasAttributeNS(KoXmlNS::dr3d, "vpn") 0188 && !sceneElement.hasAttributeNS(KoXmlNS::dr3d, "vup")) 0189 { 0190 return false; 0191 } 0192 0193 // 1. Load the scene attributes. 0194 0195 // Camera attributes 0196 dummy = sceneElement.attributeNS(KoXmlNS::dr3d, "vrp"); 0197 d->vrp = odfToVector3D(dummy); 0198 dummy = sceneElement.attributeNS(KoXmlNS::dr3d, "vpn"); 0199 d->vpn = odfToVector3D(dummy); 0200 dummy = sceneElement.attributeNS(KoXmlNS::dr3d, "vup", "(0.0 0.0 1.0)"); 0201 d->vup = odfToVector3D(dummy); 0202 0203 dummy = sceneElement.attributeNS(KoXmlNS::dr3d, "projection", "perspective"); 0204 if (dummy == "parallel") { 0205 d->projection = Parallel; 0206 } 0207 else { 0208 d->projection = Perspective; 0209 } 0210 0211 d->distance = sceneElement.attributeNS(KoXmlNS::dr3d, "distance"); 0212 d->focalLength = sceneElement.attributeNS(KoXmlNS::dr3d, "focal-length"); 0213 d->shadowSlant = sceneElement.attributeNS(KoXmlNS::dr3d, "shadow-slant"); 0214 d->ambientColor = QColor(sceneElement.attributeNS(KoXmlNS::dr3d, "ambient-color", "#888888")); 0215 0216 // Rendering attributes 0217 dummy = sceneElement.attributeNS(KoXmlNS::dr3d, "shade-mode", "gouraud"); 0218 if (dummy == "flat") { 0219 d->shadeMode = Flat; 0220 } 0221 else if (dummy == "phong") { 0222 d->shadeMode = Phong; 0223 } 0224 else if (dummy == "draft") { 0225 d->shadeMode = Draft; 0226 } 0227 else { 0228 d->shadeMode = Gouraud; 0229 } 0230 0231 d->lightingMode = (sceneElement.attributeNS(KoXmlNS::dr3d, "lighting-mode") == "true"); 0232 d->transform = sceneElement.attributeNS(KoXmlNS::dr3d, "transform"); 0233 0234 // 2. Load the light sources. 0235 0236 // From the ODF 1.1 spec section 9.4.1: 0237 KoXmlElement elem; 0238 forEachElement(elem, sceneElement) { 0239 if (elem.localName() == "light" && elem.namespaceURI() == KoXmlNS::dr3d) { 0240 Lightsource light; 0241 light.loadOdf(elem); 0242 d->lights.append(light); 0243 } 0244 } 0245 0246 //debugOdf << "Lights:" << d->lights.size(); 0247 0248 return true; 0249 } 0250 0251 void Ko3dScene::saveOdfAttributes(KoXmlWriter &writer) const 0252 { 0253 // 1. Write scene attributes 0254 // Camera attributes 0255 writer.addAttribute("dr3d:vrp", (QString("(%1 %2 %3)") 0256 .arg(d->vrp.x(), 0, 'f', 11) 0257 .arg(d->vrp.y(), 0, 'f', 11) 0258 .arg(d->vrp.z(), 0, 'f', 11))); 0259 writer.addAttribute("dr3d:vpn", (QString("(%1 %2 %3)") 0260 .arg(d->vpn.x(), 0, 'f', 11) 0261 .arg(d->vpn.y(), 0, 'f', 11) 0262 .arg(d->vpn.z(), 0, 'f', 11))); 0263 writer.addAttribute("dr3d:vup", (QString("(%1 %2 %3)") 0264 .arg(d->vup.x(), 0, 'f', 11) 0265 .arg(d->vup.y(), 0, 'f', 11) 0266 .arg(d->vup.z(), 0, 'f', 11))); 0267 0268 writer.addAttribute("dr3d:projection", (d->projection == Parallel) ? "parallel" : "perspective"); 0269 0270 writer.addAttribute("dr3d:distance", d->distance); 0271 writer.addAttribute("dr3d:focal-length", d->focalLength); 0272 writer.addAttribute("dr3d:shadow-slant", d->shadowSlant); 0273 writer.addAttribute("dr3d:ambient-color", d->ambientColor.name()); 0274 0275 // Rendering attributes 0276 switch (d->shadeMode) { 0277 case Flat: 0278 writer.addAttribute("dr3d:shade-mode", "flat"); 0279 break; 0280 case Phong: 0281 writer.addAttribute("dr3d:shade-mode", "phong"); 0282 break; 0283 case Draft: 0284 writer.addAttribute("dr3d:shade-mode", "draft"); 0285 break; 0286 case Gouraud: 0287 default: 0288 writer.addAttribute("dr3d:shade-mode", "gouraud"); 0289 break; 0290 } 0291 0292 writer.addAttribute("dr3d:lighting-mode", d->lightingMode); 0293 writer.addAttribute("dr3d:transform", d->transform); 0294 } 0295 0296 0297 void Ko3dScene::saveOdfChildren(KoXmlWriter &writer) const 0298 { 0299 // Write light sources. 0300 foreach (const Lightsource &light, d->lights) { 0301 light.saveOdf(writer); 0302 } 0303 } 0304 0305 0306 // ---------------------------------------------------------------- 0307 // Public functions 0308 0309 0310 KOODF_EXPORT Ko3dScene *load3dScene(const KoXmlElement &element) 0311 { 0312 Ko3dScene *scene = new Ko3dScene(); 0313 0314 if (scene->loadOdf(element)) { 0315 return scene; 0316 } 0317 0318 delete scene; 0319 return 0; 0320 } 0321 0322 0323 // ---------------------------------------------------------------- 0324 // Static functions 0325 0326 0327 QVector3D odfToVector3D(const QString &string) 0328 { 0329 // The string comes into this function in the form "(0 3.5 0.3)". 0330 QStringList elements = string.mid(1, string.size() - 2).split(' ', QString::SkipEmptyParts); 0331 if (elements.size() == 3) { 0332 return QVector3D(elements[0].toDouble(), elements[1].toDouble(), elements[2].toDouble()); 0333 } 0334 else { 0335 return QVector3D(0, 0, 1); 0336 } 0337 }