diff --git a/Pdf4QtLib/sources/pdf3d_u3d.cpp b/Pdf4QtLib/sources/pdf3d_u3d.cpp index 31c2d5b..1e45683 100644 --- a/Pdf4QtLib/sources/pdf3d_u3d.cpp +++ b/Pdf4QtLib/sources/pdf3d_u3d.cpp @@ -245,6 +245,60 @@ QStringList PDF3D_U3D_DataReader::readStringList(uint32_t count, QTextCodec* tex return stringList; } +PDF3D_U3D_QuantizedVec4 PDF3D_U3D_DataReader::readQuantizedVec4(uint32_t contextSign, + uint32_t context1, + uint32_t context2, + uint32_t context3, + uint32_t context4) +{ + PDF3D_U3D_QuantizedVec4 result; + + result.signBits = readCompressedU8(contextSign); + result.diff1 = readCompressedU32(context1); + result.diff2 = readCompressedU32(context2); + result.diff3 = readCompressedU32(context3); + result.diff4 = readCompressedU32(context4); + + return result; +} + +PDF3D_U3D_QuantizedVec3 PDF3D_U3D_DataReader::readQuantizedVec3(uint32_t contextSign, + uint32_t context1, + uint32_t context2, + uint32_t context3) +{ + PDF3D_U3D_QuantizedVec3 result; + + result.signBits = readCompressedU8(contextSign); + result.diff1 = readCompressedU32(context1); + result.diff2 = readCompressedU32(context2); + result.diff3 = readCompressedU32(context3); + + return result; +} + +std::vector PDF3D_U3D_DataReader::readShadingDescriptions(uint32_t count) +{ + std::vector result; + + for (uint32_t i = 0; i < count; ++i) + { + PDF3D_U3D_ShadingDescription item; + + item.shadingAttributes = readU32(); + item.textureLayerCount = readU32(); + for (uint32_t j = 0; j < item.textureLayerCount; ++j) + { + item.textureCoordDimensions.push_back(readU32()); + } + item.originalShading = readU32(); + + result.emplace_back(std::move(item)); + } + + return result; +} + bool PDF3D_U3D_DataReader::isAtEnd() const { return m_position >= uint32_t(m_data.size()) * 8; @@ -505,7 +559,7 @@ void PDF3D_U3D_ContextManager::addSymbol(uint32_t context, uint32_t symbol) { it = contextData.symbols.insert(std::make_pair(symbol, ContextData::Data())).first; - if (it != contextData.symbols.cend()) + if (std::next(it) != contextData.symbols.cend()) { it->second.cumulativeSymbolCount = std::next(it)->second.cumulativeSymbolCount; } @@ -559,7 +613,8 @@ PDF3D_U3D_AbstractBlockPtr PDF3D_U3D::parseBlockWithDeclaration(PDF3D_U3D_DataRe info.blockType = blockType; info.dataSize = dataSize; info.metaDataSize = metaDataSize; - m_blockLoadFails.push_back(info); + info.block = block; + m_allBlocks.push_back(info); return block; } @@ -580,36 +635,33 @@ PDF3D_U3D PDF3D_U3D::parse(QByteArray data) return object; } -const PDF3D_U3D_CLODMeshDeclarationBlock* PDF3D_U3D::getCLODMeshDeclarationBlock(const QString& meshName) const +template +const T* PDF3D_U3D::getBlock(const QString& name) const { - for (const auto& block : m_blocks) + for (const auto& block : m_allBlocks) { - if (auto typedBlock = dynamic_cast(block.data())) + if (auto typedBlock = dynamic_cast(block.block.data())) { - if (typedBlock->getMeshName() == meshName) + if (typedBlock->getName() == name) { return typedBlock; } } - - if (auto typedBlock = dynamic_cast(block.data())) - { - for (const auto& modifierChainChildBlock : typedBlock->getModifierDeclarationBlocks()) - { - if (auto modifierChainChildTypedBlock = dynamic_cast(modifierChainChildBlock.data())) - { - if (modifierChainChildTypedBlock->getMeshName() == meshName) - { - return modifierChainChildTypedBlock; - } - } - } - } } return nullptr; } +const PDF3D_U3D_CLODMeshDeclarationBlock* PDF3D_U3D::getCLODMeshDeclarationBlock(const QString& meshName) const +{ + return getBlock(meshName); +} + +const PDF3D_U3D_LineSetDeclarationBlock* PDF3D_U3D::getLineSetDeclarationBlock(const QString& lineSetName) const +{ + return getBlock(lineSetName); +} + PDF3D_U3D_AbstractBlockPtr PDF3D_U3D::parseBlock(uint32_t blockType, const QByteArray& data, const QByteArray& metaData) @@ -666,6 +718,12 @@ PDF3D_U3D_AbstractBlockPtr PDF3D_U3D::parseBlock(uint32_t blockType, case PDF3D_U3D_CLODBaseMeshContinuationBlock::ID: return PDF3D_U3D_CLODBaseMeshContinuationBlock::parse(data, metaData, this); + case PDF3D_U3D_LineSetDeclarationBlock::ID: + return PDF3D_U3D_LineSetDeclarationBlock::parse(data, metaData, this); + + case PDF3D_U3D_LineSetContinuationBlock::ID: + return PDF3D_U3D_LineSetContinuationBlock::parse(data, metaData, this); + default: break; } @@ -1360,22 +1418,7 @@ PDF3D_U3D_AbstractBlockPtr PDF3D_U3D_CLODMeshDeclarationBlock::parse(QByteArray block->m_diffuseColorCount = reader.readU32(); block->m_specularColorCount = reader.readU32(); block->m_textureColorCount = reader.readU32(); - block->m_shadingCount = reader.readU32(); - - for (uint32_t i = 0; i < block->m_shadingCount; ++i) - { - ShadingDescription item; - - item.shadingAttributes = reader.readU32(); - item.textureLayerCount = reader.readU32(); - for (uint32_t j = 0; j < item.textureLayerCount; ++j) - { - item.textureCoordDimensions.push_back(reader.readU32()); - } - item.originalShading = reader.readU32(); - - block->m_shadingDescription.emplace_back(std::move(item)); - } + block->m_shadingDescription = reader.readShadingDescriptions(reader.readU32()); /* clod description */ block->m_minimumResolution = reader.readU32(); @@ -1485,12 +1528,7 @@ uint32_t PDF3D_U3D_CLODMeshDeclarationBlock::getTextureColorCount() const return m_textureColorCount; } -uint32_t PDF3D_U3D_CLODMeshDeclarationBlock::getShadingCount() const -{ - return m_shadingCount; -} - -const std::vector& PDF3D_U3D_CLODMeshDeclarationBlock::getShadingDescription() const +const std::vector& PDF3D_U3D_CLODMeshDeclarationBlock::getShadingDescription() const { return m_shadingDescription; } @@ -1605,7 +1643,7 @@ PDF3D_U3D_AbstractBlockPtr PDF3D_U3D_CLODBaseMeshContinuationBlock::parse(QByteA BaseFace face; face.m_shadingId = reader.readCompressedU32(reader.getStaticContext(cShading)); - const PDF3D_U3D_CLODMeshDeclarationBlock::ShadingDescription* shadingDescription = declarationBlock->getShadingDescriptionItem(face.m_shadingId); + const PDF3D_U3D_ShadingDescription* shadingDescription = declarationBlock->getShadingDescriptionItem(face.m_shadingId); if (!shadingDescription) { return nullptr; @@ -1648,6 +1686,401 @@ PDF3D_U3D_AbstractBlockPtr PDF3D_U3D_CLODBaseMeshContinuationBlock::parse(QByteA return pointer; } +uint32_t PDF3D_U3D_CLODBaseMeshContinuationBlock::getFaceCount() const +{ + return m_faceCount; +} + +uint32_t PDF3D_U3D_CLODBaseMeshContinuationBlock::getPositionCount() const +{ + return m_positionCount; +} + +uint32_t PDF3D_U3D_CLODBaseMeshContinuationBlock::getNormalCount() const +{ + return m_normalCount; +} + +uint32_t PDF3D_U3D_CLODBaseMeshContinuationBlock::getDiffuseColorCount() const +{ + return m_diffuseColorCount; +} + +uint32_t PDF3D_U3D_CLODBaseMeshContinuationBlock::getSpecularColorCount() const +{ + return m_specularColorCount; +} + +uint32_t PDF3D_U3D_CLODBaseMeshContinuationBlock::getTextureColorCount() const +{ + return m_textureColorCount; +} + +const std::vector& PDF3D_U3D_CLODBaseMeshContinuationBlock::getBasePositions() const +{ + return m_basePositions; +} + +const std::vector& PDF3D_U3D_CLODBaseMeshContinuationBlock::getBaseNormals() const +{ + return m_baseNormals; +} + +const std::vector& PDF3D_U3D_CLODBaseMeshContinuationBlock::getBaseDiffuseColors() const +{ + return m_baseDiffuseColors; +} + +const std::vector& PDF3D_U3D_CLODBaseMeshContinuationBlock::getBaseSpecularColors() const +{ + return m_baseSpecularColors; +} + +const std::vector& PDF3D_U3D_CLODBaseMeshContinuationBlock::getBaseTextureCoords() const +{ + return m_baseTextureCoords; +} + +const std::vector& PDF3D_U3D_CLODBaseMeshContinuationBlock::getBaseFaces() const +{ + return m_baseFaces; +} + +PDF3D_U3D_AbstractBlockPtr PDF3D_U3D_CLODProgressiveMeshContinuationBlock::parse(QByteArray data, QByteArray metaData, PDF3D_U3D* object) +{ + PDF3D_U3D_CLODProgressiveMeshContinuationBlock* block = new PDF3D_U3D_CLODProgressiveMeshContinuationBlock(); + PDF3D_U3D_AbstractBlockPtr pointer(block); + + PDF3D_U3D_DataReader reader(data, object->isCompressed()); + + // TODO: finish this block + return nullptr; + + // Read the data + block->m_meshName = reader.readString(object->getTextCodec()); + block->m_chainIndex = reader.readU32(); + + block->m_startResolution = reader.readU32(); + block->m_endResolution = reader.readU32(); + + if (block->m_endResolution < block->m_startResolution) + { + // Error - bad resolution + return nullptr; + } + + block->m_resolutionUpdateCount = block->m_endResolution - block->m_startResolution; + uint32_t rCurrentPositionCount = block->m_startResolution; + + for (uint32_t i = 0; i < block->m_resolutionUpdateCount; ++i) + { + ResolutionUpdate updateItem; + ++rCurrentPositionCount; + + if (i == 0) + { + updateItem.splitPositionIndex = reader.readCompressedU32(reader.getStaticContext(cZero)); + } + else + { + updateItem.splitPositionIndex = reader.readCompressedU32(reader.getRangeContext(i)); + } + + // Read diffuse color info + uint16_t newDiffuseColors = reader.readCompressedU16(reader.getStaticContext(cDiffuseCount)); + for (uint16_t i = 0; i < newDiffuseColors; ++i) + { + auto colorDiffInfo = reader.readQuantizedVec4(reader.getStaticContext(cDiffuseColorSign), + reader.getStaticContext(cColorDiffR), + reader.getStaticContext(cColorDiffG), + reader.getStaticContext(cColorDiffB), + reader.getStaticContext(cColorDiffA)); + updateItem.newDiffuseColors.emplace_back(colorDiffInfo); + } + + // Read specular color info + uint16_t newSpecularColors = reader.readCompressedU16(reader.getStaticContext(cSpecularCount)); + for (uint16_t i = 0; i < newSpecularColors; ++i) + { + auto colorSpecularInfo = reader.readQuantizedVec4(reader.getStaticContext(cSpecularColorSign), + reader.getStaticContext(cColorDiffR), + reader.getStaticContext(cColorDiffG), + reader.getStaticContext(cColorDiffB), + reader.getStaticContext(cColorDiffA)); + updateItem.newSpecularColors.emplace_back(colorSpecularInfo); + } + + // Read texture coordinates + uint16_t newTextureCoords = reader.readCompressedU16(reader.getStaticContext(cTexCoordCount)); + for (uint16_t i = 0; i < newTextureCoords; ++i) + { + auto textureCoordsInfo = reader.readQuantizedVec4(reader.getStaticContext(cTexCoordSign), + reader.getStaticContext(cTexCDiffU), + reader.getStaticContext(cTexCDiffV), + reader.getStaticContext(cTexCDiffS), + reader.getStaticContext(cTexCDiffT)); + updateItem.newTextureCoords.emplace_back(textureCoordsInfo); + } + + const uint32_t newFaceCount = reader.readCompressedU32(reader.getStaticContext(cFaceCnt)); + for (uint32_t i = 0; i < newFaceCount; ++i) + { + NewFacePositionInfo facePositionInfo; + + facePositionInfo.shadingId = reader.readCompressedU32(reader.getStaticContext(cShading)); + facePositionInfo.faceOrientation = reader.readCompressedU8(reader.getStaticContext(cFaceOrnt)); + facePositionInfo.thirdPositionType = reader.readCompressedU8(reader.getStaticContext(cThrdPosType)); + + if (facePositionInfo.thirdPositionType & 0x01) + { + facePositionInfo.localThirdPositionIndex = reader.readCompressedU32(reader.getStaticContext(cLocal3rdPos)); + } + else + { + facePositionInfo.globalThirdPositionIndex = reader.readCompressedU32(reader.getRangeContext(rCurrentPositionCount)); + } + + updateItem.newFaces.emplace_back(std::move(facePositionInfo)); + } + + block->m_resolutionUpdates.emplace_back(std::move(updateItem)); + } + + block->parseMetadata(metaData, object); + return pointer; +} + +PDF3D_U3D_AbstractBlockPtr PDF3D_U3D_LineSetDeclarationBlock::parse(QByteArray data, QByteArray metaData, PDF3D_U3D* object) +{ + PDF3D_U3D_LineSetDeclarationBlock* block = new PDF3D_U3D_LineSetDeclarationBlock(); + PDF3D_U3D_AbstractBlockPtr pointer(block); + + PDF3D_U3D_DataReader reader(data, object->isCompressed()); + + // Read the data + block->m_lineSetName = reader.readString(object->getTextCodec()); + block->m_chainIndex = reader.readU32(); + + // line set description + block->m_lineSetReserved = reader.readU32(); + block->m_lineCount = reader.readU32(); + block->m_positionCount = reader.readU32(); + block->m_normalCount = reader.readU32(); + block->m_diffuseColorCount = reader.readU32(); + block->m_specularColorCount = reader.readU32(); + block->m_textureCoordCount = reader.readU32(); + block->m_shadingDescriptions = reader.readShadingDescriptions(reader.readU32()); + + // resource description + block->m_positionQualityFactor = reader.readU32(); + block->m_normalQualityFactor = reader.readU32(); + block->m_textureCoordQualityFactor = reader.readU32(); + block->m_positionInverseQuant = reader.readF32(); + block->m_normalInverseQuant = reader.readF32(); + block->m_textureCoordInverseQuant = reader.readF32(); + block->m_diffuseColorInverseQuant = reader.readF32(); + block->m_specularColorInverseQuant = reader.readF32(); + block->m_reserved1 = reader.readF32(); + block->m_reserved2 = reader.readF32(); + block->m_reserved3 = reader.readF32(); + + block->parseMetadata(metaData, object); + return pointer; +} + +uint32_t PDF3D_U3D_LineSetDeclarationBlock::getLineCount() const +{ + return m_lineCount; +} + +uint32_t PDF3D_U3D_LineSetDeclarationBlock::getPositionCount() const +{ + return m_positionCount; +} + +uint32_t PDF3D_U3D_LineSetDeclarationBlock::getNormalCount() const +{ + return m_normalCount; +} + +uint32_t PDF3D_U3D_LineSetDeclarationBlock::getDiffuseColorCount() const +{ + return m_diffuseColorCount; +} + +uint32_t PDF3D_U3D_LineSetDeclarationBlock::getSpecularColorCount() const +{ + return m_specularColorCount; +} + +uint32_t PDF3D_U3D_LineSetDeclarationBlock::getTextureCoordCount() const +{ + return m_textureCoordCount; +} + +const std::vector& PDF3D_U3D_LineSetDeclarationBlock::getShadingDescriptions() const +{ + return m_shadingDescriptions; +} + +uint32_t PDF3D_U3D_LineSetDeclarationBlock::getPositionQualityFactor() const +{ + return m_positionQualityFactor; +} + +uint32_t PDF3D_U3D_LineSetDeclarationBlock::getNormalQualityFactor() const +{ + return m_normalQualityFactor; +} + +uint32_t PDF3D_U3D_LineSetDeclarationBlock::getTextureCoordQualityFactor() const +{ + return m_textureCoordQualityFactor; +} + +float PDF3D_U3D_LineSetDeclarationBlock::getPositionInverseQuant() const +{ + return m_positionInverseQuant; +} + +float PDF3D_U3D_LineSetDeclarationBlock::getNormalInverseQuant() const +{ + return m_normalInverseQuant; +} + +float PDF3D_U3D_LineSetDeclarationBlock::getTextureCoordInverseQuant() const +{ + return m_textureCoordInverseQuant; +} + +float PDF3D_U3D_LineSetDeclarationBlock::getDiffuseColorInverseQuant() const +{ + return m_diffuseColorInverseQuant; +} + +float PDF3D_U3D_LineSetDeclarationBlock::getSpecularColorInverseQuant() const +{ + return m_specularColorInverseQuant; +} + +PDF3D_U3D_AbstractBlockPtr PDF3D_U3D_LineSetContinuationBlock::parse(QByteArray data, QByteArray metaData, PDF3D_U3D* object) +{ + PDF3D_U3D_LineSetContinuationBlock* block = new PDF3D_U3D_LineSetContinuationBlock(); + PDF3D_U3D_AbstractBlockPtr pointer(block); + + PDF3D_U3D_DataReader reader(data, object->isCompressed()); + + // Read the data + block->m_lineSetName = reader.readString(object->getTextCodec()); + block->m_chainIndex = reader.readU32(); + + block->m_startResolution = reader.readU32(); + block->m_endResolution = reader.readU32(); + + if (auto declarationBlock = object->getLineSetDeclarationBlock(block->m_lineSetName)) + { + for (uint32_t i = block->m_startResolution; i < block->m_endResolution; ++i) + { + UpdateItem item; + item.splitPositionIndex = reader.readCompressedU32(reader.getRangeContext(qMax(i, 1u))); + item.newPositionInfo = reader.readQuantizedVec3(reader.getStaticContext(cPosDiffSign), + reader.getStaticContext(cPosDiffX), + reader.getStaticContext(cPosDiffY), + reader.getStaticContext(cPosDiffZ)); + + const uint32_t newNormalCount = reader.readCompressedU32(reader.getStaticContext(cNormlCnt)); + for (uint32_t ni = 0; ni < newNormalCount; ++ni) + { + item.newNormals.push_back(reader.readQuantizedVec3(reader.getStaticContext(cDiffNormalSign), + reader.getStaticContext(cDiffNormalX), + reader.getStaticContext(cDiffNormalY), + reader.getStaticContext(cDiffNormalZ))); + } + + const uint32_t newLineCount = reader.readCompressedU32(reader.getStaticContext(cLineCnt)); + for (uint32_t li = 0; li < newLineCount; ++li) + { + NewLineInfo lineInfo; + + lineInfo.shadingId = reader.readCompressedU32(reader.getStaticContext(cShading)); + lineInfo.firstPositionIndex = reader.readCompressedU32(reader.getRangeContext(i)); + + const PDF3D_U3D_ShadingDescription* shadingDescription = declarationBlock->getShadingDescriptionItem(lineInfo.shadingId); + if (!shadingDescription) + { + return nullptr; + } + + for (NewLineEndingInfo* endingInfo : { &lineInfo.p1, &lineInfo.p2 }) + { + endingInfo->normalLocalIndex = reader.readCompressedU32(reader.getStaticContext(cNormlIdx)); + + if (shadingDescription->hasDiffuseColors()) + { + endingInfo->duplicateDiffuse = reader.readCompressedU8(reader.getStaticContext(cDiffDup)) & 0x02; + + if (!endingInfo->duplicateDiffuse) + { + endingInfo->diffuseColor = reader.readQuantizedVec4(reader.getStaticContext(cDiffuseColorSign), + reader.getStaticContext(cColorDiffR), + reader.getStaticContext(cColorDiffG), + reader.getStaticContext(cColorDiffB), + reader.getStaticContext(cColorDiffA)); + } + } + + if (shadingDescription->hasSpecularColors()) + { + endingInfo->duplicateSpecular = reader.readCompressedU8(reader.getStaticContext(cSpecDup)) & 0x02; + + if (!endingInfo->duplicateSpecular) + { + endingInfo->specularColor = reader.readQuantizedVec4(reader.getStaticContext(cSpecularColorSign), + reader.getStaticContext(cColorDiffR), + reader.getStaticContext(cColorDiffG), + reader.getStaticContext(cColorDiffB), + reader.getStaticContext(cColorDiffA)); + } + } + + for (uint32_t ti = 0; ti < shadingDescription->textureLayerCount; ++ti) + { + PDF3D_U3D_QuantizedVec4 textCoord = { }; + const bool duplicateTextCoord = reader.readCompressedU8(reader.getStaticContext(cTexCDup)) & 0x02; + + if (!duplicateTextCoord) + { + textCoord = reader.readQuantizedVec4(reader.getStaticContext(cTexCoordSign), + reader.getStaticContext(cTexCDiffU), + reader.getStaticContext(cTexCDiffV), + reader.getStaticContext(cTexCDiffS), + reader.getStaticContext(cTexCDiffT)); + } + + endingInfo->textureCoords.emplace_back(duplicateTextCoord, textCoord); + } + } + + item.newLines.emplace_back(std::move(lineInfo)); + } + + block->m_updateItems.emplace_back(std::move(item)); + } + } + else + { + return nullptr; + } + + block->parseMetadata(metaData, object); + return pointer; +} + +const std::vector& PDF3D_U3D_LineSetContinuationBlock::updateItems() const +{ + return m_updateItems; +} + } // namespace u3d } // namespace pdf diff --git a/Pdf4QtLib/sources/pdf3d_u3d.h b/Pdf4QtLib/sources/pdf3d_u3d.h index df2cc1f..5330d13 100644 --- a/Pdf4QtLib/sources/pdf3d_u3d.h +++ b/Pdf4QtLib/sources/pdf3d_u3d.h @@ -44,6 +44,34 @@ 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_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: @@ -389,17 +417,6 @@ public: static PDF3D_U3D_AbstractBlockPtr parse(QByteArray data, QByteArray metaData, PDF3D_U3D* object); - struct 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; } - }; - struct BoneJoint { float jointCenterU = 0.0; @@ -427,6 +444,7 @@ public: bool isJointPresent() const { return boneAttributes & 0x00000002; } }; + const QString& getName() const { return getMeshName(); } const QString& getMeshName() const; uint32_t getChainIndex() const; @@ -441,8 +459,8 @@ public: uint32_t getSpecularColorCount() const; uint32_t getTextureColorCount() const; uint32_t getShadingCount() const; - const std::vector& getShadingDescription() const; - const ShadingDescription* getShadingDescriptionItem(uint32_t index) const { return index < m_shadingDescription.size() ? &m_shadingDescription[index] : nullptr; } + 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; @@ -477,8 +495,7 @@ private: uint32_t m_diffuseColorCount = 0; uint32_t m_specularColorCount = 0; uint32_t m_textureColorCount = 0; - uint32_t m_shadingCount = 0; - std::vector m_shadingDescription; + std::vector m_shadingDescription; /* clod description */ uint32_t m_minimumResolution = 0; @@ -527,6 +544,20 @@ public: 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: enum Context { @@ -552,6 +583,203 @@ private: std::vector m_baseFaces; }; +class PDF3D_U3D_CLODProgressiveMeshContinuationBlock : public PDF3D_U3D_AbstractBlock +{ +public: + static constexpr uint32_t ID = 0xFFFFFF3C; + + static PDF3D_U3D_AbstractBlockPtr parse(QByteArray data, QByteArray metaData, PDF3D_U3D* 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: + enum Context + { + cZero = 1, + cDiffuseCount, + cDiffuseColorSign, + cColorDiffR, + cColorDiffG, + cColorDiffB, + cColorDiffA, + cSpecularCount, + cSpecularColorSign, + cTexCoordCount, + cTexCoordSign, + cTexCDiffU, + cTexCDiffV, + cTexCDiffS, + cTexCDiffT, + cFaceCnt, + cShading, + cFaceOrnt, + cLocal3rdPos, + cThrdPosType + }; + + 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_LineSetDeclarationBlock : public PDF3D_U3D_AbstractBlock +{ +public: + static constexpr uint32_t ID = 0xFFFFFF37; + + static PDF3D_U3D_AbstractBlockPtr parse(QByteArray data, QByteArray metaData, PDF3D_U3D* 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 = 0xFFFFFF3F; + + static PDF3D_U3D_AbstractBlockPtr parse(QByteArray data, QByteArray metaData, PDF3D_U3D* object); + + 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& updateItems() const; + +private: + + enum Context + { + cPosDiffSign = 1, + cPosDiffX, + cPosDiffY, + cPosDiffZ, + cNormlCnt, + cDiffNormalSign, + cDiffNormalX, + cDiffNormalY, + cDiffNormalZ, + cLineCnt, + cShading, + cNormlIdx, + cDiffDup, + cDiffuseColorSign, + cColorDiffR, + cColorDiffG, + cColorDiffB, + cColorDiffA, + cSpecDup, + cSpecularColorSign, + cTexCDup, + cTexCoordSign, + cTexCDiffU, + cTexCDiffV, + cTexCDiffS, + cTexCDiffT + }; + + QString m_lineSetName; + uint32_t m_chainIndex = 0; + + uint32_t m_startResolution = 0; + uint32_t m_endResolution = 0; + + std::vector m_updateItems; +}; + // ------------------------------------------------------------------------------- // PDF3D_U3D // ------------------------------------------------------------------------------- @@ -567,6 +795,10 @@ public: static PDF3D_U3D parse(QByteArray data); const PDF3D_U3D_CLODMeshDeclarationBlock* getCLODMeshDeclarationBlock(const QString& meshName) const; + const PDF3D_U3D_LineSetDeclarationBlock* getLineSetDeclarationBlock(const QString& lineSetName) const; + + template + const T* getBlock(const QString& name) const; PDF3D_U3D_AbstractBlockPtr parseBlockWithDeclaration(PDF3D_U3D_DataReader& reader); @@ -581,10 +813,11 @@ private: uint32_t blockType = 0; uint32_t dataSize = 0; uint32_t metaDataSize = 0; + PDF3D_U3D_AbstractBlockPtr block; }; std::vector m_blocks; - std::vector m_blockLoadFails; + std::vector m_allBlocks; const PDF3D_U3D_FileBlock* m_fileBlock = nullptr; QTextCodec* m_textCodec = nullptr; bool m_isCompressed = true; @@ -677,6 +910,19 @@ public: QString readString(QTextCodec* textCodec); QStringList readStringList(uint32_t count, QTextCodec* textCodec); + 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); + bool isAtEnd() const; template