diff --git a/Pdf4QtLib/sources/pdf3d_u3d.cpp b/Pdf4QtLib/sources/pdf3d_u3d.cpp index 423477b..50f5a37 100644 --- a/Pdf4QtLib/sources/pdf3d_u3d.cpp +++ b/Pdf4QtLib/sources/pdf3d_u3d.cpp @@ -29,7 +29,7 @@ namespace u3d PDF3D_U3D_DataReader::PDF3D_U3D_DataReader(QByteArray data, bool isCompressed, PDF3D_U3D_ContextManager* contextManager) : m_data(std::move(data)), - m_contextManager(contextManager), + m_contextManager(), m_high(0x0000FFFF), m_low(0), m_underflow(0), @@ -107,7 +107,7 @@ double PDF3D_U3D_DataReader::readF64() uint8_t PDF3D_U3D_DataReader::readCompressedU8(uint32_t context) { - if (m_isCompressed && m_contextManager->isContextCompressed(context)) + if (m_isCompressed && m_contextManager.isContextCompressed(context)) { const uint32_t symbol = readSymbol(context); if (symbol != 0) @@ -119,7 +119,7 @@ uint8_t PDF3D_U3D_DataReader::readCompressedU8(uint32_t context) { // New symbol const uint32_t value = readU8(); - m_contextManager->addSymbol(context, value + 1); + m_contextManager.addSymbol(context, value + 1); return value; } } @@ -129,7 +129,7 @@ uint8_t PDF3D_U3D_DataReader::readCompressedU8(uint32_t context) uint16_t PDF3D_U3D_DataReader::readCompressedU16(uint32_t context) { - if (m_isCompressed && m_contextManager->isContextCompressed(context)) + if (m_isCompressed && m_contextManager.isContextCompressed(context)) { const uint32_t symbol = readSymbol(context); if (symbol != 0) @@ -141,7 +141,7 @@ uint16_t PDF3D_U3D_DataReader::readCompressedU16(uint32_t context) { // New symbol const uint32_t value = readU16(); - m_contextManager->addSymbol(context, value + 1); + m_contextManager.addSymbol(context, value + 1); return value; } } @@ -151,7 +151,7 @@ uint16_t PDF3D_U3D_DataReader::readCompressedU16(uint32_t context) uint32_t PDF3D_U3D_DataReader::readCompressedU32(uint32_t context) { - if (m_isCompressed && m_contextManager->isContextCompressed(context)) + if (m_isCompressed && m_contextManager.isContextCompressed(context)) { const uint32_t symbol = readSymbol(context); if (symbol != 0) @@ -163,7 +163,7 @@ uint32_t PDF3D_U3D_DataReader::readCompressedU32(uint32_t context) { // New symbol const uint32_t value = readU32(); - m_contextManager->addSymbol(context, value + 1); + m_contextManager.addSymbol(context, value + 1); return value; } } @@ -300,6 +300,53 @@ std::vector PDF3D_U3D_DataReader::readShadingDescr return result; } +std::vector PDF3D_U3D_DataReader::readBoneDescriptions(QTextCodec* textCodec, uint32_t count) +{ + std::vector result; + + for (uint32_t i = 0; i < count; ++i) + { + PDF3D_U3D_BoneDescription item; + + item.boneName = readString(textCodec); + item.parentBoneName = readString(textCodec); + item.boneAttributes = readU32(); + item.boneLength = readF32(); + readFloats32(item.boneDisplacement); + readFloats32(item.boneOrientation); + + if (item.isLinkPresent()) + { + item.boneLinkCount = readU32(); + item.boneLinkLength = readF32(); + } + + if (item.isJointPresent()) + { + item.startJoint.jointCenterU = readF32(); + item.startJoint.jointCenterV = readF32(); + item.startJoint.jointScaleU = readF32(); + item.startJoint.jointScaleV = readF32(); + + item.endJoint.jointCenterU = readF32(); + item.endJoint.jointCenterV = readF32(); + item.endJoint.jointScaleU = readF32(); + item.endJoint.jointScaleV = readF32(); + } + + item.rotationConstraintMax[0] = readF32(); + item.rotationConstraintMin[0] = readF32(); + item.rotationConstraintMax[1] = readF32(); + item.rotationConstraintMin[1] = readF32(); + item.rotationConstraintMax[2] = readF32(); + item.rotationConstraintMin[2] = readF32(); + + result.emplace_back(std::move(item)); + } + + return result; +} + bool PDF3D_U3D_DataReader::isAtEnd() const { return m_position >= uint32_t(m_data.size()) * 8; @@ -313,19 +360,19 @@ uint32_t PDF3D_U3D_DataReader::readSymbol(uint32_t context) m_code = (m_code << 15) | read15Bits(); m_position = position; - const uint32_t totalCumFreq = m_contextManager->getTotalSymbolFrequency(context); + const uint32_t totalCumFreq = m_contextManager.getTotalSymbolFrequency(context); const uint32_t range = (m_high + 1) - m_low; const uint32_t codeCumFreq = ((totalCumFreq) * (1 + m_code - m_low) - 1) / range; - const uint32_t value = m_contextManager->getSymbolFromFrequency(context, codeCumFreq); - const uint32_t valueCumFreq = m_contextManager->getCumulativeSymbolFrequency(context, value); - const uint32_t valueFreq = m_contextManager->getSymbolFrequency(context, value); + const uint32_t value = m_contextManager.getSymbolFromFrequency(context, codeCumFreq); + const uint32_t valueCumFreq = m_contextManager.getCumulativeSymbolFrequency(context, value); + const uint32_t valueFreq = m_contextManager.getSymbolFrequency(context, value); uint32_t low = m_low; uint32_t high = m_high; high = low - 1 + range * (valueCumFreq + valueFreq) / totalCumFreq; low = low + range * valueCumFreq / totalCumFreq; - m_contextManager->addSymbol(context, value); + m_contextManager.addSymbol(context, value); constexpr std::array S_BIT_COUNTS = { 4, 3, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 }; uint32_t bitCount = S_BIT_COUNTS[((low >> 12) ^ (high >> 12)) & 0x0000000F]; @@ -617,6 +664,87 @@ PDF3D_U3D_Block_Data PDF3D_U3D_Parser::readBlockData(PDF3D_U3D_DataReader& reade return data; } +void PDF3D_U3D_Parser::processCLODMesh(const PDF3D_U3D_Decoder& decoder) +{ + auto block = parseBlock(decoder.front()); + const PDF3D_U3D_CLODMeshDeclarationBlock* declarationBlock = dynamic_cast(block.data()); + + for (auto it = std::next(decoder.begin()); it != decoder.end(); ++it) + { + auto blockData = *it; + switch (blockData.blockType) + { + case PDF3D_U3D_Block_Info::BT_GeneratorCLODBaseMesh: + { + // TODO: process block data + auto currentBlock = PDF3D_U3D_CLODBaseMeshContinuationBlock::parse(blockData.blockData, blockData.metaData, this, declarationBlock); + break; + } + + case PDF3D_U3D_Block_Info::BT_GeneratorCLODProgMesh: + { + // TODO: process block data + auto currentBlock = PDF3D_U3D_CLODProgressiveMeshContinuationBlock::parse(blockData.blockData, blockData.metaData, this/*, declarationBlock*/); + break; + } + + default: + m_errors << QString("Invalid block type for CLOD mesh!"); + } + } +} + +void PDF3D_U3D_Parser::processPointSet(const PDF3D_U3D_Decoder& decoder) +{ + auto block = parseBlock(decoder.front()); + const PDF3D_U3D_PointSetDeclarationBlock* declarationBlock = dynamic_cast(block.data()); + + for (auto it = std::next(decoder.begin()); it != decoder.end(); ++it) + { + auto blockData = *it; + switch (blockData.blockType) + { + case PDF3D_U3D_Block_Info::BT_GeneratorPointSetCont: + { + // TODO: process block data + auto currentBlock = PDF3D_U3D_PointSetContinuationBlock::parse(blockData.blockData, blockData.metaData, this, declarationBlock); + break; + } + + default: + m_errors << QString("Invalid block type for Point set!"); + } + } +} + +void PDF3D_U3D_Parser::processLineSet(const PDF3D_U3D_Decoder& decoder) +{ + auto block = parseBlock(decoder.front()); + const PDF3D_U3D_LineSetDeclarationBlock* declarationBlock = dynamic_cast(block.data()); + + for (auto it = std::next(decoder.begin()); it != decoder.end(); ++it) + { + auto blockData = *it; + switch (blockData.blockType) + { + case PDF3D_U3D_Block_Info::BT_GeneratorLineSetCont: + { + // TODO: process block data + auto currentBlock = PDF3D_U3D_LineSetContinuationBlock::parse(blockData.blockData, blockData.metaData, this, declarationBlock); + break; + } + + default: + m_errors << QString("Invalid block type for line set!"); + } + } +} + +void PDF3D_U3D_Parser::addBlockToU3D(PDF3D_U3D_AbstractBlockPtr block) +{ + // TODO: add block to U3D +} + PDF3D_U3D_Parser::PDF3D_U3D_Parser() { // Jakub Melka: 106 is default value for U3D strings @@ -634,6 +762,42 @@ PDF3D_U3D PDF3D_U3D_Parser::parse(QByteArray data) processBlock(blockData, PDF3D_U3D_Block_Info::PL_LastPalette); } + for (const PDF3D_U3D_DecoderPalette& palette : m_decoderPalettes) + { + for (const PDF3D_U3D_DecoderChain& chain : palette) + { + for (const PDF3D_U3D_Decoder& decoder : chain) + { + if (decoder.isEmpty()) + { + continue; + } + + const PDF3D_U3D_Block_Data& blockData = decoder.front(); + switch (blockData.blockType) + { + case PDF3D_U3D_Block_Info::BT_GeneratorCLODMeshDecl: + processCLODMesh(decoder); + break; + + case PDF3D_U3D_Block_Info::BT_GeneratorPointSet: + processPointSet(decoder); + break; + + case PDF3D_U3D_Block_Info::BT_GeneratorLineSet: + processLineSet(decoder); + break; + + default: + { + auto block = parseBlock(blockData); + addBlockToU3D(block); + } + } + } + } + } + return m_object; } @@ -649,11 +813,11 @@ void PDF3D_U3D_Parser::processBlock(const PDF3D_U3D_Block_Data& blockData, break; } - case PDF3D_U3D_PriorityUpdateBlock::ID: + case PDF3D_U3D_FilePriorityUpdateBlock::ID: { // Parse priority update block auto block = parseBlock(blockData); - const PDF3D_U3D_PriorityUpdateBlock* priorityUpdateBlock = dynamic_cast(block.get()); + const PDF3D_U3D_FilePriorityUpdateBlock* priorityUpdateBlock = dynamic_cast(block.get()); m_priority = priorityUpdateBlock->getNewPriority(); break; } @@ -716,7 +880,7 @@ void PDF3D_U3D_Parser::processGenericBlock(const PDF3D_U3D_Block_Data& blockData PDF3D_U3D_Block_Info::EPalette effectivePalette = PDF3D_U3D_Block_Info::isChain(blockData.blockType) ? palette : PDF3D_U3D_Block_Info::getPalette(blockData.blockType); - PDF3D_U3D_DecoderPalette* decoderPalette = m_decoderLists.getDecoderPalette(effectivePalette); + PDF3D_U3D_DecoderPalette* decoderPalette = m_decoderPalettes.getDecoderPalette(effectivePalette); if (PDF3D_U3D_Block_Info::isContinuation(blockData.blockType)) { @@ -756,18 +920,6 @@ void PDF3D_U3D_Parser::processGenericBlock(const PDF3D_U3D_Block_Data& blockData } } -const PDF3D_U3D_CLODMeshDeclarationBlock* PDF3D_U3D::getCLODMeshDeclarationBlock(const QString& meshName) const -{ - // TODO: Opravit - return nullptr; //getBlock(meshName); -} - -const PDF3D_U3D_LineSetDeclarationBlock* PDF3D_U3D::getLineSetDeclarationBlock(const QString& lineSetName) const -{ - // TODO: Opravit - return nullptr; //getBlock(lineSetName); -} - PDF3D_U3D_AbstractBlockPtr PDF3D_U3D_Parser::parseBlock(uint32_t blockType, const QByteArray& data, const QByteArray& metaData) @@ -800,8 +952,8 @@ PDF3D_U3D_AbstractBlockPtr PDF3D_U3D_Parser::parseBlock(uint32_t blockType, case PDF3D_U3D_ModifierChainBlock::ID: return PDF3D_U3D_ModifierChainBlock::parse(data, metaData, this); - case PDF3D_U3D_PriorityUpdateBlock::ID: - return PDF3D_U3D_PriorityUpdateBlock::parse(data, metaData, this); + case PDF3D_U3D_FilePriorityUpdateBlock::ID: + return PDF3D_U3D_FilePriorityUpdateBlock::parse(data, metaData, this); case PDF3D_U3D_NewObjectTypeBlock::ID: return PDF3D_U3D_NewObjectTypeBlock::parse(data, metaData, this); @@ -821,16 +973,11 @@ PDF3D_U3D_AbstractBlockPtr PDF3D_U3D_Parser::parseBlock(uint32_t blockType, case PDF3D_U3D_CLODMeshDeclarationBlock::ID: return PDF3D_U3D_CLODMeshDeclarationBlock::parse(data, metaData, this); - 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: + m_errors << QString("Unable to parse block."); break; } @@ -1141,9 +1288,9 @@ const std::vector& PDF3D_U3D_ModifierChainBlock::getModifi return m_modifierDeclarationBlocks; } -PDF3D_U3D_AbstractBlockPtr PDF3D_U3D_PriorityUpdateBlock::parse(QByteArray data, QByteArray metaData, PDF3D_U3D_Parser* object) +PDF3D_U3D_AbstractBlockPtr PDF3D_U3D_FilePriorityUpdateBlock::parse(QByteArray data, QByteArray metaData, PDF3D_U3D_Parser* object) { - PDF3D_U3D_PriorityUpdateBlock* block = new PDF3D_U3D_PriorityUpdateBlock(); + PDF3D_U3D_FilePriorityUpdateBlock* block = new PDF3D_U3D_FilePriorityUpdateBlock(); PDF3D_U3D_AbstractBlockPtr pointer(block); PDF3D_U3D_DataReader reader(data, object->isCompressed(), object->getContextManager()); @@ -1155,7 +1302,7 @@ PDF3D_U3D_AbstractBlockPtr PDF3D_U3D_PriorityUpdateBlock::parse(QByteArray data, return pointer; } -uint32_t PDF3D_U3D_PriorityUpdateBlock::getNewPriority() const +uint32_t PDF3D_U3D_FilePriorityUpdateBlock::getNewPriority() const { return m_newPriority; } @@ -1548,45 +1695,7 @@ PDF3D_U3D_AbstractBlockPtr PDF3D_U3D_CLODMeshDeclarationBlock::parse(QByteArray /* bone description */ block->m_boneCount = reader.readU32(); - for (uint32_t i = 0; i < block->m_boneCount; ++i) - { - BoneDescription item; - - item.boneName = reader.readString(object->getTextCodec()); - item.parentBoneName = reader.readString(object->getTextCodec()); - item.boneAttributes = reader.readU32(); - item.boneLength = reader.readF32(); - reader.readFloats32(item.boneDisplacement); - reader.readFloats32(item.boneOrientation); - - if (item.isLinkPresent()) - { - item.boneLinkCount = reader.readU32(); - item.boneLinkLength = reader.readF32(); - } - - if (item.isJointPresent()) - { - item.startJoint.jointCenterU = reader.readF32(); - item.startJoint.jointCenterV = reader.readF32(); - item.startJoint.jointScaleU = reader.readF32(); - item.startJoint.jointScaleV = reader.readF32(); - - item.endJoint.jointCenterU = reader.readF32(); - item.endJoint.jointCenterV = reader.readF32(); - item.endJoint.jointScaleU = reader.readF32(); - item.endJoint.jointScaleV = reader.readF32(); - } - - item.rotationConstraintMax[0] = reader.readF32(); - item.rotationConstraintMin[0] = reader.readF32(); - item.rotationConstraintMax[1] = reader.readF32(); - item.rotationConstraintMin[1] = reader.readF32(); - item.rotationConstraintMax[2] = reader.readF32(); - item.rotationConstraintMin[2] = reader.readF32(); - - block->m_boneDescription.emplace_back(std::move(item)); - } + block->m_boneDescription = reader.readBoneDescriptions(object->getTextCodec(), block->m_boneCount); block->parseMetadata(metaData, object); return pointer; @@ -1712,12 +1821,15 @@ uint32_t PDF3D_U3D_CLODMeshDeclarationBlock::getBoneCount() const return m_boneCount; } -const std::vector& PDF3D_U3D_CLODMeshDeclarationBlock::getBoneDescription() const +const std::vector& PDF3D_U3D_CLODMeshDeclarationBlock::getBoneDescription() const { return m_boneDescription; } -PDF3D_U3D_AbstractBlockPtr PDF3D_U3D_CLODBaseMeshContinuationBlock::parse(QByteArray data, QByteArray metaData, PDF3D_U3D_Parser* object) +PDF3D_U3D_AbstractBlockPtr PDF3D_U3D_CLODBaseMeshContinuationBlock::parse(QByteArray data, + QByteArray metaData, + PDF3D_U3D_Parser* object, + const PDF3D_U3D_CLODMeshDeclarationBlock* declarationBlock) { PDF3D_U3D_CLODBaseMeshContinuationBlock* block = new PDF3D_U3D_CLODBaseMeshContinuationBlock(); PDF3D_U3D_AbstractBlockPtr pointer(block); @@ -1742,55 +1854,51 @@ PDF3D_U3D_AbstractBlockPtr PDF3D_U3D_CLODBaseMeshContinuationBlock::parse(QByteA block->m_baseSpecularColors = reader.readVectorFloats32(block->m_specularColorCount); block->m_baseTextureCoords = reader.readVectorFloats32(block->m_textureColorCount); - // TODO: Fix this // We must read attributes of the mesh to read faces - /*if (auto declarationBlock = object->getCLODMeshDeclarationBlock(block->m_meshName)) + const bool hasNormals = !declarationBlock->isNormalsExcluded(); + + for (size_t i = 0; i < block->m_faceCount; ++i) { - const bool hasNormals = !declarationBlock->isNormalsExcluded(); + BaseFace face; + face.m_shadingId = reader.readCompressedU32(reader.getStaticContext(cShading)); - for (size_t i = 0; i < block->m_faceCount; ++i) + const PDF3D_U3D_ShadingDescription* shadingDescription = declarationBlock->getShadingDescriptionItem(face.m_shadingId); + if (!shadingDescription) { - BaseFace face; - face.m_shadingId = reader.readCompressedU32(reader.getStaticContext(cShading)); - - const PDF3D_U3D_ShadingDescription* shadingDescription = declarationBlock->getShadingDescriptionItem(face.m_shadingId); - if (!shadingDescription) - { - return nullptr; - } - - for (size_t ci = 0; ci < face.m_corners.size(); ++ci) - { - BaseCornerInfo cornerInfo; - - cornerInfo.basePositionIndex = reader.readCompressedU32(reader.getRangeContext(block->m_positionCount)); - - if (hasNormals) - { - cornerInfo.baseNormalIndex = reader.readCompressedU32(reader.getRangeContext(block->m_normalCount)); - } - - if (shadingDescription->hasDiffuseColors()) - { - cornerInfo.baseDiffuseColorIndex = reader.readCompressedU32(reader.getRangeContext(block->m_diffuseColorCount)); - } - - if (shadingDescription->hasSpecularColors()) - { - cornerInfo.baseSpecularColorIndex = reader.readCompressedU32(reader.getRangeContext(block->m_specularColorCount)); - } - - for (uint32_t ti = 0; ti < shadingDescription->textureLayerCount; ++ti) - { - cornerInfo.baseTextureCoordIndex.push_back(reader.readCompressedU32(reader.getRangeContext(block->m_textureColorCount))); - } - - face.m_corners[ci] = std::move(cornerInfo); - } - - block->m_baseFaces.emplace_back(std::move(face)); + return nullptr; } - }*/ + + for (size_t ci = 0; ci < face.m_corners.size(); ++ci) + { + BaseCornerInfo cornerInfo; + + cornerInfo.basePositionIndex = reader.readCompressedU32(reader.getRangeContext(block->m_positionCount)); + + if (hasNormals) + { + cornerInfo.baseNormalIndex = reader.readCompressedU32(reader.getRangeContext(block->m_normalCount)); + } + + if (shadingDescription->hasDiffuseColors()) + { + cornerInfo.baseDiffuseColorIndex = reader.readCompressedU32(reader.getRangeContext(block->m_diffuseColorCount)); + } + + if (shadingDescription->hasSpecularColors()) + { + cornerInfo.baseSpecularColorIndex = reader.readCompressedU32(reader.getRangeContext(block->m_specularColorCount)); + } + + for (uint32_t ti = 0; ti < shadingDescription->textureLayerCount; ++ti) + { + cornerInfo.baseTextureCoordIndex.push_back(reader.readCompressedU32(reader.getRangeContext(block->m_textureColorCount))); + } + + face.m_corners[ci] = std::move(cornerInfo); + } + + block->m_baseFaces.emplace_back(std::move(face)); + } block->parseMetadata(metaData, object); return pointer; @@ -1948,6 +2056,8 @@ PDF3D_U3D_AbstractBlockPtr PDF3D_U3D_CLODProgressiveMeshContinuationBlock::parse updateItem.newFaces.emplace_back(std::move(facePositionInfo)); } + // TODO: Fixme + block->m_resolutionUpdates.emplace_back(std::move(updateItem)); } @@ -2068,7 +2178,10 @@ float PDF3D_U3D_LineSetDeclarationBlock::getSpecularColorInverseQuant() const return m_specularColorInverseQuant; } -PDF3D_U3D_AbstractBlockPtr PDF3D_U3D_LineSetContinuationBlock::parse(QByteArray data, QByteArray metaData, PDF3D_U3D_Parser* object) +PDF3D_U3D_AbstractBlockPtr PDF3D_U3D_LineSetContinuationBlock::parse(QByteArray data, + QByteArray metaData, + PDF3D_U3D_Parser* object, + const PDF3D_U3D_LineSetDeclarationBlock* declarationBlock) { PDF3D_U3D_LineSetContinuationBlock* block = new PDF3D_U3D_LineSetContinuationBlock(); PDF3D_U3D_AbstractBlockPtr pointer(block); @@ -2082,110 +2195,102 @@ PDF3D_U3D_AbstractBlockPtr PDF3D_U3D_LineSetContinuationBlock::parse(QByteArray block->m_startResolution = reader.readU32(); block->m_endResolution = reader.readU32(); - // TODO: Fix this - /*if (auto declarationBlock = object->getLineSetDeclarationBlock(block->m_lineSetName)) + for (uint32_t i = block->m_startResolution; i < block->m_endResolution; ++i) { - for (uint32_t i = block->m_startResolution; i < block->m_endResolution; ++i) + UpdateItem item; + + if (i > 0) { - UpdateItem item; - - if (i > 0) - { - item.splitPositionIndex = reader.readCompressedU32(reader.getRangeContext(i)); - } - else - { - item.splitPositionIndex = reader.readCompressedU32(reader.getRangeContext(i + 1)); - } - - 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)); + item.splitPositionIndex = reader.readCompressedU32(reader.getRangeContext(i)); } + else + { + item.splitPositionIndex = reader.readCompressedU32(reader.getRangeContext(i + 1)); + } + + 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; @@ -2337,6 +2442,248 @@ PDF3D_U3D_DecoderChain* PDF3D_U3D_DecoderPalette::createDecoderChain(const QStri return &m_decoderChains.back(); } +PDF3D_U3D_AbstractBlockPtr PDF3D_U3D_PointSetDeclarationBlock::parse(QByteArray data, + QByteArray metaData, + PDF3D_U3D_Parser* object) +{ + PDF3D_U3D_PointSetDeclarationBlock* block = new PDF3D_U3D_PointSetDeclarationBlock(); + PDF3D_U3D_AbstractBlockPtr pointer(block); + + PDF3D_U3D_DataReader reader(data, object->isCompressed(), object->getContextManager()); + + // Read the data + block->m_pointSetName = reader.readString(object->getTextCodec()); + block->m_chainIndex = reader.readU32(); + + // point set description + block->m_pointSetReserved = reader.readU32(); + block->m_pointCount = 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(); + + /* bone description */ + block->m_boneCount = reader.readU32(); + block->m_boneDescription = reader.readBoneDescriptions(object->getTextCodec(), block->m_boneCount); + + block->parseMetadata(metaData, object); + return pointer; +} + +uint32_t PDF3D_U3D_PointSetDeclarationBlock::getPointCount() const +{ + return m_pointCount; +} + +uint32_t PDF3D_U3D_PointSetDeclarationBlock::getPositionCount() const +{ + return m_positionCount; +} + +uint32_t PDF3D_U3D_PointSetDeclarationBlock::getNormalCount() const +{ + return m_normalCount; +} + +uint32_t PDF3D_U3D_PointSetDeclarationBlock::getDiffuseColorCount() const +{ + return m_diffuseColorCount; +} + +uint32_t PDF3D_U3D_PointSetDeclarationBlock::getSpecularColorCount() const +{ + return m_specularColorCount; +} + +uint32_t PDF3D_U3D_PointSetDeclarationBlock::getTextureCoordCount() const +{ + return m_textureCoordCount; +} + +const std::vector& PDF3D_U3D_PointSetDeclarationBlock::getShadingDescriptions() const +{ + return m_shadingDescriptions; +} + +uint32_t PDF3D_U3D_PointSetDeclarationBlock::getPositionQualityFactor() const +{ + return m_positionQualityFactor; +} + +uint32_t PDF3D_U3D_PointSetDeclarationBlock::getNormalQualityFactor() const +{ + return m_normalQualityFactor; +} + +uint32_t PDF3D_U3D_PointSetDeclarationBlock::getTextureCoordQualityFactor() const +{ + return m_textureCoordQualityFactor; +} + +float PDF3D_U3D_PointSetDeclarationBlock::getPositionInverseQuant() const +{ + return m_positionInverseQuant; +} + +float PDF3D_U3D_PointSetDeclarationBlock::getNormalInverseQuant() const +{ + return m_normalInverseQuant; +} + +float PDF3D_U3D_PointSetDeclarationBlock::getTextureCoordInverseQuant() const +{ + return m_textureCoordInverseQuant; +} + +float PDF3D_U3D_PointSetDeclarationBlock::getDiffuseColorInverseQuant() const +{ + return m_diffuseColorInverseQuant; +} + +float PDF3D_U3D_PointSetDeclarationBlock::getSpecularColorInverseQuant() const +{ + return m_specularColorInverseQuant; +} + +uint32_t PDF3D_U3D_PointSetDeclarationBlock::getBoneCount() const +{ + return m_boneCount; +} + +const std::vector& PDF3D_U3D_PointSetDeclarationBlock::getBoneDescription() const +{ + return m_boneDescription; +} + +PDF3D_U3D_AbstractBlockPtr PDF3D_U3D_PointSetContinuationBlock::parse(QByteArray data, + QByteArray metaData, + PDF3D_U3D_Parser* object, + const PDF3D_U3D_PointSetDeclarationBlock* declarationBlock) +{ + PDF3D_U3D_PointSetContinuationBlock* block = new PDF3D_U3D_PointSetContinuationBlock(); + PDF3D_U3D_AbstractBlockPtr pointer(block); + + PDF3D_U3D_DataReader reader(data, object->isCompressed(), object->getContextManager()); + + // Read the data + block->m_pointSetName = reader.readString(object->getTextCodec()); + block->m_chainIndex = reader.readU32(); + + block->m_startResolution = reader.readU32(); + block->m_endResolution = reader.readU32(); + + for (uint32_t i = block->m_startResolution; i < block->m_endResolution; ++i) + { + UpdateItem item; + + if (i > 0) + { + item.splitPositionIndex = reader.readCompressedU32(reader.getRangeContext(i)); + } + else + { + item.splitPositionIndex = reader.readCompressedU32(reader.getRangeContext(i + 1)); + } + + 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 newPointCount = reader.readCompressedU32(reader.getStaticContext(cPointCnt)); + for (uint32_t li = 0; li < newPointCount; ++li) + { + NewPointInfo pointInfo; + pointInfo.shadingId = reader.readCompressedU32(reader.getStaticContext(cShading)); + + const PDF3D_U3D_ShadingDescription* shadingDescription = declarationBlock->getShadingDescriptionItem(pointInfo.shadingId); + if (!shadingDescription) + { + return nullptr; + } + + pointInfo.normalLocalIndex = reader.readCompressedU32(reader.getStaticContext(cNormlIdx)); + + if (shadingDescription->hasDiffuseColors()) + { + pointInfo.duplicateDiffuse = reader.readCompressedU8(reader.getStaticContext(cDiffDup)) & 0x02; + + if (!pointInfo.duplicateDiffuse) + { + pointInfo.diffuseColor = reader.readQuantizedVec4(reader.getStaticContext(cDiffuseColorSign), + reader.getStaticContext(cColorDiffR), + reader.getStaticContext(cColorDiffG), + reader.getStaticContext(cColorDiffB), + reader.getStaticContext(cColorDiffA)); + } + } + + if (shadingDescription->hasSpecularColors()) + { + pointInfo.duplicateSpecular = reader.readCompressedU8(reader.getStaticContext(cSpecDup)) & 0x02; + + if (!pointInfo.duplicateSpecular) + { + pointInfo.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)); + } + + pointInfo.textureCoords.emplace_back(duplicateTextCoord, textCoord); + } + + item.newPoints.emplace_back(std::move(pointInfo)); + } + + block->m_updateItems.emplace_back(std::move(item)); + } + + block->parseMetadata(metaData, object); + return pointer; +} + } // namespace u3d } // namespace pdf diff --git a/Pdf4QtLib/sources/pdf3d_u3d.h b/Pdf4QtLib/sources/pdf3d_u3d.h index d7798c7..27d6c37 100644 --- a/Pdf4QtLib/sources/pdf3d_u3d.h +++ b/Pdf4QtLib/sources/pdf3d_u3d.h @@ -46,8 +46,9 @@ enum Context cDiffNormalX, cDiffNormalY, cDiffNormalZ, - cLineCnt, cShading, + cLineCnt = cShading, // Undocumented, that cLineCnt equals to cShading + cPointCnt = cShading, // Undocumented, that cPointCnt equals to cShading cNormlIdx, cDiffDup, cDiffuseColorSign, @@ -169,6 +170,33 @@ struct PDF3D_U3D_Block_Data 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; @@ -223,7 +251,7 @@ using PDF3D_U3D_AxisAlignedBoundingBox = std::array; class PDF3D_U3D_FileBlock : public PDF3D_U3D_AbstractBlock { public: - static constexpr uint32_t ID = 0x00443355; + static constexpr uint32_t ID = PDF3D_U3D_Block_Info::BT_FileHeader; static PDF3D_U3D_AbstractBlockPtr parse(QByteArray data, QByteArray metaData, PDF3D_U3D_Parser* object); @@ -252,7 +280,7 @@ private: class PDF3D_U3D_FileReferenceBlock : public PDF3D_U3D_AbstractBlock { public: - static constexpr uint32_t ID = 0xFFFFFF12; + static constexpr uint32_t ID = PDF3D_U3D_Block_Info::BT_FileReference; bool isBoundingSpherePresent() const { return m_fileReferenceAttributes & 0x00000001; } bool isAxisAlignedBoundingBoxPresent() const { return m_fileReferenceAttributes & 0x00000002; } @@ -293,7 +321,7 @@ private: class PDF3D_U3D_ModifierChainBlock : public PDF3D_U3D_AbstractBlock { public: - static constexpr uint32_t ID = 0xFFFFFF14; + static constexpr uint32_t ID = PDF3D_U3D_Block_Info::BT_FileModifierChain; static PDF3D_U3D_AbstractBlockPtr parse(QByteArray data, QByteArray metaData, PDF3D_U3D_Parser* object); @@ -323,10 +351,10 @@ private: std::vector m_modifierDeclarationBlocks; }; -class PDF3D_U3D_PriorityUpdateBlock : public PDF3D_U3D_AbstractBlock +class PDF3D_U3D_FilePriorityUpdateBlock : public PDF3D_U3D_AbstractBlock { public: - static constexpr uint32_t ID = 0xFFFFFF15; + static constexpr uint32_t ID = PDF3D_U3D_Block_Info::BT_FilePriorityUpdate; static PDF3D_U3D_AbstractBlockPtr parse(QByteArray data, QByteArray metaData, PDF3D_U3D_Parser* object); @@ -339,7 +367,7 @@ private: class PDF3D_U3D_NewObjectTypeBlock : public PDF3D_U3D_AbstractBlock { public: - static constexpr uint32_t ID = 0xFFFFFF16; + static constexpr uint32_t ID = PDF3D_U3D_Block_Info::BT_FileNewObject; static PDF3D_U3D_AbstractBlockPtr parse(QByteArray data, QByteArray metaData, PDF3D_U3D_Parser* object); @@ -392,7 +420,7 @@ private: class PDF3D_U3D_GroupNodeBlock : public PDF3D_U3D_AbstractBlock { public: - static constexpr uint32_t ID = 0xFFFFFF21; + static constexpr uint32_t ID = PDF3D_U3D_Block_Info::BT_NodeGroup; static PDF3D_U3D_AbstractBlockPtr parse(QByteArray data, QByteArray metaData, PDF3D_U3D_Parser* object); @@ -407,7 +435,7 @@ private: class PDF3D_U3D_ModelNodeBlock : public PDF3D_U3D_AbstractBlock { public: - static constexpr uint32_t ID = 0xFFFFFF22; + static constexpr uint32_t ID = PDF3D_U3D_Block_Info::BT_NodeModel; static PDF3D_U3D_AbstractBlockPtr parse(QByteArray data, QByteArray metaData, PDF3D_U3D_Parser* object); @@ -431,7 +459,7 @@ private: class PDF3D_U3D_LightNodeBlock : public PDF3D_U3D_AbstractBlock { public: - static constexpr uint32_t ID = 0xFFFFFF23; + static constexpr uint32_t ID = PDF3D_U3D_Block_Info::BT_NodeLight; static PDF3D_U3D_AbstractBlockPtr parse(QByteArray data, QByteArray metaData, PDF3D_U3D_Parser* object); @@ -448,7 +476,7 @@ private: class PDF3D_U3D_ViewNodeBlock : public PDF3D_U3D_AbstractBlock { public: - static constexpr uint32_t ID = 0xFFFFFF24; + static constexpr uint32_t ID = PDF3D_U3D_Block_Info::BT_NodeView; static PDF3D_U3D_AbstractBlockPtr parse(QByteArray data, QByteArray metaData, PDF3D_U3D_Parser* object); @@ -521,37 +549,10 @@ private: class PDF3D_U3D_CLODMeshDeclarationBlock : public PDF3D_U3D_AbstractBlock { public: - static constexpr uint32_t ID = 0xFFFFFF31; + static constexpr uint32_t ID = PDF3D_U3D_Block_Info::BT_GeneratorCLODMeshDecl; static PDF3D_U3D_AbstractBlockPtr parse(QByteArray data, QByteArray metaData, PDF3D_U3D_Parser* object); - struct BoneJoint - { - float jointCenterU = 0.0; - float jointCenterV = 0.0; - float jointScaleU = 0.0; - float jointScaleV = 0.0; - }; - - struct 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; - BoneJoint startJoint = BoneJoint(); - BoneJoint endJoint = 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; } - }; - const QString& getName() const { return getMeshName(); } const QString& getMeshName() const; uint32_t getChainIndex() const; @@ -589,7 +590,7 @@ public: /* bone description */ uint32_t getBoneCount() const; - const std::vector& getBoneDescription() const; + const std::vector& getBoneDescription() const; private: QString m_meshName; @@ -624,15 +625,15 @@ private: /* bone description */ uint32_t m_boneCount = 0; - std::vector m_boneDescription; + std::vector m_boneDescription; }; class PDF3D_U3D_CLODBaseMeshContinuationBlock : public PDF3D_U3D_AbstractBlock { public: - static constexpr uint32_t ID = 0xFFFFFF3B; + static constexpr uint32_t ID = PDF3D_U3D_Block_Info::BT_GeneratorCLODBaseMesh; - static PDF3D_U3D_AbstractBlockPtr parse(QByteArray data, QByteArray metaData, PDF3D_U3D_Parser* object); + static PDF3D_U3D_AbstractBlockPtr parse(QByteArray data, QByteArray metaData, PDF3D_U3D_Parser* object, const PDF3D_U3D_CLODMeshDeclarationBlock* declarationBlock); struct BaseCornerInfo { @@ -689,7 +690,7 @@ private: class PDF3D_U3D_CLODProgressiveMeshContinuationBlock : public PDF3D_U3D_AbstractBlock { public: - static constexpr uint32_t ID = 0xFFFFFF3C; + static constexpr uint32_t ID = PDF3D_U3D_Block_Info::BT_GeneratorCLODProgMesh; static PDF3D_U3D_AbstractBlockPtr parse(QByteArray data, QByteArray metaData, PDF3D_U3D_Parser* object); @@ -723,10 +724,114 @@ private: std::vector m_resolutionUpdates; }; +class PDF3D_U3D_PointSetDeclarationBlock : public PDF3D_U3D_AbstractBlock +{ +public: + static constexpr uint32_t ID = PDF3D_U3D_Block_Info::BT_GeneratorPointSet; + + 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; + + 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 = 0xFFFFFF37; + static constexpr uint32_t ID = PDF3D_U3D_Block_Info::BT_GeneratorLineSet; static PDF3D_U3D_AbstractBlockPtr parse(QByteArray data, QByteArray metaData, PDF3D_U3D_Parser* object); @@ -780,9 +885,9 @@ private: class PDF3D_U3D_LineSetContinuationBlock : public PDF3D_U3D_AbstractBlock { public: - static constexpr uint32_t ID = 0xFFFFFF3F; + static constexpr uint32_t ID = PDF3D_U3D_Block_Info::BT_GeneratorLineSetCont; - static PDF3D_U3D_AbstractBlockPtr parse(QByteArray data, QByteArray metaData, PDF3D_U3D_Parser* object); + static PDF3D_U3D_AbstractBlockPtr parse(QByteArray data, QByteArray metaData, PDF3D_U3D_Parser* object, const PDF3D_U3D_LineSetDeclarationBlock* declarationBlock); struct NewLineEndingInfo { @@ -836,9 +941,6 @@ class PDF4QTLIBSHARED_EXPORT PDF3D_U3D { public: PDF3D_U3D(); - - const PDF3D_U3D_CLODMeshDeclarationBlock* getCLODMeshDeclarationBlock(const QString& meshName) const; - const PDF3D_U3D_LineSetDeclarationBlock* getLineSetDeclarationBlock(const QString& lineSetName) const; }; // ------------------------------------------------------------------------------- @@ -901,6 +1003,14 @@ 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(); } + private: std::vector m_blocks; }; @@ -915,6 +1025,9 @@ public: 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; @@ -927,6 +1040,9 @@ 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; }; @@ -938,6 +1054,9 @@ public: 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; }; @@ -964,6 +1083,12 @@ public: 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 addBlockToU3D(PDF3D_U3D_AbstractBlockPtr block); + private: struct LoadBlockInfo { @@ -979,7 +1104,7 @@ private: std::vector m_allBlocks; QStringList m_errors; - PDF3D_U3D_DecoderPalettes m_decoderLists; + PDF3D_U3D_DecoderPalettes m_decoderPalettes; PDF3D_U3D_ContextManager m_contextManager; PDF3D_U3D m_object; PDF3D_U3D_AbstractBlockPtr m_fileBlock; @@ -1033,6 +1158,7 @@ public: uint32_t context3); std::vector readShadingDescriptions(uint32_t count); + std::vector readBoneDescriptions(QTextCodec* textCodec, uint32_t count); bool isAtEnd() const; @@ -1068,7 +1194,7 @@ private: uint32_t read15Bits(); QByteArray m_data; - PDF3D_U3D_ContextManager* m_contextManager; + PDF3D_U3D_ContextManager m_contextManager; uint32_t m_high; uint32_t m_low;