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
|
||||
|
||||
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);
|
||||
|
||||
|
@@ -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;
|
||||
|
@@ -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<QVector3D> 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<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, QImage> m_textureResources;
|
||||
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 "pdfannotation.h"
|
||||
#include "pdf3d_u3d.h"
|
||||
#include "pdf3dsceneprocessor.h"
|
||||
#include "pdfdbgheap.h"
|
||||
|
||||
#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,
|
||||
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
|
||||
|
@@ -19,6 +19,7 @@
|
||||
#define PDFMEDIAVIEWERDIALOG_H
|
||||
|
||||
#include "pdfglobal.h"
|
||||
#include "pdf3d_u3d.h"
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
@@ -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<pdf::u3d::PDF3D_U3D> m_sceneU3d;
|
||||
};
|
||||
|
||||
} // namespace pdfviewer
|
||||
|
Reference in New Issue
Block a user