diff --git a/Pdf4QtDocDiff/mainwindow.cpp b/Pdf4QtDocDiff/mainwindow.cpp index f14d2f0..9218190 100644 --- a/Pdf4QtDocDiff/mainwindow.cpp +++ b/Pdf4QtDocDiff/mainwindow.cpp @@ -70,7 +70,7 @@ MainWindow::MainWindow(QWidget* parent) : #endif m_settingsDockWidget = new SettingsDockWidget(&m_settings, this); - addDockWidget(Qt::LeftDockWidgetArea, m_settingsDockWidget);; + addDockWidget(Qt::LeftDockWidgetArea, m_settingsDockWidget); connect(m_settingsDockWidget, &SettingsDockWidget::colorsChanged, this, &MainWindow::onColorsChanged); connect(m_settingsDockWidget, &SettingsDockWidget::transparencySliderChanged, this, &MainWindow::updateOverlayTransparency); diff --git a/Pdf4QtLib/sources/pdf3d_u3d.cpp b/Pdf4QtLib/sources/pdf3d_u3d.cpp index 7ceb8bf..af82025 100644 --- a/Pdf4QtLib/sources/pdf3d_u3d.cpp +++ b/Pdf4QtLib/sources/pdf3d_u3d.cpp @@ -2276,9 +2276,75 @@ PDF3D_U3D_Node& PDF3D_U3D::getOrCreateNode(const QString& nodeName) return m_sceneGraph[nodeName]; } +const PDF3D_U3D_View* PDF3D_U3D::getView(const QString& viewName) const +{ + auto it = m_viewResources.find(viewName); + if (it != m_viewResources.cend()) + { + return &it->second; + } + + return nullptr; +} + +const PDF3D_U3D_Light* PDF3D_U3D::getLight(const QString& lightName) const +{ + auto it = m_lightResources.find(lightName); + if (it != m_lightResources.cend()) + { + return &it->second; + } + + return nullptr; +} + +QImage PDF3D_U3D::getTexture(const QString& textureName) const +{ + auto it = m_textureResources.find(textureName); + if (it != m_textureResources.cend()) + { + return it->second; + } + + return QImage(); +} + +const PDF3D_U3D_Shader* PDF3D_U3D::getShader(const QString& shaderName) const +{ + auto it = m_shaderResources.find(shaderName); + if (it != m_shaderResources.cend()) + { + return &it->second; + } + + return nullptr; +} + +const PDF3D_U3D_Material* PDF3D_U3D::getMaterial(const QString& materialName) const +{ + auto it = m_materialResources.find(materialName); + if (it != m_materialResources.cend()) + { + return &it->second; + } + + return nullptr; +} + +const PDF3D_U3D_Geometry* PDF3D_U3D::getGeometry(const QString& geometryName) const +{ + auto it = m_geometries.find(geometryName); + if (it != m_geometries.cend()) + { + return it->second.data(); + } + + return nullptr; +} + void PDF3D_U3D::setViewResource(const QString& viewName, PDF3D_U3D_View view) { - m_viewResoures[viewName] = std::move(view); + m_viewResources[viewName] = std::move(view); } void PDF3D_U3D::setLightResource(const QString& lightName, PDF3D_U3D_Light light) @@ -6412,6 +6478,43 @@ void PDF3D_U3D_Node::addChild(const QString& child, QMatrix4x4 childTransform) } } +QMatrix4x4 PDF3D_U3D_Node::getChildTransform(const QString& nodeName) const +{ + auto it = m_childTransforms.find(nodeName); + if (it != m_childTransforms.cend()) + { + return it->second; + } + + return QMatrix4x4(); +} + +QMatrix4x4 PDF3D_U3D_Node::getConstantChildTransform() const +{ + if (!m_childTransforms.empty()) + { + auto it = m_childTransforms.begin(); + return it->second; + } + + return QMatrix4x4(); +} + +bool PDF3D_U3D_Node::hasChildTransform() const +{ + return !m_childTransforms.empty(); +} + +bool PDF3D_U3D_Node::hasConstantChildTransform() const +{ + if (m_childTransforms.size() < 2) + { + return true; + } + + return false; +} + bool PDF3D_U3D_Node::isEnabled() const { return m_isEnabled; diff --git a/Pdf4QtLib/sources/pdf3d_u3d.h b/Pdf4QtLib/sources/pdf3d_u3d.h index 596dedd..f34a680 100644 --- a/Pdf4QtLib/sources/pdf3d_u3d.h +++ b/Pdf4QtLib/sources/pdf3d_u3d.h @@ -70,6 +70,16 @@ public: void addChild(const QString& child, QMatrix4x4 childTransform); + /// Returns transform of the child node + QMatrix4x4 getChildTransform(const QString& nodeName) const; + + /// Returns constant child transform (if all children have the same transform), + /// otherwise identity matrix is returned. + QMatrix4x4 getConstantChildTransform() const; + + bool hasChildTransform() const; + bool hasConstantChildTransform() const; + bool isEnabled() const; void setIsEnabled(bool newIsEnabled); @@ -235,6 +245,7 @@ public: QVector3D getNormal(size_t index) const { return index < m_normals.size() ? m_normals[index] : QVector3D(0, 0, 0); } QVector4D getDiffuseColor(size_t index) const { return index < m_diffuseColors.size() ? m_diffuseColors[index] : QVector4D(0, 0, 0, 0); } QVector4D getSpecularColor(size_t index) const { return index < m_specularColors.size() ? m_specularColors[index] : QVector4D(0, 0, 0, 0); } + const Line& getLine(size_t index) const { return m_lines[index]; } void addPosition(const QVector3D& position) { m_positions.emplace_back(position); } void addNormal(const QVector3D& normal) { m_normals.emplace_back(normal); } @@ -249,6 +260,7 @@ public: size_t getNormalCount() const { return m_normals.size(); } size_t getDiffuseColorCount() const { return m_diffuseColors.size(); } size_t getSpecularColorCount() const { return m_specularColors.size(); } + size_t getLineCount() const { return m_lines.size(); } private: std::vector m_positions; @@ -516,6 +528,13 @@ public: const PDF3D_U3D_Node& getNode(const QString& nodeName) const; PDF3D_U3D_Node& getOrCreateNode(const QString& nodeName); + const PDF3D_U3D_View* getView(const QString& viewName) const; + const PDF3D_U3D_Light* getLight(const QString& lightName) const; + QImage getTexture(const QString& textureName) const; + const PDF3D_U3D_Shader* getShader(const QString& shaderName) const; + const PDF3D_U3D_Material* getMaterial(const QString& materialName) const; + const PDF3D_U3D_Geometry* getGeometry(const QString& geometryName) const; + void setViewResource(const QString& viewName, PDF3D_U3D_View view); void setLightResource(const QString& lightName, PDF3D_U3D_Light light); void setTextureResource(const QString& textureName, QImage texture); @@ -527,7 +546,7 @@ public: private: std::map m_sceneGraph; - std::map m_viewResoures; + std::map m_viewResources; std::map m_lightResources; std::map m_textureResources; std::map m_shaderResources; diff --git a/Pdf4QtViewer/pdf3dsceneprocessor.cpp b/Pdf4QtViewer/pdf3dsceneprocessor.cpp new file mode 100644 index 0000000..89e511b --- /dev/null +++ b/Pdf4QtViewer/pdf3dsceneprocessor.cpp @@ -0,0 +1,461 @@ +// Copyright (C) 2022 Jakub Melka +// +// This file is part of PDF4QT. +// +// PDF4QT is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// with the written consent of the copyright owner, any later version. +// +// PDF4QT 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 Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with PDF4QT. If not, see . + +#include "pdf3dsceneprocessor.h" +#include "pdf3d_u3d.h" +#include "pdfdbgheap.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace pdfviewer +{ + +/* + English name Acrobat czech translation + + Solid Plny + SolidWireframe Plny dratovy model + Transparent Pruhledne + TransparentWireframe Pruhledny dratovy model + BoundingBox Ohranicovaci ramecek + TransparentBoundingBox Pruhledny ohranicovaci ramecek + TransparentBoundingBoxOutline Obrys pruhledneho ohranicovaciho ramecku + Wireframe Dratovy model + ShadedWireframe Stinovany dratovy model + HiddenWireframe Skryty dratovy model + Vertices Vrcholy + ShadedVertices Stinovane vrcholy + Illustration Ilustrace + SolidOutline Plny obrys + ShadedIllustration Stinovana ilustrace +*/ + +PDF3DSceneProcessor::Scene PDF3DSceneProcessor::createScene(const pdf::u3d::PDF3D_U3D* sceneData) +{ + Scene scene; + + // Clear processed nodes + m_processedNodes.clear(); + m_sceneData = sceneData; + + scene.sceneRoot = createNode(sceneData->getNode(m_sceneRoot)); + + return scene; +} + +PDF3DSceneProcessor::SceneMode PDF3DSceneProcessor::getMode() const +{ + return m_mode; +} + +void PDF3DSceneProcessor::setMode(SceneMode newMode) +{ + m_mode = newMode; +} + +const QColor& PDF3DSceneProcessor::getAuxiliaryColor() const +{ + return m_auxiliaryColor; +} + +void PDF3DSceneProcessor::setAuxiliaryColor(const QColor& newAuxiliaryColor) +{ + m_auxiliaryColor = newAuxiliaryColor; +} + +const QColor& PDF3DSceneProcessor::getFaceColor() const +{ + return m_faceColor; +} + +void PDF3DSceneProcessor::setFaceColor(const QColor& newFaceColor) +{ + m_faceColor = newFaceColor; +} + +const pdf::PDFReal& PDF3DSceneProcessor::getOpacity() const +{ + return m_opacity; +} + +void PDF3DSceneProcessor::setOpacity(const pdf::PDFReal& newOpacity) +{ + m_opacity = newOpacity; +} + +const pdf::PDFReal& PDF3DSceneProcessor::getCreaseAngle() const +{ + return m_creaseAngle; +} + +void PDF3DSceneProcessor::setCreaseAngle(const pdf::PDFReal& newCreaseAngle) +{ + m_creaseAngle = newCreaseAngle; +} + +const QString& PDF3DSceneProcessor::getSceneRoot() const +{ + return m_sceneRoot; +} + +void PDF3DSceneProcessor::setSceneRoot(const QString& newSceneRoot) +{ + m_sceneRoot = newSceneRoot; +} + +Qt3DCore::QNode* PDF3DSceneProcessor::createNode(const pdf::u3d::PDF3D_U3D_Node& node) +{ + Qt3DCore::QNode* processedNode = nullptr; + + switch (node.getType()) + { + case pdf::u3d::PDF3D_U3D_Node::Unknown: + processedNode = new Qt3DCore::QNode(nullptr); + break; + + case pdf::u3d::PDF3D_U3D_Node::Group: + { + if (node.hasChildTransform() && node.hasConstantChildTransform()) + { + Qt3DCore::QEntity* entity = new Qt3DCore::QEntity(nullptr); + Qt3DCore::QTransform* transform = new Qt3DCore::QTransform(nullptr); + transform->setMatrix(node.getConstantChildTransform()); + entity->addComponent(transform); + processedNode = entity; + } + else + { + processedNode = new Qt3DCore::QNode(nullptr); + } + break; + } + + case pdf::u3d::PDF3D_U3D_Node::Model: + { + processedNode = createModelNode(node); + break; + } + + case pdf::u3d::PDF3D_U3D_Node::Light: + { + processedNode = createLightNode(node); + break; + } + + case pdf::u3d::PDF3D_U3D_Node::View: + return nullptr; + + default: + Q_ASSERT(false); + break; + } + + if (!processedNode) + { + return processedNode; + } + + processedNode->setObjectName(node.getNodeName()); + + for (const QString& childNodeName : node.getChildren()) + { + Qt3DCore::QNode* childNode = createNode(m_sceneData->getNode(childNodeName)); + + if (!childNode) + { + continue; + } + + if (node.hasChildTransform() && !node.hasConstantChildTransform()) + { + Qt3DCore::QEntity* entity = new Qt3DCore::QEntity(processedNode); + Qt3DCore::QTransform* transform = new Qt3DCore::QTransform(nullptr); + transform->setMatrix(node.getChildTransform(childNodeName)); + entity->addComponent(transform); + childNode->setParent(entity); + } + else + { + childNode->setParent(processedNode); + } + } + + return processedNode; +} + +Qt3DCore::QNode* PDF3DSceneProcessor::createModelNode(const pdf::u3d::PDF3D_U3D_Node& node) +{ + Qt3DCore::QNode* processedNode = nullptr; + + if (const pdf::u3d::PDF3D_U3D_Geometry* geometry = m_sceneData->getGeometry(node.getResourceName())) + { + if (auto meshGeometry = geometry->asMeshGeometry()) + { + processedNode = createMeshGeometry(meshGeometry); + } + else if (auto pointSetGeometry = geometry->asPointSetGeometry()) + { + processedNode = createPointSetGeometry(pointSetGeometry); + } + else if (auto lineSetGeometry = geometry->asLineSetGeometry()) + { + processedNode = createLineSetGeometry(lineSetGeometry); + } + } + + if (processedNode) + { + processedNode->setObjectName(node.getNodeName()); + } + + return processedNode; +} + +Qt3DCore::QNode* PDF3DSceneProcessor::createLightNode(const pdf::u3d::PDF3D_U3D_Node& node) +{ + Q_ASSERT(node.getType() == pdf::u3d::PDF3D_U3D_Node::NodeType::Light); + + if (const pdf::u3d::PDF3D_U3D_Light* light = m_sceneData->getLight(node.getResourceName())) + { + switch (light->getType()) + { + case pdf::u3d::PDF3D_U3D_Light::Ambient: + { + m_globalAmbientColor.setRedF(m_globalAmbientColor.redF() + light->getColor().redF() * light->getIntensity()); + m_globalAmbientColor.setGreenF(m_globalAmbientColor.greenF() + light->getColor().greenF() * light->getIntensity()); + m_globalAmbientColor.setBlueF(m_globalAmbientColor.blueF() + light->getColor().blueF() * light->getIntensity()); + return nullptr; + } + + case pdf::u3d::PDF3D_U3D_Light::Directional: + { + Qt3DCore::QEntity* entity = new Qt3DCore::QEntity(); + Qt3DRender::QDirectionalLight* processedLight = new Qt3DRender::QDirectionalLight(); + processedLight->setColor(light->getColor()); + processedLight->setIntensity(light->getIntensity()); + entity->addComponent(processedLight); + return entity; + } + + case pdf::u3d::PDF3D_U3D_Light::Point: + { + Qt3DCore::QEntity* entity = new Qt3DCore::QEntity(); + Qt3DRender::QPointLight* processedLight = new Qt3DRender::QPointLight(); + processedLight->setColor(light->getColor()); + processedLight->setIntensity(light->getIntensity()); + processedLight->setConstantAttenuation(light->getAttenuation()[0]); + processedLight->setLinearAttenuation(light->getAttenuation()[1]); + processedLight->setQuadraticAttenuation(light->getAttenuation()[2]); + entity->addComponent(processedLight); + return entity; + } + + case pdf::u3d::PDF3D_U3D_Light::Spot: + { + Qt3DCore::QEntity* entity = new Qt3DCore::QEntity(); + Qt3DRender::QSpotLight* processedLight = new Qt3DRender::QSpotLight(); + processedLight->setColor(light->getColor()); + processedLight->setIntensity(light->getIntensity()); + processedLight->setConstantAttenuation(light->getAttenuation()[0]); + processedLight->setLinearAttenuation(light->getAttenuation()[1]); + processedLight->setQuadraticAttenuation(light->getAttenuation()[2]); + processedLight->setCutOffAngle(light->getSpotAngle()); + entity->addComponent(processedLight); + return entity; + } + + default: + Q_ASSERT(false); + break; + } + } + + return nullptr; +} + +Qt3DCore::QNode* PDF3DSceneProcessor::createMeshGeometry(const pdf::u3d::PDF3D_U3D_MeshGeometry* meshGeometry) +{ + // TODO: Implement mesh geometry + return nullptr; +} + +Qt3DCore::QNode* PDF3DSceneProcessor::createPointSetGeometry(const pdf::u3d::PDF3D_U3D_PointSetGeometry* pointSetGeometry) +{ + // TODO: Implement mesh geometry + return nullptr; +} + +Qt3DCore::QNode* PDF3DSceneProcessor::createLineSetGeometry(const pdf::u3d::PDF3D_U3D_LineSetGeometry* lineSetGeometry) +{ + if (lineSetGeometry->isEmpty()) + { + return nullptr; + } + + switch (m_mode) + { + case BoundingBox: + { + // We will display bounding box only, bounding + // box has only edges colored with auxiliary color and faces are missing. + // TODO: implement this + break; + } + + case TransparentBoundingBox: + { + // We will display bounding box only, bounding + // box has no edges missing and faces are transparent. + // TODO: implement this + break; + } + + case TransparentBoundingBoxOutline: + { + // We will display bounding box only, bounding + // box has edges colored with auxiliary color and faces are + // transparent. + // TODO: implement this + break; + } + + case Illustration: + case ShadedIllustration: + case Wireframe: + { + // We will display lines colored by auxiliary color + + // Vertex buffer + Qt3DRender::QBuffer* vertexBuffer = new Qt3DRender::QBuffer(); + vertexBuffer->setType(Qt3DRender::QBuffer::VertexBuffer); + + uint positionCount = lineSetGeometry->getPositionCount(); + QByteArray vertexBufferData; + vertexBufferData.resize(positionCount * 3 * sizeof(float)); + float* vertexBufferDataPtr = reinterpret_cast(vertexBufferData.data()); + + for (size_t i = 0; i < positionCount; ++i) + { + QVector3D position = lineSetGeometry->getPosition(i); + *vertexBufferDataPtr++ = position.x(); + *vertexBufferDataPtr++ = position.y(); + *vertexBufferDataPtr++ = position.z(); + } + vertexBuffer->setData(vertexBufferData); + + constexpr uint elementSize = 3; + constexpr uint byteStride = elementSize * sizeof(float); + + Qt3DRender::QAttribute* positionAttribute = new Qt3DRender::QAttribute(); + positionAttribute->setName(Qt3DRender::QAttribute::defaultPositionAttributeName()); + positionAttribute->setVertexBaseType(Qt3DRender::QAttribute::Float); + positionAttribute->setVertexSize(3); + positionAttribute->setAttributeType(Qt3DRender::QAttribute::VertexAttribute); + positionAttribute->setBuffer(vertexBuffer); + positionAttribute->setByteOffset(0); + positionAttribute->setByteStride(byteStride); + positionAttribute->setCount(positionCount); + + // Index buffer + uint lineCount = lineSetGeometry->getLineCount(); + QByteArray indexBufferData; + indexBufferData.resize(lineCount * 2 * sizeof(unsigned int)); + unsigned int* indexBufferDataPtr = reinterpret_cast(indexBufferData.data()); + + Qt3DRender::QBuffer* indexBuffer = new Qt3DRender::QBuffer(); + indexBuffer->setType(Qt3DRender::QBuffer::IndexBuffer); + + for (size_t i = 0; i < lineCount; ++i) + { + const auto& line = lineSetGeometry->getLine(i); + *indexBufferDataPtr++ = line.position1; + *indexBufferDataPtr++ = line.position2; + } + indexBuffer->setData(indexBufferData); + + Qt3DRender::QAttribute* indexAttribute = new Qt3DRender::QAttribute(); + indexAttribute->setAttributeType(Qt3DRender::QAttribute::IndexAttribute); + indexAttribute->setVertexBaseType(Qt3DRender::QAttribute::UnsignedInt); + indexAttribute->setBuffer(indexBuffer); + indexAttribute->setCount(2 * lineCount); + + // Geometry + Qt3DRender::QGeometry* geometry = new Qt3DRender::QGeometry(); + geometry->addAttribute(positionAttribute); + geometry->addAttribute(indexAttribute); + + Qt3DRender::QGeometryRenderer* geometryRenderer = new Qt3DRender::QGeometryRenderer(); + geometryRenderer->setGeometry(geometry); + geometryRenderer->setPrimitiveRestartEnabled(false); + geometryRenderer->setPrimitiveType(Qt3DRender::QGeometryRenderer::Lines); + + Qt3DExtras::QDiffuseSpecularMaterial* material = new Qt3DExtras::QDiffuseSpecularMaterial(); + material->setAmbient(getAuxiliaryColor()); + material->setDiffuse(QColor(Qt::transparent)); + material->setSpecular(QColor(Qt::transparent)); + + Qt3DCore::QEntity* entity = new Qt3DCore::QEntity(); + entity->addComponent(geometryRenderer); + entity->addComponent(material); + return entity; + } + + case ShadedWireframe: + case HiddenWireframe: + case SolidOutline: + case Transparent: + case TransparentWireframe: + case Solid: + case SolidWireframe: + { + // We will display classic colored lines + // TODO: implement this + break; + } + + case Vertices: + { + // We will display only vertices, with auxiliary color + // TODO: implement this + break; + } + + case ShadedVertices: + { + // We will display vertices with line color + // TODO: implement this + break; + } + + default: + Q_ASSERT(false); + break; + } + + return nullptr; +} + +} // namespace pdfviewer diff --git a/Pdf4QtViewer/pdf3dsceneprocessor.h b/Pdf4QtViewer/pdf3dsceneprocessor.h new file mode 100644 index 0000000..b9aaeee --- /dev/null +++ b/Pdf4QtViewer/pdf3dsceneprocessor.h @@ -0,0 +1,120 @@ +// Copyright (C) 2022 Jakub Melka +// +// This file is part of PDF4QT. +// +// PDF4QT is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// with the written consent of the copyright owner, any later version. +// +// PDF4QT 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 Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with PDF4QT. If not, see . + +#ifndef PDF3DSCENEPROCESSOR_H +#define PDF3DSCENEPROCESSOR_H + +#include "pdfglobal.h" + +#include + +#include + +class QComboBox; + +namespace Qt3DCore +{ +class QNode; +class QEntity; +} + +namespace pdf +{ +namespace u3d +{ +class PDF3D_U3D; +class PDF3D_U3D_Node; +class PDF3D_U3D_MeshGeometry; +class PDF3D_U3D_LineSetGeometry; +class PDF3D_U3D_PointSetGeometry; +} +} + +namespace pdfviewer +{ + +class PDF3DSceneProcessor +{ +public: + + enum SceneMode + { + Solid, + SolidWireframe, + Transparent, + TransparentWireframe, + BoundingBox, + TransparentBoundingBox, + TransparentBoundingBoxOutline, + Wireframe, + ShadedWireframe, + HiddenWireframe, + Vertices, + ShadedVertices, + Illustration, + SolidOutline, + ShadedIllustration + }; + + struct Scene + { + Qt3DCore::QNode* sceneRoot = nullptr; + }; + + Scene createScene(const pdf::u3d::PDF3D_U3D* sceneData); + + SceneMode getMode() const; + void setMode(SceneMode newMode); + + const QColor& getAuxiliaryColor() const; + void setAuxiliaryColor(const QColor& newAuxiliaryColor); + + const QColor& getFaceColor() const; + void setFaceColor(const QColor& newFaceColor); + + const pdf::PDFReal& getOpacity() const; + void setOpacity(const pdf::PDFReal& newOpacity); + + const pdf::PDFReal& getCreaseAngle() const; + void setCreaseAngle(const pdf::PDFReal& newCreaseAngle); + + const QString& getSceneRoot() const; + void setSceneRoot(const QString& newSceneRoot); + +private: + Qt3DCore::QNode* createNode(const pdf::u3d::PDF3D_U3D_Node& node); + Qt3DCore::QNode* createModelNode(const pdf::u3d::PDF3D_U3D_Node& node); + Qt3DCore::QNode* createLightNode(const pdf::u3d::PDF3D_U3D_Node& node); + Qt3DCore::QNode* createMeshGeometry(const pdf::u3d::PDF3D_U3D_MeshGeometry* meshGeometry); + Qt3DCore::QNode* createPointSetGeometry(const pdf::u3d::PDF3D_U3D_PointSetGeometry* pointSetGeometry); + Qt3DCore::QNode* createLineSetGeometry(const pdf::u3d::PDF3D_U3D_LineSetGeometry* lineSetGeometry); + + SceneMode m_mode = Solid; + QColor m_auxiliaryColor = Qt::black; + QColor m_faceColor = Qt::black; + pdf::PDFReal m_opacity = 0.5; + pdf::PDFReal m_creaseAngle = 45.0; + QString m_sceneRoot; + + std::set m_processedNodes; + const pdf::u3d::PDF3D_U3D* m_sceneData = nullptr; + QColor m_globalAmbientColor; +}; + +} // namespace pdfviewer + +#endif // PDF3DSCENEPROCESSOR_H diff --git a/Pdf4QtViewer/pdfmediaviewerdialog.cpp b/Pdf4QtViewer/pdfmediaviewerdialog.cpp index 20db698..4d2bd1b 100644 --- a/Pdf4QtViewer/pdfmediaviewerdialog.cpp +++ b/Pdf4QtViewer/pdfmediaviewerdialog.cpp @@ -21,6 +21,7 @@ #include "pdfdocument.h" #include "pdfannotation.h" #include "pdf3d_u3d.h" +#include "pdf3dsceneprocessor.h" #include "pdfdbgheap.h" #include @@ -184,11 +185,35 @@ void PDFMediaViewerDialog::initFromAnnotation(const pdf::PDFDocument* document, } } +void PDFMediaViewerDialog::regenerateScene() +{ + for (Qt3DCore::QNode* node : m_sceneEntity->childNodes()) + { + Qt3DCore::QNode* nullNode = nullptr; + node->setParent(nullNode); + delete node; + } + + if (m_sceneU3d.has_value()) + { + PDF3DSceneProcessor processor; + processor.setMode(PDF3DSceneProcessor::Wireframe); + processor.setSceneRoot("PDF3D Scene"); + auto scene = processor.createScene(&m_sceneU3d.value()); + if (scene.sceneRoot) + { + scene.sceneRoot->setParent(m_sceneEntity); + } + } +} + void PDFMediaViewerDialog::initFrom3DAnnotation(const pdf::PDFDocument* document, const pdf::PDF3DAnnotation* annotation) { const pdf::PDF3DStream& stream = annotation->getStream(); + m_sceneU3d = std::nullopt; + pdf::PDFObject object = document->getObject(stream.getStream()); if (object.isStream()) { @@ -198,17 +223,8 @@ void PDFMediaViewerDialog::initFrom3DAnnotation(const pdf::PDFDocument* document { case pdf::PDF3DStream::Type::U3D: { - // TODO: Smazat - /*QString file = "K:\\Programming\\PDF\\PDF_For_Qt\\U3D_parser\\u3d-tools\\src\\test.u3d"; - QFile f(file); - if (f.open(QFile::WriteOnly | QFile::Truncate)) - { - f.write(data); - f.close(); - }*/ - QStringList errors; - pdf::u3d::PDF3D_U3D u3d = pdf::u3d::PDF3D_U3D::parse(data, &errors); + m_sceneU3d = pdf::u3d::PDF3D_U3D::parse(data, &errors); break; } @@ -219,6 +235,8 @@ void PDFMediaViewerDialog::initFrom3DAnnotation(const pdf::PDFDocument* document break; } } + + regenerateScene(); } } // namespace pdfviewer diff --git a/Pdf4QtViewer/pdfmediaviewerdialog.h b/Pdf4QtViewer/pdfmediaviewerdialog.h index 0cb53b2..0738db6 100644 --- a/Pdf4QtViewer/pdfmediaviewerdialog.h +++ b/Pdf4QtViewer/pdfmediaviewerdialog.h @@ -19,6 +19,7 @@ #define PDFMEDIAVIEWERDIALOG_H #include "pdfglobal.h" +#include "pdf3d_u3d.h" #include @@ -59,12 +60,14 @@ public: void initFromAnnotation(const pdf::PDFDocument* document, const pdf::PDFAnnotation* annotation); private: + void regenerateScene(); void initFrom3DAnnotation(const pdf::PDFDocument* document, const pdf::PDF3DAnnotation* annotation); Ui::PDFMediaViewerDialog* ui; Qt3DExtras::Qt3DWindow* m_3dWindow = nullptr; Qt3DCore::QEntity* m_rootEntity = nullptr; Qt3DCore::QEntity* m_sceneEntity = nullptr; + std::optional m_sceneU3d; }; } // namespace pdfviewer