From cebfd9d9891c0535d0c5aae3ba189ca6778e058a Mon Sep 17 00:00:00 2001 From: Jakub Melka Date: Sun, 4 Dec 2022 19:14:23 +0100 Subject: [PATCH] 3D PDF: Solid painting --- Pdf4QtLib/sources/pdf3d_u3d.h | 6 + Pdf4QtViewer/pdf3dsceneprocessor.cpp | 556 ++++++++++++++++++++++++-- Pdf4QtViewer/pdf3dsceneprocessor.h | 2 + Pdf4QtViewer/pdfmediaviewerdialog.cpp | 2 +- 4 files changed, 530 insertions(+), 36 deletions(-) diff --git a/Pdf4QtLib/sources/pdf3d_u3d.h b/Pdf4QtLib/sources/pdf3d_u3d.h index 7625b32..10041e3 100644 --- a/Pdf4QtLib/sources/pdf3d_u3d.h +++ b/Pdf4QtLib/sources/pdf3d_u3d.h @@ -164,6 +164,10 @@ public: size_t getDiffuseColorCount() const { return m_diffuseColors.size(); } size_t getSpecularColorCount() const { return m_specularColors.size(); } size_t getTextureCoordinateCount() const { return m_textureCoordinates.size(); } + size_t getTriangleCount() const { return m_triangles.size(); } + + const std::vector& getPositions() const { return m_positions; } + const std::vector& getTriangles() const { return m_triangles; } private: std::vector m_positions; @@ -211,6 +215,8 @@ public: size_t getDiffuseColorCount() const { return m_diffuseColors.size(); } size_t getSpecularColorCount() const { return m_specularColors.size(); } + const std::vector& getPositions() const { return m_positions; } + private: std::vector m_positions; std::vector m_normals; diff --git a/Pdf4QtViewer/pdf3dsceneprocessor.cpp b/Pdf4QtViewer/pdf3dsceneprocessor.cpp index cbb3fd9..a3f0ecc 100644 --- a/Pdf4QtViewer/pdf3dsceneprocessor.cpp +++ b/Pdf4QtViewer/pdf3dsceneprocessor.cpp @@ -19,6 +19,8 @@ #include "pdf3d_u3d.h" #include "pdfdbgheap.h" +#include + #include #include #include @@ -33,9 +35,13 @@ #include #include #include +#include +#include +#include #include #include #include +#include namespace pdfviewer { @@ -60,6 +66,35 @@ namespace pdfviewer ShadedIllustration Stinovana ilustrace */ +class PDF3DTextureImage : public Qt3DRender::QPaintedTextureImage +{ + using BaseClass = Qt3DRender::QPaintedTextureImage; +public: + explicit PDF3DTextureImage(QImage image, Qt3DCore::QNode* parent) : + BaseClass(parent), + m_image(std::move(image)) + { + + } + + virtual ~PDF3DTextureImage() override + { + + } + +protected: + virtual void paint(QPainter* painter) override; + +private: + QImage m_image; +}; + +void PDF3DTextureImage::paint(QPainter* painter) +{ + painter->setViewport(0, height(), width(), -height()); + painter->drawImage(QRectF(QPointF(0, 0), size()), m_image); +} + PDF3DSceneProcessor::Scene PDF3DSceneProcessor::createScene(const pdf::u3d::PDF3D_U3D* sceneData) { Scene scene; @@ -305,13 +340,449 @@ Qt3DCore::QNode* PDF3DSceneProcessor::createLightNode(const pdf::u3d::PDF3D_U3D_ Qt3DCore::QNode* PDF3DSceneProcessor::createMeshGeometry(const pdf::u3d::PDF3D_U3D_MeshGeometry* meshGeometry) { - // TODO: Implement mesh geometry + if (meshGeometry->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. + + PDF3DBoundingBox boundingBox = PDF3DBoundingBox::getBoundingBox(meshGeometry->getPositions()); + if (!boundingBox.isEmpty()) + { + return createBoundingBoxWireGeometry(boundingBox); + } + + break; + } + + case TransparentBoundingBox: + { + // We will display bounding box only, bounding + // box has no edges missing and faces are transparent. + + PDF3DBoundingBox boundingBox = PDF3DBoundingBox::getBoundingBox(meshGeometry->getPositions()); + if (!boundingBox.isEmpty()) + { + return createBoundingBoxTransparentGeometry(boundingBox); + } + + break; + } + + case TransparentBoundingBoxOutline: + { + // We will display bounding box only, bounding + // box has edges colored with auxiliary color and faces are + // transparent. + + PDF3DBoundingBox boundingBox = PDF3DBoundingBox::getBoundingBox(meshGeometry->getPositions()); + if (!boundingBox.isEmpty()) + { + Qt3DCore::QNode* wireGeometry = createBoundingBoxWireGeometry(boundingBox); + Qt3DCore::QNode* transparentGeometry = createBoundingBoxTransparentGeometry(boundingBox); + + Q_ASSERT(wireGeometry); + Q_ASSERT(transparentGeometry); + + Qt3DCore::QNode* node = new Qt3DCore::QNode(); + wireGeometry->setParent(node); + transparentGeometry->setParent(node); + return node; + } + + break; + } + + case Wireframe: + { + // We will display lines colored by auxiliary color + + // Vertex buffer + Qt3DRender::QAttribute* positionAttribute = createPositionAttribute(meshGeometry->getPositions()); + + // Index buffer + uint lineCount = static_cast(meshGeometry->getTriangleCount()) * 3; + 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 (const pdf::u3d::PDF3D_U3D_MeshGeometry::Triangle& triangle : meshGeometry->getTriangles()) + { + *indexBufferDataPtr++ = triangle.vertices[0].positionIndex; + *indexBufferDataPtr++ = triangle.vertices[1].positionIndex; + *indexBufferDataPtr++ = triangle.vertices[1].positionIndex; + *indexBufferDataPtr++ = triangle.vertices[2].positionIndex; + *indexBufferDataPtr++ = triangle.vertices[2].positionIndex; + *indexBufferDataPtr++ = triangle.vertices[0].positionIndex; + } + 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 Vertices: + { + // We will display only vertices, with auxiliary color + + return createVertexGeometry(meshGeometry->getPositions()); + } + + case Solid: + { + // We will display solid color + + // Vertex buffer - we create vertex buffer with position(3), normal(3), color(4), texture coordinate (2) + constexpr int positionVertexSize = 3; + constexpr int normalVertexSize = 3; + constexpr int colorVertexSize = 4; + constexpr int textureVertexSize = 2; + + const uint triangleCount = static_cast(meshGeometry->getTriangleCount()); + constexpr uint32_t stride = (positionVertexSize + normalVertexSize + colorVertexSize + textureVertexSize) * sizeof(float); + constexpr uint32_t positionVertexByteOffset = 0; + constexpr uint32_t normalVertexByteOffset = positionVertexByteOffset + positionVertexSize * sizeof(float); + constexpr uint32_t colorVertexByteOffset = normalVertexByteOffset + normalVertexSize * sizeof(float); + constexpr uint32_t textureVertexByteOffset = colorVertexByteOffset + colorVertexSize * sizeof(float); + + QByteArray vertexBufferData; + vertexBufferData.resize(triangleCount * 3 * stride); + float* vertexBufferDataPtr = reinterpret_cast(vertexBufferData.data()); + + bool hasTextures = false; + bool hasDiffuse = false; + bool hasSpecular = false; + + Qt3DRender::QBuffer* vertexBuffer = new Qt3DRender::QBuffer(); + vertexBuffer->setType(Qt3DRender::QBuffer::VertexBuffer); + + for (const pdf::u3d::PDF3D_U3D_MeshGeometry::Triangle& triangle : meshGeometry->getTriangles()) + { + hasTextures = hasTextures || triangle.hasTexture; + hasDiffuse = hasDiffuse || triangle.hasDiffuse; + hasSpecular = hasSpecular || triangle.hasSpecular; + + for (const pdf::u3d::PDF3D_U3D_MeshGeometry::Vertex& vertex : triangle.vertices) + { + QVector3D position = meshGeometry->getPosition(vertex.positionIndex); + QVector3D normal = meshGeometry->getNormal(vertex.normalIndex); + QVector4D diffuseColor = meshGeometry->getDiffuseColor(vertex.diffuseColorIndex); + QVector4D textureCoordinate = meshGeometry->getTextureCoordinate(vertex.textureCoordIndex); + + // Vertex + *vertexBufferDataPtr++ = position[0]; + *vertexBufferDataPtr++ = position[1]; + *vertexBufferDataPtr++ = position[2]; + + // Normal + *vertexBufferDataPtr++ = normal[0]; + *vertexBufferDataPtr++ = normal[1]; + *vertexBufferDataPtr++ = normal[2]; + + // Diffuse + *vertexBufferDataPtr++ = diffuseColor[0]; + *vertexBufferDataPtr++ = diffuseColor[1]; + *vertexBufferDataPtr++ = diffuseColor[2]; + *vertexBufferDataPtr++ = diffuseColor[3]; + + // Texture coordinate + *vertexBufferDataPtr++ = textureCoordinate[0]; + *vertexBufferDataPtr++ = textureCoordinate[1]; + + Q_ASSERT(vertexBufferDataPtr <= reinterpret_cast(vertexBufferData.data() + vertexBufferData.size())); + } + } + vertexBuffer->setData(vertexBufferData); + + // Position attribute + Qt3DRender::QAttribute* positionAttribute = new Qt3DRender::QAttribute(); + positionAttribute->setName(Qt3DRender::QAttribute::defaultPositionAttributeName()); + positionAttribute->setAttributeType(Qt3DRender::QAttribute::VertexAttribute); + positionAttribute->setDataType(Qt3DRender::QAttribute::Float); + positionAttribute->setDataSize(positionVertexSize); + positionAttribute->setBuffer(vertexBuffer); + positionAttribute->setByteOffset(positionVertexByteOffset); + positionAttribute->setByteStride(stride); + positionAttribute->setCount(triangleCount * 3); + + // Normal attribute + Qt3DRender::QAttribute* normalAttribute = new Qt3DRender::QAttribute(); + normalAttribute->setName(Qt3DRender::QAttribute::defaultNormalAttributeName()); + normalAttribute->setAttributeType(Qt3DRender::QAttribute::VertexAttribute); + normalAttribute->setDataType(Qt3DRender::QAttribute::Float); + normalAttribute->setDataSize(normalVertexSize); + normalAttribute->setBuffer(vertexBuffer); + normalAttribute->setByteOffset(normalVertexByteOffset); + normalAttribute->setByteStride(stride); + normalAttribute->setCount(triangleCount * 3); + + // Color attribute + Qt3DRender::QAttribute* colorAttribute = new Qt3DRender::QAttribute(); + colorAttribute->setName(Qt3DRender::QAttribute::defaultColorAttributeName()); + colorAttribute->setAttributeType(Qt3DRender::QAttribute::VertexAttribute); + colorAttribute->setDataType(Qt3DRender::QAttribute::Float); + colorAttribute->setDataSize(colorVertexSize); + colorAttribute->setBuffer(vertexBuffer); + colorAttribute->setByteOffset(colorVertexByteOffset); + colorAttribute->setByteStride(stride); + colorAttribute->setCount(triangleCount * 3); + + // Texture attribute + Qt3DRender::QAttribute* textureAttribute = new Qt3DRender::QAttribute(); + textureAttribute->setName(Qt3DRender::QAttribute::defaultTextureCoordinateAttributeName()); + textureAttribute->setAttributeType(Qt3DRender::QAttribute::VertexAttribute); + textureAttribute->setDataType(Qt3DRender::QAttribute::Float); + textureAttribute->setDataSize(textureVertexSize); + textureAttribute->setBuffer(vertexBuffer); + textureAttribute->setByteOffset(textureVertexByteOffset); + textureAttribute->setByteStride(stride); + textureAttribute->setCount(triangleCount * 3); + + // Geometry + Qt3DRender::QGeometry* geometry = new Qt3DRender::QGeometry(); + geometry->addAttribute(positionAttribute); + geometry->addAttribute(normalAttribute); + geometry->addAttribute(colorAttribute); + geometry->addAttribute(textureAttribute); + + Qt3DRender::QGeometryRenderer* geometryRenderer = new Qt3DRender::QGeometryRenderer(); + geometryRenderer->setGeometry(geometry); + geometryRenderer->setPrimitiveRestartEnabled(false); + geometryRenderer->setPrimitiveType(Qt3DRender::QGeometryRenderer::Triangles); + + Qt3DCore::QEntity* entity = new Qt3DCore::QEntity(); + entity->addComponent(geometryRenderer); + + if (hasTextures) + { + Qt3DExtras::QTextureMaterial* material = new Qt3DExtras::QTextureMaterial(); + material->setAlphaBlendingEnabled(true); + + QImage image(512, 512, QImage::Format_RGBA8888); + image.fill(QColor::fromRgbF(0.0, 0.5, 0.0, 0.5)); + + PDF3DTextureImage* textureImage = new PDF3DTextureImage(image, material); + textureImage->setSize(image.size()); + material->texture()->setSize(image.width(), image.height()); + material->texture()->addTextureImage(textureImage); + + entity->addComponent(material); + } + else + { + Qt3DExtras::QPerVertexColorMaterial* material = new Qt3DExtras::QPerVertexColorMaterial(); + entity->addComponent(material); + } + + return entity; + } + + case Illustration: + case ShadedIllustration: + case ShadedWireframe: + case HiddenWireframe: + case SolidOutline: + case Transparent: + case TransparentWireframe: + case SolidWireframe: + case ShadedVertices: + + default: + Q_ASSERT(false); + break; + } + return nullptr; } Qt3DCore::QNode* PDF3DSceneProcessor::createPointSetGeometry(const pdf::u3d::PDF3D_U3D_PointSetGeometry* pointSetGeometry) { - // TODO: Implement mesh geometry + if (pointSetGeometry->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. + + PDF3DBoundingBox boundingBox = PDF3DBoundingBox::getBoundingBox(pointSetGeometry->getPositions()); + if (!boundingBox.isEmpty()) + { + return createBoundingBoxWireGeometry(boundingBox); + } + + break; + } + + case TransparentBoundingBox: + { + // We will display bounding box only, bounding + // box has no edges missing and faces are transparent. + + PDF3DBoundingBox boundingBox = PDF3DBoundingBox::getBoundingBox(pointSetGeometry->getPositions()); + if (!boundingBox.isEmpty()) + { + return createBoundingBoxTransparentGeometry(boundingBox); + } + + break; + } + + case TransparentBoundingBoxOutline: + { + // We will display bounding box only, bounding + // box has edges colored with auxiliary color and faces are + // transparent. + + PDF3DBoundingBox boundingBox = PDF3DBoundingBox::getBoundingBox(pointSetGeometry->getPositions()); + if (!boundingBox.isEmpty()) + { + Qt3DCore::QNode* wireGeometry = createBoundingBoxWireGeometry(boundingBox); + Qt3DCore::QNode* transparentGeometry = createBoundingBoxTransparentGeometry(boundingBox); + + Q_ASSERT(wireGeometry); + Q_ASSERT(transparentGeometry); + + Qt3DCore::QNode* node = new Qt3DCore::QNode(); + wireGeometry->setParent(node); + transparentGeometry->setParent(node); + return node; + } + + break; + } + + case Illustration: + case ShadedIllustration: + case Wireframe: + case Vertices: + { + // We will display only vertices, with auxiliary color + + return createVertexGeometry(pointSetGeometry->getPositions()); + } + + case ShadedWireframe: + case HiddenWireframe: + case SolidOutline: + case Transparent: + case TransparentWireframe: + case Solid: + case SolidWireframe: + case ShadedVertices: + { + // We will display vertices with line color + + // Vertex buffer + Qt3DRender::QAttribute* positionAttribute = createPositionAttribute(pointSetGeometry->getPositions()); + + // Color buffer + Qt3DRender::QBuffer* colorBuffer = new Qt3DRender::QBuffer(); + colorBuffer->setType(Qt3DRender::QBuffer::VertexBuffer); + const uint positionCount = positionAttribute->count(); + + QByteArray colorBufferData; + colorBufferData.resize(positionCount * 3 * sizeof(float)); + float* colorBufferDataPtr = reinterpret_cast(colorBufferData.data()); + + for (size_t i = 0; i < positionCount; ++i) + { + QVector3D color(0.0, 0.0, 0.0); + std::vector points = pointSetGeometry->queryPointsByVertexIndex(i); + + if (!points.empty()) + { + pdf::u3d::PDF3D_U3D_PointSetGeometry::Point point = points.front(); + color = pointSetGeometry->getDiffuseColor(point.diffuseColor).toVector3D(); + } + + *colorBufferDataPtr++ = color.x(); + *colorBufferDataPtr++ = color.y(); + *colorBufferDataPtr++ = color.z(); + } + colorBuffer->setData(colorBufferData); + + Qt3DRender::QAttribute* colorAttribute = new Qt3DRender::QAttribute(); + colorAttribute->setName(Qt3DRender::QAttribute::defaultColorAttributeName()); + colorAttribute->setVertexBaseType(Qt3DRender::QAttribute::Float); + colorAttribute->setVertexSize(3); + colorAttribute->setAttributeType(Qt3DRender::QAttribute::VertexAttribute); + colorAttribute->setBuffer(colorBuffer); + colorAttribute->setByteOffset(0); + colorAttribute->setByteStride(3 * sizeof(float)); + colorAttribute->setCount(positionCount); + + // Geometry + Qt3DRender::QGeometry* geometry = new Qt3DRender::QGeometry(); + geometry->addAttribute(positionAttribute); + geometry->addAttribute(colorAttribute); + + Qt3DRender::QGeometryRenderer* geometryRenderer = new Qt3DRender::QGeometryRenderer(); + geometryRenderer->setGeometry(geometry); + geometryRenderer->setPrimitiveRestartEnabled(false); + geometryRenderer->setPrimitiveType(Qt3DRender::QGeometryRenderer::Points); + + Qt3DExtras::QPerVertexColorMaterial* material = new Qt3DExtras::QPerVertexColorMaterial(); + + Qt3DRender::QEffect* effect = material->effect(); + for (Qt3DRender::QTechnique* technique : effect->techniques()) + { + for (Qt3DRender::QRenderPass* renderPass : technique->renderPasses()) + { + Qt3DRender::QPointSize* pointSize = new Qt3DRender::QPointSize(); + pointSize->setSizeMode(Qt3DRender::QPointSize::Fixed); + pointSize->setValue(m_pointSize); + renderPass->addRenderState(pointSize); + } + } + + Qt3DCore::QEntity* entity = new Qt3DCore::QEntity(); + entity->addComponent(geometryRenderer); + entity->addComponent(material); + return entity; + } + + default: + Q_ASSERT(false); + break; + } + return nullptr; } @@ -322,6 +793,9 @@ Qt3DCore::QNode* PDF3DSceneProcessor::createLineSetGeometry(const pdf::u3d::PDF3 return nullptr; } + // TODO: Odstranit + return nullptr; + switch (m_mode) { case BoundingBox: @@ -478,39 +952,7 @@ Qt3DCore::QNode* PDF3DSceneProcessor::createLineSetGeometry(const pdf::u3d::PDF3 { // We will display only vertices, with auxiliary color - // Vertex buffer - Qt3DRender::QAttribute* positionAttribute = createPositionAttribute(lineSetGeometry->getPositions()); - - // Geometry - Qt3DRender::QGeometry* geometry = new Qt3DRender::QGeometry(); - geometry->addAttribute(positionAttribute); - - Qt3DRender::QGeometryRenderer* geometryRenderer = new Qt3DRender::QGeometryRenderer(); - geometryRenderer->setGeometry(geometry); - geometryRenderer->setPrimitiveRestartEnabled(false); - geometryRenderer->setPrimitiveType(Qt3DRender::QGeometryRenderer::Points); - - Qt3DExtras::QDiffuseSpecularMaterial* material = new Qt3DExtras::QDiffuseSpecularMaterial(); - material->setAmbient(getAuxiliaryColor()); - material->setDiffuse(QColor(Qt::transparent)); - material->setSpecular(QColor(Qt::transparent)); - - Qt3DRender::QEffect* effect = material->effect(); - for (Qt3DRender::QTechnique* technique : effect->techniques()) - { - for (Qt3DRender::QRenderPass* renderPass : technique->renderPasses()) - { - Qt3DRender::QPointSize* pointSize = new Qt3DRender::QPointSize(); - pointSize->setSizeMode(Qt3DRender::QPointSize::Fixed); - pointSize->setValue(m_pointSize); - renderPass->addRenderState(pointSize); - } - } - - Qt3DCore::QEntity* entity = new Qt3DCore::QEntity(); - entity->addComponent(geometryRenderer); - entity->addComponent(material); - return entity; + return createVertexGeometry(lineSetGeometry->getPositions()); } case ShadedVertices: @@ -603,6 +1045,43 @@ Qt3DCore::QNode* PDF3DSceneProcessor::createLineSetGeometry(const pdf::u3d::PDF3 return nullptr; } +Qt3DCore::QNode* PDF3DSceneProcessor::createVertexGeometry(const std::vector& positions) +{ + // Vertex buffer + Qt3DRender::QAttribute* positionAttribute = createPositionAttribute(positions); + + // Geometry + Qt3DRender::QGeometry* geometry = new Qt3DRender::QGeometry(); + geometry->addAttribute(positionAttribute); + + Qt3DRender::QGeometryRenderer* geometryRenderer = new Qt3DRender::QGeometryRenderer(); + geometryRenderer->setGeometry(geometry); + geometryRenderer->setPrimitiveRestartEnabled(false); + geometryRenderer->setPrimitiveType(Qt3DRender::QGeometryRenderer::Points); + + Qt3DExtras::QDiffuseSpecularMaterial* material = new Qt3DExtras::QDiffuseSpecularMaterial(); + material->setAmbient(getAuxiliaryColor()); + material->setDiffuse(QColor(Qt::transparent)); + material->setSpecular(QColor(Qt::transparent)); + + Qt3DRender::QEffect* effect = material->effect(); + for (Qt3DRender::QTechnique* technique : effect->techniques()) + { + for (Qt3DRender::QRenderPass* renderPass : technique->renderPasses()) + { + Qt3DRender::QPointSize* pointSize = new Qt3DRender::QPointSize(); + pointSize->setSizeMode(Qt3DRender::QPointSize::Fixed); + pointSize->setValue(m_pointSize); + renderPass->addRenderState(pointSize); + } + } + + Qt3DCore::QEntity* entity = new Qt3DCore::QEntity(); + entity->addComponent(geometryRenderer); + entity->addComponent(material); + return entity; +} + Qt3DCore::QNode* PDF3DSceneProcessor::createBoundingBoxWireGeometry(const PDF3DBoundingBox& boundingBox) { std::array positions; @@ -858,6 +1337,13 @@ Qt3DRender::QAttribute* PDF3DSceneProcessor::createPositionAttribute(const std:: return attribute; } +Qt3DRender::QAttribute* PDF3DSceneProcessor::createNormalAttribute(const std::vector& normals) const +{ + Qt3DRender::QAttribute* attribute = createGenericAttribute(normals); + attribute->setName(Qt3DRender::QAttribute::defaultNormalAttributeName()); + return attribute; +} + Qt3DRender::QAttribute* PDF3DSceneProcessor::createColorAttribute(const std::vector& colors) const { Qt3DRender::QAttribute* attribute = createGenericAttribute(colors); diff --git a/Pdf4QtViewer/pdf3dsceneprocessor.h b/Pdf4QtViewer/pdf3dsceneprocessor.h index f371d06..7994ee1 100644 --- a/Pdf4QtViewer/pdf3dsceneprocessor.h +++ b/Pdf4QtViewer/pdf3dsceneprocessor.h @@ -131,11 +131,13 @@ private: Qt3DCore::QNode* createPointSetGeometry(const pdf::u3d::PDF3D_U3D_PointSetGeometry* pointSetGeometry); Qt3DCore::QNode* createLineSetGeometry(const pdf::u3d::PDF3D_U3D_LineSetGeometry* lineSetGeometry); + Qt3DCore::QNode* createVertexGeometry(const std::vector& positions); Qt3DCore::QNode* createBoundingBoxWireGeometry(const PDF3DBoundingBox& boundingBox); Qt3DCore::QNode* createBoundingBoxTransparentGeometry(const PDF3DBoundingBox& boundingBox); Qt3DRender::QAttribute* createGenericAttribute(const std::vector& values) const; Qt3DRender::QAttribute* createPositionAttribute(const std::vector& positions) const; + Qt3DRender::QAttribute* createNormalAttribute(const std::vector& normals) const; Qt3DRender::QAttribute* createColorAttribute(const std::vector& colors) const; SceneMode m_mode = Solid; diff --git a/Pdf4QtViewer/pdfmediaviewerdialog.cpp b/Pdf4QtViewer/pdfmediaviewerdialog.cpp index 852ea0a..35f65f7 100644 --- a/Pdf4QtViewer/pdfmediaviewerdialog.cpp +++ b/Pdf4QtViewer/pdfmediaviewerdialog.cpp @@ -197,7 +197,7 @@ void PDFMediaViewerDialog::regenerateScene() if (m_sceneU3d.has_value()) { PDF3DSceneProcessor processor; - processor.setMode(PDF3DSceneProcessor::Wireframe); + processor.setMode(PDF3DSceneProcessor::Solid); processor.setSceneRoot("PDF3D Scene"); processor.setPointSize(6.0f); auto scene = processor.createScene(&m_sceneU3d.value());