// Load the mesh from binary data stream void GLC_Mesh::loadFromDataStream(QDataStream& stream, const MaterialHash& materialHash, const QHash<GLC_uint, GLC_uint>& materialIdMap) { quint32 chunckId; stream >> chunckId; Q_ASSERT(chunckId == m_ChunkId); // The mesh name QString meshName; stream >> meshName; setName(meshName); // The wire data stream >> GLC_Geometry::m_WireData; // The mesh next primitive local id GLC_uint localId; stream >> localId; setNextPrimitiveLocalId(localId); // Retrieve geom mesh data stream >> m_MeshData; // Retrieve primitiveGroupLodList QList<int> primitiveGroupLodList; stream >> primitiveGroupLodList; // Retrieve primitiveGroup list QList<QList<GLC_PrimitiveGroup> > primitiveListOfGroupList; stream >> primitiveListOfGroupList; // Construct mesh primitiveGroupHash const int lodCount= primitiveGroupLodList.size(); for (int i= 0; i < lodCount; ++i) { GLC_Mesh::LodPrimitiveGroups* pCurrentPrimitiveGroup= new GLC_Mesh::LodPrimitiveGroups(); m_PrimitiveGroups.insert(primitiveGroupLodList.at(i), pCurrentPrimitiveGroup); const int groupCount= primitiveListOfGroupList.at(i).size(); for (int iGroup= 0; iGroup < groupCount; ++iGroup) { Q_ASSERT(materialIdMap.contains(primitiveListOfGroupList.at(i).at(iGroup).id())); const GLC_uint newId= materialIdMap.value(primitiveListOfGroupList.at(i).at(iGroup).id()); // Test if the mesh contains the material if (!containsMaterial(newId)) { addMaterial(materialHash.value(newId)); } GLC_PrimitiveGroup* pGroup= new GLC_PrimitiveGroup(primitiveListOfGroupList.at(i).at(iGroup), newId); Q_ASSERT(! m_PrimitiveGroups.value(primitiveGroupLodList.at(i))->contains(newId)); m_PrimitiveGroups.value(primitiveGroupLodList.at(i))->insert(newId, pGroup); } } stream >> m_NumberOfVertice; stream >> m_NumberOfNormals; finishSerialized(); //qDebug() << "Mesh mem size= " << memmorySize(); }
// Replace the material specified by id with another one void GLC_Mesh::replaceMaterial(const GLC_uint oldId, GLC_Material* pMat) { Q_ASSERT(containsMaterial(oldId)); Q_ASSERT(!containsMaterial(pMat->id()) || (pMat->id() == oldId)); if (pMat->id() != oldId) { // Iterate over Level of detail PrimitiveGroupsHash::const_iterator iGroups= m_PrimitiveGroups.constBegin(); while (m_PrimitiveGroups.constEnd() != iGroups) { LodPrimitiveGroups* pPrimitiveGroups= iGroups.value(); // Iterate over material group LodPrimitiveGroups::iterator iGroup= pPrimitiveGroups->begin(); while (pPrimitiveGroups->constEnd() != iGroup) { if (iGroup.key() == oldId) { GLC_PrimitiveGroup* pGroup= iGroup.value(); // Erase old group pointer pPrimitiveGroups->erase(iGroup); // Change the group ID pGroup->setId(pMat->id()); // Add the group with new ID pPrimitiveGroups->insert(pMat->id(), pGroup); iGroup= pPrimitiveGroups->end(); } else { ++iGroup; } } ++iGroups; } } if (pMat != m_MaterialHash.value(oldId)) { // Remove old material removeMaterial(oldId); addMaterial(pMat); } }
// Set the current material GLC_uint GLC_Mesh::setCurrentMaterial(GLC_Material* pMaterial, int lod, double accuracy) { // Test if a primitive group hash exists for the specified lod if (!m_PrimitiveGroups.contains(lod)) { m_PrimitiveGroups.insert(lod, new LodPrimitiveGroups()); m_MeshData.appendLod(accuracy); } GLC_uint returnId; if (NULL == pMaterial) { returnId= m_DefaultMaterialId; // Default material id // Test if the material has been already load if (m_DefaultMaterialId == 0) { pMaterial= new GLC_Material(); // Add the material to the mesh addMaterial(pMaterial); m_DefaultMaterialId= pMaterial->id(); returnId= m_DefaultMaterialId; } // Test if a primitive group for this material exist if (!m_PrimitiveGroups.value(lod)->contains(returnId)) { m_PrimitiveGroups.value(lod)->insert(returnId, new GLC_PrimitiveGroup(returnId)); } } else { returnId= pMaterial->id(); // Test if the material has been already load if (!containsMaterial(returnId)) { // Add the material to the mesh addMaterial(pMaterial); m_PrimitiveGroups.value(lod)->insert(returnId, new GLC_PrimitiveGroup(returnId)); } else if (!m_PrimitiveGroups.value(lod)->contains(returnId)) { // Add the material to the group m_PrimitiveGroups.value(lod)->insert(returnId, new GLC_PrimitiveGroup(returnId)); } } return returnId; }
// Remove the specified material from the geometry void GLC_Geometry::removeMaterial(GLC_uint id) { Q_ASSERT(containsMaterial(id)); // Remove the first material GLC_Material* pMaterial= m_MaterialHash.value(id); // delete the material if necessary pMaterial->delGLC_Geom(this->id()); if (pMaterial->isTransparent()) { --m_TransparentMaterialNumber; } if (pMaterial->isUnused()) delete pMaterial; m_MaterialHash.remove(id); }