mirror of
https://github.com/JakubMelka/PDF4QT.git
synced 2025-06-05 21:59:17 +02:00
3D PDF: Scene graph - počáteční práce - liniová grafika
This commit is contained in:
@@ -70,7 +70,7 @@ MainWindow::MainWindow(QWidget* parent) :
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
m_settingsDockWidget = new SettingsDockWidget(&m_settings, this);
|
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::colorsChanged, this, &MainWindow::onColorsChanged);
|
||||||
connect(m_settingsDockWidget, &SettingsDockWidget::transparencySliderChanged, this, &MainWindow::updateOverlayTransparency);
|
connect(m_settingsDockWidget, &SettingsDockWidget::transparencySliderChanged, this, &MainWindow::updateOverlayTransparency);
|
||||||
|
|
||||||
|
@@ -2276,9 +2276,75 @@ PDF3D_U3D_Node& PDF3D_U3D::getOrCreateNode(const QString& nodeName)
|
|||||||
return m_sceneGraph[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)
|
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)
|
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
|
bool PDF3D_U3D_Node::isEnabled() const
|
||||||
{
|
{
|
||||||
return m_isEnabled;
|
return m_isEnabled;
|
||||||
|
@@ -70,6 +70,16 @@ public:
|
|||||||
|
|
||||||
void addChild(const QString& child, QMatrix4x4 childTransform);
|
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;
|
bool isEnabled() const;
|
||||||
void setIsEnabled(bool newIsEnabled);
|
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); }
|
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 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); }
|
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 addPosition(const QVector3D& position) { m_positions.emplace_back(position); }
|
||||||
void addNormal(const QVector3D& normal) { m_normals.emplace_back(normal); }
|
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 getNormalCount() const { return m_normals.size(); }
|
||||||
size_t getDiffuseColorCount() const { return m_diffuseColors.size(); }
|
size_t getDiffuseColorCount() const { return m_diffuseColors.size(); }
|
||||||
size_t getSpecularColorCount() const { return m_specularColors.size(); }
|
size_t getSpecularColorCount() const { return m_specularColors.size(); }
|
||||||
|
size_t getLineCount() const { return m_lines.size(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<QVector3D> m_positions;
|
std::vector<QVector3D> m_positions;
|
||||||
@@ -516,6 +528,13 @@ public:
|
|||||||
const PDF3D_U3D_Node& getNode(const QString& nodeName) const;
|
const PDF3D_U3D_Node& getNode(const QString& nodeName) const;
|
||||||
PDF3D_U3D_Node& getOrCreateNode(const QString& nodeName);
|
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 setViewResource(const QString& viewName, PDF3D_U3D_View view);
|
||||||
void setLightResource(const QString& lightName, PDF3D_U3D_Light light);
|
void setLightResource(const QString& lightName, PDF3D_U3D_Light light);
|
||||||
void setTextureResource(const QString& textureName, QImage texture);
|
void setTextureResource(const QString& textureName, QImage texture);
|
||||||
@@ -527,7 +546,7 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
std::map<QString, PDF3D_U3D_Node> m_sceneGraph;
|
std::map<QString, PDF3D_U3D_Node> m_sceneGraph;
|
||||||
std::map<QString, PDF3D_U3D_View> m_viewResoures;
|
std::map<QString, PDF3D_U3D_View> m_viewResources;
|
||||||
std::map<QString, PDF3D_U3D_Light> m_lightResources;
|
std::map<QString, PDF3D_U3D_Light> m_lightResources;
|
||||||
std::map<QString, QImage> m_textureResources;
|
std::map<QString, QImage> m_textureResources;
|
||||||
std::map<QString, PDF3D_U3D_Shader> m_shaderResources;
|
std::map<QString, PDF3D_U3D_Shader> m_shaderResources;
|
||||||
|
461
Pdf4QtViewer/pdf3dsceneprocessor.cpp
Normal file
461
Pdf4QtViewer/pdf3dsceneprocessor.cpp
Normal file
@@ -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 <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#include "pdf3dsceneprocessor.h"
|
||||||
|
#include "pdf3d_u3d.h"
|
||||||
|
#include "pdfdbgheap.h"
|
||||||
|
|
||||||
|
#include <Qt3DCore/QEntity>
|
||||||
|
#include <Qt3DCore/QTransform>
|
||||||
|
#include <Qt3DRender/QSpotLight>
|
||||||
|
#include <Qt3DRender/QPointLight>
|
||||||
|
#include <Qt3DRender/QDirectionalLight>
|
||||||
|
#include <Qt3DRender/QAttribute>
|
||||||
|
#include <Qt3DRender/QGeometry>
|
||||||
|
#include <Qt3DRender/QGeometryRenderer>
|
||||||
|
#include <Qt3DRender/QBuffer>
|
||||||
|
#include <Qt3DExtras/QDiffuseSpecularMaterial>
|
||||||
|
|
||||||
|
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<float*>(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<unsigned int*>(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
|
120
Pdf4QtViewer/pdf3dsceneprocessor.h
Normal file
120
Pdf4QtViewer/pdf3dsceneprocessor.h
Normal file
@@ -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 <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#ifndef PDF3DSCENEPROCESSOR_H
|
||||||
|
#define PDF3DSCENEPROCESSOR_H
|
||||||
|
|
||||||
|
#include "pdfglobal.h"
|
||||||
|
|
||||||
|
#include <QColor>
|
||||||
|
|
||||||
|
#include <set>
|
||||||
|
|
||||||
|
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<QString> m_processedNodes;
|
||||||
|
const pdf::u3d::PDF3D_U3D* m_sceneData = nullptr;
|
||||||
|
QColor m_globalAmbientColor;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace pdfviewer
|
||||||
|
|
||||||
|
#endif // PDF3DSCENEPROCESSOR_H
|
@@ -21,6 +21,7 @@
|
|||||||
#include "pdfdocument.h"
|
#include "pdfdocument.h"
|
||||||
#include "pdfannotation.h"
|
#include "pdfannotation.h"
|
||||||
#include "pdf3d_u3d.h"
|
#include "pdf3d_u3d.h"
|
||||||
|
#include "pdf3dsceneprocessor.h"
|
||||||
#include "pdfdbgheap.h"
|
#include "pdfdbgheap.h"
|
||||||
|
|
||||||
#include <QColor>
|
#include <QColor>
|
||||||
@@ -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,
|
void PDFMediaViewerDialog::initFrom3DAnnotation(const pdf::PDFDocument* document,
|
||||||
const pdf::PDF3DAnnotation* annotation)
|
const pdf::PDF3DAnnotation* annotation)
|
||||||
{
|
{
|
||||||
const pdf::PDF3DStream& stream = annotation->getStream();
|
const pdf::PDF3DStream& stream = annotation->getStream();
|
||||||
|
|
||||||
|
m_sceneU3d = std::nullopt;
|
||||||
|
|
||||||
pdf::PDFObject object = document->getObject(stream.getStream());
|
pdf::PDFObject object = document->getObject(stream.getStream());
|
||||||
if (object.isStream())
|
if (object.isStream())
|
||||||
{
|
{
|
||||||
@@ -198,17 +223,8 @@ void PDFMediaViewerDialog::initFrom3DAnnotation(const pdf::PDFDocument* document
|
|||||||
{
|
{
|
||||||
case pdf::PDF3DStream::Type::U3D:
|
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;
|
QStringList errors;
|
||||||
pdf::u3d::PDF3D_U3D u3d = pdf::u3d::PDF3D_U3D::parse(data, &errors);
|
m_sceneU3d = pdf::u3d::PDF3D_U3D::parse(data, &errors);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -219,6 +235,8 @@ void PDFMediaViewerDialog::initFrom3DAnnotation(const pdf::PDFDocument* document
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
regenerateScene();
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace pdfviewer
|
} // namespace pdfviewer
|
||||||
|
@@ -19,6 +19,7 @@
|
|||||||
#define PDFMEDIAVIEWERDIALOG_H
|
#define PDFMEDIAVIEWERDIALOG_H
|
||||||
|
|
||||||
#include "pdfglobal.h"
|
#include "pdfglobal.h"
|
||||||
|
#include "pdf3d_u3d.h"
|
||||||
|
|
||||||
#include <QDialog>
|
#include <QDialog>
|
||||||
|
|
||||||
@@ -59,12 +60,14 @@ public:
|
|||||||
void initFromAnnotation(const pdf::PDFDocument* document, const pdf::PDFAnnotation* annotation);
|
void initFromAnnotation(const pdf::PDFDocument* document, const pdf::PDFAnnotation* annotation);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void regenerateScene();
|
||||||
void initFrom3DAnnotation(const pdf::PDFDocument* document, const pdf::PDF3DAnnotation* annotation);
|
void initFrom3DAnnotation(const pdf::PDFDocument* document, const pdf::PDF3DAnnotation* annotation);
|
||||||
|
|
||||||
Ui::PDFMediaViewerDialog* ui;
|
Ui::PDFMediaViewerDialog* ui;
|
||||||
Qt3DExtras::Qt3DWindow* m_3dWindow = nullptr;
|
Qt3DExtras::Qt3DWindow* m_3dWindow = nullptr;
|
||||||
Qt3DCore::QEntity* m_rootEntity = nullptr;
|
Qt3DCore::QEntity* m_rootEntity = nullptr;
|
||||||
Qt3DCore::QEntity* m_sceneEntity = nullptr;
|
Qt3DCore::QEntity* m_sceneEntity = nullptr;
|
||||||
|
std::optional<pdf::u3d::PDF3D_U3D> m_sceneU3d;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace pdfviewer
|
} // namespace pdfviewer
|
||||||
|
Reference in New Issue
Block a user