diff options
Diffstat (limited to 'src/Authoring/Client/Code/Core/Doc/ClientDataModelBridge/ClientDataModelBridge.cpp')
-rw-r--r-- | src/Authoring/Client/Code/Core/Doc/ClientDataModelBridge/ClientDataModelBridge.cpp | 222 |
1 files changed, 163 insertions, 59 deletions
diff --git a/src/Authoring/Client/Code/Core/Doc/ClientDataModelBridge/ClientDataModelBridge.cpp b/src/Authoring/Client/Code/Core/Doc/ClientDataModelBridge/ClientDataModelBridge.cpp index 45c126b9..95540fe6 100644 --- a/src/Authoring/Client/Code/Core/Doc/ClientDataModelBridge/ClientDataModelBridge.cpp +++ b/src/Authoring/Client/Code/Core/Doc/ClientDataModelBridge/ClientDataModelBridge.cpp @@ -520,7 +520,7 @@ void CClientDataModelBridge::SetName(qt3dsdm::Qt3DSDMInstanceHandle inInstanceHa } Q3DStudio::CString CClientDataModelBridge::GetName( - qt3dsdm::Qt3DSDMInstanceHandle inInstanceHandle, bool renameMaterials) const + qt3dsdm::Qt3DSDMInstanceHandle inInstanceHandle, bool renameMaterials) { IPropertySystem *thePropertySystem = m_Doc->GetStudioSystem()->GetPropertySystem(); TDataStrPtr theString; @@ -576,12 +576,29 @@ std::wstring GetInstanceType(IPropertySystem *inPropertySystem, Qt3DSDMInstanceH // Find which material that uses this image instance bool CClientDataModelBridge::GetMaterialFromImageInstance( qt3dsdm::Qt3DSDMInstanceHandle inInstance, qt3dsdm::Qt3DSDMInstanceHandle &outMaterialInstance, - qt3dsdm::Qt3DSDMPropertyHandle &outProperty) const + qt3dsdm::Qt3DSDMPropertyHandle &outProperty) { IPropertySystem *thePropertySystem = m_Doc->GetStudioSystem()->GetPropertySystem(); SLong4 theDeletedImageLong4 = GetNamedInstancePropertyValue<SLong4>(thePropertySystem, inInstance, L"id"); + auto iter = m_cachedImageParents.find(inInstance); + if (iter != m_cachedImageParents.end()) { + // We have to recheck the property + qt3dsdm::Qt3DSDMInstanceHandle theInstance = iter->second.first; + qt3dsdm::Qt3DSDMPropertyHandle theProperty = iter->second.second; + SValue value = GetInstancePropertyValue(thePropertySystem, theInstance, theProperty); + if (!value.empty()) { + SLong4 theLong4PropertyValue = value.getData<SLong4>(); + if (theLong4PropertyValue == theDeletedImageLong4) { + outMaterialInstance = theInstance; + outProperty = theProperty; + return true; + } + } + m_cachedImageParents.erase(iter); + } + TInstanceHandleList theInstances; m_DataCore->GetInstancesDerivedFrom( theInstances, m_DefaultMaterial.m_Instance); // Get all default material instances @@ -605,6 +622,7 @@ bool CClientDataModelBridge::GetMaterialFromImageInstance( if (theDeletedImageLong4 == theLong4PropertyValue) { outMaterialInstance = theInstance; outProperty = theProperty; + m_cachedImageParents.insert({inInstance, std::make_pair(theInstance, theProperty)}); return true; } } @@ -634,6 +652,7 @@ bool CClientDataModelBridge::GetMaterialFromImageInstance( if (theDeletedImageLong4 == theLong4PropertyValue) { outMaterialInstance = theInstance; outProperty = theProperty; + m_cachedImageParents.insert({inInstance, std::make_pair(theInstance, theProperty)}); return true; } } @@ -1172,34 +1191,55 @@ Qt3DSDMInstanceHandle CClientDataModelBridge::getMaterialReference(Qt3DSDMInstan return Qt3DSDMInstanceHandle(); } -bool CClientDataModelBridge::isMaterialContainer(Qt3DSDMInstanceHandle instance) const +bool CClientDataModelBridge::isMaterialContainer(Qt3DSDMInstanceHandle instance, + Qt3DSDMInstanceHandle materialContainer) const +{ + return instance.Valid() && instance == materialContainer; +} + +bool CClientDataModelBridge::isMaterialContainer(Qt3DSDMInstanceHandle instance) { return instance.Valid() && instance == getMaterialContainer(); } -bool CClientDataModelBridge::isInsideMaterialContainer(Qt3DSDMInstanceHandle instance) const +bool CClientDataModelBridge::isInsideMaterialContainer(Qt3DSDMInstanceHandle instance) { - auto parentInstance = GetParentInstance(instance); - if (parentInstance.Valid() && isMaterialContainer(parentInstance)) + return isInsideMaterialContainer(instance, GetParentInstance(instance), getMaterialContainer()); +} + +bool CClientDataModelBridge::isInsideMaterialContainer( + qt3dsdm::Qt3DSDMInstanceHandle instance, qt3dsdm::Qt3DSDMInstanceHandle parentInstance, + qt3dsdm::Qt3DSDMInstanceHandle materialContainer) +{ + Q_UNUSED(instance); + if (parentInstance.Valid() && isMaterialContainer(parentInstance, materialContainer)) return true; //Check if an image inside a material inside the material container parentInstance = GetParentInstance(parentInstance); if (parentInstance.Valid()) - return isMaterialContainer(parentInstance); + return isMaterialContainer(parentInstance, materialContainer); return false; } bool CClientDataModelBridge::isInsideMaterialContainerAndNotReferenced( - Qt3DSDMInstanceHandle instance) const + qt3dsdm::Qt3DSDMInstanceHandle instance) +{ + return isInsideMaterialContainerAndNotReferenced(instance, GetParentInstance(instance), + getMaterialContainer()); +} + +bool CClientDataModelBridge::isInsideMaterialContainerAndNotReferenced( + Qt3DSDMInstanceHandle instance, qt3dsdm::Qt3DSDMInstanceHandle parentInstance, + Qt3DSDMInstanceHandle materialContainer) { - if (isInsideMaterialContainer(instance)) { + if (isInsideMaterialContainer(instance, parentInstance, materialContainer)) { QVector<Qt3DSDMInstanceHandle> usedMats; m_Doc->getUsedSharedMaterials(usedMats); bool isReferenced = false; for (auto &usedMat : qAsConst(usedMats)) { - if (usedMat == instance || usedMat == GetParentInstance(instance)) { + if (usedMat == instance || usedMat == parentInstance) { isReferenced = true; break; } @@ -1219,12 +1259,12 @@ QString CClientDataModelBridge::getMaterialContainerName() const return QStringLiteral("__Container"); } -QString CClientDataModelBridge::getMaterialContainerParentPath() const +QString CClientDataModelBridge::getMaterialContainerParentPath() { return GetName(m_Doc->GetSceneInstance()).toQString(); } -QString CClientDataModelBridge::getMaterialContainerPath() const +QString CClientDataModelBridge::getMaterialContainerPath() { return getMaterialContainerParentPath() + QStringLiteral(".") + getMaterialContainerName(); } @@ -1252,7 +1292,7 @@ bool CClientDataModelBridge::isBasicMaterial(Qt3DSDMInstanceHandle instance) return false; } -Qt3DSDMInstanceHandle CClientDataModelBridge::getMaterialContainer() const +Qt3DSDMInstanceHandle CClientDataModelBridge::getMaterialContainer() { IObjectReferenceHelper *objRefHelper = m_Doc->GetDataModelObjectReferenceHelper(); if (objRefHelper) { @@ -1277,37 +1317,6 @@ TInstanceHandleList CClientDataModelBridge::GetItemBaseInstances() const } /** - * Get list of values from all instances derived from inParentInstance - */ -std::vector<SValue> CClientDataModelBridge::GetValueList(Qt3DSDMInstanceHandle inParentInstance, - Qt3DSDMPropertyHandle inProperty, - IValueFilter *inFilter) const -{ - std::vector<SValue> theValueList; - TInstanceHandleList theInstances; - m_DataCore->GetInstancesDerivedFrom(theInstances, inParentInstance); - - // Iterate through each instance derived from inParentInstance and get the inProperty property - // value. - for (TInstanceHandleList::const_iterator theIter = theInstances.begin(); - theIter != theInstances.end(); ++theIter) { - // Skip the parent instance. - if (*theIter == inParentInstance) - continue; - - if (!GetParentInstance(*theIter).Valid()) - continue; - - if (isInsideMaterialContainerAndNotReferenced(*theIter)) - continue; - - GetValueListFromAllSlides(*theIter, inProperty, theValueList, inFilter); - } - - return theValueList; -} - -/** * Get list of values from all slides */ void CClientDataModelBridge::GetValueListFromAllSlides(Qt3DSDMInstanceHandle inInstance, @@ -1364,15 +1373,111 @@ struct SValueListFilter : public IValueFilter } }; +std::vector<SValue> CClientDataModelBridge::getSourcePathListFromInstances( + const std::vector<Qt3DSDMInstanceHandle> &inParentInstance, + const std::vector<Qt3DSDMPropertyHandle> &inProperty, + IValueFilter *inFilter) +{ + IPropertySystem *thePropertySystem = m_Doc->GetStudioSystem()->GetPropertySystem(); + + auto getImageIds = [this, thePropertySystem](TInstanceHandleList instances) { + std::vector<std::pair<SLong4, qt3dsdm::Qt3DSDMInstanceHandle>> imageIds; + for (TInstanceHandleList::const_iterator theIter = instances.begin(); + theIter != instances.end(); ++theIter) { + TPropertyHandleList theProperties; + auto theInstance = *theIter; + thePropertySystem->GetAggregateInstanceProperties(theInstance, theProperties); + size_t thePropertyCount = theProperties.size(); + for (size_t thePropertyIndex = 0; thePropertyIndex < thePropertyCount; + ++thePropertyIndex) { + Qt3DSDMPropertyHandle theProperty = theProperties[thePropertyIndex]; + AdditionalMetaDataType::Value theAdditionalMetaDataType = + thePropertySystem->GetAdditionalMetaDataType(theInstance, theProperty); + + if (theAdditionalMetaDataType == AdditionalMetaDataType::Image) { + theProperties.push_back(theProperty); + SLong4 theLong4PropertyValue = GetSpecificInstancePropertyValue<SLong4>( + thePropertySystem, theInstance, theProperty); + imageIds.push_back(std::make_pair(theLong4PropertyValue, theInstance)); + } + } + } + return imageIds; + }; + + auto materialContainer = getMaterialContainer(); + + // Get all image parent instances + TInstanceHandleList parentInstances; + m_DataCore->GetInstancesDerivedFrom(parentInstances, m_DefaultMaterial.m_Instance); + m_DataCore->GetInstancesDerivedFrom(parentInstances, m_CustomMaterial.m_Instance); + m_DataCore->GetInstancesDerivedFrom(parentInstances, m_Layer.m_Instance); + + // Get all image properties + std::vector<std::pair<SLong4, qt3dsdm::Qt3DSDMInstanceHandle>> imageIdsParents + = getImageIds(parentInstances); + + auto getValueList = [this, thePropertySystem, materialContainer](std::vector<SValue> &theValueList, + Qt3DSDMInstanceHandle parentInstance, + Qt3DSDMPropertyHandle property, IValueFilter *inFilter, + const std::vector<std::pair<SLong4, qt3dsdm::Qt3DSDMInstanceHandle>> &imageIdsParents) { + TInstanceHandleList theInstances; + m_DataCore->GetInstancesDerivedFrom(theInstances, parentInstance); + + auto findParent = [](std::vector<std::pair<SLong4, qt3dsdm::Qt3DSDMInstanceHandle>> pairs, + const SLong4 &long4) -> qt3dsdm::Qt3DSDMInstanceHandle { + for (auto iter = pairs.begin(); iter != pairs.end(); iter++) { + if (iter->first == long4) + return iter->second; + } + return {}; + }; + + Q3DStudio::TGraphPtr theGraph = m_Doc->GetAssetGraph(); + + // Iterate through each instance derived from inParentInstance and get the inProperty property + // value. + for (TInstanceHandleList::const_iterator theIter = theInstances.begin(); + theIter != theInstances.end(); ++theIter) { + auto instance = *theIter; + // Skip the parent instance. + if (*theIter == m_SceneAsset.m_Instance) + continue; + + qt3dsdm::Qt3DSDMInstanceHandle parentInstance; + if (IsImageInstance(instance)) { + // find the image from the image properties + SLong4 theDeletedImageLong4 = + GetNamedInstancePropertyValue<SLong4>(thePropertySystem, instance, L"id"); + parentInstance = findParent(imageIdsParents, theDeletedImageLong4); + } else if (theGraph->IsExist(instance)) { + parentInstance = theGraph->GetParent(instance); + } + + if (!parentInstance.Valid()) + continue; + + if (isInsideMaterialContainerAndNotReferenced(*theIter, parentInstance, materialContainer)) + continue; + + GetValueListFromAllSlides(*theIter, property, theValueList, inFilter); + } + }; + std::vector<SValue> theValueList; + for (int i = 0; i < inParentInstance.size(); i++) + getValueList(theValueList, inParentInstance[i], inProperty[i], inFilter, imageIdsParents); + return theValueList; +} + /** * Get SourcePath list from all instances */ -std::set<QString> CClientDataModelBridge::GetSourcePathList() const +std::set<QString> CClientDataModelBridge::GetSourcePathList() { // Get the source path property list SValueListFilter theFilter(*this); - std::vector<SValue> theValueList = - GetValueList(m_SceneAsset.m_Instance, m_SceneAsset.m_SourcePath, &theFilter); + auto theValueList = getSourcePathListFromInstances({m_SceneAsset.m_Instance}, + {m_SceneAsset.m_SourcePath}, &theFilter); // Translate from SValue to QString and also remove the identifier std::set<QString> theSourcePathList; @@ -1388,10 +1493,11 @@ std::set<QString> CClientDataModelBridge::GetSourcePathList() const /** * Get Font file list from all Text instances */ -std::set<QString> CClientDataModelBridge::GetFontFileList() const +std::set<QString> CClientDataModelBridge::GetFontFileList() { // Get the font name property list - std::vector<SValue> theValueList = GetValueList(m_Text.m_Instance, m_Text.m_Font); + std::vector<SValue> theValueList = getSourcePathListFromInstances({m_Text.m_Instance}, + {m_Text.m_Font}, nullptr); std::set<QString> theFontNameList; for (auto &val : theValueList) { QString font = get<QString>(val); @@ -1432,7 +1538,7 @@ std::set<QString> CClientDataModelBridge::GetFontFileList() const static void GetDynamicObjecTextures(IDataCore &inDataCore, IPropertySystem &inPropertySystem, Qt3DSDMInstanceHandle inBaseInstance, std::vector<SValue> &outValues, - const CClientDataModelBridge &inBridge) + CClientDataModelBridge &inBridge) { std::vector<SValue> &theValueList(outValues); // Get all effect instances @@ -1481,7 +1587,7 @@ static void GetDynamicObjecTextures(IDataCore &inDataCore, IPropertySystem &inPr /** * Get texture list from all effect instances */ -std::set<QString> CClientDataModelBridge::GetDynamicObjectTextureList() const +std::set<QString> CClientDataModelBridge::GetDynamicObjectTextureList() { std::vector<SValue> theValueList; @@ -1505,7 +1611,7 @@ std::set<QString> CClientDataModelBridge::GetDynamicObjectTextureList() const return theSourcePathList; } -TInstanceHandleList CClientDataModelBridge::GetShaderInstances() const +TInstanceHandleList CClientDataModelBridge::GetShaderInstances() { TInstanceHandleList theCustomMatInstances; TInstanceHandleList theEffectInstances; @@ -1530,13 +1636,11 @@ TInstanceHandleList CClientDataModelBridge::GetShaderInstances() const return cleanedFxInstances; } -std::set<QString> CClientDataModelBridge::getRenderableList() const +std::set<QString> CClientDataModelBridge::getRenderableList() { - std::vector<SValue> valueList - = GetValueList(m_Layer.m_Instance, m_SceneAsset.m_SourcePath, nullptr); - std::vector<SValue> imageList - = GetValueList(m_SceneImage.m_Instance, m_SceneImage.m_SubPresentation, nullptr); - valueList.insert(valueList.end(), imageList.begin(), imageList.end()); + auto valueList = getSourcePathListFromInstances( + {m_Layer.m_Instance, m_SceneImage.m_Instance}, + {m_SceneAsset.m_SourcePath, m_SceneImage.m_SubPresentation}, nullptr); std::set<QString> idList; for (auto &val : valueList) { @@ -1710,7 +1814,7 @@ Q3DStudio::CId CClientDataModelBridge::GetGUID(qt3dsdm::Qt3DSDMInstanceHandle in } qt3dsdm::Qt3DSDMInstanceHandle -CClientDataModelBridge::GetParentInstance(qt3dsdm::Qt3DSDMInstanceHandle inInstance) const +CClientDataModelBridge::GetParentInstance(qt3dsdm::Qt3DSDMInstanceHandle inInstance) { if (IsImageInstance(inInstance)) { qt3dsdm::Qt3DSDMInstanceHandle theParentInstance; |