diff --git a/Pdf4QtLib/sources/pdf3d_u3d.cpp b/Pdf4QtLib/sources/pdf3d_u3d.cpp index da1a503..d058e3a 100644 --- a/Pdf4QtLib/sources/pdf3d_u3d.cpp +++ b/Pdf4QtLib/sources/pdf3d_u3d.cpp @@ -28,6 +28,1598 @@ namespace pdf namespace u3d { +enum Context +{ + cPosDiffSign = 1, + cPosDiffX, + cPosDiffY, + cPosDiffZ, + cNormlCnt, + cDiffNormalSign, + cDiffNormalX, + cDiffNormalY, + cDiffNormalZ, + cShading, + cLineCnt = cShading, // Undocumented, that cLineCnt equals to cShading + cPointCnt = cShading, // Undocumented, that cPointCnt equals to cShading + cNormlIdx, + cDiffDup, + cDiffuseColorSign, + cColorDiffR, + cColorDiffG, + cColorDiffB, + cColorDiffA, + cSpecDup, + cSpecularColorSign, + cTexCDup, + cTexCoordSign, + cTexCDiffU, + cTexCDiffV, + cTexCDiffS, + cTexCDiffT, + cZero, + cDiffuseCount, + cSpecularCount, + cTexCoordCount, + cFaceCnt, + cFaceOrnt, + cLocal3rdPos, + cThrdPosType, + cBoneWeightCnt, + cBoneIdx, + cQntBoneWeight, + cTimeSign, + cTimeDiff, + cDispSign, + cDispDiff, + cRotSign, + cRotDiff, + cScalSign, + cScalDiff +}; + +class PDF3D_U3D; +class PDF3D_U3D_Parser; +class PDF3D_U3D_DataReader; +class PDF3D_U3D_ContextManager; + +struct PDF3D_U3D_Block_Data; + +class PDF3D_U3D_AbstractBlock; +using PDF3D_U3D_AbstractBlockPtr = QSharedPointer; + +using PDF3D_U3D_Vec3 = std::array; +using PDF3D_U3D_Vec4 = std::array; + +struct PDF3D_U3D_QuantizedVec4 +{ + uint8_t signBits; + uint32_t diff1; + uint32_t diff2; + uint32_t diff3; + uint32_t diff4; +}; + +struct PDF3D_U3D_QuantizedVec3 +{ + uint8_t signBits; + uint32_t diff1; + uint32_t diff2; + uint32_t diff3; +}; + +struct PDF3D_U3D_QuantizedVec1 +{ + uint8_t signBits; + uint32_t diff1; +}; + +struct PDF3D_U3D_Block_Info +{ + enum EBlockType : uint32_t + { + BT_Unknown = 0x00000000, + BT_FileHeader = 0x00443355, + BT_FileReference = 0xFFFFFF12, + BT_FileModifierChain = 0xFFFFFF14, + BT_FilePriorityUpdate = 0xFFFFFF15, + BT_FileNewObject = 0xFFFFFF16, + + BT_NodeGroup = 0xFFFFFF21, + BT_NodeModel = 0xFFFFFF22, + BT_NodeLight = 0xFFFFFF23, + BT_NodeView = 0xFFFFFF24, + + BT_GeneratorCLODMeshDecl = 0xFFFFFF31, + BT_GeneratorCLODBaseMesh = 0xFFFFFF3B, + BT_GeneratorCLODProgMesh = 0xFFFFFF3C, + BT_GeneratorPointSet = 0xFFFFFF36, + BT_GeneratorPointSetCont = 0xFFFFFF3E, + BT_GeneratorLineSet = 0xFFFFFF37, + BT_GeneratorLineSetCont = 0xFFFFFF3F, + + BT_Modifier2DGlyph = 0xFFFFFF41, + BT_ModifierSubdivision = 0xFFFFFF42, + BT_ModifierAnimation = 0xFFFFFF43, + BT_ModifierBoneWeights = 0xFFFFFF44, + BT_ModifierShading = 0xFFFFFF45, + BT_ModifierCLOD = 0xFFFFFF46, + + BT_ResourceLight = 0xFFFFFF51, + BT_ResourceView = 0xFFFFFF52, + BT_ResourceLitShader = 0xFFFFFF53, + BT_ResourceMaterial = 0xFFFFFF54, + BT_ResourceTexture = 0xFFFFFF55, + BT_ResourceTextureCont = 0xFFFFFF5C, + BT_ResourceMotion = 0xFFFFFF56 + }; + + enum EPalette + { + PL_Material, + PL_Generator, + PL_Shader, + PL_Texture, + PL_Motion, + PL_Node, + PL_View, + PL_Light, + PL_LastPalette + }; + + static constexpr bool isChain(EBlockType blockType); + static constexpr bool isContinuation(EBlockType blockType); + static EPalette getPalette(EBlockType blockType); +}; + +struct PDF3D_U3D_Block_Data +{ + PDF3D_U3D_Block_Info::EBlockType blockType = PDF3D_U3D_Block_Info::EBlockType(); + + QByteArray blockData; + QByteArray metaData; +}; + +struct PDF3D_U3D_BoneJoint +{ + float jointCenterU = 0.0; + float jointCenterV = 0.0; + float jointScaleU = 0.0; + float jointScaleV = 0.0; +}; + +struct PDF3D_U3D_BoneDescription +{ + QString boneName; + QString parentBoneName; + uint32_t boneAttributes = 0; + float boneLength = 0.0; + PDF3D_U3D_Vec3 boneDisplacement = PDF3D_U3D_Vec3(); + PDF3D_U3D_Vec4 boneOrientation = PDF3D_U3D_Vec4(); + uint32_t boneLinkCount = 0; + float boneLinkLength = 0.0; + PDF3D_U3D_BoneJoint startJoint = PDF3D_U3D_BoneJoint(); + PDF3D_U3D_BoneJoint endJoint = PDF3D_U3D_BoneJoint(); + PDF3D_U3D_Vec3 rotationConstraintMin = PDF3D_U3D_Vec3(); + PDF3D_U3D_Vec3 rotationConstraintMax = PDF3D_U3D_Vec3(); + + bool isLinkPresent() const { return boneAttributes & 0x00000001; } + bool isJointPresent() const { return boneAttributes & 0x00000002; } +}; + +struct PDF3D_U3D_ShadingDescription +{ + uint32_t shadingAttributes = 0; + uint32_t textureLayerCount = 0; + std::vector textureCoordDimensions; + uint32_t originalShading = 0; + + bool hasDiffuseColors() const { return shadingAttributes & 0x00000001; } + bool hasSpecularColors() const { return shadingAttributes & 0x00000002; } + bool hasTextures() const { return textureLayerCount > 0; } +}; + +class PDF3D_U3D_AbstractBlock +{ +public: + inline constexpr PDF3D_U3D_AbstractBlock() = default; + virtual ~PDF3D_U3D_AbstractBlock() = default; + + using EBlockType = PDF3D_U3D_Block_Info::EBlockType; + + virtual EBlockType getBlockType() const = 0; + + void parseMetadata(QByteArray metaData, PDF3D_U3D_Parser* object); + + struct ParentNodeData + { + QString parentNodeName; + QMatrix4x4 transformMatrix; + }; + + using ParentNodesData = std::vector; + + struct MetaDataItem + { + uint32_t attributes = 0; + QString key; + QString value; + QByteArray binaryData; + }; + + static ParentNodesData parseParentNodeData(PDF3D_U3D_DataReader& reader, PDF3D_U3D_Parser* object); + +private: + std::vector m_metaData; +}; + +// Bounding sphere - x, y, z position and radius +using PDF3D_U3D_BoundingSphere = std::array; + +// Bounding box - min (x,y,z), max (x,y,z) - six values +using PDF3D_U3D_AxisAlignedBoundingBox = std::array; + +// ------------------------------------------------------------------------------- +// FILE STRUCTURE BLOCKS +// ------------------------------------------------------------------------------- + +class PDF3D_U3D_FileBlock : public PDF3D_U3D_AbstractBlock +{ +public: + static constexpr uint32_t ID = PDF3D_U3D_Block_Info::BT_FileHeader; + virtual EBlockType getBlockType() const override { return static_cast(ID); } + + static PDF3D_U3D_AbstractBlockPtr parse(QByteArray data, QByteArray metaData, PDF3D_U3D_Parser* object); + + bool isExtensibleProfile() const { return m_profileIdentifier & 0x00000002; } + bool isNoCompressionMode() const { return m_profileIdentifier & 0x00000004; } + bool isDefinedUnits() const { return m_profileIdentifier & 0x00000008; } + + int16_t getMajorVersion() const; + int16_t getMinorVersion() const; + uint32_t getProfileIdentifier() const; + uint32_t getDeclarationSize() const; + uint64_t getFileSize() const; + uint32_t getCharacterEncoding() const; + PDFReal getUnitScalingFactor() const; + +private: + int16_t m_majorVersion = 0; + int16_t m_minorVersion = 0; + uint32_t m_profileIdentifier = 0; + uint32_t m_declarationSize = 0; + uint64_t m_fileSize = 0; + uint32_t m_characterEncoding = 0; + PDFReal m_unitScalingFactor = 1.0; +}; + +class PDF3D_U3D_FileReferenceBlock : public PDF3D_U3D_AbstractBlock +{ +public: + static constexpr uint32_t ID = PDF3D_U3D_Block_Info::BT_FileReference; + virtual EBlockType getBlockType() const override { return static_cast(ID); } + + bool isBoundingSpherePresent() const { return m_fileReferenceAttributes & 0x00000001; } + bool isAxisAlignedBoundingBoxPresent() const { return m_fileReferenceAttributes & 0x00000002; } + + static PDF3D_U3D_AbstractBlockPtr parse(QByteArray data, QByteArray metaData, PDF3D_U3D_Parser* object); + + struct Filter + { + uint8_t filterType = 0; + QString objectNameFilter; + uint32_t objectTypeFilter = 0; + }; + + const QString& getScopeName() const; + uint32_t getFileReferenceAttributes() const; + const PDF3D_U3D_BoundingSphere& getBoundingSphere() const; + const PDF3D_U3D_AxisAlignedBoundingBox& getBoundingBox() const; + uint32_t getUrlCount() const; + const QStringList& getUrls() const; + uint32_t getFilterCount() const; + const std::vector& getFilters() const; + uint8_t getNameCollisionPolicy() const; + const QString& getWorldAliasName() const; + +private: + QString m_scopeName; + uint32_t m_fileReferenceAttributes = 0; + PDF3D_U3D_BoundingSphere m_boundingSphere = PDF3D_U3D_BoundingSphere(); + PDF3D_U3D_AxisAlignedBoundingBox m_boundingBox = PDF3D_U3D_AxisAlignedBoundingBox(); + uint32_t m_urlCount = 0; + QStringList m_urls; + uint32_t m_filterCount = 0; + std::vector m_filters; + uint8_t m_nameCollisionPolicy = 0; + QString m_worldAliasName; +}; + +class PDF3D_U3D_ModifierChainBlock : public PDF3D_U3D_AbstractBlock +{ +public: + static constexpr uint32_t ID = PDF3D_U3D_Block_Info::BT_FileModifierChain; + virtual EBlockType getBlockType() const override { return static_cast(ID); } + + static PDF3D_U3D_AbstractBlockPtr parse(QByteArray data, QByteArray metaData, PDF3D_U3D_Parser* object); + + bool isBoundingSpherePresent() const { return m_modifierChainAttributes & 0x00000001; } + bool isAxisAlignedBoundingBoxPresent() const { return m_modifierChainAttributes & 0x00000002; } + + bool isNodeModifierChain() const { return m_modifierChainType == 0; } + bool isModelResourceModifierChain() const { return m_modifierChainType == 1; } + bool isTextureModifierChain() const { return m_modifierChainType == 2; } + + const QString& getModifierChainName() const; + uint32_t getModifierChainType() const; + uint32_t getModifierChainAttributes() const; + const PDF3D_U3D_BoundingSphere& getBoundingSphere() const; + const PDF3D_U3D_AxisAlignedBoundingBox& getBoundingBox() const; + uint32_t getModifierCount() const; + const std::vector& getModifierDeclarationBlocks() const; + +private: + QString m_modifierChainName; + uint32_t m_modifierChainType = 0; + uint32_t m_modifierChainAttributes = 0; + PDF3D_U3D_BoundingSphere m_boundingSphere = PDF3D_U3D_BoundingSphere(); + PDF3D_U3D_AxisAlignedBoundingBox m_boundingBox = PDF3D_U3D_AxisAlignedBoundingBox(); + // Padding 0-3 bytes + uint32_t m_modifierCount = 0; + std::vector m_modifierDeclarationBlocks; +}; + +class PDF3D_U3D_FilePriorityUpdateBlock : public PDF3D_U3D_AbstractBlock +{ +public: + static constexpr uint32_t ID = PDF3D_U3D_Block_Info::BT_FilePriorityUpdate; + virtual EBlockType getBlockType() const override { return static_cast(ID); } + + static PDF3D_U3D_AbstractBlockPtr parse(QByteArray data, QByteArray metaData, PDF3D_U3D_Parser* object); + + uint32_t getNewPriority() const; + +private: + uint32_t m_newPriority = 0; +}; + +class PDF3D_U3D_NewObjectTypeBlock : public PDF3D_U3D_AbstractBlock +{ +public: + static constexpr uint32_t ID = PDF3D_U3D_Block_Info::BT_FileNewObject; + virtual EBlockType getBlockType() const override { return static_cast(ID); } + + static PDF3D_U3D_AbstractBlockPtr parse(QByteArray data, QByteArray metaData, PDF3D_U3D_Parser* object); + + const QString& getNewObjectTypeName() const; + uint32_t getModifierType() const; + const QUuid& getExtensionId() const; + uint32_t getNewDeclarationBlockType() const; + uint32_t getContinuationBlockTypeCount() const; + const std::vector& getContinuationBlockTypes() const; + const QString& getExtensionVendorName() const; + uint32_t getUrlCount() const; + const QStringList& getUrls() const; + const QString& getExtensionInformationString() const; + +private: + QString m_newObjectTypeName; + uint32_t m_modifierType = 0; + QUuid m_extensionId; + uint32_t m_newDeclarationBlockType = 0; + uint32_t m_continuationBlockTypeCount = 0; + std::vector m_continuationBlockTypes; + QString m_extensionVendorName; + uint32_t m_urlCount = 0; + QStringList m_urls; + QString m_extensionInformationString; +}; + +class PDF3D_U3D_NewObjectBlock : public PDF3D_U3D_AbstractBlock +{ +public: + static constexpr uint32_t ID_MIN = 0x00000100; + static constexpr uint32_t ID_MAX = 0x00FFFFFF; + + virtual EBlockType getBlockType() const override { return PDF3D_U3D_Block_Info::BT_FileNewObject; } + + static PDF3D_U3D_AbstractBlockPtr parse(QByteArray data, QByteArray metaData, PDF3D_U3D_Parser* object); + + const QString& getObjectName() const; + uint32_t getChainIndex() const; + const QByteArray& getData() const; + +private: + QString m_objectName; + uint32_t m_chainIndex = 0; + QByteArray m_data; +}; + +// ------------------------------------------------------------------------------- +// NODE BLOCKS +// ------------------------------------------------------------------------------- + +class PDF3D_U3D_GroupNodeBlock : public PDF3D_U3D_AbstractBlock +{ +public: + static constexpr uint32_t ID = PDF3D_U3D_Block_Info::BT_NodeGroup; + virtual EBlockType getBlockType() const override { return static_cast(ID); } + + static PDF3D_U3D_AbstractBlockPtr parse(QByteArray data, QByteArray metaData, PDF3D_U3D_Parser* object); + + const QString& getGroupNodeName() const; + const ParentNodesData& getParentNodesData() const; + +private: + QString m_groupNodeName; + ParentNodesData m_parentNodesData; +}; + +class PDF3D_U3D_ModelNodeBlock : public PDF3D_U3D_AbstractBlock +{ +public: + static constexpr uint32_t ID = PDF3D_U3D_Block_Info::BT_NodeModel; + virtual EBlockType getBlockType() const override { return static_cast(ID); } + + static PDF3D_U3D_AbstractBlockPtr parse(QByteArray data, QByteArray metaData, PDF3D_U3D_Parser* object); + + bool isHidden() const { return m_modelVisibility == 0; } + bool isFrontVisible() const { return m_modelVisibility == 1; } + bool isBackVisible() const { return m_modelVisibility == 2; } + bool isFrontAndBackVisible() const { return m_modelVisibility == 3; } + + const QString& getModelNodeName() const; + const ParentNodesData& getParentNodesData() const; + const QString& getModelResourceName() const; + uint32_t getModelVisibility() const; + +private: + QString m_modelNodeName; + ParentNodesData m_parentNodesData; + QString m_modelResourceName; + uint32_t m_modelVisibility; +}; + +class PDF3D_U3D_LightNodeBlock : public PDF3D_U3D_AbstractBlock +{ +public: + static constexpr uint32_t ID = PDF3D_U3D_Block_Info::BT_NodeLight; + virtual EBlockType getBlockType() const override { return static_cast(ID); } + + static PDF3D_U3D_AbstractBlockPtr parse(QByteArray data, QByteArray metaData, PDF3D_U3D_Parser* object); + + const QString& getLightNodeName() const; + const ParentNodesData& getParentNodesData() const; + const QString& getLightResourceName() const; + +private: + QString m_lightNodeName; + ParentNodesData m_parentNodesData; + QString m_lightResourceName; +}; + +class PDF3D_U3D_ViewNodeBlock : public PDF3D_U3D_AbstractBlock +{ +public: + static constexpr uint32_t ID = PDF3D_U3D_Block_Info::BT_NodeView; + virtual EBlockType getBlockType() const override { return static_cast(ID); } + + static PDF3D_U3D_AbstractBlockPtr parse(QByteArray data, QByteArray metaData, PDF3D_U3D_Parser* object); + + struct BackdropOrOverlay + { + QString m_textureName; + float m_textureBlend = 0.0; + float m_rotation = 0.0; + float m_locationX = 0.0; + float m_locationY = 0.0; + int32_t m_registrationPointX = 0; + int32_t m_registrationPointY = 0; + float m_scaleX = 0.0; + float m_scaleY = 0.0; + }; + + using BackdropItem = BackdropOrOverlay; + using OverlayItem = BackdropOrOverlay; + + bool isScreenPositionRelative() const { return m_viewNodeAttributes & 0x00000001; } + bool isProjectionOrthographic() const { return m_viewNodeAttributes & 0x00000002; } + bool isProjectionTwoPointPerspective() const { return m_viewNodeAttributes & 0x00000004; } + bool isProjectionOnePointPerspective() const { return (m_viewNodeAttributes & 0x00000002) && (m_viewNodeAttributes & 0x00000004); } + bool isProjectionThreePointPerspective() const { return !isProjectionOrthographic() && !isProjectionTwoPointPerspective() && !isProjectionOnePointPerspective(); } + + const QString& getViewNodeName() const; + const ParentNodesData& getParentNodesData() const; + const QString& getViewResourceName() const; + uint32_t getViewNodeAttributes() const; + float getViewNearFlipping() const; + float getViewFarFlipping() const; + float getViewProjection() const; + float getViewOrthographicHeight() const; + const PDF3D_U3D_Vec3& getViewProjectionVector() const; + float getViewPortWidth() const; + float getViewPortHeight() const; + float getViewPortHorizontalPosition() const; + float getViewPortVerticalPosition() const; + const std::vector& getBackdrop() const; + const std::vector& getOverlay() const; + +private: + QString m_viewNodeName; + ParentNodesData m_parentNodesData; + QString m_viewResourceName; + uint32_t m_viewNodeAttributes = 0; + float m_viewNearFlipping = 0.0; + float m_viewFarFlipping = 0.0; + float m_viewProjection = 0.0; + float m_viewOrthographicHeight = 0.0; + PDF3D_U3D_Vec3 m_viewProjectionVector = PDF3D_U3D_Vec3(); + + // Viewport + float m_viewPortWidth = 0.0; + float m_viewPortHeight = 0.0; + float m_viewPortHorizontalPosition = 0.0; + float m_viewPortVerticalPosition = 0.0; + + // Backdrop + std::vector m_backdrop; + + // Overlay + std::vector m_overlay; +}; + +// ------------------------------------------------------------------------------- +// GEOMETRY BLOCKS +// ------------------------------------------------------------------------------- + +class PDF3D_U3D_CLODMeshDeclarationBlock : public PDF3D_U3D_AbstractBlock +{ +public: + static constexpr uint32_t ID = PDF3D_U3D_Block_Info::BT_GeneratorCLODMeshDecl; + virtual EBlockType getBlockType() const override { return static_cast(ID); } + + static PDF3D_U3D_AbstractBlockPtr parse(QByteArray data, QByteArray metaData, PDF3D_U3D_Parser* object); + + const QString& getName() const { return getMeshName(); } + const QString& getMeshName() const; + uint32_t getChainIndex() const; + + bool isNormalsExcluded() const { return getMeshAttributes() & 0x00000001; } + + /* max mesh description */ + uint32_t getMeshAttributes() const; + uint32_t getFaceCount() const; + uint32_t getPositionCount() const; + uint32_t getNormalCount() const; + uint32_t getDiffuseColorCount() const; + uint32_t getSpecularColorCount() const; + uint32_t getTextureColorCount() const; + uint32_t getShadingCount() const; + const std::vector& getShadingDescription() const; + const PDF3D_U3D_ShadingDescription* getShadingDescriptionItem(uint32_t index) const { return index < m_shadingDescription.size() ? &m_shadingDescription[index] : nullptr; } + + /* clod description */ + uint32_t getMinimumResolution() const; + uint32_t getFinalResolution() const; + + /* resource description */ + uint32_t getPositionQualityFactor() const; + uint32_t getNormalQualityFactor() const; + uint32_t getTextureCoordQualityFactor() const; + float getPositionInverseQuant() const; + float getNormalInverseQuant() const; + float getTextureCoordInverseQuant() const; + float getDiffuseColorInverseQuant() const; + float getSpecularColorInverseQuant() const; + float getNormalCreaseParameter() const; + float getNormalUpdateParameter() const; + float getNormalToleranceParameter() const; + + /* bone description */ + uint32_t getBoneCount() const; + const std::vector& getBoneDescription() const; + +private: + QString m_meshName; + uint32_t m_chainIndex = 0; + + /* max mesh description */ + uint32_t m_meshAttributes = 0; + uint32_t m_faceCount = 0; + uint32_t m_positionCount = 0; + uint32_t m_normalCount = 0; + uint32_t m_diffuseColorCount = 0; + uint32_t m_specularColorCount = 0; + uint32_t m_textureColorCount = 0; + std::vector m_shadingDescription; + + /* clod description */ + uint32_t m_minimumResolution = 0; + uint32_t m_finalResolution = 0; + + /* resource description */ + uint32_t m_positionQualityFactor = 0; + uint32_t m_normalQualityFactor = 0; + uint32_t m_textureCoordQualityFactor = 0; + float m_positionInverseQuant = 0.0; + float m_normalInverseQuant = 0.0; + float m_textureCoordInverseQuant = 0.0; + float m_diffuseColorInverseQuant = 0.0; + float m_specularColorInverseQuant = 0.0; + float m_normalCreaseParameter = 0.0; + float m_normalUpdateParameter = 0.0; + float m_normalToleranceParameter = 0.0; + + /* bone description */ + uint32_t m_boneCount = 0; + std::vector m_boneDescription; +}; + +class PDF3D_U3D_CLODBaseMeshContinuationBlock : public PDF3D_U3D_AbstractBlock +{ +public: + static constexpr uint32_t ID = PDF3D_U3D_Block_Info::BT_GeneratorCLODBaseMesh; + virtual EBlockType getBlockType() const override { return static_cast(ID); } + + static PDF3D_U3D_AbstractBlockPtr parse(QByteArray data, QByteArray metaData, PDF3D_U3D_Parser* object, const PDF3D_U3D_CLODMeshDeclarationBlock* declarationBlock); + + struct BaseCornerInfo + { + uint32_t basePositionIndex = 0; // rBasePositionCount + uint32_t baseNormalIndex = 0; // rBaseNormalCount + uint32_t baseDiffuseColorIndex = 0; // rBaseDiffColorCnt + uint32_t baseSpecularColorIndex = 0; // rBaseSpecColorCnt + std::vector baseTextureCoordIndex; // rBaseTexCoordCnt + }; + + struct BaseFace + { + uint32_t m_shadingId = 0; // cShading + std::array m_corners = { }; + }; + + const QString& getMeshName() const; + uint32_t getChainIndex() const; + + uint32_t getFaceCount() const; + uint32_t getPositionCount() const; + uint32_t getNormalCount() const; + uint32_t getDiffuseColorCount() const; + uint32_t getSpecularColorCount() const; + uint32_t getTextureColorCount() const; + + const std::vector& getBasePositions() const; + const std::vector& getBaseNormals() const; + const std::vector& getBaseDiffuseColors() const; + const std::vector& getBaseSpecularColors() const; + const std::vector& getBaseTextureCoords() const; + const std::vector& getBaseFaces() const; + +private: + QString m_meshName; + uint32_t m_chainIndex = 0; + + /* base mesh description */ + uint32_t m_faceCount = 0; + uint32_t m_positionCount = 0; + uint32_t m_normalCount = 0; + uint32_t m_diffuseColorCount = 0; + uint32_t m_specularColorCount = 0; + uint32_t m_textureColorCount = 0; + + std::vector m_basePositions; + std::vector m_baseNormals; + std::vector m_baseDiffuseColors; + std::vector m_baseSpecularColors; + std::vector m_baseTextureCoords; + std::vector m_baseFaces; +}; + +class PDF3D_U3D_CLODProgressiveMeshContinuationBlock : public PDF3D_U3D_AbstractBlock +{ +public: + static constexpr uint32_t ID = PDF3D_U3D_Block_Info::BT_GeneratorCLODProgMesh; + virtual EBlockType getBlockType() const override { return static_cast(ID); } + + static PDF3D_U3D_AbstractBlockPtr parse(QByteArray data, QByteArray metaData, PDF3D_U3D_Parser* object); + + struct NewFacePositionInfo + { + uint32_t shadingId = 0; + uint8_t faceOrientation = 0; + uint8_t thirdPositionType = 0; + uint32_t localThirdPositionIndex = 0; + uint32_t globalThirdPositionIndex = 0; + }; + + struct ResolutionUpdate + { + uint32_t splitPositionIndex = 0; + + std::vector newDiffuseColors; + std::vector newSpecularColors; + std::vector newTextureCoords; + std::vector newFaces; + }; + +private: + QString m_meshName; + uint32_t m_chainIndex = 0; + + uint32_t m_startResolution = 0; + uint32_t m_endResolution = 0; + uint32_t m_resolutionUpdateCount = 0; + + std::vector m_resolutionUpdates; +}; + +class PDF3D_U3D_PointSetDeclarationBlock : public PDF3D_U3D_AbstractBlock +{ +public: + static constexpr uint32_t ID = PDF3D_U3D_Block_Info::BT_GeneratorPointSet; + virtual EBlockType getBlockType() const override { return static_cast(ID); } + + static PDF3D_U3D_AbstractBlockPtr parse(QByteArray data, QByteArray metaData, PDF3D_U3D_Parser* object); + + const QString& getName() const { return m_pointSetName; } + uint32_t getPointCount() const; + uint32_t getPositionCount() const; + uint32_t getNormalCount() const; + uint32_t getDiffuseColorCount() const; + uint32_t getSpecularColorCount() const; + uint32_t getTextureCoordCount() const; + const std::vector& getShadingDescriptions() const; + const PDF3D_U3D_ShadingDescription* getShadingDescriptionItem(uint32_t index) const { return index < m_shadingDescriptions.size() ? &m_shadingDescriptions[index] : nullptr; } + + uint32_t getPositionQualityFactor() const; + uint32_t getNormalQualityFactor() const; + uint32_t getTextureCoordQualityFactor() const; + float getPositionInverseQuant() const; + float getNormalInverseQuant() const; + float getTextureCoordInverseQuant() const; + float getDiffuseColorInverseQuant() const; + float getSpecularColorInverseQuant() const; + + uint32_t getBoneCount() const; + + const std::vector& getBoneDescription() const; + +private: + QString m_pointSetName; + uint32_t m_chainIndex = 0; + + /* point set description */ + uint32_t m_pointSetReserved = 0; + uint32_t m_pointCount = 0; + uint32_t m_positionCount = 0; + uint32_t m_normalCount = 0; + uint32_t m_diffuseColorCount = 0; + uint32_t m_specularColorCount = 0; + uint32_t m_textureCoordCount = 0; + std::vector m_shadingDescriptions; + + /* resource description */ + uint32_t m_positionQualityFactor = 0; + uint32_t m_normalQualityFactor = 0; + uint32_t m_textureCoordQualityFactor = 0; + float m_positionInverseQuant = 0.0; + float m_normalInverseQuant = 0.0; + float m_textureCoordInverseQuant = 0.0; + float m_diffuseColorInverseQuant = 0.0; + float m_specularColorInverseQuant = 0.0; + float m_reserved1 = 0.0; + float m_reserved2 = 0.0; + float m_reserved3 = 0.0; + + /* bone description */ + uint32_t m_boneCount = 0; + std::vector m_boneDescription; +}; + +class PDF3D_U3D_PointSetContinuationBlock : public PDF3D_U3D_AbstractBlock +{ +public: + static constexpr uint32_t ID = PDF3D_U3D_Block_Info::BT_GeneratorPointSetCont; + virtual EBlockType getBlockType() const override { return static_cast(ID); } + + static PDF3D_U3D_AbstractBlockPtr parse(QByteArray data, QByteArray metaData, PDF3D_U3D_Parser* object, const PDF3D_U3D_PointSetDeclarationBlock* declarationBlock); + + struct NewPointInfo + { + uint32_t shadingId = 0; + uint32_t normalLocalIndex = 0; + + bool duplicateDiffuse = false; + bool duplicateSpecular = false; + + PDF3D_U3D_QuantizedVec4 diffuseColor = PDF3D_U3D_QuantizedVec4(); + PDF3D_U3D_QuantizedVec4 specularColor = PDF3D_U3D_QuantizedVec4(); + std::vector> textureCoords; + }; + + struct UpdateItem + { + uint32_t splitPositionIndex = 0; + + PDF3D_U3D_QuantizedVec3 newPositionInfo; + std::vector newNormals; + std::vector newPoints; + }; + + const QString& getName() const { return m_pointSetName; } + const std::vector& getUpdateItems() const; + +private: + QString m_pointSetName; + uint32_t m_chainIndex = 0; + + uint32_t m_startResolution = 0; + uint32_t m_endResolution = 0; + + std::vector m_updateItems; +}; + +class PDF3D_U3D_LineSetDeclarationBlock : public PDF3D_U3D_AbstractBlock +{ +public: + static constexpr uint32_t ID = PDF3D_U3D_Block_Info::BT_GeneratorLineSet; + virtual EBlockType getBlockType() const override { return static_cast(ID); } + + static PDF3D_U3D_AbstractBlockPtr parse(QByteArray data, QByteArray metaData, PDF3D_U3D_Parser* object); + + const QString& getName() const { return m_lineSetName; } + uint32_t getLineCount() const; + uint32_t getPositionCount() const; + uint32_t getNormalCount() const; + uint32_t getDiffuseColorCount() const; + uint32_t getSpecularColorCount() const; + uint32_t getTextureCoordCount() const; + const std::vector& getShadingDescriptions() const; + const PDF3D_U3D_ShadingDescription* getShadingDescriptionItem(uint32_t index) const { return index < m_shadingDescriptions.size() ? &m_shadingDescriptions[index] : nullptr; } + + uint32_t getPositionQualityFactor() const; + uint32_t getNormalQualityFactor() const; + uint32_t getTextureCoordQualityFactor() const; + float getPositionInverseQuant() const; + float getNormalInverseQuant() const; + float getTextureCoordInverseQuant() const; + float getDiffuseColorInverseQuant() const; + float getSpecularColorInverseQuant() const; + +private: + QString m_lineSetName; + uint32_t m_chainIndex = 0; + + /* line set description */ + uint32_t m_lineSetReserved = 0; + uint32_t m_lineCount = 0; + uint32_t m_positionCount = 0; + uint32_t m_normalCount = 0; + uint32_t m_diffuseColorCount = 0; + uint32_t m_specularColorCount = 0; + uint32_t m_textureCoordCount = 0; + std::vector m_shadingDescriptions; + + /* resource description */ + uint32_t m_positionQualityFactor = 0; + uint32_t m_normalQualityFactor = 0; + uint32_t m_textureCoordQualityFactor = 0; + float m_positionInverseQuant = 0.0; + float m_normalInverseQuant = 0.0; + float m_textureCoordInverseQuant = 0.0; + float m_diffuseColorInverseQuant = 0.0; + float m_specularColorInverseQuant = 0.0; + float m_reserved1 = 0.0; + float m_reserved2 = 0.0; + float m_reserved3 = 0.0; +}; + +class PDF3D_U3D_LineSetContinuationBlock : public PDF3D_U3D_AbstractBlock +{ +public: + static constexpr uint32_t ID = PDF3D_U3D_Block_Info::BT_GeneratorLineSetCont; + virtual EBlockType getBlockType() const override { return static_cast(ID); } + + static PDF3D_U3D_AbstractBlockPtr parse(QByteArray data, QByteArray metaData, PDF3D_U3D_Parser* object, const PDF3D_U3D_LineSetDeclarationBlock* declarationBlock); + + struct NewLineEndingInfo + { + uint32_t normalLocalIndex = 0; + + bool duplicateDiffuse = false; + bool duplicateSpecular = false; + + PDF3D_U3D_QuantizedVec4 diffuseColor = PDF3D_U3D_QuantizedVec4(); + PDF3D_U3D_QuantizedVec4 specularColor = PDF3D_U3D_QuantizedVec4(); + std::vector> textureCoords; + }; + + struct NewLineInfo + { + uint32_t shadingId = 0; + uint32_t firstPositionIndex = 0; + + NewLineEndingInfo p1; + NewLineEndingInfo p2; + }; + + struct UpdateItem + { + uint32_t splitPositionIndex = 0; + + PDF3D_U3D_QuantizedVec3 newPositionInfo; + std::vector newNormals; + std::vector newLines; + }; + + const QString& getName() const { return m_lineSetName; } + + const std::vector& getUpdateItems() const; + +private: + QString m_lineSetName; + uint32_t m_chainIndex = 0; + + uint32_t m_startResolution = 0; + uint32_t m_endResolution = 0; + + std::vector m_updateItems; +}; + +class PDF3D_U3D_2DGlyphModifierBlock : public PDF3D_U3D_AbstractBlock +{ +public: + static constexpr uint32_t ID = PDF3D_U3D_Block_Info::BT_Modifier2DGlyph; + virtual EBlockType getBlockType() const override { return static_cast(ID); } + + static PDF3D_U3D_AbstractBlockPtr parse(QByteArray data, QByteArray metaData, PDF3D_U3D_Parser* object); + + const QString& getModifierName() const; + uint32_t getChainIndex() const; + uint32_t getGlyphAttributes() const; + QPainterPath getPath() const; + const QMatrix4x4& getMatrix() const; + +private: + QString m_modifierName; + uint32_t m_chainIndex = 0; + uint32_t m_glyphAttributes = 0; + + QPainterPath m_path; + QMatrix4x4 m_matrix; +}; + +class PDF3D_U3D_SubdivisionModifierBlock : public PDF3D_U3D_AbstractBlock +{ +public: + static constexpr uint32_t ID = PDF3D_U3D_Block_Info::BT_ModifierSubdivision; + virtual EBlockType getBlockType() const override { return static_cast(ID); } + + static PDF3D_U3D_AbstractBlockPtr parse(QByteArray data, QByteArray metaData, PDF3D_U3D_Parser* object); + + const QString& getModifierName() const; + uint32_t getChainIndex() const; + uint32_t getAttributes() const; + uint32_t getDepth() const; + float getTension() const; + float getError() const; + +private: + QString m_modifierName; + uint32_t m_chainIndex = 0; + uint32_t m_attributes = 0; + uint32_t m_depth = 0; + + float m_tension = 0.0; + float m_error = 0.0; +}; + +class PDF3D_U3D_AnimationModifierBlock : public PDF3D_U3D_AbstractBlock +{ +public: + static constexpr uint32_t ID = PDF3D_U3D_Block_Info::BT_ModifierAnimation; + virtual EBlockType getBlockType() const override { return static_cast(ID); } + + static PDF3D_U3D_AbstractBlockPtr parse(QByteArray data, QByteArray metaData, PDF3D_U3D_Parser* object); + + struct MotionInformation + { + QString motionName; + uint32_t motionAttributes = 0; + float timeOffset = 0.0; + float timeScale = 0.0; + }; + + const QString& getModifierName() const; + uint32_t getChainIndex() const; + + uint32_t getAttributes() const; + float getTimescale() const; + uint32_t getMotionCount() const; + const std::vector& getMotionInformations() const; + float getBlendTime() const; + +private: + QString m_modifierName; + uint32_t m_chainIndex = 0; + + uint32_t m_attributes = 0; + float m_timescale = 0.0; + uint32_t m_motionCount = 0; + std::vector m_motionInformations; + + float m_blendTime = 0.0; +}; + +class PDF3D_U3D_BoneWeightModifierBlock : public PDF3D_U3D_AbstractBlock +{ +public: + static constexpr uint32_t ID = PDF3D_U3D_Block_Info::BT_ModifierBoneWeights; + virtual EBlockType getBlockType() const override { return static_cast(ID); } + + static PDF3D_U3D_AbstractBlockPtr parse(QByteArray data, QByteArray metaData, PDF3D_U3D_Parser* object); + + struct BoneWeightList + { + std::vector boneIndex; + std::vector boneWeight; + }; + + const QString& getModifierName() const; + uint32_t getChainIndex() const; + uint32_t getAttributes() const; + float getInverseQuant() const; + const std::vector& getBoneWeightLists() const; + +private: + QString m_modifierName; + uint32_t m_chainIndex = 0; + uint32_t m_attributes = 0; + float m_inverseQuant = 0.0; + std::vector m_boneWeightLists; +}; + +class PDF3D_U3D_ShadingModifierBlock : public PDF3D_U3D_AbstractBlock +{ +public: + static constexpr uint32_t ID = PDF3D_U3D_Block_Info::BT_ModifierShading; + virtual EBlockType getBlockType() const override { return static_cast(ID); } + + static PDF3D_U3D_AbstractBlockPtr parse(QByteArray data, QByteArray metaData, PDF3D_U3D_Parser* object); + + using ShaderLists = std::vector; + + const QString& getModifierName() const; + uint32_t getChainIndex() const; + uint32_t getAttributes() const; + const ShaderLists& getShaderLists() const; + +private: + QString m_modifierName; + uint32_t m_chainIndex = 0; + uint32_t m_attributes = 0; + ShaderLists m_shaderLists; +}; + +class PDF3D_U3D_CLODModifierBlock : public PDF3D_U3D_AbstractBlock +{ +public: + static constexpr uint32_t ID = PDF3D_U3D_Block_Info::BT_ModifierCLOD; + virtual EBlockType getBlockType() const override { return static_cast(ID); } + + static PDF3D_U3D_AbstractBlockPtr parse(QByteArray data, QByteArray metaData, PDF3D_U3D_Parser* object); + + const QString& getModifierName() const; + uint32_t getChainIndex() const; + uint32_t getAttributes() const; + float getCLODAutomaticLevelOfDetails() const; + float getCLODModifierLevel() const; + +private: + QString m_modifierName; + uint32_t m_chainIndex = 0; + uint32_t m_attributes = 0; + float m_CLODAutomaticLevelOfDetails = 0.0; + float m_CLODModifierLevel = 0.0; +}; + +class PDF3D_U3D_LightResourceBlock : public PDF3D_U3D_AbstractBlock +{ +public: + static constexpr uint32_t ID = PDF3D_U3D_Block_Info::BT_ResourceLight; + virtual EBlockType getBlockType() const override { return static_cast(ID); } + + static PDF3D_U3D_AbstractBlockPtr parse(QByteArray data, QByteArray metaData, PDF3D_U3D_Parser* object); + + const QString& getResourceName() const; + uint32_t getAttributes() const; + uint8_t getType() const; + const PDF3D_U3D_Vec4& getColor() const; + const PDF3D_U3D_Vec3& getAttenuation() const; + float getSpotAngle() const; + float getIntensity() const; + +private: + QString m_resourceName; + uint32_t m_attributes = 0; + uint8_t m_type = 0; + PDF3D_U3D_Vec4 m_color = { }; + PDF3D_U3D_Vec3 m_attenuation = { }; + float m_spotAngle = 0.0; + float m_intensity = 0.0; +}; + +class PDF3D_U3D_ViewResourceBlock : public PDF3D_U3D_AbstractBlock +{ +public: + static constexpr uint32_t ID = PDF3D_U3D_Block_Info::BT_ResourceView; + virtual EBlockType getBlockType() const override { return static_cast(ID); } + + static PDF3D_U3D_AbstractBlockPtr parse(QByteArray data, QByteArray metaData, PDF3D_U3D_Parser* object); + + struct Pass + { + QString rootNodeName; + uint32_t renderAttributes = 0; + uint32_t fogMode = 0; + PDF3D_U3D_Vec4 fogColor = { }; + float fogNear = 0.0; + float fogFar = 0.0; + }; + + const QString& getResourceName() const; + const std::vector& getRenderPasses() const; + +private: + QString m_resourceName; + std::vector m_renderPasses; +}; + +class PDF3D_U3D_LitTextureShaderResourceBlock : public PDF3D_U3D_AbstractBlock +{ +public: + static constexpr uint32_t ID = PDF3D_U3D_Block_Info::BT_ResourceLitShader; + virtual EBlockType getBlockType() const override { return static_cast(ID); } + + static PDF3D_U3D_AbstractBlockPtr parse(QByteArray data, QByteArray metaData, PDF3D_U3D_Parser* object); + + struct TextureInfo + { + QString textureName; + float textureIntensity = 0.0; + uint8_t blendFunction = 0; + uint8_t blendSource = 0; + float blendConstant = 0.0; + uint8_t textureMode = 0; + QMatrix4x4 textureTransform; + QMatrix4x4 textureMap; + uint8_t repeat = 0; + }; + + const QString& getResourceName() const; + uint32_t getAttributes() const; + float getAlphaTestReference() const; + uint32_t getColorBlendFunction() const; + uint32_t getAlphaTestFunction() const; + uint32_t getRenderPassEnabled() const; + uint32_t getShaderChannels() const; + uint32_t getAlphaTextureChannels() const; + const QString& getMaterialName() const; + const std::vector& getTextureInfos() const; + +private: + QString m_resourceName; + uint32_t m_attributes = 0; + float m_alphaTestReference = 0.0; + uint32_t m_alphaTestFunction = 0; + uint32_t m_colorBlendFunction = 0; + uint32_t m_renderPassEnabled = 0; + uint32_t m_shaderChannels = 0; + uint32_t m_alphaTextureChannels = 0; + QString m_materialName; + std::vector m_textureInfos; +}; + +class PDF3D_U3D_MaterialResourceBlock : public PDF3D_U3D_AbstractBlock +{ +public: + static constexpr uint32_t ID = PDF3D_U3D_Block_Info::BT_ResourceMaterial; + virtual EBlockType getBlockType() const override { return static_cast(ID); } + + static PDF3D_U3D_AbstractBlockPtr parse(QByteArray data, QByteArray metaData, PDF3D_U3D_Parser* object); + + const QString& getResourceName() const; + uint32_t getMaterialAttributes() const; + const PDF3D_U3D_Vec3& getAmbientColor() const; + const PDF3D_U3D_Vec3& getDiffuseColor() const; + const PDF3D_U3D_Vec3& getSpecularColor() const; + const PDF3D_U3D_Vec3& getEmissiveColor() const; + float getReflectivity() const; + float getOpacity() const; + +private: + QString m_resourceName; + uint32_t m_materialAttributes = 0; + PDF3D_U3D_Vec3 m_ambientColor = { }; + PDF3D_U3D_Vec3 m_diffuseColor = { }; + PDF3D_U3D_Vec3 m_specularColor = { }; + PDF3D_U3D_Vec3 m_emissiveColor = { }; + float m_reflectivity = 0.0; + float m_opacity = 0.0; +}; + +class PDF3D_U3D_TextureResourceBlock : public PDF3D_U3D_AbstractBlock +{ +public: + static constexpr uint32_t ID = PDF3D_U3D_Block_Info::BT_ResourceTexture; + virtual EBlockType getBlockType() const override { return static_cast(ID); } + + static PDF3D_U3D_AbstractBlockPtr parse(QByteArray data, QByteArray metaData, PDF3D_U3D_Parser* object); + + struct ContinuationImageFormat + { + bool isExternal() const { return attributes & 0x0001; } + + uint8_t compressionType = 0; + uint8_t channels = 0; + uint16_t attributes = 0; + uint32_t imageDataByteCount = 0; + uint32_t imageURLCount = 0; + QStringList imageURLs; + }; + + const QString& getResourceName() const; + uint32_t getTextureHeight() const; + uint32_t getTextureWidth() const; + uint8_t getType() const; + const std::vector& getFormats() const; + +private: + QString m_resourceName; + uint32_t m_textureHeight = 0; + uint32_t m_textureWidth = 0; + uint8_t m_type = 0; + std::vector m_formats; +}; + +class PDF3D_U3D_TextureContinuationResourceBlock : public PDF3D_U3D_AbstractBlock +{ +public: + static constexpr uint32_t ID = PDF3D_U3D_Block_Info::BT_ResourceTextureCont; + virtual EBlockType getBlockType() const override { return static_cast(ID); } + + static PDF3D_U3D_AbstractBlockPtr parse(QByteArray data, QByteArray metaData, PDF3D_U3D_Parser* object); + + const QString& getResourceName() const; + uint32_t getImageIndex() const; + const QByteArray& getImageData() const; + +private: + QString m_resourceName; + uint32_t m_imageIndex = 0; + QByteArray m_imageData; +}; + +class PDF3D_U3D_MotionResourceBlock : public PDF3D_U3D_AbstractBlock +{ +public: + static constexpr uint32_t ID = PDF3D_U3D_Block_Info::BT_ResourceMotion; + virtual EBlockType getBlockType() const override { return static_cast(ID); } + + static PDF3D_U3D_AbstractBlockPtr parse(QByteArray data, QByteArray metaData, PDF3D_U3D_Parser* object); + + struct KeyFrame + { + float time = 0.0; + PDF3D_U3D_Vec3 displacement = { }; + PDF3D_U3D_Vec4 rotation = { }; + PDF3D_U3D_Vec3 scale = { }; + + PDF3D_U3D_QuantizedVec1 timeDiff; + PDF3D_U3D_QuantizedVec3 displacementDiff; + PDF3D_U3D_QuantizedVec3 rotationDiff; + PDF3D_U3D_QuantizedVec3 scaleDiff; + }; + + struct Motion + { + QString trackName; + uint32_t timeCount = 0; + float displacementInverseQuant = 0.0; + float rotationInverseQuant = 0.0; + std::vector keyFrames; + }; + + const QString& getResourceName() const; + uint32_t getTrackCount() const; + float getTimeInverseQuant() const; + float getRotationInverseQuant() const; + const std::vector& getMotions() const; + +private: + QString m_resourceName; + uint32_t m_trackCount = 0; + float m_timeInverseQuant = 0.0f; + float m_rotationInverseQuant = 0.0f; + std::vector m_motions; +}; + +// ------------------------------------------------------------------------------- +// READER OBJECTS +// ------------------------------------------------------------------------------- + +class PDF3D_U3D_ContextManager +{ +public: + bool isContextCompressed(uint32_t context) const; + bool isContextStaticAndCompressed(uint32_t context) const; + + uint32_t getTotalSymbolFrequency(uint32_t context) const; + uint32_t getSymbolFrequency(uint32_t context, uint32_t symbol) const; + uint32_t getCumulativeSymbolFrequency(uint32_t context, uint32_t symbol) const; + uint32_t getSymbolFromFrequency(uint32_t context, uint32_t symbolFrequency) const; + + void addSymbol(uint32_t context, uint32_t symbol); + +private: + struct ContextData + { + ContextData() + { + symbols= { { 0, Data{ 1, 1} } }; + } + + struct Data + { + uint32_t symbolCount = 0; + uint32_t cumulativeSymbolCount = 0; + }; + + std::map symbols; + }; + + const ContextData* getContextData(uint32_t context) const; + + std::map m_contexts; +}; + +class PDF3D_U3D_Constants +{ +public: + static constexpr uint32_t S_NOT_THREE_QUARTER_MASK = 0x00003FFF; + static constexpr uint32_t S_QUARTER_MASK = 0x00004000; + static constexpr uint32_t S_NOT_HALF_MASK = 0x00007FFF; + static constexpr uint32_t S_HALF_MASK = 0x00008000; + static constexpr uint32_t S_STATIC_FULL = 0x00000400; + static constexpr uint32_t S_MAX_RANGE = S_STATIC_FULL + 0x00003FFF; + static constexpr uint32_t S_CONTEXT_8 = 0; + + static constexpr uint32_t S_MAX_CUMULATIVE_SYMBOL_COUNT = 0x00001fff; + static constexpr uint32_t S_MAXIMUM_SYMBOL_IN_HISTOGRAM = 0x0000FFFF; +}; + +class PDF3D_U3D_Decoder +{ +public: + + void addBlock(const PDF3D_U3D_Block_Data& block) { m_blocks.push_back(block); } + + bool isEmpty() const { return m_blocks.empty(); } + + auto begin() const { return m_blocks.begin(); } + auto end() const { return m_blocks.end(); } + + auto front() const { return m_blocks.front(); } + auto back() const { return m_blocks.back(); } + + auto size() const { return m_blocks.size(); } + +private: + std::vector m_blocks; +}; + +class PDF3D_U3D_DecoderChain +{ +public: + + const QString& getName() const; + void setName(const QString& newName); + + PDF3D_U3D_Decoder* getDecoder(uint32_t chainPosition); + void addDecoder(PDF3D_U3D_Decoder&& decoder) { m_decoders.emplace_back(std::move(decoder)); } + + auto begin() const { return m_decoders.begin(); } + auto end() const { return m_decoders.end(); } + +private: + QString m_name; + std::vector m_decoders; +}; + +class PDF3D_U3D_DecoderPalette +{ +public: + + PDF3D_U3D_DecoderChain* getDecoderChain(const QString& name); + PDF3D_U3D_DecoderChain* createDecoderChain(const QString& name); + + auto begin() const { return m_decoderChains.begin(); } + auto end() const { return m_decoderChains.end(); } + +private: + std::vector m_decoderChains; +}; + +class PDF3D_U3D_DecoderPalettes +{ +public: + using EPalette = PDF3D_U3D_Block_Info::EPalette; + + PDF3D_U3D_DecoderPalette* getDecoderPalette(EPalette palette); + + auto begin() const { return m_decoderLists.begin(); } + auto end() const { return m_decoderLists.end(); } + +private: + std::array m_decoderLists; +}; + +class PDF4QTLIBSHARED_EXPORT PDF3D_U3D_Parser +{ +public: + PDF3D_U3D_Parser(); + + PDF3D_U3D parse(QByteArray data); + + void processBlock(const PDF3D_U3D_Block_Data& blockData, PDF3D_U3D_Block_Info::EPalette palette); + void processModifierBlock(const PDF3D_U3D_Block_Data& blockData); + void processGenericBlock(const PDF3D_U3D_Block_Data& blockData, PDF3D_U3D_Block_Info::EPalette palette); + + bool isCompressed() const { return m_isCompressed; } + QTextCodec* getTextCodec() const { return m_textCodec; } + + PDF3D_U3D_AbstractBlockPtr parseBlock(uint32_t blockType, const QByteArray& data, const QByteArray& metaData); + PDF3D_U3D_AbstractBlockPtr parseBlock(const PDF3D_U3D_Block_Data& data); + + static uint32_t getBlockPadding(uint32_t blockSize); + + static PDF3D_U3D_Block_Data readBlockData(PDF3D_U3D_DataReader& reader); + + void processCLODMesh(const PDF3D_U3D_Decoder& decoder); + void processPointSet(const PDF3D_U3D_Decoder& decoder); + void processLineSet(const PDF3D_U3D_Decoder& decoder); + void processTexture(const PDF3D_U3D_Decoder& decoder); + + void addLineSetGeometry(PDF3D_U3D_LineSetGeometry* geometry, + const PDF3D_U3D_LineSetDeclarationBlock* declarationBlock, + const PDF3D_U3D_LineSetContinuationBlock* geometryBlock); + + QVector3D getDequantizedVec3(PDF3D_U3D_QuantizedVec3 quantizedV3, QVector3D prediction, float inverseQuant); + QVector4D getDequantizedVec4(PDF3D_U3D_QuantizedVec4 quantizedV4, QVector4D prediction, float inverseQuant); + + void addBlockToU3D(PDF3D_U3D_AbstractBlockPtr block); + + QStringList getErrors() const { return m_errors; } + +private: + struct LoadBlockInfo + { + QString typeName; + bool success = false; + PDF3D_U3D_Block_Info::EBlockType blockType = PDF3D_U3D_Block_Info::EBlockType(); + uint32_t dataSize = 0; + uint32_t metaDataSize = 0; + PDF3D_U3D_AbstractBlockPtr block; + }; + + std::vector m_blocks; + std::vector m_allBlocks; + + QStringList m_errors; + PDF3D_U3D_DecoderPalettes m_decoderPalettes; + PDF3D_U3D m_object; + PDF3D_U3D_AbstractBlockPtr m_fileBlock; + QTextCodec* m_textCodec = nullptr; + bool m_isCompressed = true; + uint32_t m_priority = 0; +}; + +class PDF3D_U3D_DataReader +{ +public: + PDF3D_U3D_DataReader(QByteArray data, bool isCompressed); + ~PDF3D_U3D_DataReader(); + + void setData(QByteArray data); + + static constexpr uint32_t getRangeContext(uint32_t value) { return value + PDF3D_U3D_Constants::S_STATIC_FULL; } + static constexpr uint32_t getStaticContext(uint32_t value) { return value; } + + uint8_t readU8(); + uint16_t readU16(); + uint32_t readU32(); + uint64_t readU64(); + int16_t readI16(); + int32_t readI32(); + float readF32(); + double readF64(); + + uint8_t readCompressedU8(uint32_t context); + uint16_t readCompressedU16(uint32_t context); + uint32_t readCompressedU32(uint32_t context); + + QByteArray readByteArray(uint32_t size); + QByteArray readRemainingData(); + void skipBytes(uint32_t size); + void padTo32Bits(); + + QUuid readUuid(); + QString readString(QTextCodec* textCodec); + QStringList readStringList(uint32_t count, QTextCodec* textCodec); + + QMatrix4x4 readMatrix4x4(); + + PDF3D_U3D_QuantizedVec1 readQuantizedVec1(uint32_t contextSign, + uint32_t context1); + + PDF3D_U3D_QuantizedVec4 readQuantizedVec4(uint32_t contextSign, + uint32_t context1, + uint32_t context2, + uint32_t context3, + uint32_t context4); + + PDF3D_U3D_QuantizedVec3 readQuantizedVec3(uint32_t contextSign, + uint32_t context1, + uint32_t context2, + uint32_t context3); + + std::vector readShadingDescriptions(uint32_t count); + std::vector readBoneDescriptions(QTextCodec* textCodec, uint32_t count); + + bool isAtEnd() const; + + template + void readFloats32(T& container) + { + for (auto& value : container) + { + value = readF32(); + } + } + + template + std::vector readVectorFloats32(uint32_t count) + { + std::vector result; + result.reserve(count); + + for (uint32_t i = 0; i < count; ++i) + { + T value = T(); + readFloats32(value); + result.emplace_back(std::move(value)); + } + + return result; + } + +private: + uint32_t readSymbol(uint32_t context); + uint8_t swapBits8(uint8_t source); + uint32_t readBit(); + uint32_t read15Bits(); + + QByteArray m_data; + PDF3D_U3D_ContextManager m_contextManager; + + uint32_t m_high; + uint32_t m_low; + uint32_t m_underflow; + uint32_t m_code; + uint32_t m_position; + bool m_isCompressed; +}; + PDF3D_U3D_DataReader::PDF3D_U3D_DataReader(QByteArray data, bool isCompressed) : m_data(std::move(data)), m_contextManager(), @@ -664,7 +2256,7 @@ const PDF3D_U3D_Node& PDF3D_U3D::getNode(const QString& nodeName) const auto it = m_sceneGraph.find(nodeName); if (it != m_sceneGraph.end()) { - return it.second; + return it->second; } static const PDF3D_U3D_Node dummyNode; @@ -701,6 +2293,24 @@ void PDF3D_U3D::setMaterialResource(const QString& materialName, PDF3D_U3D_Mater m_materialResources[materialName] = std::move(material); } +void PDF3D_U3D::setGeometry(const QString& geometryName, QSharedPointer geometry) +{ + m_geometries[geometryName] = std::move(geometry); +} + +PDF3D_U3D PDF3D_U3D::parse(const QByteArray& data, QStringList* errors) +{ + PDF3D_U3D_Parser parser; + PDF3D_U3D result = parser.parse(data); + + if (errors) + { + *errors = parser.getErrors(); + } + + return result; +} + PDF3D_U3D_Block_Data PDF3D_U3D_Parser::readBlockData(PDF3D_U3D_DataReader& reader) { PDF3D_U3D_Block_Data data; @@ -785,6 +2395,8 @@ void PDF3D_U3D_Parser::processLineSet(const PDF3D_U3D_Decoder& decoder) auto block = parseBlock(decoder.front()); const PDF3D_U3D_LineSetDeclarationBlock* declarationBlock = dynamic_cast(block.data()); + QSharedPointer geometry(new PDF3D_U3D_LineSetGeometry()); + for (auto it = std::next(decoder.begin()); it != decoder.end(); ++it) { auto blockData = *it; @@ -792,8 +2404,10 @@ void PDF3D_U3D_Parser::processLineSet(const PDF3D_U3D_Decoder& decoder) { case PDF3D_U3D_Block_Info::BT_GeneratorLineSetCont: { - // TODO: process block data auto currentBlock = PDF3D_U3D_LineSetContinuationBlock::parse(blockData.blockData, blockData.metaData, this, declarationBlock); + const PDF3D_U3D_LineSetContinuationBlock* typedBlock = dynamic_cast(currentBlock.data()); + + addLineSetGeometry(geometry.data(), declarationBlock, typedBlock); break; } @@ -801,6 +2415,11 @@ void PDF3D_U3D_Parser::processLineSet(const PDF3D_U3D_Decoder& decoder) m_errors << PDFTranslationContext::tr("Invalid block type '%1' for line set!").arg(blockData.blockType, 8, 16); } } + + if (!geometry->isEmpty()) + { + m_object.setGeometry(declarationBlock->getName(), std::move(geometry)); + } } void PDF3D_U3D_Parser::processTexture(const PDF3D_U3D_Decoder& decoder) @@ -931,6 +2550,264 @@ void PDF3D_U3D_Parser::processTexture(const PDF3D_U3D_Decoder& decoder) m_object.setTextureResource(declarationBlock->getResourceName(), std::move(texture)); } +void PDF3D_U3D_Parser::addLineSetGeometry(PDF3D_U3D_LineSetGeometry* geometry, + const PDF3D_U3D_LineSetDeclarationBlock* declarationBlock, + const PDF3D_U3D_LineSetContinuationBlock* geometryBlock) +{ + const auto& updateItems = geometryBlock->getUpdateItems(); + + if (geometry->isEmpty()) + { + geometry->addNormal(QVector3D()); + geometry->addDiffuseColor(QVector4D()); + geometry->addSpecularColor(QVector4D()); + } + + bool hasTextures = false; + + for (const PDF3D_U3D_LineSetContinuationBlock::UpdateItem& item : updateItems) + { + // 1. Determine position + const size_t splitPositionIndex = item.splitPositionIndex; + + QVector3D splitPosition = geometry->getPosition(splitPositionIndex); + QVector3D currentPosition = getDequantizedVec3(item.newPositionInfo, splitPosition, declarationBlock->getPositionInverseQuant()); + + geometry->addPosition(currentPosition); + auto lines = geometry->queryLinesByVertexIndex(splitPositionIndex); + + size_t predictedNormalCount = 0; + size_t predictedDiffuseCount = 0; + size_t predictedSpecularCount = 0; + QVector3D predictedNormal(0, 0, 0); + QVector4D predictedDiffuseColor(0, 0, 0, 0); + QVector4D predictedSpecularColor(0, 0, 0, 0); + + // 2. Prepare predicted values + for (const PDF3D_U3D_LineSetGeometry::Line & line : lines) + { + auto description = declarationBlock->getShadingDescriptionItem(line.shadingId); + const bool hasDiffuse = description && description->hasDiffuseColors(); + const bool hasSpecular = description && description->hasSpecularColors(); + + if (line.position1 == splitPositionIndex) + { + predictedNormal += geometry->getNormal(line.normal1); + ++predictedNormalCount; + + if (hasDiffuse) + { + predictedDiffuseColor += geometry->getDiffuseColor(line.diffuseColor1); + ++predictedDiffuseCount; + } + + if (hasSpecular) + { + predictedSpecularColor += geometry->getSpecularColor(line.specularColor1); + ++predictedSpecularCount; + } + + } + if (line.position2 == splitPositionIndex) + { + predictedNormal += geometry->getNormal(line.normal2); + ++predictedNormalCount; + + if (hasDiffuse) + { + predictedDiffuseColor += geometry->getDiffuseColor(line.diffuseColor2); + ++predictedDiffuseCount; + } + + if (hasSpecular) + { + predictedSpecularColor += geometry->getSpecularColor(line.specularColor2); + ++predictedSpecularCount; + } + } + } + + if (predictedNormalCount > 0) + { + predictedNormal /= qreal(predictedNormalCount); + } + + if (predictedDiffuseCount > 0) + { + predictedDiffuseColor /= qreal(predictedDiffuseCount); + } + + if (predictedSpecularCount > 0) + { + predictedSpecularColor /= qreal(predictedSpecularCount); + } + + const size_t normalCount = geometry->getNormalCount(); + for (const auto& normal : item.newNormals) + { + QVector3D normalVector = getDequantizedVec3(normal, predictedNormal, declarationBlock->getNormalInverseQuant()); + geometry->addNormal(normalVector); + } + + for (const PDF3D_U3D_LineSetContinuationBlock::NewLineInfo& line : item.newLines) + { + PDF3D_U3D_LineSetGeometry::Line processedLine; + + processedLine.shadingId = static_cast(line.shadingId); + processedLine.position1 = static_cast(line.firstPositionIndex); + processedLine.position2 = static_cast(geometry->getPositionCount() - 1); + processedLine.normal1 = static_cast(line.p1.normalLocalIndex + normalCount); + processedLine.normal2 = static_cast(line.p2.normalLocalIndex + normalCount); + + if (auto description = declarationBlock->getShadingDescriptionItem(line.shadingId)) + { + if (description->hasDiffuseColors()) + { + if (line.p1.duplicateDiffuse) + { + processedLine.diffuseColor1 = static_cast(geometry->getDiffuseColorCount() - 1); + } + else + { + processedLine.diffuseColor1 = static_cast(geometry->getDiffuseColorCount()); + QVector4D diffuseColor = getDequantizedVec4(line.p1.diffuseColor, predictedDiffuseColor, declarationBlock->getDiffuseColorInverseQuant()); + geometry->addDiffuseColor(diffuseColor); + } + + if (line.p2.duplicateDiffuse) + { + processedLine.diffuseColor2 = static_cast(geometry->getDiffuseColorCount() - 1); + } + else + { + processedLine.diffuseColor2 = static_cast(geometry->getDiffuseColorCount()); + QVector4D diffuseColor = getDequantizedVec4(line.p2.diffuseColor, predictedDiffuseColor, declarationBlock->getDiffuseColorInverseQuant()); + geometry->addDiffuseColor(diffuseColor); + } + } + + if (description->hasSpecularColors()) + { + if (line.p1.duplicateSpecular) + { + processedLine.specularColor1 = static_cast(geometry->getSpecularColorCount() - 1); + } + else + { + processedLine.specularColor1 = static_cast(geometry->getSpecularColorCount()); + QVector4D specularColor = getDequantizedVec4(line.p1.specularColor, predictedSpecularColor, declarationBlock->getSpecularColorInverseQuant()); + geometry->addSpecularColor(specularColor); + } + + if (line.p2.duplicateSpecular) + { + processedLine.specularColor2 = static_cast(geometry->getSpecularColorCount() - 1); + } + else + { + processedLine.specularColor2 = static_cast(geometry->getSpecularColorCount()); + QVector4D specularColor = getDequantizedVec4(line.p2.specularColor, predictedSpecularColor, declarationBlock->getSpecularColorInverseQuant()); + geometry->addSpecularColor(specularColor); + } + } + + if (description->hasTextures()) + { + hasTextures = true; + } + } + + geometry->addLine(std::move(processedLine)); + } + } + + if (hasTextures) + { + m_errors << PDFTranslationContext::tr("Textures for lines are not supported."); + } +} + +QVector3D PDF3D_U3D_Parser::getDequantizedVec3(PDF3D_U3D_QuantizedVec3 quantizedV3, + QVector3D prediction, + float inverseQuant) +{ + QVector3D result = prediction; + + if (quantizedV3.signBits & 0x01) + { + result[0] -= quantizedV3.diff1 * inverseQuant; + } + else + { + result[0] += quantizedV3.diff1 * inverseQuant; + } + + if (quantizedV3.signBits & 0x02) + { + result[1] -= quantizedV3.diff2 * inverseQuant; + } + else + { + result[1] += quantizedV3.diff2 * inverseQuant; + } + + if (quantizedV3.signBits & 0x04) + { + result[2] -= quantizedV3.diff3 * inverseQuant; + } + else + { + result[2] += quantizedV3.diff3 * inverseQuant; + } + + return result; +} + +QVector4D PDF3D_U3D_Parser::getDequantizedVec4(PDF3D_U3D_QuantizedVec4 quantizedV4, + QVector4D prediction, + float inverseQuant) +{ + QVector4D result = prediction; + + if (quantizedV4.signBits & 0x01) + { + result[0] -= quantizedV4.diff1 * inverseQuant; + } + else + { + result[0] += quantizedV4.diff1 * inverseQuant; + } + + if (quantizedV4.signBits & 0x02) + { + result[1] -= quantizedV4.diff2 * inverseQuant; + } + else + { + result[1] += quantizedV4.diff2 * inverseQuant; + } + + if (quantizedV4.signBits & 0x04) + { + result[2] -= quantizedV4.diff3 * inverseQuant; + } + else + { + result[2] += quantizedV4.diff3 * inverseQuant; + } + + if (quantizedV4.signBits & 0x08) + { + result[3] -= quantizedV4.diff4 * inverseQuant; + } + else + { + result[3] += quantizedV4.diff4 * inverseQuant; + } + + return result; +} + void PDF3D_U3D_Parser::addBlockToU3D(PDF3D_U3D_AbstractBlockPtr block) { switch (block->getBlockType()) @@ -1098,7 +2975,7 @@ void PDF3D_U3D_Parser::addBlockToU3D(PDF3D_U3D_AbstractBlockPtr block) { const PDF3D_U3D_GroupNodeBlock* groupNodeBlock = dynamic_cast(block.data()); - PDF3D_U3D_Node& node = m_object.getOrCreateNode(groupNodeBlock); + PDF3D_U3D_Node& node = m_object.getOrCreateNode(groupNodeBlock->getGroupNodeName()); node.setNodeName(groupNodeBlock->getGroupNodeName()); node.setType(PDF3D_U3D_Node::Group); @@ -1114,7 +2991,7 @@ void PDF3D_U3D_Parser::addBlockToU3D(PDF3D_U3D_AbstractBlockPtr block) { const PDF3D_U3D_ModelNodeBlock* modelNodeBlock = dynamic_cast(block.data()); - PDF3D_U3D_Node& node = m_object.getOrCreateNode(modelNodeBlock); + PDF3D_U3D_Node& node = m_object.getOrCreateNode(modelNodeBlock->getModelNodeName()); node.setNodeName(modelNodeBlock->getModelNodeName()); node.setResourceName(modelNodeBlock->getModelResourceName()); node.setType(PDF3D_U3D_Node::Model); @@ -1134,7 +3011,7 @@ void PDF3D_U3D_Parser::addBlockToU3D(PDF3D_U3D_AbstractBlockPtr block) { const PDF3D_U3D_LightNodeBlock* lightNodeBlock = dynamic_cast(block.data()); - PDF3D_U3D_Node& node = m_object.getOrCreateNode(lightNodeBlock); + PDF3D_U3D_Node& node = m_object.getOrCreateNode(lightNodeBlock->getLightNodeName()); node.setNodeName(lightNodeBlock->getLightNodeName()); node.setResourceName(lightNodeBlock->getLightResourceName()); node.setType(PDF3D_U3D_Node::Light); @@ -1151,6 +3028,16 @@ void PDF3D_U3D_Parser::addBlockToU3D(PDF3D_U3D_AbstractBlockPtr block) { const PDF3D_U3D_ViewNodeBlock* viewNodeBlock = dynamic_cast(block.data()); + PDF3D_U3D_Node& node = m_object.getOrCreateNode(viewNodeBlock->getViewNodeName()); + node.setNodeName(viewNodeBlock->getViewNodeName()); + node.setResourceName(viewNodeBlock->getViewResourceName()); + node.setType(PDF3D_U3D_Node::View); + + for (const PDF3D_U3D_AbstractBlock::ParentNodeData& parentNodeData : viewNodeBlock->getParentNodesData()) + { + m_object.getOrCreateNode(parentNodeData.parentNodeName).addChild(viewNodeBlock->getViewNodeName(), parentNodeData.transformMatrix); + } + break; } @@ -4315,6 +6202,28 @@ void PDF3D_U3D_Node::setIsBackVisible(bool newIsBackVisible) m_isBackVisible = newIsBackVisible; } +void PDF3D_U3D_LineSetGeometry::addLine(Line line) +{ + const size_t lineIndex = m_lines.size(); + m_lines.emplace_back(std::move(line)); + m_mapPosIndexToLine.insert(std::make_pair(m_lines.back().position1, lineIndex)); + m_mapPosIndexToLine.insert(std::make_pair(m_lines.back().position2, lineIndex)); +} + +std::vector PDF3D_U3D_LineSetGeometry::queryLinesByVertexIndex(size_t vertexIndex) const +{ + std::vector result; + auto iterators = m_mapPosIndexToLine.equal_range(vertexIndex); + result.reserve(std::distance(iterators.first, iterators.second)); + + for (auto it = iterators.first; it != iterators.second; ++it) + { + result.push_back(m_lines[it->second]); + } + + return result; +} + } // namespace u3d } // namespace pdf diff --git a/Pdf4QtLib/sources/pdf3d_u3d.h b/Pdf4QtLib/sources/pdf3d_u3d.h index 7eafcb1..aebb817 100644 --- a/Pdf4QtLib/sources/pdf3d_u3d.h +++ b/Pdf4QtLib/sources/pdf3d_u3d.h @@ -38,1321 +38,6 @@ namespace pdf namespace u3d { -enum Context -{ - cPosDiffSign = 1, - cPosDiffX, - cPosDiffY, - cPosDiffZ, - cNormlCnt, - cDiffNormalSign, - cDiffNormalX, - cDiffNormalY, - cDiffNormalZ, - cShading, - cLineCnt = cShading, // Undocumented, that cLineCnt equals to cShading - cPointCnt = cShading, // Undocumented, that cPointCnt equals to cShading - cNormlIdx, - cDiffDup, - cDiffuseColorSign, - cColorDiffR, - cColorDiffG, - cColorDiffB, - cColorDiffA, - cSpecDup, - cSpecularColorSign, - cTexCDup, - cTexCoordSign, - cTexCDiffU, - cTexCDiffV, - cTexCDiffS, - cTexCDiffT, - cZero, - cDiffuseCount, - cSpecularCount, - cTexCoordCount, - cFaceCnt, - cFaceOrnt, - cLocal3rdPos, - cThrdPosType, - cBoneWeightCnt, - cBoneIdx, - cQntBoneWeight, - cTimeSign, - cTimeDiff, - cDispSign, - cDispDiff, - cRotSign, - cRotDiff, - cScalSign, - cScalDiff -}; - -class PDF3D_U3D; -class PDF3D_U3D_Parser; -class PDF3D_U3D_DataReader; -class PDF3D_U3D_ContextManager; - -struct PDF3D_U3D_Block_Data; - -class PDF3D_U3D_AbstractBlock; -using PDF3D_U3D_AbstractBlockPtr = QSharedPointer; - -using PDF3D_U3D_Vec3 = std::array; -using PDF3D_U3D_Vec4 = std::array; - -struct PDF3D_U3D_QuantizedVec4 -{ - uint8_t signBits; - uint32_t diff1; - uint32_t diff2; - uint32_t diff3; - uint32_t diff4; -}; - -struct PDF3D_U3D_QuantizedVec3 -{ - uint8_t signBits; - uint32_t diff1; - uint32_t diff2; - uint32_t diff3; -}; - -struct PDF3D_U3D_QuantizedVec1 -{ - uint8_t signBits; - uint32_t diff1; -}; - -struct PDF3D_U3D_Block_Info -{ - enum EBlockType : uint32_t - { - BT_Unknown = 0x00000000, - BT_FileHeader = 0x00443355, - BT_FileReference = 0xFFFFFF12, - BT_FileModifierChain = 0xFFFFFF14, - BT_FilePriorityUpdate = 0xFFFFFF15, - BT_FileNewObject = 0xFFFFFF16, - - BT_NodeGroup = 0xFFFFFF21, - BT_NodeModel = 0xFFFFFF22, - BT_NodeLight = 0xFFFFFF23, - BT_NodeView = 0xFFFFFF24, - - BT_GeneratorCLODMeshDecl = 0xFFFFFF31, - BT_GeneratorCLODBaseMesh = 0xFFFFFF3B, - BT_GeneratorCLODProgMesh = 0xFFFFFF3C, - BT_GeneratorPointSet = 0xFFFFFF36, - BT_GeneratorPointSetCont = 0xFFFFFF3E, - BT_GeneratorLineSet = 0xFFFFFF37, - BT_GeneratorLineSetCont = 0xFFFFFF3F, - - BT_Modifier2DGlyph = 0xFFFFFF41, - BT_ModifierSubdivision = 0xFFFFFF42, - BT_ModifierAnimation = 0xFFFFFF43, - BT_ModifierBoneWeights = 0xFFFFFF44, - BT_ModifierShading = 0xFFFFFF45, - BT_ModifierCLOD = 0xFFFFFF46, - - BT_ResourceLight = 0xFFFFFF51, - BT_ResourceView = 0xFFFFFF52, - BT_ResourceLitShader = 0xFFFFFF53, - BT_ResourceMaterial = 0xFFFFFF54, - BT_ResourceTexture = 0xFFFFFF55, - BT_ResourceTextureCont = 0xFFFFFF5C, - BT_ResourceMotion = 0xFFFFFF56 - }; - - enum EPalette - { - PL_Material, - PL_Generator, - PL_Shader, - PL_Texture, - PL_Motion, - PL_Node, - PL_View, - PL_Light, - PL_LastPalette - }; - - static constexpr bool isChain(EBlockType blockType); - static constexpr bool isContinuation(EBlockType blockType); - static EPalette getPalette(EBlockType blockType); -}; - -struct PDF3D_U3D_Block_Data -{ - PDF3D_U3D_Block_Info::EBlockType blockType = PDF3D_U3D_Block_Info::EBlockType(); - - QByteArray blockData; - QByteArray metaData; -}; - -struct PDF3D_U3D_BoneJoint -{ - float jointCenterU = 0.0; - float jointCenterV = 0.0; - float jointScaleU = 0.0; - float jointScaleV = 0.0; -}; - -struct PDF3D_U3D_BoneDescription -{ - QString boneName; - QString parentBoneName; - uint32_t boneAttributes = 0; - float boneLength = 0.0; - PDF3D_U3D_Vec3 boneDisplacement = PDF3D_U3D_Vec3(); - PDF3D_U3D_Vec4 boneOrientation = PDF3D_U3D_Vec4(); - uint32_t boneLinkCount = 0; - float boneLinkLength = 0.0; - PDF3D_U3D_BoneJoint startJoint = PDF3D_U3D_BoneJoint(); - PDF3D_U3D_BoneJoint endJoint = PDF3D_U3D_BoneJoint(); - PDF3D_U3D_Vec3 rotationConstraintMin = PDF3D_U3D_Vec3(); - PDF3D_U3D_Vec3 rotationConstraintMax = PDF3D_U3D_Vec3(); - - bool isLinkPresent() const { return boneAttributes & 0x00000001; } - bool isJointPresent() const { return boneAttributes & 0x00000002; } -}; - -struct PDF3D_U3D_ShadingDescription -{ - uint32_t shadingAttributes = 0; - uint32_t textureLayerCount = 0; - std::vector textureCoordDimensions; - uint32_t originalShading = 0; - - bool hasDiffuseColors() const { return shadingAttributes & 0x00000001; } - bool hasSpecularColors() const { return shadingAttributes & 0x00000002; } -}; - -class PDF3D_U3D_AbstractBlock -{ -public: - inline constexpr PDF3D_U3D_AbstractBlock() = default; - virtual ~PDF3D_U3D_AbstractBlock() = default; - - using EBlockType = PDF3D_U3D_Block_Info::EBlockType; - - virtual EBlockType getBlockType() const = 0; - - void parseMetadata(QByteArray metaData, PDF3D_U3D_Parser* object); - - struct ParentNodeData - { - QString parentNodeName; - QMatrix4x4 transformMatrix; - }; - - using ParentNodesData = std::vector; - - struct MetaDataItem - { - uint32_t attributes = 0; - QString key; - QString value; - QByteArray binaryData; - }; - - static ParentNodesData parseParentNodeData(PDF3D_U3D_DataReader& reader, PDF3D_U3D_Parser* object); - -private: - std::vector m_metaData; -}; - -// Bounding sphere - x, y, z position and radius -using PDF3D_U3D_BoundingSphere = std::array; - -// Bounding box - min (x,y,z), max (x,y,z) - six values -using PDF3D_U3D_AxisAlignedBoundingBox = std::array; - -// ------------------------------------------------------------------------------- -// FILE STRUCTURE BLOCKS -// ------------------------------------------------------------------------------- - -class PDF3D_U3D_FileBlock : public PDF3D_U3D_AbstractBlock -{ -public: - static constexpr uint32_t ID = PDF3D_U3D_Block_Info::BT_FileHeader; - virtual EBlockType getBlockType() const override { return static_cast(ID); } - - static PDF3D_U3D_AbstractBlockPtr parse(QByteArray data, QByteArray metaData, PDF3D_U3D_Parser* object); - - bool isExtensibleProfile() const { return m_profileIdentifier & 0x00000002; } - bool isNoCompressionMode() const { return m_profileIdentifier & 0x00000004; } - bool isDefinedUnits() const { return m_profileIdentifier & 0x00000008; } - - int16_t getMajorVersion() const; - int16_t getMinorVersion() const; - uint32_t getProfileIdentifier() const; - uint32_t getDeclarationSize() const; - uint64_t getFileSize() const; - uint32_t getCharacterEncoding() const; - PDFReal getUnitScalingFactor() const; - -private: - int16_t m_majorVersion = 0; - int16_t m_minorVersion = 0; - uint32_t m_profileIdentifier = 0; - uint32_t m_declarationSize = 0; - uint64_t m_fileSize = 0; - uint32_t m_characterEncoding = 0; - PDFReal m_unitScalingFactor = 1.0; -}; - -class PDF3D_U3D_FileReferenceBlock : public PDF3D_U3D_AbstractBlock -{ -public: - static constexpr uint32_t ID = PDF3D_U3D_Block_Info::BT_FileReference; - virtual EBlockType getBlockType() const override { return static_cast(ID); } - - bool isBoundingSpherePresent() const { return m_fileReferenceAttributes & 0x00000001; } - bool isAxisAlignedBoundingBoxPresent() const { return m_fileReferenceAttributes & 0x00000002; } - - static PDF3D_U3D_AbstractBlockPtr parse(QByteArray data, QByteArray metaData, PDF3D_U3D_Parser* object); - - struct Filter - { - uint8_t filterType = 0; - QString objectNameFilter; - uint32_t objectTypeFilter = 0; - }; - - const QString& getScopeName() const; - uint32_t getFileReferenceAttributes() const; - const PDF3D_U3D_BoundingSphere& getBoundingSphere() const; - const PDF3D_U3D_AxisAlignedBoundingBox& getBoundingBox() const; - uint32_t getUrlCount() const; - const QStringList& getUrls() const; - uint32_t getFilterCount() const; - const std::vector& getFilters() const; - uint8_t getNameCollisionPolicy() const; - const QString& getWorldAliasName() const; - -private: - QString m_scopeName; - uint32_t m_fileReferenceAttributes = 0; - PDF3D_U3D_BoundingSphere m_boundingSphere = PDF3D_U3D_BoundingSphere(); - PDF3D_U3D_AxisAlignedBoundingBox m_boundingBox = PDF3D_U3D_AxisAlignedBoundingBox(); - uint32_t m_urlCount = 0; - QStringList m_urls; - uint32_t m_filterCount = 0; - std::vector m_filters; - uint8_t m_nameCollisionPolicy = 0; - QString m_worldAliasName; -}; - -class PDF3D_U3D_ModifierChainBlock : public PDF3D_U3D_AbstractBlock -{ -public: - static constexpr uint32_t ID = PDF3D_U3D_Block_Info::BT_FileModifierChain; - virtual EBlockType getBlockType() const override { return static_cast(ID); } - - static PDF3D_U3D_AbstractBlockPtr parse(QByteArray data, QByteArray metaData, PDF3D_U3D_Parser* object); - - bool isBoundingSpherePresent() const { return m_modifierChainAttributes & 0x00000001; } - bool isAxisAlignedBoundingBoxPresent() const { return m_modifierChainAttributes & 0x00000002; } - - bool isNodeModifierChain() const { return m_modifierChainType == 0; } - bool isModelResourceModifierChain() const { return m_modifierChainType == 1; } - bool isTextureModifierChain() const { return m_modifierChainType == 2; } - - const QString& getModifierChainName() const; - uint32_t getModifierChainType() const; - uint32_t getModifierChainAttributes() const; - const PDF3D_U3D_BoundingSphere& getBoundingSphere() const; - const PDF3D_U3D_AxisAlignedBoundingBox& getBoundingBox() const; - uint32_t getModifierCount() const; - const std::vector& getModifierDeclarationBlocks() const; - -private: - QString m_modifierChainName; - uint32_t m_modifierChainType = 0; - uint32_t m_modifierChainAttributes = 0; - PDF3D_U3D_BoundingSphere m_boundingSphere = PDF3D_U3D_BoundingSphere(); - PDF3D_U3D_AxisAlignedBoundingBox m_boundingBox = PDF3D_U3D_AxisAlignedBoundingBox(); - // Padding 0-3 bytes - uint32_t m_modifierCount = 0; - std::vector m_modifierDeclarationBlocks; -}; - -class PDF3D_U3D_FilePriorityUpdateBlock : public PDF3D_U3D_AbstractBlock -{ -public: - static constexpr uint32_t ID = PDF3D_U3D_Block_Info::BT_FilePriorityUpdate; - virtual EBlockType getBlockType() const override { return static_cast(ID); } - - static PDF3D_U3D_AbstractBlockPtr parse(QByteArray data, QByteArray metaData, PDF3D_U3D_Parser* object); - - uint32_t getNewPriority() const; - -private: - uint32_t m_newPriority = 0; -}; - -class PDF3D_U3D_NewObjectTypeBlock : public PDF3D_U3D_AbstractBlock -{ -public: - static constexpr uint32_t ID = PDF3D_U3D_Block_Info::BT_FileNewObject; - virtual EBlockType getBlockType() const override { return static_cast(ID); } - - static PDF3D_U3D_AbstractBlockPtr parse(QByteArray data, QByteArray metaData, PDF3D_U3D_Parser* object); - - const QString& getNewObjectTypeName() const; - uint32_t getModifierType() const; - const QUuid& getExtensionId() const; - uint32_t getNewDeclarationBlockType() const; - uint32_t getContinuationBlockTypeCount() const; - const std::vector& getContinuationBlockTypes() const; - const QString& getExtensionVendorName() const; - uint32_t getUrlCount() const; - const QStringList& getUrls() const; - const QString& getExtensionInformationString() const; - -private: - QString m_newObjectTypeName; - uint32_t m_modifierType = 0; - QUuid m_extensionId; - uint32_t m_newDeclarationBlockType = 0; - uint32_t m_continuationBlockTypeCount = 0; - std::vector m_continuationBlockTypes; - QString m_extensionVendorName; - uint32_t m_urlCount = 0; - QStringList m_urls; - QString m_extensionInformationString; -}; - -class PDF3D_U3D_NewObjectBlock : public PDF3D_U3D_AbstractBlock -{ -public: - static constexpr uint32_t ID_MIN = 0x00000100; - static constexpr uint32_t ID_MAX = 0x00FFFFFF; - - virtual EBlockType getBlockType() const override { return PDF3D_U3D_Block_Info::BT_FileNewObject; } - - static PDF3D_U3D_AbstractBlockPtr parse(QByteArray data, QByteArray metaData, PDF3D_U3D_Parser* object); - - const QString& getObjectName() const; - uint32_t getChainIndex() const; - const QByteArray& getData() const; - -private: - QString m_objectName; - uint32_t m_chainIndex = 0; - QByteArray m_data; -}; - -// ------------------------------------------------------------------------------- -// NODE BLOCKS -// ------------------------------------------------------------------------------- - -class PDF3D_U3D_GroupNodeBlock : public PDF3D_U3D_AbstractBlock -{ -public: - static constexpr uint32_t ID = PDF3D_U3D_Block_Info::BT_NodeGroup; - virtual EBlockType getBlockType() const override { return static_cast(ID); } - - static PDF3D_U3D_AbstractBlockPtr parse(QByteArray data, QByteArray metaData, PDF3D_U3D_Parser* object); - - const QString& getGroupNodeName() const; - const ParentNodesData& getParentNodesData() const; - -private: - QString m_groupNodeName; - ParentNodesData m_parentNodesData; -}; - -class PDF3D_U3D_ModelNodeBlock : public PDF3D_U3D_AbstractBlock -{ -public: - static constexpr uint32_t ID = PDF3D_U3D_Block_Info::BT_NodeModel; - virtual EBlockType getBlockType() const override { return static_cast(ID); } - - static PDF3D_U3D_AbstractBlockPtr parse(QByteArray data, QByteArray metaData, PDF3D_U3D_Parser* object); - - bool isHidden() const { return m_modelVisibility == 0; } - bool isFrontVisible() const { return m_modelVisibility == 1; } - bool isBackVisible() const { return m_modelVisibility == 2; } - bool isFrontAndBackVisible() const { return m_modelVisibility == 3; } - - const QString& getModelNodeName() const; - const ParentNodesData& getParentNodesData() const; - const QString& getModelResourceName() const; - uint32_t getModelVisibility() const; - -private: - QString m_modelNodeName; - ParentNodesData m_parentNodesData; - QString m_modelResourceName; - uint32_t m_modelVisibility; -}; - -class PDF3D_U3D_LightNodeBlock : public PDF3D_U3D_AbstractBlock -{ -public: - static constexpr uint32_t ID = PDF3D_U3D_Block_Info::BT_NodeLight; - virtual EBlockType getBlockType() const override { return static_cast(ID); } - - static PDF3D_U3D_AbstractBlockPtr parse(QByteArray data, QByteArray metaData, PDF3D_U3D_Parser* object); - - const QString& getLightNodeName() const; - const ParentNodesData& getParentNodesData() const; - const QString& getLightResourceName() const; - -private: - QString m_lightNodeName; - ParentNodesData m_parentNodesData; - QString m_lightResourceName; -}; - -class PDF3D_U3D_ViewNodeBlock : public PDF3D_U3D_AbstractBlock -{ -public: - static constexpr uint32_t ID = PDF3D_U3D_Block_Info::BT_NodeView; - virtual EBlockType getBlockType() const override { return static_cast(ID); } - - static PDF3D_U3D_AbstractBlockPtr parse(QByteArray data, QByteArray metaData, PDF3D_U3D_Parser* object); - - struct BackdropOrOverlay - { - QString m_textureName; - float m_textureBlend = 0.0; - float m_rotation = 0.0; - float m_locationX = 0.0; - float m_locationY = 0.0; - int32_t m_registrationPointX = 0; - int32_t m_registrationPointY = 0; - float m_scaleX = 0.0; - float m_scaleY = 0.0; - }; - - using BackdropItem = BackdropOrOverlay; - using OverlayItem = BackdropOrOverlay; - - bool isScreenPositionRelative() const { return m_viewNodeAttributes & 0x00000001; } - bool isProjectionOrthographic() const { return m_viewNodeAttributes & 0x00000002; } - bool isProjectionTwoPointPerspective() const { return m_viewNodeAttributes & 0x00000004; } - bool isProjectionOnePointPerspective() const { return (m_viewNodeAttributes & 0x00000002) && (m_viewNodeAttributes & 0x00000004); } - bool isProjectionThreePointPerspective() const { return !isProjectionOrthographic() && !isProjectionTwoPointPerspective() && !isProjectionOnePointPerspective(); } - - const QString& getViewNodeName() const; - const ParentNodesData& getParentNodesData() const; - const QString& getViewResourceName() const; - uint32_t getViewNodeAttributes() const; - float getViewNearFlipping() const; - float getViewFarFlipping() const; - float getViewProjection() const; - float getViewOrthographicHeight() const; - const PDF3D_U3D_Vec3& getViewProjectionVector() const; - float getViewPortWidth() const; - float getViewPortHeight() const; - float getViewPortHorizontalPosition() const; - float getViewPortVerticalPosition() const; - const std::vector& getBackdrop() const; - const std::vector& getOverlay() const; - -private: - QString m_viewNodeName; - ParentNodesData m_parentNodesData; - QString m_viewResourceName; - uint32_t m_viewNodeAttributes = 0; - float m_viewNearFlipping = 0.0; - float m_viewFarFlipping = 0.0; - float m_viewProjection = 0.0; - float m_viewOrthographicHeight = 0.0; - PDF3D_U3D_Vec3 m_viewProjectionVector = PDF3D_U3D_Vec3(); - - // Viewport - float m_viewPortWidth = 0.0; - float m_viewPortHeight = 0.0; - float m_viewPortHorizontalPosition = 0.0; - float m_viewPortVerticalPosition = 0.0; - - // Backdrop - std::vector m_backdrop; - - // Overlay - std::vector m_overlay; -}; - -// ------------------------------------------------------------------------------- -// GEOMETRY BLOCKS -// ------------------------------------------------------------------------------- - -class PDF3D_U3D_CLODMeshDeclarationBlock : public PDF3D_U3D_AbstractBlock -{ -public: - static constexpr uint32_t ID = PDF3D_U3D_Block_Info::BT_GeneratorCLODMeshDecl; - virtual EBlockType getBlockType() const override { return static_cast(ID); } - - static PDF3D_U3D_AbstractBlockPtr parse(QByteArray data, QByteArray metaData, PDF3D_U3D_Parser* object); - - const QString& getName() const { return getMeshName(); } - const QString& getMeshName() const; - uint32_t getChainIndex() const; - - bool isNormalsExcluded() const { return getMeshAttributes() & 0x00000001; } - - /* max mesh description */ - uint32_t getMeshAttributes() const; - uint32_t getFaceCount() const; - uint32_t getPositionCount() const; - uint32_t getNormalCount() const; - uint32_t getDiffuseColorCount() const; - uint32_t getSpecularColorCount() const; - uint32_t getTextureColorCount() const; - uint32_t getShadingCount() const; - const std::vector& getShadingDescription() const; - const PDF3D_U3D_ShadingDescription* getShadingDescriptionItem(uint32_t index) const { return index < m_shadingDescription.size() ? &m_shadingDescription[index] : nullptr; } - - /* clod description */ - uint32_t getMinimumResolution() const; - uint32_t getFinalResolution() const; - - /* resource description */ - uint32_t getPositionQualityFactor() const; - uint32_t getNormalQualityFactor() const; - uint32_t getTextureCoordQualityFactor() const; - float getPositionInverseQuant() const; - float getNormalInverseQuant() const; - float getTextureCoordInverseQuant() const; - float getDiffuseColorInverseQuant() const; - float getSpecularColorInverseQuant() const; - float getNormalCreaseParameter() const; - float getNormalUpdateParameter() const; - float getNormalToleranceParameter() const; - - /* bone description */ - uint32_t getBoneCount() const; - const std::vector& getBoneDescription() const; - -private: - QString m_meshName; - uint32_t m_chainIndex = 0; - - /* max mesh description */ - uint32_t m_meshAttributes = 0; - uint32_t m_faceCount = 0; - uint32_t m_positionCount = 0; - uint32_t m_normalCount = 0; - uint32_t m_diffuseColorCount = 0; - uint32_t m_specularColorCount = 0; - uint32_t m_textureColorCount = 0; - std::vector m_shadingDescription; - - /* clod description */ - uint32_t m_minimumResolution = 0; - uint32_t m_finalResolution = 0; - - /* resource description */ - uint32_t m_positionQualityFactor = 0; - uint32_t m_normalQualityFactor = 0; - uint32_t m_textureCoordQualityFactor = 0; - float m_positionInverseQuant = 0.0; - float m_normalInverseQuant = 0.0; - float m_textureCoordInverseQuant = 0.0; - float m_diffuseColorInverseQuant = 0.0; - float m_specularColorInverseQuant = 0.0; - float m_normalCreaseParameter = 0.0; - float m_normalUpdateParameter = 0.0; - float m_normalToleranceParameter = 0.0; - - /* bone description */ - uint32_t m_boneCount = 0; - std::vector m_boneDescription; -}; - -class PDF3D_U3D_CLODBaseMeshContinuationBlock : public PDF3D_U3D_AbstractBlock -{ -public: - static constexpr uint32_t ID = PDF3D_U3D_Block_Info::BT_GeneratorCLODBaseMesh; - virtual EBlockType getBlockType() const override { return static_cast(ID); } - - static PDF3D_U3D_AbstractBlockPtr parse(QByteArray data, QByteArray metaData, PDF3D_U3D_Parser* object, const PDF3D_U3D_CLODMeshDeclarationBlock* declarationBlock); - - struct BaseCornerInfo - { - uint32_t basePositionIndex = 0; // rBasePositionCount - uint32_t baseNormalIndex = 0; // rBaseNormalCount - uint32_t baseDiffuseColorIndex = 0; // rBaseDiffColorCnt - uint32_t baseSpecularColorIndex = 0; // rBaseSpecColorCnt - std::vector baseTextureCoordIndex; // rBaseTexCoordCnt - }; - - struct BaseFace - { - uint32_t m_shadingId = 0; // cShading - std::array m_corners = { }; - }; - - const QString& getMeshName() const; - uint32_t getChainIndex() const; - - uint32_t getFaceCount() const; - uint32_t getPositionCount() const; - uint32_t getNormalCount() const; - uint32_t getDiffuseColorCount() const; - uint32_t getSpecularColorCount() const; - uint32_t getTextureColorCount() const; - - const std::vector& getBasePositions() const; - const std::vector& getBaseNormals() const; - const std::vector& getBaseDiffuseColors() const; - const std::vector& getBaseSpecularColors() const; - const std::vector& getBaseTextureCoords() const; - const std::vector& getBaseFaces() const; - -private: - QString m_meshName; - uint32_t m_chainIndex = 0; - - /* base mesh description */ - uint32_t m_faceCount = 0; - uint32_t m_positionCount = 0; - uint32_t m_normalCount = 0; - uint32_t m_diffuseColorCount = 0; - uint32_t m_specularColorCount = 0; - uint32_t m_textureColorCount = 0; - - std::vector m_basePositions; - std::vector m_baseNormals; - std::vector m_baseDiffuseColors; - std::vector m_baseSpecularColors; - std::vector m_baseTextureCoords; - std::vector m_baseFaces; -}; - -class PDF3D_U3D_CLODProgressiveMeshContinuationBlock : public PDF3D_U3D_AbstractBlock -{ -public: - static constexpr uint32_t ID = PDF3D_U3D_Block_Info::BT_GeneratorCLODProgMesh; - virtual EBlockType getBlockType() const override { return static_cast(ID); } - - static PDF3D_U3D_AbstractBlockPtr parse(QByteArray data, QByteArray metaData, PDF3D_U3D_Parser* object); - - struct NewFacePositionInfo - { - uint32_t shadingId = 0; - uint8_t faceOrientation = 0; - uint8_t thirdPositionType = 0; - uint32_t localThirdPositionIndex = 0; - uint32_t globalThirdPositionIndex = 0; - }; - - struct ResolutionUpdate - { - uint32_t splitPositionIndex = 0; - - std::vector newDiffuseColors; - std::vector newSpecularColors; - std::vector newTextureCoords; - std::vector newFaces; - }; - -private: - QString m_meshName; - uint32_t m_chainIndex = 0; - - uint32_t m_startResolution = 0; - uint32_t m_endResolution = 0; - uint32_t m_resolutionUpdateCount = 0; - - std::vector m_resolutionUpdates; -}; - -class PDF3D_U3D_PointSetDeclarationBlock : public PDF3D_U3D_AbstractBlock -{ -public: - static constexpr uint32_t ID = PDF3D_U3D_Block_Info::BT_GeneratorPointSet; - virtual EBlockType getBlockType() const override { return static_cast(ID); } - - static PDF3D_U3D_AbstractBlockPtr parse(QByteArray data, QByteArray metaData, PDF3D_U3D_Parser* object); - - const QString& getName() const { return m_pointSetName; } - uint32_t getPointCount() const; - uint32_t getPositionCount() const; - uint32_t getNormalCount() const; - uint32_t getDiffuseColorCount() const; - uint32_t getSpecularColorCount() const; - uint32_t getTextureCoordCount() const; - const std::vector& getShadingDescriptions() const; - const PDF3D_U3D_ShadingDescription* getShadingDescriptionItem(uint32_t index) const { return index < m_shadingDescriptions.size() ? &m_shadingDescriptions[index] : nullptr; } - - uint32_t getPositionQualityFactor() const; - uint32_t getNormalQualityFactor() const; - uint32_t getTextureCoordQualityFactor() const; - float getPositionInverseQuant() const; - float getNormalInverseQuant() const; - float getTextureCoordInverseQuant() const; - float getDiffuseColorInverseQuant() const; - float getSpecularColorInverseQuant() const; - - uint32_t getBoneCount() const; - - const std::vector& getBoneDescription() const; - -private: - QString m_pointSetName; - uint32_t m_chainIndex = 0; - - /* point set description */ - uint32_t m_pointSetReserved = 0; - uint32_t m_pointCount = 0; - uint32_t m_positionCount = 0; - uint32_t m_normalCount = 0; - uint32_t m_diffuseColorCount = 0; - uint32_t m_specularColorCount = 0; - uint32_t m_textureCoordCount = 0; - std::vector m_shadingDescriptions; - - /* resource description */ - uint32_t m_positionQualityFactor = 0; - uint32_t m_normalQualityFactor = 0; - uint32_t m_textureCoordQualityFactor = 0; - float m_positionInverseQuant = 0.0; - float m_normalInverseQuant = 0.0; - float m_textureCoordInverseQuant = 0.0; - float m_diffuseColorInverseQuant = 0.0; - float m_specularColorInverseQuant = 0.0; - float m_reserved1 = 0.0; - float m_reserved2 = 0.0; - float m_reserved3 = 0.0; - - /* bone description */ - uint32_t m_boneCount = 0; - std::vector m_boneDescription; -}; - -class PDF3D_U3D_PointSetContinuationBlock : public PDF3D_U3D_AbstractBlock -{ -public: - static constexpr uint32_t ID = PDF3D_U3D_Block_Info::BT_GeneratorPointSetCont; - virtual EBlockType getBlockType() const override { return static_cast(ID); } - - static PDF3D_U3D_AbstractBlockPtr parse(QByteArray data, QByteArray metaData, PDF3D_U3D_Parser* object, const PDF3D_U3D_PointSetDeclarationBlock* declarationBlock); - - struct NewPointInfo - { - uint32_t shadingId = 0; - uint32_t normalLocalIndex = 0; - - bool duplicateDiffuse = false; - bool duplicateSpecular = false; - - PDF3D_U3D_QuantizedVec4 diffuseColor = PDF3D_U3D_QuantizedVec4(); - PDF3D_U3D_QuantizedVec4 specularColor = PDF3D_U3D_QuantizedVec4(); - std::vector> textureCoords; - }; - - struct UpdateItem - { - uint32_t splitPositionIndex = 0; - - PDF3D_U3D_QuantizedVec3 newPositionInfo; - std::vector newNormals; - std::vector newPoints; - }; - - const QString& getName() const { return m_pointSetName; } - const std::vector& getUpdateItems() const; - -private: - QString m_pointSetName; - uint32_t m_chainIndex = 0; - - uint32_t m_startResolution = 0; - uint32_t m_endResolution = 0; - - std::vector m_updateItems; -}; - -class PDF3D_U3D_LineSetDeclarationBlock : public PDF3D_U3D_AbstractBlock -{ -public: - static constexpr uint32_t ID = PDF3D_U3D_Block_Info::BT_GeneratorLineSet; - virtual EBlockType getBlockType() const override { return static_cast(ID); } - - static PDF3D_U3D_AbstractBlockPtr parse(QByteArray data, QByteArray metaData, PDF3D_U3D_Parser* object); - - const QString& getName() const { return m_lineSetName; } - uint32_t getLineCount() const; - uint32_t getPositionCount() const; - uint32_t getNormalCount() const; - uint32_t getDiffuseColorCount() const; - uint32_t getSpecularColorCount() const; - uint32_t getTextureCoordCount() const; - const std::vector& getShadingDescriptions() const; - const PDF3D_U3D_ShadingDescription* getShadingDescriptionItem(uint32_t index) const { return index < m_shadingDescriptions.size() ? &m_shadingDescriptions[index] : nullptr; } - - uint32_t getPositionQualityFactor() const; - uint32_t getNormalQualityFactor() const; - uint32_t getTextureCoordQualityFactor() const; - float getPositionInverseQuant() const; - float getNormalInverseQuant() const; - float getTextureCoordInverseQuant() const; - float getDiffuseColorInverseQuant() const; - float getSpecularColorInverseQuant() const; - -private: - QString m_lineSetName; - uint32_t m_chainIndex = 0; - - /* line set description */ - uint32_t m_lineSetReserved = 0; - uint32_t m_lineCount = 0; - uint32_t m_positionCount = 0; - uint32_t m_normalCount = 0; - uint32_t m_diffuseColorCount = 0; - uint32_t m_specularColorCount = 0; - uint32_t m_textureCoordCount = 0; - std::vector m_shadingDescriptions; - - /* resource description */ - uint32_t m_positionQualityFactor = 0; - uint32_t m_normalQualityFactor = 0; - uint32_t m_textureCoordQualityFactor = 0; - float m_positionInverseQuant = 0.0; - float m_normalInverseQuant = 0.0; - float m_textureCoordInverseQuant = 0.0; - float m_diffuseColorInverseQuant = 0.0; - float m_specularColorInverseQuant = 0.0; - float m_reserved1 = 0.0; - float m_reserved2 = 0.0; - float m_reserved3 = 0.0; -}; - -class PDF3D_U3D_LineSetContinuationBlock : public PDF3D_U3D_AbstractBlock -{ -public: - static constexpr uint32_t ID = PDF3D_U3D_Block_Info::BT_GeneratorLineSetCont; - virtual EBlockType getBlockType() const override { return static_cast(ID); } - - static PDF3D_U3D_AbstractBlockPtr parse(QByteArray data, QByteArray metaData, PDF3D_U3D_Parser* object, const PDF3D_U3D_LineSetDeclarationBlock* declarationBlock); - - struct NewLineEndingInfo - { - uint32_t normalLocalIndex = 0; - - bool duplicateDiffuse = false; - bool duplicateSpecular = false; - - PDF3D_U3D_QuantizedVec4 diffuseColor = PDF3D_U3D_QuantizedVec4(); - PDF3D_U3D_QuantizedVec4 specularColor = PDF3D_U3D_QuantizedVec4(); - std::vector> textureCoords; - }; - - struct NewLineInfo - { - uint32_t shadingId = 0; - uint32_t firstPositionIndex = 0; - - NewLineEndingInfo p1; - NewLineEndingInfo p2; - }; - - struct UpdateItem - { - uint32_t splitPositionIndex = 0; - - PDF3D_U3D_QuantizedVec3 newPositionInfo; - std::vector newNormals; - std::vector newLines; - }; - - const QString& getName() const { return m_lineSetName; } - - const std::vector& getUpdateItems() const; - -private: - QString m_lineSetName; - uint32_t m_chainIndex = 0; - - uint32_t m_startResolution = 0; - uint32_t m_endResolution = 0; - - std::vector m_updateItems; -}; - -class PDF3D_U3D_2DGlyphModifierBlock : public PDF3D_U3D_AbstractBlock -{ -public: - static constexpr uint32_t ID = PDF3D_U3D_Block_Info::BT_Modifier2DGlyph; - virtual EBlockType getBlockType() const override { return static_cast(ID); } - - static PDF3D_U3D_AbstractBlockPtr parse(QByteArray data, QByteArray metaData, PDF3D_U3D_Parser* object); - - const QString& getModifierName() const; - uint32_t getChainIndex() const; - uint32_t getGlyphAttributes() const; - QPainterPath getPath() const; - const QMatrix4x4& getMatrix() const; - -private: - QString m_modifierName; - uint32_t m_chainIndex = 0; - uint32_t m_glyphAttributes = 0; - - QPainterPath m_path; - QMatrix4x4 m_matrix; -}; - -class PDF3D_U3D_SubdivisionModifierBlock : public PDF3D_U3D_AbstractBlock -{ -public: - static constexpr uint32_t ID = PDF3D_U3D_Block_Info::BT_ModifierSubdivision; - virtual EBlockType getBlockType() const override { return static_cast(ID); } - - static PDF3D_U3D_AbstractBlockPtr parse(QByteArray data, QByteArray metaData, PDF3D_U3D_Parser* object); - - const QString& getModifierName() const; - uint32_t getChainIndex() const; - uint32_t getAttributes() const; - uint32_t getDepth() const; - float getTension() const; - float getError() const; - -private: - QString m_modifierName; - uint32_t m_chainIndex = 0; - uint32_t m_attributes = 0; - uint32_t m_depth = 0; - - float m_tension = 0.0; - float m_error = 0.0; -}; - -class PDF3D_U3D_AnimationModifierBlock : public PDF3D_U3D_AbstractBlock -{ -public: - static constexpr uint32_t ID = PDF3D_U3D_Block_Info::BT_ModifierAnimation; - virtual EBlockType getBlockType() const override { return static_cast(ID); } - - static PDF3D_U3D_AbstractBlockPtr parse(QByteArray data, QByteArray metaData, PDF3D_U3D_Parser* object); - - struct MotionInformation - { - QString motionName; - uint32_t motionAttributes = 0; - float timeOffset = 0.0; - float timeScale = 0.0; - }; - - const QString& getModifierName() const; - uint32_t getChainIndex() const; - - uint32_t getAttributes() const; - float getTimescale() const; - uint32_t getMotionCount() const; - const std::vector& getMotionInformations() const; - float getBlendTime() const; - -private: - QString m_modifierName; - uint32_t m_chainIndex = 0; - - uint32_t m_attributes = 0; - float m_timescale = 0.0; - uint32_t m_motionCount = 0; - std::vector m_motionInformations; - - float m_blendTime = 0.0; -}; - -class PDF3D_U3D_BoneWeightModifierBlock : public PDF3D_U3D_AbstractBlock -{ -public: - static constexpr uint32_t ID = PDF3D_U3D_Block_Info::BT_ModifierBoneWeights; - virtual EBlockType getBlockType() const override { return static_cast(ID); } - - static PDF3D_U3D_AbstractBlockPtr parse(QByteArray data, QByteArray metaData, PDF3D_U3D_Parser* object); - - struct BoneWeightList - { - std::vector boneIndex; - std::vector boneWeight; - }; - - const QString& getModifierName() const; - uint32_t getChainIndex() const; - uint32_t getAttributes() const; - float getInverseQuant() const; - const std::vector& getBoneWeightLists() const; - -private: - QString m_modifierName; - uint32_t m_chainIndex = 0; - uint32_t m_attributes = 0; - float m_inverseQuant = 0.0; - std::vector m_boneWeightLists; -}; - -class PDF3D_U3D_ShadingModifierBlock : public PDF3D_U3D_AbstractBlock -{ -public: - static constexpr uint32_t ID = PDF3D_U3D_Block_Info::BT_ModifierShading; - virtual EBlockType getBlockType() const override { return static_cast(ID); } - - static PDF3D_U3D_AbstractBlockPtr parse(QByteArray data, QByteArray metaData, PDF3D_U3D_Parser* object); - - using ShaderLists = std::vector; - - const QString& getModifierName() const; - uint32_t getChainIndex() const; - uint32_t getAttributes() const; - const ShaderLists& getShaderLists() const; - -private: - QString m_modifierName; - uint32_t m_chainIndex = 0; - uint32_t m_attributes = 0; - ShaderLists m_shaderLists; -}; - -class PDF3D_U3D_CLODModifierBlock : public PDF3D_U3D_AbstractBlock -{ -public: - static constexpr uint32_t ID = PDF3D_U3D_Block_Info::BT_ModifierCLOD; - virtual EBlockType getBlockType() const override { return static_cast(ID); } - - static PDF3D_U3D_AbstractBlockPtr parse(QByteArray data, QByteArray metaData, PDF3D_U3D_Parser* object); - - const QString& getModifierName() const; - uint32_t getChainIndex() const; - uint32_t getAttributes() const; - float getCLODAutomaticLevelOfDetails() const; - float getCLODModifierLevel() const; - -private: - QString m_modifierName; - uint32_t m_chainIndex = 0; - uint32_t m_attributes = 0; - float m_CLODAutomaticLevelOfDetails = 0.0; - float m_CLODModifierLevel = 0.0; -}; - -class PDF3D_U3D_LightResourceBlock : public PDF3D_U3D_AbstractBlock -{ -public: - static constexpr uint32_t ID = PDF3D_U3D_Block_Info::BT_ResourceLight; - virtual EBlockType getBlockType() const override { return static_cast(ID); } - - static PDF3D_U3D_AbstractBlockPtr parse(QByteArray data, QByteArray metaData, PDF3D_U3D_Parser* object); - - const QString& getResourceName() const; - uint32_t getAttributes() const; - uint8_t getType() const; - const PDF3D_U3D_Vec4& getColor() const; - const PDF3D_U3D_Vec3& getAttenuation() const; - float getSpotAngle() const; - float getIntensity() const; - -private: - QString m_resourceName; - uint32_t m_attributes = 0; - uint8_t m_type = 0; - PDF3D_U3D_Vec4 m_color = { }; - PDF3D_U3D_Vec3 m_attenuation = { }; - float m_spotAngle = 0.0; - float m_intensity = 0.0; -}; - -class PDF3D_U3D_ViewResourceBlock : public PDF3D_U3D_AbstractBlock -{ -public: - static constexpr uint32_t ID = PDF3D_U3D_Block_Info::BT_ResourceView; - virtual EBlockType getBlockType() const override { return static_cast(ID); } - - static PDF3D_U3D_AbstractBlockPtr parse(QByteArray data, QByteArray metaData, PDF3D_U3D_Parser* object); - - struct Pass - { - QString rootNodeName; - uint32_t renderAttributes = 0; - uint32_t fogMode = 0; - PDF3D_U3D_Vec4 fogColor = { }; - float fogNear = 0.0; - float fogFar = 0.0; - }; - - const QString& getResourceName() const; - const std::vector& getRenderPasses() const; - -private: - QString m_resourceName; - std::vector m_renderPasses; -}; - -class PDF3D_U3D_LitTextureShaderResourceBlock : public PDF3D_U3D_AbstractBlock -{ -public: - static constexpr uint32_t ID = PDF3D_U3D_Block_Info::BT_ResourceLitShader; - virtual EBlockType getBlockType() const override { return static_cast(ID); } - - static PDF3D_U3D_AbstractBlockPtr parse(QByteArray data, QByteArray metaData, PDF3D_U3D_Parser* object); - - struct TextureInfo - { - QString textureName; - float textureIntensity = 0.0; - uint8_t blendFunction = 0; - uint8_t blendSource = 0; - float blendConstant = 0.0; - uint8_t textureMode = 0; - QMatrix4x4 textureTransform; - QMatrix4x4 textureMap; - uint8_t repeat = 0; - }; - - const QString& getResourceName() const; - uint32_t getAttributes() const; - float getAlphaTestReference() const; - uint32_t getColorBlendFunction() const; - uint32_t getAlphaTestFunction() const; - uint32_t getRenderPassEnabled() const; - uint32_t getShaderChannels() const; - uint32_t getAlphaTextureChannels() const; - const QString& getMaterialName() const; - const std::vector& getTextureInfos() const; - -private: - QString m_resourceName; - uint32_t m_attributes = 0; - float m_alphaTestReference = 0.0; - uint32_t m_alphaTestFunction = 0; - uint32_t m_colorBlendFunction = 0; - uint32_t m_renderPassEnabled = 0; - uint32_t m_shaderChannels = 0; - uint32_t m_alphaTextureChannels = 0; - QString m_materialName; - std::vector m_textureInfos; -}; - -class PDF3D_U3D_MaterialResourceBlock : public PDF3D_U3D_AbstractBlock -{ -public: - static constexpr uint32_t ID = PDF3D_U3D_Block_Info::BT_ResourceMaterial; - virtual EBlockType getBlockType() const override { return static_cast(ID); } - - static PDF3D_U3D_AbstractBlockPtr parse(QByteArray data, QByteArray metaData, PDF3D_U3D_Parser* object); - - const QString& getResourceName() const; - uint32_t getMaterialAttributes() const; - const PDF3D_U3D_Vec3& getAmbientColor() const; - const PDF3D_U3D_Vec3& getDiffuseColor() const; - const PDF3D_U3D_Vec3& getSpecularColor() const; - const PDF3D_U3D_Vec3& getEmissiveColor() const; - float getReflectivity() const; - float getOpacity() const; - -private: - QString m_resourceName; - uint32_t m_materialAttributes = 0; - PDF3D_U3D_Vec3 m_ambientColor = { }; - PDF3D_U3D_Vec3 m_diffuseColor = { }; - PDF3D_U3D_Vec3 m_specularColor = { }; - PDF3D_U3D_Vec3 m_emissiveColor = { }; - float m_reflectivity = 0.0; - float m_opacity = 0.0; -}; - -class PDF3D_U3D_TextureResourceBlock : public PDF3D_U3D_AbstractBlock -{ -public: - static constexpr uint32_t ID = PDF3D_U3D_Block_Info::BT_ResourceTexture; - virtual EBlockType getBlockType() const override { return static_cast(ID); } - - static PDF3D_U3D_AbstractBlockPtr parse(QByteArray data, QByteArray metaData, PDF3D_U3D_Parser* object); - - struct ContinuationImageFormat - { - bool isExternal() const { return attributes & 0x0001; } - - uint8_t compressionType = 0; - uint8_t channels = 0; - uint16_t attributes = 0; - uint32_t imageDataByteCount = 0; - uint32_t imageURLCount = 0; - QStringList imageURLs; - }; - - const QString& getResourceName() const; - uint32_t getTextureHeight() const; - uint32_t getTextureWidth() const; - uint8_t getType() const; - const std::vector& getFormats() const; - -private: - QString m_resourceName; - uint32_t m_textureHeight = 0; - uint32_t m_textureWidth = 0; - uint8_t m_type = 0; - std::vector m_formats; -}; - -class PDF3D_U3D_TextureContinuationResourceBlock : public PDF3D_U3D_AbstractBlock -{ -public: - static constexpr uint32_t ID = PDF3D_U3D_Block_Info::BT_ResourceTextureCont; - virtual EBlockType getBlockType() const override { return static_cast(ID); } - - static PDF3D_U3D_AbstractBlockPtr parse(QByteArray data, QByteArray metaData, PDF3D_U3D_Parser* object); - - const QString& getResourceName() const; - uint32_t getImageIndex() const; - const QByteArray& getImageData() const; - -private: - QString m_resourceName; - uint32_t m_imageIndex = 0; - QByteArray m_imageData; -}; - -class PDF3D_U3D_MotionResourceBlock : public PDF3D_U3D_AbstractBlock -{ -public: - static constexpr uint32_t ID = PDF3D_U3D_Block_Info::BT_ResourceMotion; - virtual EBlockType getBlockType() const override { return static_cast(ID); } - - static PDF3D_U3D_AbstractBlockPtr parse(QByteArray data, QByteArray metaData, PDF3D_U3D_Parser* object); - - struct KeyFrame - { - float time = 0.0; - PDF3D_U3D_Vec3 displacement = { }; - PDF3D_U3D_Vec4 rotation = { }; - PDF3D_U3D_Vec3 scale = { }; - - PDF3D_U3D_QuantizedVec1 timeDiff; - PDF3D_U3D_QuantizedVec3 displacementDiff; - PDF3D_U3D_QuantizedVec3 rotationDiff; - PDF3D_U3D_QuantizedVec3 scaleDiff; - }; - - struct Motion - { - QString trackName; - uint32_t timeCount = 0; - float displacementInverseQuant = 0.0; - float rotationInverseQuant = 0.0; - std::vector keyFrames; - }; - - const QString& getResourceName() const; - uint32_t getTrackCount() const; - float getTimeInverseQuant() const; - float getRotationInverseQuant() const; - const std::vector& getMotions() const; - -private: - QString m_resourceName; - uint32_t m_trackCount = 0; - float m_timeInverseQuant = 0.0f; - float m_rotationInverseQuant = 0.0f; - std::vector m_motions; -}; - // ------------------------------------------------------------------------------- // PDF3D_U3D // ------------------------------------------------------------------------------- @@ -1405,6 +90,67 @@ private: bool m_isBackVisible = true; }; +class PDF3D_U3D_LineSetGeometry; + +class PDF4QTLIBSHARED_EXPORT PDF3D_U3D_Geometry +{ +public: + PDF3D_U3D_Geometry() = default; + virtual ~PDF3D_U3D_Geometry() = default; + + virtual PDF3D_U3D_LineSetGeometry* asLineSetGeometry() { return nullptr; } + virtual const PDF3D_U3D_LineSetGeometry* asLineSetGeometry() const { return nullptr; } +}; + +class PDF4QTLIBSHARED_EXPORT PDF3D_U3D_LineSetGeometry : public PDF3D_U3D_Geometry +{ +public: + virtual PDF3D_U3D_LineSetGeometry* asLineSetGeometry() override { return this; } + virtual const PDF3D_U3D_LineSetGeometry* asLineSetGeometry() const override { return this; } + + struct Line + { + uint32_t shadingId = 0; + uint32_t position1 = 0; + uint32_t position2 = 0; + uint32_t normal1 = 0; + uint32_t normal2 = 0; + uint32_t diffuseColor1 = 0; + uint32_t diffuseColor2 = 0; + uint32_t specularColor1 = 0; + uint32_t specularColor2 = 0; + }; + + bool isEmpty() const { return m_positions.empty(); } + + QVector3D getPosition(size_t index) const { return index < m_positions.size() ? m_positions[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 getSpecularColor(size_t index) const { return index < m_specularColors.size() ? m_specularColors[index] : QVector4D(0, 0, 0, 0); } + + void addPosition(const QVector3D& position) { m_positions.emplace_back(position); } + void addNormal(const QVector3D& normal) { m_normals.emplace_back(normal); } + void addDiffuseColor(const QVector4D& color) { m_diffuseColors.emplace_back(color); } + void addSpecularColor(const QVector4D& color) { m_specularColors.emplace_back(color); } + void addLine(Line line); + + /// Returns all lines containing given vertex index + std::vector queryLinesByVertexIndex(size_t vertexIndex) const; + + size_t getPositionCount() const { return m_positions.size(); } + size_t getNormalCount() const { return m_normals.size(); } + size_t getDiffuseColorCount() const { return m_diffuseColors.size(); } + size_t getSpecularColorCount() const { return m_specularColors.size(); } + +private: + std::vector m_positions; + std::vector m_normals; + std::vector m_diffuseColors; + std::vector m_specularColors; + std::vector m_lines; + std::unordered_multimap m_mapPosIndexToLine; +}; + class PDF4QTLIBSHARED_EXPORT PDF3D_U3D_Light { public: @@ -1667,6 +413,9 @@ public: void setTextureResource(const QString& textureName, QImage texture); void setShaderResource(const QString& shaderName, PDF3D_U3D_Shader shader); void setMaterialResource(const QString& materialName, PDF3D_U3D_Material material); + void setGeometry(const QString& geometryName, QSharedPointer geometry); + + static PDF3D_U3D parse(const QByteArray& data, QStringList* errors); private: std::map m_sceneGraph; @@ -1675,273 +424,7 @@ private: std::map m_textureResources; std::map m_shaderResources; std::map m_materialResources; -}; - -// ------------------------------------------------------------------------------- -// READER OBJECTS -// ------------------------------------------------------------------------------- - -class PDF3D_U3D_ContextManager -{ -public: - bool isContextCompressed(uint32_t context) const; - bool isContextStaticAndCompressed(uint32_t context) const; - - uint32_t getTotalSymbolFrequency(uint32_t context) const; - uint32_t getSymbolFrequency(uint32_t context, uint32_t symbol) const; - uint32_t getCumulativeSymbolFrequency(uint32_t context, uint32_t symbol) const; - uint32_t getSymbolFromFrequency(uint32_t context, uint32_t symbolFrequency) const; - - void addSymbol(uint32_t context, uint32_t symbol); - -private: - struct ContextData - { - ContextData() - { - symbols= { { 0, Data{ 1, 1} } }; - } - - struct Data - { - uint32_t symbolCount = 0; - uint32_t cumulativeSymbolCount = 0; - }; - - std::map symbols; - }; - - const ContextData* getContextData(uint32_t context) const; - - std::map m_contexts; -}; - -class PDF3D_U3D_Constants -{ -public: - static constexpr uint32_t S_NOT_THREE_QUARTER_MASK = 0x00003FFF; - static constexpr uint32_t S_QUARTER_MASK = 0x00004000; - static constexpr uint32_t S_NOT_HALF_MASK = 0x00007FFF; - static constexpr uint32_t S_HALF_MASK = 0x00008000; - static constexpr uint32_t S_STATIC_FULL = 0x00000400; - static constexpr uint32_t S_MAX_RANGE = S_STATIC_FULL + 0x00003FFF; - static constexpr uint32_t S_CONTEXT_8 = 0; - - static constexpr uint32_t S_MAX_CUMULATIVE_SYMBOL_COUNT = 0x00001fff; - static constexpr uint32_t S_MAXIMUM_SYMBOL_IN_HISTOGRAM = 0x0000FFFF; -}; - -class PDF3D_U3D_Decoder -{ -public: - - void addBlock(const PDF3D_U3D_Block_Data& block) { m_blocks.push_back(block); } - - bool isEmpty() const { return m_blocks.empty(); } - - auto begin() const { return m_blocks.begin(); } - auto end() const { return m_blocks.end(); } - - auto front() const { return m_blocks.front(); } - auto back() const { return m_blocks.back(); } - - auto size() const { return m_blocks.size(); } - -private: - std::vector m_blocks; -}; - -class PDF3D_U3D_DecoderChain -{ -public: - - const QString& getName() const; - void setName(const QString& newName); - - PDF3D_U3D_Decoder* getDecoder(uint32_t chainPosition); - void addDecoder(PDF3D_U3D_Decoder&& decoder) { m_decoders.emplace_back(std::move(decoder)); } - - auto begin() const { return m_decoders.begin(); } - auto end() const { return m_decoders.end(); } - -private: - QString m_name; - std::vector m_decoders; -}; - -class PDF3D_U3D_DecoderPalette -{ -public: - - PDF3D_U3D_DecoderChain* getDecoderChain(const QString& name); - PDF3D_U3D_DecoderChain* createDecoderChain(const QString& name); - - auto begin() const { return m_decoderChains.begin(); } - auto end() const { return m_decoderChains.end(); } - -private: - std::vector m_decoderChains; -}; - -class PDF3D_U3D_DecoderPalettes -{ -public: - using EPalette = PDF3D_U3D_Block_Info::EPalette; - - PDF3D_U3D_DecoderPalette* getDecoderPalette(EPalette palette); - - auto begin() const { return m_decoderLists.begin(); } - auto end() const { return m_decoderLists.end(); } - -private: - std::array m_decoderLists; -}; - -class PDF4QTLIBSHARED_EXPORT PDF3D_U3D_Parser -{ -public: - PDF3D_U3D_Parser(); - - PDF3D_U3D parse(QByteArray data); - - void processBlock(const PDF3D_U3D_Block_Data& blockData, PDF3D_U3D_Block_Info::EPalette palette); - void processModifierBlock(const PDF3D_U3D_Block_Data& blockData); - void processGenericBlock(const PDF3D_U3D_Block_Data& blockData, PDF3D_U3D_Block_Info::EPalette palette); - - bool isCompressed() const { return m_isCompressed; } - QTextCodec* getTextCodec() const { return m_textCodec; } - - PDF3D_U3D_AbstractBlockPtr parseBlock(uint32_t blockType, const QByteArray& data, const QByteArray& metaData); - PDF3D_U3D_AbstractBlockPtr parseBlock(const PDF3D_U3D_Block_Data& data); - - static uint32_t getBlockPadding(uint32_t blockSize); - - static PDF3D_U3D_Block_Data readBlockData(PDF3D_U3D_DataReader& reader); - - void processCLODMesh(const PDF3D_U3D_Decoder& decoder); - void processPointSet(const PDF3D_U3D_Decoder& decoder); - void processLineSet(const PDF3D_U3D_Decoder& decoder); - void processTexture(const PDF3D_U3D_Decoder& decoder); - - void addBlockToU3D(PDF3D_U3D_AbstractBlockPtr block); - -private: - struct LoadBlockInfo - { - QString typeName; - bool success = false; - PDF3D_U3D_Block_Info::EBlockType blockType = PDF3D_U3D_Block_Info::EBlockType(); - uint32_t dataSize = 0; - uint32_t metaDataSize = 0; - PDF3D_U3D_AbstractBlockPtr block; - }; - - std::vector m_blocks; - std::vector m_allBlocks; - - QStringList m_errors; - PDF3D_U3D_DecoderPalettes m_decoderPalettes; - PDF3D_U3D m_object; - PDF3D_U3D_AbstractBlockPtr m_fileBlock; - QTextCodec* m_textCodec = nullptr; - bool m_isCompressed = true; - uint32_t m_priority = 0; -}; - -class PDF3D_U3D_DataReader -{ -public: - PDF3D_U3D_DataReader(QByteArray data, bool isCompressed); - ~PDF3D_U3D_DataReader(); - - void setData(QByteArray data); - - static constexpr uint32_t getRangeContext(uint32_t value) { return value + PDF3D_U3D_Constants::S_STATIC_FULL; } - static constexpr uint32_t getStaticContext(uint32_t value) { return value; } - - uint8_t readU8(); - uint16_t readU16(); - uint32_t readU32(); - uint64_t readU64(); - int16_t readI16(); - int32_t readI32(); - float readF32(); - double readF64(); - - uint8_t readCompressedU8(uint32_t context); - uint16_t readCompressedU16(uint32_t context); - uint32_t readCompressedU32(uint32_t context); - - QByteArray readByteArray(uint32_t size); - QByteArray readRemainingData(); - void skipBytes(uint32_t size); - void padTo32Bits(); - - QUuid readUuid(); - QString readString(QTextCodec* textCodec); - QStringList readStringList(uint32_t count, QTextCodec* textCodec); - - QMatrix4x4 readMatrix4x4(); - - PDF3D_U3D_QuantizedVec1 readQuantizedVec1(uint32_t contextSign, - uint32_t context1); - - PDF3D_U3D_QuantizedVec4 readQuantizedVec4(uint32_t contextSign, - uint32_t context1, - uint32_t context2, - uint32_t context3, - uint32_t context4); - - PDF3D_U3D_QuantizedVec3 readQuantizedVec3(uint32_t contextSign, - uint32_t context1, - uint32_t context2, - uint32_t context3); - - std::vector readShadingDescriptions(uint32_t count); - std::vector readBoneDescriptions(QTextCodec* textCodec, uint32_t count); - - bool isAtEnd() const; - - template - void readFloats32(T& container) - { - for (auto& value : container) - { - value = readF32(); - } - } - - template - std::vector readVectorFloats32(uint32_t count) - { - std::vector result; - result.reserve(count); - - for (uint32_t i = 0; i < count; ++i) - { - T value = T(); - readFloats32(value); - result.emplace_back(std::move(value)); - } - - return result; - } - -private: - uint32_t readSymbol(uint32_t context); - uint8_t swapBits8(uint8_t source); - uint32_t readBit(); - uint32_t read15Bits(); - - QByteArray m_data; - PDF3D_U3D_ContextManager m_contextManager; - - uint32_t m_high; - uint32_t m_low; - uint32_t m_underflow; - uint32_t m_code; - uint32_t m_position; - bool m_isCompressed; + std::map> m_geometries; }; } // namespace u3d diff --git a/Pdf4QtViewer/pdfmediaviewerdialog.cpp b/Pdf4QtViewer/pdfmediaviewerdialog.cpp index 0638c66..20db698 100644 --- a/Pdf4QtViewer/pdfmediaviewerdialog.cpp +++ b/Pdf4QtViewer/pdfmediaviewerdialog.cpp @@ -207,8 +207,8 @@ void PDFMediaViewerDialog::initFrom3DAnnotation(const pdf::PDFDocument* document f.close(); }*/ - pdf::u3d::PDF3D_U3D_Parser parser; - pdf::u3d::PDF3D_U3D u3d = parser.parse(data); + QStringList errors; + pdf::u3d::PDF3D_U3D u3d = pdf::u3d::PDF3D_U3D::parse(data, &errors); break; }