diff options
Diffstat (limited to 'src/Authoring/Client/Code/Core/Doc/IComposerSerializer.cpp')
-rw-r--r-- | src/Authoring/Client/Code/Core/Doc/IComposerSerializer.cpp | 450 |
1 files changed, 336 insertions, 114 deletions
diff --git a/src/Authoring/Client/Code/Core/Doc/IComposerSerializer.cpp b/src/Authoring/Client/Code/Core/Doc/IComposerSerializer.cpp index 07b24bc6..d3355260 100644 --- a/src/Authoring/Client/Code/Core/Doc/IComposerSerializer.cpp +++ b/src/Authoring/Client/Code/Core/Doc/IComposerSerializer.cpp @@ -48,9 +48,14 @@ #include "Qt3DSRenderPathManager.h" #include "Qt3DSDMGuides.h" #include "foundation/Qt3DSLogging.h" +#include "Qt3DSRenderDynamicObjectSystem.h" + #include <unordered_map> #include <unordered_set> +#include <QtCore/qrandom.h> +#include <QtCore/qdatetime.h> + using namespace qt3dsdm; using namespace std; using namespace Q3DStudio; @@ -120,47 +125,60 @@ using std::hash; template <typename TOperator> static void HandleKeyframe(SLinearKeyframe &inKeyframe, TOperator &inOperator) { - inOperator(inKeyframe.m_KeyframeSeconds); - inOperator(inKeyframe.m_KeyframeSeconds); + float kfTime = float(inKeyframe.m_time / 1000.f); + + inOperator(kfTime); + inOperator(inKeyframe.m_value); + + inKeyframe.m_time = long(kfTime * 1000.f); } template <typename TOperator> static void HandleKeyframe(SBezierKeyframe &inKeyframe, TOperator &inOperator) { - inOperator(inKeyframe.m_KeyframeSeconds); - inOperator(inKeyframe.m_KeyframeValue); - inOperator(inKeyframe.m_InTangentTime); + float kfTime = float(inKeyframe.m_time / 1000.f); + float tangentInTime = float(inKeyframe.m_InTangentTime / 1000.f); + float tangentOutTime = float(inKeyframe.m_OutTangentTime / 1000.f); + + inOperator(kfTime); + inOperator(inKeyframe.m_value); + inOperator(tangentInTime); inOperator(inKeyframe.m_InTangentValue); - inOperator(inKeyframe.m_OutTangentTime); + inOperator(tangentOutTime); inOperator(inKeyframe.m_OutTangentValue); + + inKeyframe.m_time = long(kfTime * 1000.f); + inKeyframe.m_InTangentTime = long(tangentInTime * 1000.f); + inKeyframe.m_OutTangentTime = long(tangentOutTime * 1000.f); } template <typename TOperator> static void HandleKeyframe(SEaseInEaseOutKeyframe &inKeyframe, TOperator &inOperator) { - inOperator(inKeyframe.m_KeyframeSeconds); - inOperator(inKeyframe.m_KeyframeValue); + float kfTime = float(inKeyframe.m_time / 1000.f); + inOperator(kfTime); + inOperator(inKeyframe.m_value); inOperator(inKeyframe.m_EaseIn); inOperator(inKeyframe.m_EaseOut); + + inKeyframe.m_time = long(kfTime * 1000.f); } -template <typename TItemType> -struct SVectorWriteOperator +struct KeyframeWriter { - vector<TItemType> &m_Vector; - SVectorWriteOperator(vector<TItemType> &vec) - : m_Vector(vec) + vector<float> &m_vector; + KeyframeWriter(vector<float> &vec) + : m_vector(vec) { } - void operator()(const TItemType &inValue) { m_Vector.push_back(inValue); } + void operator()(const float &inValue) { m_vector.push_back(inValue); } }; -template <typename TItemType> -struct SMemReadOperator +struct KeyframeReader { - const TItemType *m_Ptr; - const TItemType *m_End; - SMemReadOperator(const TItemType *s, const TItemType *e) + const float *m_Ptr; + const float *m_End; + KeyframeReader(const float *s, const float *e) : m_Ptr(s) , m_End(e) { @@ -168,7 +186,7 @@ struct SMemReadOperator bool IsDone() { return m_Ptr >= m_End; } - void operator()(TItemType &outValue) + void operator()(float &outValue) { if (m_Ptr < m_End) { outValue = *m_Ptr; @@ -183,7 +201,7 @@ template <typename TKeyframeType> static void WriteKeyframes(TKeyframeHandleList &inKeyframes, IAnimationCore &inCore, vector<float> &outValues) { - SVectorWriteOperator<float> theOperator(outValues); + KeyframeWriter theOperator(outValues); for (size_t idx = 0, end = inKeyframes.size(); idx < end; ++idx) { TKeyframe theKeyframeVariant(inCore.GetKeyframeData(inKeyframes[idx])); TKeyframeType theData(get<TKeyframeType>(theKeyframeVariant)); @@ -195,7 +213,7 @@ template <typename TKeyframeType> static void ReadKeyframes(Qt3DSDMAnimationHandle inAnimation, IAnimationCore &inCore, const float *inStart, const float *inEnd) { - SMemReadOperator<float> theOperator(inStart, inEnd); + KeyframeReader theOperator(inStart, inEnd); while (theOperator.IsDone() == false) { TKeyframeType theData; HandleKeyframe(theData, theOperator); @@ -290,22 +308,21 @@ struct SMetaDataPropertyEraser }; using std::unordered_set; using std::unordered_map; -using std::tuple; // Algorithm to write is to run through the graph, starting at the root instances // and write out the instances as we come to them. struct SComposerSerializerImpl : public IComposerSerializer { - typedef unordered_set<Qt3DSDMInstanceHandle, hash<int>> TInstanceSet; - typedef unordered_set<Qt3DSDMSlideHandle, hash<int>> TSlideSet; - typedef unordered_set<Qt3DSDMActionHandle, hash<int>> TActionSet; - typedef vector<Qt3DSDMInstanceHandle> TInstanceList; typedef unordered_map<int, TCharPtr> THandleToIdMap; typedef unordered_map<TCharPtr, int> TIdToHandleMap; typedef unordered_map<SLong4, int> TGUIDToHandleMap; typedef unordered_map<int, SLong4> THandleToGUIDMap; typedef unordered_map<Qt3DSDMInstanceHandle, int, hash<int>> TInstanceIntMap; typedef unordered_map<Qt3DSDMInstanceHandle, TCharPtr, hash<int>> TInstanceToSiblingMap; + typedef unordered_set<Qt3DSDMInstanceHandle, hash<int>> TInstanceSet; + typedef unordered_set<Qt3DSDMSlideHandle, hash<int>> TSlideSet; + typedef unordered_set<Qt3DSDMActionHandle, hash<int>> TActionSet; + typedef vector<Qt3DSDMInstanceHandle> TInstanceList; IDataCore &m_DataCore; IMetaData &m_MetaData; @@ -323,19 +340,16 @@ struct SComposerSerializerImpl : public IComposerSerializer qt3ds::render::IPathManager &m_PathManager; IPropertySystem &m_propertySystem; - // The instances we have discovered when we are writing + Qt3DSDMSlideHandle m_ActiveSlide; + Qt3DSDMSlideHandle m_ActiveSlideParent; + + // The unique ids for instances THandleToIdMap m_HandleToIdMap; TIdToHandleMap m_IdToHandleMap; - TGUIDToHandleMap m_GUIDToHandleMap; THandleToGUIDMap m_HandleToGUIDMap; - - Qt3DSDMSlideHandle m_ActiveSlide; - Qt3DSDMSlideHandle m_ActiveSlideParent; - THandleToIdMap m_ActionToIdMap; TIdToHandleMap m_IdToActionMap; - THandleToIdMap m_SlideToIdMap; TIdToHandleMap m_IdToSlideMap; @@ -365,6 +379,9 @@ struct SComposerSerializerImpl : public IComposerSerializer Option<int> m_UIPVersion; + QRandomGenerator m_randomGenerator; + QString m_documentPath; + SComposerSerializerImpl(IDataCore &inDataCore, IMetaData &inMetaData, ISlideCore &inSlideCore, IAnimationCore &inAnimationCore, IActionCore &inActionCore, CGraph &inAssetGraph, ISlideSystem &inSlideSystem, @@ -372,7 +389,7 @@ struct SComposerSerializerImpl : public IComposerSerializer SComposerObjectDefinitions &inObjectDefinitions, std::shared_ptr<Q3DStudio::IImportFailedHandler> inFailedHandler, IGuideSystem &inGuideSystem, qt3ds::render::IPathManager &inPathManager, - IPropertySystem &inPropSystem) + IPropertySystem &inPropSystem, const QString &documentPath) : m_DataCore(inDataCore) , m_MetaData(inMetaData) , m_SlideCore(inSlideCore) @@ -391,7 +408,9 @@ struct SComposerSerializerImpl : public IComposerSerializer , m_Foundation(Q3DStudio::Foundation::SStudioFoundation::Create()) , m_InputStreamFactory(qt3ds::render::IInputStreamFactory::Create(*m_Foundation.m_Foundation)) , m_PreserveFileIds(true) + , m_documentPath(documentPath) { + m_randomGenerator.seed(quint32(QTime::currentTime().msecsSinceStartOfDay())); } void reset() @@ -402,15 +421,15 @@ struct SComposerSerializerImpl : public IComposerSerializer m_GUIDToHandleMap.clear(); m_HandleToGUIDMap.clear(); - m_ActiveSlide = 0; - m_ActiveSlideParent = 0; - m_ActionToIdMap.clear(); m_IdToActionMap.clear(); m_SlideToIdMap.clear(); m_IdToSlideMap.clear(); + m_ActiveSlide = 0; + m_ActiveSlideParent = 0; + m_InstanceSet.clear(); m_SlideSet.clear(); m_ExternalReferences.clear(); @@ -430,6 +449,13 @@ struct SComposerSerializerImpl : public IComposerSerializer TCharPtr AddId(const wstring &inId, Qt3DSDMInstanceHandle inHandle) { TCharPtr theIdStr = m_StringTable.RegisterStr(inId.c_str()); + if (m_IdToHandleMap.find(theIdStr) != m_IdToHandleMap.end() + && m_IdToHandleMap.find(theIdStr)->second != inHandle) { + m_ImportFailedHandler->DisplayImportFailed( + m_documentPath, QObject::tr("Duplicate object id detected: ") + + QString::fromWCharArray(theIdStr), false); + return theIdStr; + } m_IdToHandleMap.insert(make_pair(theIdStr, inHandle)); m_HandleToIdMap.insert(make_pair(inHandle, theIdStr)); if (m_PreserveFileIds) @@ -452,16 +478,39 @@ struct SComposerSerializerImpl : public IComposerSerializer TCharPtr AddActionId(const wstring &inId, Qt3DSDMActionHandle inHandle) { TCharPtr theIdStr = m_StringTable.RegisterStr(inId.c_str()); + if (m_IdToActionMap.find(theIdStr) != m_IdToActionMap.end() + && m_IdToActionMap.find(theIdStr)->second != inHandle) { + m_ImportFailedHandler->DisplayImportFailed( + m_documentPath, QObject::tr("Duplicate action id detected: ") + + QString::fromWCharArray(theIdStr), false); + return theIdStr; + } m_IdToActionMap.insert(make_pair(theIdStr, inHandle)); m_ActionToIdMap.insert(make_pair(inHandle, theIdStr)); + if (m_PreserveFileIds) { + m_DataCore.SetInstancePropertyValue(m_ActionCore.GetActionInstance(inHandle), + m_ObjectDefinitions.m_Action.m_FileId, + std::make_shared<CDataStr>(inId.c_str())); + } return theIdStr; } TCharPtr AddSlideId(const wstring &inId, Qt3DSDMSlideHandle inHandle) { TCharPtr theIdStr = m_StringTable.RegisterStr(inId.c_str()); + if (m_IdToActionMap.find(theIdStr) != m_IdToActionMap.end() + && m_IdToActionMap.find(theIdStr)->second != inHandle) { + m_ImportFailedHandler->DisplayImportFailed( + m_documentPath, QObject::tr("Duplicate slide id detected: ") + + QString::fromWCharArray(theIdStr), false); + return theIdStr; + } m_IdToSlideMap.insert(make_pair(theIdStr, inHandle)); m_SlideToIdMap.insert(make_pair(inHandle, theIdStr)); + if (m_PreserveFileIds) + m_DataCore.SetInstancePropertyValue(m_SlideCore.GetSlideInstance(inHandle), + m_ObjectDefinitions.m_Slide.m_FileId, + std::make_shared<CDataStr>(inId.c_str())); return theIdStr; } @@ -569,30 +618,69 @@ struct SComposerSerializerImpl : public IComposerSerializer return GetInstanceName(inInstance); } - TCharPtr GetId(const wstring &inIdStem) + TCharPtr GetId(const wstring &inIdStem, CDataModelHandle instance) { // Create an ID for this instance - wstring theTypeStr(inIdStem); - wstring theTypeStem(theTypeStr); - wstring::size_type thePos = theTypeStem.find_last_of('_'); - if (thePos != wstring::npos && thePos < theTypeStem.size() - 2) { - if (theTypeStem[thePos + 1] >= '0' && theTypeStem[thePos + 1] <= '1') - theTypeStem = theTypeStem.substr(0, thePos); - } - QT3DSU32 idIdx = 1; + if (m_PreserveFileIds) { + // permanent id + QString stem = instanceId(instance); + if (stem.isEmpty()) + stem = QString::fromWCharArray(inIdStem.c_str()); + int pos = stem.lastIndexOf(QLatin1Char('_')); + if (pos > 0) { + // Already has unique id + bool isNumber; + stem.mid(pos+2).toInt(&isNumber); + if (stem.at(pos+1) == QLatin1Char('u') && isNumber) { + QByteArray warr; + warr.resize(sizeof(wchar_t) * (stem.length() + 1)); + warr.fill(0); + stem.toWCharArray(reinterpret_cast<wchar_t *>(warr.data())); + return m_StringTable.RegisterStr(reinterpret_cast<wchar_t *>(warr.data())); + } + } - while (m_IdToActionMap.find(m_StringTable.RegisterStr(theTypeStr.c_str())) - != m_IdToActionMap.end() - || m_IdToHandleMap.find(m_StringTable.RegisterStr(theTypeStr.c_str())) - != m_IdToHandleMap.end() - || m_IdToSlideMap.find(m_StringTable.RegisterStr(theTypeStr.c_str())) - != m_IdToSlideMap.end()) { - wchar_t theBuffer[16]; - swprintf(theBuffer, 16, L"_%03d", idIdx); - theTypeStr = theTypeStem + theBuffer; - ++idIdx; + // Create an ID for this instance + QByteArray buffer; + wchar_t *str; + do { + int rid = m_randomGenerator.bounded(65536); + QString nid = QStringLiteral("%1_u%2").arg(stem).arg(rid); + buffer.resize((nid.length() + 1) * sizeof(wchar_t)); + buffer.fill(0); + str = reinterpret_cast<wchar_t *>(buffer.data()); + nid.toWCharArray(str); + } while (m_IdToActionMap.find(m_StringTable.RegisterStr(str)) != m_IdToActionMap.end() + || m_IdToHandleMap.find(m_StringTable.RegisterStr(str)) + != m_IdToHandleMap.end() + || m_IdToSlideMap.find(m_StringTable.RegisterStr(str)) + != m_IdToSlideMap.end()); + + return m_StringTable.RegisterStr(str); + } else { + // temporary id + wstring theTypeStr(inIdStem); + wstring theTypeStem(theTypeStr); + wstring::size_type thePos = theTypeStem.find_last_of('_'); + if (thePos != wstring::npos && thePos < theTypeStem.size() - 2) { + if (theTypeStem[thePos + 1] >= '0' && theTypeStem[thePos + 1] <= '9') + theTypeStem = theTypeStem.substr(0, thePos); + } + QT3DSU32 idIdx = 1; + + while (m_IdToActionMap.find(m_StringTable.RegisterStr(theTypeStr.c_str())) + != m_IdToActionMap.end() + || m_IdToHandleMap.find(m_StringTable.RegisterStr(theTypeStr.c_str())) + != m_IdToHandleMap.end() + || m_IdToSlideMap.find(m_StringTable.RegisterStr(theTypeStr.c_str())) + != m_IdToSlideMap.end()) { + wchar_t theBuffer[16]; + swprintf(theBuffer, 16, L"_%03d", idIdx); + theTypeStr = theTypeStem + theBuffer; + ++idIdx; + } + return m_StringTable.RegisterStr(theTypeStr.c_str()); } - return m_StringTable.RegisterStr(theTypeStr.c_str()); } TCharPtr GetInstanceId(Qt3DSDMInstanceHandle inInstance) @@ -647,13 +735,13 @@ struct SComposerSerializerImpl : public IComposerSerializer } if (theProperty.Valid()) { theIdStr.append(m_DataCore.GetProperty(theProperty).m_Name.wide_str()); - theNewId = GetId(theIdStr); + theNewId = GetId(theIdStr, inInstance); } } } if (IsTrivial(theNewId)) - theNewId = GetId(theName.wide_str()); + theNewId = GetId(theName.wide_str(), inInstance); return AddId(theNewId, inInstance); } @@ -667,13 +755,23 @@ struct SComposerSerializerImpl : public IComposerSerializer wstring theActionName(GetInstanceName(inInstance, inSlide)); theActionName.append(L"-Action"); - - TCharPtr theNewId = GetId(theActionName); + TCharPtr theNewId; + if (m_PreserveFileIds) { + Qt3DSDMInstanceHandle actionInstance = m_ActionCore.GetActionInstance(inAction); + SValue theValue; + if (m_DataCore.GetInstancePropertyValue( + actionInstance, m_ObjectDefinitions.m_Action.m_FileId, theValue)) { + TDataStrPtr fileId(get<TDataStrPtr>(theValue)); + theNewId = fileId->GetData(); + if (!IsTrivial(theNewId)) + return AddSlideId(GetId(theNewId, actionInstance), inSlide); + return AddSlideId(GetId(theActionName, actionInstance), inSlide); + } + } + theNewId = GetId(theActionName, inInstance); return AddActionId(theNewId, inAction); } - // If this function is called with an invalid instance and we don't already have an id - // then we assume we have an external reference and lookup the instance via the component id. TCharPtr GetSlideId(Qt3DSDMSlideHandle inSlide, Qt3DSDMInstanceHandle inInstance) { QT3DS_ASSERT(inSlide.Valid()); @@ -697,7 +795,21 @@ struct SComposerSerializerImpl : public IComposerSerializer theSlideName.append(L"-"); theSlideName.append(GetSlideName(inSlide)); - TCharPtr theNewId = GetId(theSlideName); + TCharPtr theNewId; + if (m_PreserveFileIds) { + Qt3DSDMInstanceHandle slideInstance = m_SlideCore.GetSlideInstance(inSlide); + SValue theValue; + if (m_DataCore.GetInstancePropertyValue( + slideInstance, m_ObjectDefinitions.m_Slide.m_FileId, theValue)) { + TDataStrPtr fileId(get<TDataStrPtr>(theValue)); + theNewId = fileId->GetData(); + if (!IsTrivial(theNewId)) + return AddSlideId(GetId(theNewId, slideInstance), inSlide); + return AddSlideId(GetId(theSlideName, slideInstance), inSlide); + } + } + + theNewId = GetId(theSlideName, inInstance); return AddSlideId(theNewId, inSlide); } @@ -721,6 +833,24 @@ struct SComposerSerializerImpl : public IComposerSerializer return SLong4(); } + QString instanceId(CDataModelHandle inInstance) { + SValue theInstanceIdValue; + TDataStrPtr theNamePtr; + if (!m_DataCore.GetInstancePropertyValue( + inInstance, m_ObjectDefinitions.m_Asset.m_FileId, theInstanceIdValue)) { + if (!m_DataCore.GetInstancePropertyValue( + inInstance, m_ObjectDefinitions.m_Slide.m_FileId, theInstanceIdValue)) { + m_DataCore.GetInstancePropertyValue( + inInstance, m_ObjectDefinitions.m_Action.m_FileId, theInstanceIdValue); + } + } + theNamePtr = qt3dsdm::get<TDataStrPtr>(theInstanceIdValue); + if (theNamePtr && !IsTrivial(theNamePtr->GetData())) + return theNamePtr->toQString(); + return {}; + } + + void GetAllInstanceGuids() { TInstanceHandleList theInstances; @@ -739,9 +869,23 @@ struct SComposerSerializerImpl : public IComposerSerializer theInstance, m_ObjectDefinitions.m_Asset.m_FileId, theInstanceIdValue)) { TDataStrPtr theNamePtr = qt3dsdm::get<TDataStrPtr>(theInstanceIdValue); if (theNamePtr && !IsTrivial(theNamePtr->GetData())) { - const wchar_t *theId = GetId(theNamePtr->GetData()); + const wchar_t *theId = GetId(theNamePtr->GetData(), theInstance); AddId(theId, theInstance); } + } else if (m_DataCore.GetInstancePropertyValue( + theInstance, m_ObjectDefinitions.m_Slide.m_FileId, theInstanceIdValue)) { + TDataStrPtr theNamePtr = qt3dsdm::get<TDataStrPtr>(theInstanceIdValue); + if (theNamePtr && !IsTrivial(theNamePtr->GetData())) { + const wchar_t *theId = GetId(theNamePtr->GetData(), theInstance); + AddSlideId(theId, theInstance); + } + } else if (m_DataCore.GetInstancePropertyValue( + theInstance, m_ObjectDefinitions.m_Action.m_FileId, theInstanceIdValue)) { + TDataStrPtr theNamePtr = qt3dsdm::get<TDataStrPtr>(theInstanceIdValue); + if (theNamePtr && !IsTrivial(theNamePtr->GetData())) { + const wchar_t *theId = GetId(theNamePtr->GetData(), theInstance); + AddActionId(theId, theInstance); + } } } } @@ -834,9 +978,15 @@ struct SComposerSerializerImpl : public IComposerSerializer } else { m_TempBuffer.clear(); WCharTWriter theWriter(m_TempBuffer); - WStrOps<SValue>().ToBuf(theValue, theWriter); - - if (GetValueType(theValue) == DataModelDataType::String || m_TempBuffer.size()) { + if (theValueType == DataModelDataType::String || !theValue.empty()) { + // QT3DS-3993: store line feeds as replacement chars in UIP + if (theValueType == DataModelDataType::String) { + TDataStrPtr strPtr = get<TDataStrPtr>(theValue); + auto strValue = QString::fromWCharArray(strPtr->GetData()); + strValue.replace("\n", LINE_BREAK_SUBSTITUTE); + theValue = std::make_shared<CDataStr>(CString::fromQString(strValue)); + } + WStrOps<SValue>().ToBuf(theValue, theWriter); char buffer[] = { 0, 0, 0, 0 }; m_TempBuffer.write(buffer, 4); theValueStr.assign((const wchar_t *)m_TempBuffer.begin()); @@ -865,8 +1015,13 @@ struct SComposerSerializerImpl : public IComposerSerializer return SStringOrInt(std::make_shared<CDataStr>(inValue)); } - if (inType == DataModelDataType::String) - return std::make_shared<CDataStr>(inValue); + if (inType == DataModelDataType::String) { + // QT3DS-3993: store line feeds as replacement chars in UIP + auto valueStr = std::make_shared<CDataStr>(inValue); + auto val = QString::fromStdWString(valueStr->GetData()); + val.replace(LINE_BREAK_SUBSTITUTE, "\n"); + return std::make_shared<CDataStr>(CString::fromQString(val)); + } qt3ds::foundation::ConvertUTF( reinterpret_cast<const qt3ds::foundation::TWCharEASTLConverter::TCharType *>(inValue), 0, @@ -916,6 +1071,19 @@ struct SComposerSerializerImpl : public IComposerSerializer } } + SLong4 ParseGUID(TCharPtr inValue) + { + // One of two things, either an ID reference *or* pure string. + if (IsTrivial(inValue)) + return SLong4(); + if (inValue[0] == '#') { + // absolute reference. + Qt3DSDMInstanceHandle theInstance = GetInstanceById(inValue + 1); + return theInstance.Valid() ? GetInstanceGuid(theInstance) : SLong4(); + } + return SLong4(); + } + void SerializePropertyList(qt3dsdm::IDOMWriter &inWriter, TPropertyHandleValuePairList &inList) { sort(inList.begin(), inList.end(), SAttributeNameSorter(m_DataCore)); @@ -977,7 +1145,7 @@ struct SComposerSerializerImpl : public IComposerSerializer SMetaDataPropertyInfo thePropertyInfo( m_MetaData.GetMetaDataPropertyInfo(theMetaDataProperty)); wstring theName = thePropertyInfo.m_Name.wide_str(); - size_t theArity = get<1>(GetDatatypeAnimatableAndArity(thePropertyInfo.GetDataType())); + size_t theArity = getDatatypeAnimatableArity(thePropertyInfo.GetDataType()); if (theArity > 1) { theName.append(L"."); switch (theInfo.m_Index) { @@ -1081,12 +1249,8 @@ struct SComposerSerializerImpl : public IComposerSerializer return; } SMetaDataPropertyInfo theInfo(m_MetaData.GetMetaDataPropertyInfo(theProperty)); - std::tuple<bool, size_t> theAnimAndArity = GetDatatypeAnimatableAndArity(theInfo.GetDataType()); - if (std::get<0>(theAnimAndArity) == false) { - QT3DS_ASSERT(false); - return; - } - if (std::get<1>(theAnimAndArity) <= subIndex) { + size_t theArity = getDatatypeAnimatableArity(theInfo.GetDataType()); + if (theArity == 0 || theArity <= subIndex) { QT3DS_ASSERT(false); return; } @@ -1470,6 +1634,7 @@ struct SComposerSerializerImpl : public IComposerSerializer erase_if(outList, SPropertyMatches(m_ObjectDefinitions.m_Slide.m_ComponentId)); erase_if(outList, SPropertyMatches(m_ObjectDefinitions.m_Named.m_NameProp)); erase_if(outList, SPropertyMatches(m_ObjectDefinitions.m_Typed.m_TypeProp)); + erase_if(outList, SPropertyMatches(m_ObjectDefinitions.m_Slide.m_FileId)); } Option<pair<Qt3DSDMPropertyHandle, SValue>> ParseValue(Qt3DSDMInstanceHandle inInstance, @@ -1485,7 +1650,7 @@ struct SComposerSerializerImpl : public IComposerSerializer } void ParseInstanceProperties(IDOMReader &inReader, Qt3DSDMInstanceHandle inInstance, - vector<pair<TCharPtr, TCharPtr>> &outExtraAttributes, + QVector<pair<TCharPtr, TCharPtr>> &outExtraAttributes, TPropertyHandleValuePairList &outProperties) { bool hasNoLifetime = @@ -1512,7 +1677,7 @@ struct SComposerSerializerImpl : public IComposerSerializer void ParseAndSetInstanceProperties(IDOMReader &inReader, Qt3DSDMSlideHandle inSlide, Qt3DSDMInstanceHandle inInstance, - vector<pair<TCharPtr, TCharPtr>> &outExtraAttributes, + QVector<pair<TCharPtr, TCharPtr>> &outExtraAttributes, TPropertyHandleValuePairList &ioProperties) { outExtraAttributes.clear(); @@ -1526,13 +1691,28 @@ struct SComposerSerializerImpl : public IComposerSerializer // is to preserve behavior on old presentations that relied on hardcoding. bool hasMappingAsProbe = false; bool hasTilingH = false; + bool isDynamicObjectInstance + = m_DataCore.IsInstanceOrDerivedFrom(inInstance, + m_ObjectDefinitions.m_CustomMaterial.m_Instance) + || m_DataCore.IsInstanceOrDerivedFrom(inInstance, + m_ObjectDefinitions.m_Effect.m_Instance); for (size_t idx = 0, end = ioProperties.size(); idx < end; ++idx) { + auto &prop = ioProperties[idx]; if (ioProperties[idx].first == m_ObjectDefinitions.m_Image.m_TilingU) hasTilingH = true; if (ioProperties[idx].first == m_ObjectDefinitions.m_Image.m_TextureMapping && ioProperties[idx].second.toQVariant() == QVariant("Light Probe")) { hasMappingAsProbe = true; } + if (prop.second.getType() == qt3dsdm::DataModelDataType::String + && isDynamicObjectInstance) { + qt3dsdm::TDataStrPtr value = qt3dsdm::get<qt3dsdm::TDataStrPtr>(prop.second); + QString string = QString::fromWCharArray(value->GetData()); + if (string.startsWith(QLatin1Char('#'))) { + SLong4 guid = ParseGUID(value->GetData()); + prop.second = SValue(guid); + } + } } if (!hasTilingH && hasMappingAsProbe) { @@ -1652,6 +1832,34 @@ struct SComposerSerializerImpl : public IComposerSerializer // Write out the properties for the active slide. TPropertyHandleValuePairList theValues; GetSpecificInstancePropertyValues(inInstance, theValues); + bool isDynamicObjectInstance + = m_DataCore.IsInstanceOrDerivedFrom(inInstance, + m_ObjectDefinitions.m_CustomMaterial.m_Instance) + || m_DataCore.IsInstanceOrDerivedFrom(inInstance, + m_ObjectDefinitions.m_Effect.m_Instance); + + if (isDynamicObjectInstance) { + // Remove default string values from serialized values + TInstanceHandleList parents; + m_DataCore.GetInstanceParents(inInstance, parents); + SMetaDataDynamicObject *dynObj = m_MetaData.GetDynamicObjectByInstance(parents[0]); + if (!dynObj) + return false; + for (int i = 0; i < dynObj->m_Properties.size(); i++) { + auto &prop = dynObj->m_Properties[i]; + for (auto iter = theValues.begin(); iter != theValues.end(); iter++) { + const pair<Qt3DSDMPropertyHandle, SValue> &theValue(*iter); + TCharStr theName(m_DataCore.GetProperty(theValue.first).m_Name); + CRegisteredString name = m_StringTable.GetRenderStringTable() + .RegisterStr(theName.c_str()); + if (name == prop.m_Name && prop.m_DataType + == qt3ds::render::NVRenderShaderDataTypes::NVRenderTexture2DPtr) { + theValues.erase(iter); + break; + } + } + } + } SerializePropertyList(inWriter, theValues); if (theMasterRef.size()) @@ -1742,10 +1950,6 @@ struct SComposerSerializerImpl : public IComposerSerializer m_NewInstancesToSiblings.insert(std::make_pair(theNewInstance, theSiblingRef + 1)); SLong4 theGuid = GetGuid(theNewInstance, m_ObjectDefinitions.m_Guided.m_GuidProp); - if (m_PreserveFileIds) - m_DataCore.SetInstancePropertyValue(theNewInstance, - m_ObjectDefinitions.m_Asset.m_FileId, - std::make_shared<CDataStr>(theId)); SetId(theId, theNewInstance); AddGuid(theGuid, theNewInstance); @@ -1786,7 +1990,7 @@ struct SComposerSerializerImpl : public IComposerSerializer } TPropertyHandleValuePairList theValues; - vector<pair<TCharPtr, TCharPtr>> theExtraAtts; + QVector<pair<TCharPtr, TCharPtr>> theExtraAtts; ParseAndSetInstanceProperties(inReader, 0, theNewInstance, theExtraAtts, theValues); ReadInstanceProperties(inReader); @@ -2109,7 +2313,7 @@ struct SComposerSerializerImpl : public IComposerSerializer { IDOMReader::Scope __stateScope(inReader); TPropertyHandleValuePairList theValues; - vector<pair<TCharPtr, TCharPtr>> theExtraAtts; + QVector<pair<TCharPtr, TCharPtr>> theExtraAtts; ParseAndSetInstanceProperties(inReader, 0, m_SlideCore.GetSlideInstance(inSlide), theExtraAtts, theValues); // Slides require a two-pass parsing system because slides can refer to each other via id. @@ -2385,7 +2589,8 @@ struct SComposerSerializerImpl : public IComposerSerializer } void DoSerializeScene(IDOMWriter &inWriter, const Qt3DSDMInstanceHandle *inTopInstances, - QT3DSU32 inCount, bool inWriteParentRefs = false) + QT3DSU32 inCount, bool inWriteParentRefs = false, + const Q3DStudio::CFilePath *inDocumentDirectory = nullptr) { GetAllInstanceGuids(); { @@ -2411,15 +2616,27 @@ struct SComposerSerializerImpl : public IComposerSerializer QT3DS_ASSERT(false); continue; } - IDOMWriter::Scope instScope(inWriter, theType->wide_str()); - inWriter.Att(L"id", GetInstanceId(theMaster)); - // Write out all the properties that are on the instance but are not on *this* - // instance in the meta data. - TPropertyHandleValuePairList theProperties; - GetSpecificInstancePropertyValues(theMaster, theProperties); - erase_if(theProperties, - SMetaDataPropertyEraser(theMaster, m_ObjectDefinitions)); - SerializePropertyList(inWriter, theProperties); + SValue value; + m_DataCore.GetInstancePropertyValue(theMaster, + m_ObjectDefinitions.m_Asset.m_SourcePath, + value); + if (!value.empty()) { + CFilePath sourcePath(value.getData<qt3dsdm::TDataStrPtr>()->GetData()); + CFilePath theFullPath = CFilePath::CombineBaseAndRelative( + (inDocumentDirectory ? (*inDocumentDirectory) : CFilePath()), + sourcePath); + if (!inDocumentDirectory || theFullPath.Exists()) { + IDOMWriter::Scope instScope(inWriter, theType->wide_str()); + inWriter.Att(L"id", GetInstanceId(theMaster)); + // Write out all the properties that are on the instance but are not on *this* + // instance in the meta data. + TPropertyHandleValuePairList theProperties; + GetSpecificInstancePropertyValues(theMaster, theProperties); + erase_if(theProperties, + SMetaDataPropertyEraser(theMaster, m_ObjectDefinitions)); + SerializePropertyList(inWriter, theProperties); + } + } } } inWriter.MoveBefore(L"Classes", L"Graph"); @@ -2517,7 +2734,7 @@ struct SComposerSerializerImpl : public IComposerSerializer theMaster = m_DataCore.CreateInstance(); m_DataCore.DeriveInstance(theMaster, theCanonicalType); TPropertyHandleValuePairList theValues; - vector<pair<TCharPtr, TCharPtr>> theExtraAtts; + QVector<pair<TCharPtr, TCharPtr>> theExtraAtts; m_SourcePathToMasterInstances.insert( make_pair(m_StringTable.RegisterStr(theSourcePath), theMaster)); @@ -2676,7 +2893,8 @@ struct SComposerSerializerImpl : public IComposerSerializer } }; - void SerializeScene(IDOMWriter &inWriter) override + void SerializeScene(IDOMWriter &inWriter, + const Q3DStudio::CFilePath &inDocumentDirectory) override { reset(); ScopedPreserveFileIds __preserveFileIds(m_PreserveFileIds); @@ -2690,7 +2908,7 @@ struct SComposerSerializerImpl : public IComposerSerializer if (theGraphRoots.empty()) return; QT3DS_ASSERT(theGraphRoots.size() == 1); - DoSerializeScene(inWriter, &theGraphRoots[0], 1); + DoSerializeScene(inWriter, &theGraphRoots[0], 1, false, &inDocumentDirectory); TGuideHandleList theGuides = m_GuideSystem.GetAllGuides(); // sort the guides by handle value to keep the file as stable as possible. std::sort(theGuides.begin(), theGuides.end()); @@ -2735,26 +2953,28 @@ struct SComposerSerializerImpl : public IComposerSerializer // new root. virtual qt3dsdm::TInstanceHandleList SerializeSceneGraphObject(IDOMReader &inReader, const CFilePath &inDocumentDirectory, - Qt3DSDMInstanceHandle inNewRoot, Qt3DSDMSlideHandle inActiveSlide) override + Qt3DSDMInstanceHandle inNewRoot, Qt3DSDMSlideHandle inActiveSlide, + bool preserveFileIds) override { reset(); m_ActiveSlide = inActiveSlide; - m_PreserveFileIds = false; + m_PreserveFileIds = preserveFileIds; return DoSerializeScene(inReader, inDocumentDirectory, inNewRoot); } // Write this instance and its children (and possibly its slides) to a writer. // Equivalent to the older partial serialization system void SerializeSceneGraphObjects(IDOMWriter &inWriter, - const TInstanceHandleList &inInstances, - Qt3DSDMSlideHandle inActiveSlide) override + const TInstanceHandleList &inInstances, + Qt3DSDMSlideHandle inActiveSlide, + bool preserveFileIds) override { if (inInstances.empty()) return; reset(); QT3DS_ASSERT(inActiveSlide.Valid()); m_ActiveSlide = inActiveSlide; - m_PreserveFileIds = false; + m_PreserveFileIds = preserveFileIds; // It is fine if the parent is invalid m_ActiveSlideParent = m_SlideCore.GetParentSlide(m_ActiveSlide); DoSerializeScene(inWriter, inInstances.data(), (QT3DSU32)inInstances.size()); @@ -2844,8 +3064,8 @@ struct SComposerSerializerImpl : public IComposerSerializer } Qt3DSDMSlideHandle SerializeSlide(qt3dsdm::IDOMReader &inReader, - const CFilePath &inDocumentDirectory, - qt3dsdm::Qt3DSDMSlideHandle inMaster, int newIndex) override + const CFilePath &inDocumentDirectory, + qt3dsdm::Qt3DSDMSlideHandle inMaster, int newIndex) override { reset(); m_PreserveFileIds = false; @@ -2867,13 +3087,15 @@ struct SComposerSerializerImpl : public IComposerSerializer std::shared_ptr<IComposerSerializer> IComposerSerializer::CreateGraphSlideSerializer( IDataCore &inDataCore, IMetaData &inMetaData, ISlideCore &inSlideCore, IAnimationCore &inAnimationCore, IActionCore &inActionCore, CGraph &inAssetGraph, - ISlideSystem &inSlideSystem, IActionSystem &inActionSystem, ISlideGraphCore &inSlideGraphCore, - SComposerObjectDefinitions &inObjectDefinitions, - std::shared_ptr<Q3DStudio::IImportFailedHandler> inFailedHandler, IGuideSystem &inGuideSystem, - qt3ds::render::IPathManager &inPathManager, IPropertySystem &inPropSystem) + ISlideSystem &inSlideSystem, IActionSystem &inActionSystem, + ISlideGraphCore &inSlideGraphCore, SComposerObjectDefinitions &inObjectDefinitions, + std::shared_ptr<Q3DStudio::IImportFailedHandler> inFailedHandler, + IGuideSystem &inGuideSystem, qt3ds::render::IPathManager &inPathManager, + IPropertySystem &inPropSystem, const QString &documentPath) { - return std::shared_ptr<SComposerSerializerImpl>(new SComposerSerializerImpl( - inDataCore, inMetaData, inSlideCore, inAnimationCore, inActionCore, inAssetGraph, - inSlideSystem, inActionSystem, inSlideGraphCore, inObjectDefinitions, inFailedHandler, - inGuideSystem, inPathManager, inPropSystem)); + return std::shared_ptr<SComposerSerializerImpl>( + new SComposerSerializerImpl( + inDataCore, inMetaData, inSlideCore, inAnimationCore, inActionCore, inAssetGraph, + inSlideSystem, inActionSystem, inSlideGraphCore, inObjectDefinitions, inFailedHandler, + inGuideSystem, inPathManager, inPropSystem, documentPath)); } |