mirror of
https://github.com/JakubMelka/PDF4QT.git
synced 2025-06-05 21:59:17 +02:00
3D PDF: Mesh continuation block
This commit is contained in:
@ -554,6 +554,7 @@ PDF3D_U3D_AbstractBlockPtr PDF3D_U3D::parseBlockWithDeclaration(PDF3D_U3D_DataRe
|
|||||||
auto block = parseBlock(blockType, blockData, metaData);
|
auto block = parseBlock(blockType, blockData, metaData);
|
||||||
|
|
||||||
LoadBlockInfo info;
|
LoadBlockInfo info;
|
||||||
|
info.typeName = QByteArray::fromRawData(reinterpret_cast<const char*>(&blockType), sizeof(decltype(blockType))).toHex();
|
||||||
info.success = block != nullptr;
|
info.success = block != nullptr;
|
||||||
info.blockType = blockType;
|
info.blockType = blockType;
|
||||||
info.dataSize = dataSize;
|
info.dataSize = dataSize;
|
||||||
@ -579,6 +580,36 @@ PDF3D_U3D PDF3D_U3D::parse(QByteArray data)
|
|||||||
return object;
|
return object;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const PDF3D_U3D_CLODMeshDeclarationBlock* PDF3D_U3D::getCLODMeshDeclarationBlock(const QString& meshName) const
|
||||||
|
{
|
||||||
|
for (const auto& block : m_blocks)
|
||||||
|
{
|
||||||
|
if (auto typedBlock = dynamic_cast<const PDF3D_U3D_CLODMeshDeclarationBlock*>(block.data()))
|
||||||
|
{
|
||||||
|
if (typedBlock->getMeshName() == meshName)
|
||||||
|
{
|
||||||
|
return typedBlock;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (auto typedBlock = dynamic_cast<const PDF3D_U3D_ModifierChainBlock*>(block.data()))
|
||||||
|
{
|
||||||
|
for (const auto& modifierChainChildBlock : typedBlock->getModifierDeclarationBlocks())
|
||||||
|
{
|
||||||
|
if (auto modifierChainChildTypedBlock = dynamic_cast<const PDF3D_U3D_CLODMeshDeclarationBlock*>(modifierChainChildBlock.data()))
|
||||||
|
{
|
||||||
|
if (modifierChainChildTypedBlock->getMeshName() == meshName)
|
||||||
|
{
|
||||||
|
return modifierChainChildTypedBlock;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
PDF3D_U3D_AbstractBlockPtr PDF3D_U3D::parseBlock(uint32_t blockType,
|
PDF3D_U3D_AbstractBlockPtr PDF3D_U3D::parseBlock(uint32_t blockType,
|
||||||
const QByteArray& data,
|
const QByteArray& data,
|
||||||
const QByteArray& metaData)
|
const QByteArray& metaData)
|
||||||
@ -632,6 +663,9 @@ PDF3D_U3D_AbstractBlockPtr PDF3D_U3D::parseBlock(uint32_t blockType,
|
|||||||
case PDF3D_U3D_CLODMeshDeclarationBlock::ID:
|
case PDF3D_U3D_CLODMeshDeclarationBlock::ID:
|
||||||
return PDF3D_U3D_CLODMeshDeclarationBlock::parse(data, metaData, this);
|
return PDF3D_U3D_CLODMeshDeclarationBlock::parse(data, metaData, this);
|
||||||
|
|
||||||
|
case PDF3D_U3D_CLODBaseMeshContinuationBlock::ID:
|
||||||
|
return PDF3D_U3D_CLODBaseMeshContinuationBlock::parse(data, metaData, this);
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1536,6 +1570,84 @@ const std::vector<PDF3D_U3D_CLODMeshDeclarationBlock::BoneDescription>& PDF3D_U3
|
|||||||
return m_boneDescription;
|
return m_boneDescription;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PDF3D_U3D_AbstractBlockPtr PDF3D_U3D_CLODBaseMeshContinuationBlock::parse(QByteArray data, QByteArray metaData, PDF3D_U3D* object)
|
||||||
|
{
|
||||||
|
PDF3D_U3D_CLODBaseMeshContinuationBlock* block = new PDF3D_U3D_CLODBaseMeshContinuationBlock();
|
||||||
|
PDF3D_U3D_AbstractBlockPtr pointer(block);
|
||||||
|
|
||||||
|
PDF3D_U3D_DataReader reader(data, object->isCompressed());
|
||||||
|
|
||||||
|
// Read the data
|
||||||
|
block->m_meshName = reader.readString(object->getTextCodec());
|
||||||
|
block->m_chainIndex = reader.readU32();
|
||||||
|
|
||||||
|
/* max mesh description */
|
||||||
|
block->m_faceCount = reader.readU32();
|
||||||
|
block->m_positionCount = reader.readU32();
|
||||||
|
block->m_normalCount = reader.readU32();
|
||||||
|
block->m_diffuseColorCount = reader.readU32();
|
||||||
|
block->m_specularColorCount = reader.readU32();
|
||||||
|
block->m_textureColorCount = reader.readU32();
|
||||||
|
|
||||||
|
block->m_basePositions = reader.readVectorFloats32<PDF3D_U3D_Vec3>(block->m_positionCount);
|
||||||
|
block->m_baseNormals = reader.readVectorFloats32<PDF3D_U3D_Vec3>(block->m_normalCount);
|
||||||
|
block->m_baseDiffuseColors = reader.readVectorFloats32<PDF3D_U3D_Vec4>(block->m_diffuseColorCount);
|
||||||
|
block->m_baseSpecularColors = reader.readVectorFloats32<PDF3D_U3D_Vec4>(block->m_specularColorCount);
|
||||||
|
block->m_baseTextureCoords = reader.readVectorFloats32<PDF3D_U3D_Vec4>(block->m_textureColorCount);
|
||||||
|
|
||||||
|
// 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)
|
||||||
|
{
|
||||||
|
BaseFace face;
|
||||||
|
face.m_shadingId = reader.readCompressedU32(reader.getStaticContext(cShading));
|
||||||
|
|
||||||
|
const PDF3D_U3D_CLODMeshDeclarationBlock::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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
block->parseMetadata(metaData, object);
|
||||||
|
return pointer;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace u3d
|
} // namespace u3d
|
||||||
|
|
||||||
} // namespace pdf
|
} // namespace pdf
|
||||||
|
@ -395,6 +395,9 @@ public:
|
|||||||
uint32_t textureLayerCount = 0;
|
uint32_t textureLayerCount = 0;
|
||||||
std::vector<uint32_t> textureCoordDimensions;
|
std::vector<uint32_t> textureCoordDimensions;
|
||||||
uint32_t originalShading = 0;
|
uint32_t originalShading = 0;
|
||||||
|
|
||||||
|
bool hasDiffuseColors() const { return shadingAttributes & 0x00000001; }
|
||||||
|
bool hasSpecularColors() const { return shadingAttributes & 0x00000002; }
|
||||||
};
|
};
|
||||||
|
|
||||||
struct BoneJoint
|
struct BoneJoint
|
||||||
@ -427,6 +430,8 @@ public:
|
|||||||
const QString& getMeshName() const;
|
const QString& getMeshName() const;
|
||||||
uint32_t getChainIndex() const;
|
uint32_t getChainIndex() const;
|
||||||
|
|
||||||
|
bool isNormalsExcluded() const { return getMeshAttributes() & 0x00000001; }
|
||||||
|
|
||||||
/* max mesh description */
|
/* max mesh description */
|
||||||
uint32_t getMeshAttributes() const;
|
uint32_t getMeshAttributes() const;
|
||||||
uint32_t getFaceCount() const;
|
uint32_t getFaceCount() const;
|
||||||
@ -437,6 +442,7 @@ public:
|
|||||||
uint32_t getTextureColorCount() const;
|
uint32_t getTextureColorCount() const;
|
||||||
uint32_t getShadingCount() const;
|
uint32_t getShadingCount() const;
|
||||||
const std::vector<ShadingDescription>& getShadingDescription() const;
|
const std::vector<ShadingDescription>& getShadingDescription() const;
|
||||||
|
const ShadingDescription* getShadingDescriptionItem(uint32_t index) const { return index < m_shadingDescription.size() ? &m_shadingDescription[index] : nullptr; }
|
||||||
|
|
||||||
/* clod description */
|
/* clod description */
|
||||||
uint32_t getMinimumResolution() const;
|
uint32_t getMinimumResolution() const;
|
||||||
@ -496,6 +502,56 @@ private:
|
|||||||
std::vector<BoneDescription> m_boneDescription;
|
std::vector<BoneDescription> m_boneDescription;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class PDF3D_U3D_CLODBaseMeshContinuationBlock : public PDF3D_U3D_AbstractBlock
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static constexpr uint32_t ID = 0xFFFFFF3B;
|
||||||
|
|
||||||
|
static PDF3D_U3D_AbstractBlockPtr parse(QByteArray data, QByteArray metaData, PDF3D_U3D* object);
|
||||||
|
|
||||||
|
struct BaseCornerInfo
|
||||||
|
{
|
||||||
|
uint32_t basePositionIndex = 0; // rBasePositionCount
|
||||||
|
uint32_t baseNormalIndex = 0; // rBaseNormalCount
|
||||||
|
uint32_t baseDiffuseColorIndex = 0; // rBaseDiffColorCnt
|
||||||
|
uint32_t baseSpecularColorIndex = 0; // rBaseSpecColorCnt
|
||||||
|
std::vector<uint32_t> baseTextureCoordIndex; // rBaseTexCoordCnt
|
||||||
|
};
|
||||||
|
|
||||||
|
struct BaseFace
|
||||||
|
{
|
||||||
|
uint32_t m_shadingId = 0; // cShading
|
||||||
|
std::array<BaseCornerInfo, 3> m_corners = { };
|
||||||
|
};
|
||||||
|
|
||||||
|
const QString& getMeshName() const;
|
||||||
|
uint32_t getChainIndex() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
enum Context
|
||||||
|
{
|
||||||
|
cShading = 1
|
||||||
|
};
|
||||||
|
|
||||||
|
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<PDF3D_U3D_Vec3> m_basePositions;
|
||||||
|
std::vector<PDF3D_U3D_Vec3> m_baseNormals;
|
||||||
|
std::vector<PDF3D_U3D_Vec4> m_baseDiffuseColors;
|
||||||
|
std::vector<PDF3D_U3D_Vec4> m_baseSpecularColors;
|
||||||
|
std::vector<PDF3D_U3D_Vec4> m_baseTextureCoords;
|
||||||
|
std::vector<BaseFace> m_baseFaces;
|
||||||
|
};
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
// PDF3D_U3D
|
// PDF3D_U3D
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
@ -510,6 +566,8 @@ public:
|
|||||||
|
|
||||||
static PDF3D_U3D parse(QByteArray data);
|
static PDF3D_U3D parse(QByteArray data);
|
||||||
|
|
||||||
|
const PDF3D_U3D_CLODMeshDeclarationBlock* getCLODMeshDeclarationBlock(const QString& meshName) const;
|
||||||
|
|
||||||
PDF3D_U3D_AbstractBlockPtr parseBlockWithDeclaration(PDF3D_U3D_DataReader& reader);
|
PDF3D_U3D_AbstractBlockPtr parseBlockWithDeclaration(PDF3D_U3D_DataReader& reader);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -518,6 +576,7 @@ private:
|
|||||||
|
|
||||||
struct LoadBlockInfo
|
struct LoadBlockInfo
|
||||||
{
|
{
|
||||||
|
QString typeName;
|
||||||
bool success = false;
|
bool success = false;
|
||||||
uint32_t blockType = 0;
|
uint32_t blockType = 0;
|
||||||
uint32_t dataSize = 0;
|
uint32_t dataSize = 0;
|
||||||
@ -593,6 +652,9 @@ public:
|
|||||||
|
|
||||||
void setData(QByteArray data);
|
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();
|
uint8_t readU8();
|
||||||
uint16_t readU16();
|
uint16_t readU16();
|
||||||
uint32_t readU32();
|
uint32_t readU32();
|
||||||
@ -626,6 +688,22 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
std::vector<T> readVectorFloats32(uint32_t count)
|
||||||
|
{
|
||||||
|
std::vector<T> 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:
|
private:
|
||||||
uint32_t readSymbol(uint32_t context);
|
uint32_t readSymbol(uint32_t context);
|
||||||
uint8_t swapBits8(uint8_t source);
|
uint8_t swapBits8(uint8_t source);
|
||||||
|
Reference in New Issue
Block a user