diff options
author | Miikka Heikkinen <miikka.heikkinen@qt.io> | 2019-05-24 17:56:45 +0300 |
---|---|---|
committer | Miikka Heikkinen <miikka.heikkinen@qt.io> | 2019-05-27 10:56:55 +0300 |
commit | f54d0cfb79d865374bf0f100d99cd03bfa7ce5dc (patch) | |
tree | 28c2421bb8da5b277714720550cfa2fa6ab661f0 | |
parent | 6458fc74abaeb0a0cf27024bca559da82b99cfae (diff) |
Fix creating elements in subpresentations
Task-number: QT3DS-3526
Change-Id: Ic22c1c8df61bc210250649ef59a1f56512807146
Reviewed-by: Antti Määttä <antti.maatta@qt.io>
Reviewed-by: Mahmoud Badri <mahmoud.badri@qt.io>
Reviewed-by: Tomi Korpipää <tomi.korpipaa@qt.io>
-rw-r--r-- | src/Runtime/Source/runtime/Qt3DSQmlEngine.cpp | 94 | ||||
-rw-r--r-- | src/Runtime/Source/runtimerender/rendererimpl/Qt3DSRendererImpl.cpp | 13 |
2 files changed, 59 insertions, 48 deletions
diff --git a/src/Runtime/Source/runtime/Qt3DSQmlEngine.cpp b/src/Runtime/Source/runtime/Qt3DSQmlEngine.cpp index 3249c6d4..e5aecc74 100644 --- a/src/Runtime/Source/runtime/Qt3DSQmlEngine.cpp +++ b/src/Runtime/Source/runtime/Qt3DSQmlEngine.cpp @@ -527,10 +527,8 @@ private: QVector3D parseFloat3Property(const QString &propValue); QVector4D parseFloat4Property(const QString &propValue); - void notifyElementCreation(CPresentation *pres, const QStringList &elementNames, - const QString &error); - void notifyMaterialCreation(CPresentation *pres, const QStringList &materialNames, - const QString &error); + void notifyElementCreation(const QStringList &elementNames, const QString &error); + void notifyMaterialCreation(const QStringList &materialNames, const QString &error); void deleteElements(const QVector<TElement *> &elements, qt3ds::render::IQt3DSRenderer *renderer); }; @@ -943,9 +941,18 @@ void CQmlEngineImpl::createElements(const QString &parentElementPath, const QStr CPresentation *presentation = nullptr; QStringList elementPaths; elementPaths.reserve(properties.size()); - for (auto &props : properties) { - elementPaths << parentElementPath + QLatin1Char('.') - + props.value(QStringLiteral("name")).toString(); + QVector<QHash<QString, QVariant>> theProperties = properties; + const QString namePropName = QStringLiteral("name"); + + for (int i = 0; i < theProperties.size(); ++i) { + auto &props = theProperties[i]; + QString newElementName = props.value(namePropName).toString(); + if (newElementName.isEmpty()) { + // The id number on generated name will match generated graph object identifiers + newElementName = QStringLiteral("NewElement_%1").arg(_idCounter + i + 1); + props.insert(namePropName, newElementName); + } + elementPaths << parentElementPath + QLatin1Char('.') + newElementName; } QVector<TElement *> createdElements; TElement *parentElement = nullptr; @@ -953,7 +960,7 @@ void CQmlEngineImpl::createElements(const QString &parentElementPath, const QStr auto handleError = [&]() { if (!error.isEmpty()) deleteElements(createdElements, renderer); - notifyElementCreation(presentation, elementPaths, error); + notifyElementCreation(elementPaths, error); }; // Resolve parent element @@ -962,14 +969,11 @@ void CQmlEngineImpl::createElements(const QString &parentElementPath, const QStr if (!parentElement) { error = QObject::tr("Invalid parent element: '%1'").arg(parentElementPath); - TElement *sceneElement = getTarget("Scene"); - presentation = static_cast<CPresentation *>(sceneElement->GetBelongedPresentation()); handleError(); return; } - auto parentTranslator = static_cast<Qt3DSTranslator *>( - parentElement->GetAssociation()); + auto parentTranslator = static_cast<Qt3DSTranslator *>(parentElement->GetAssociation()); if (!parentTranslator || !GraphObjectTypes::IsNodeType( parentTranslator->GetUIPType())) { @@ -1007,23 +1011,21 @@ void CQmlEngineImpl::createElements(const QString &parentElementPath, const QStr parentElement->GetAttribute(Q3DStudio::ATTRIBUTE_ENDTIME, attValue); const int parentEndTime = int(attValue.m_INT32); - for (const auto ¤tProperties : properties) { + for (const auto ¤tProps : qAsConst(theProperties)) { ++_idCounter; ++elementIndex; // Remove properties requiring custom handling - QHash<QString, QVariant> theProperties = currentProperties; - QString newElementName = theProperties.take(QStringLiteral("name")).toString(); - QString refMatName = theProperties.take(QStringLiteral("material")).toString(); + QHash<QString, QVariant> fixedProps = currentProps; + QString newElementName = fixedProps.take(namePropName).toString(); + QByteArray newElementNameBa = newElementName.toUtf8(); + + QString refMatName = fixedProps.take(QStringLiteral("material")).toString(); if (refMatName.startsWith(QLatin1Char('#'))) // Absolute reference refMatName = refMatName.mid(1); else if (!refMatName.isEmpty() && !refMatName.contains(QLatin1Char('/'))) refMatName = QStringLiteral("/") + refMatName; - if (newElementName.isEmpty()) - newElementName = QStringLiteral("NewElement_%1").arg(_idCounter); - QByteArray newElementNameBa = newElementName.toUtf8(); - // Make sure the name is not duplicate TElement *existingChild = parentElement->FindChild(CHash::HashString(newElementNameBa.constData())); @@ -1039,7 +1041,7 @@ void CQmlEngineImpl::createElements(const QString &parentElementPath, const QStr const CRegisteredString elementSubType; GraphObjectTypes::Enum objectType = GraphObjectTypes::Unknown; - QString typeStr = theProperties.take(typePropName).toString(); + QString typeStr = fixedProps.take(typePropName).toString(); if (typeStr.isEmpty() || typeStr.compare(QLatin1String("model"), Qt::CaseInsensitive) == 0) { metaType = strTable.RegisterStr("Model"); @@ -1051,21 +1053,21 @@ void CQmlEngineImpl::createElements(const QString &parentElementPath, const QStr // Set default values for missing mandatory properties bool eyeBall = true; - theProperties.value(eyeBallPropName, true).toBool(); - if (objectType == GraphObjectTypes::Model && !theProperties.contains(sourcePathPropName)) { + fixedProps.value(eyeBallPropName, true).toBool(); + if (objectType == GraphObjectTypes::Model && !fixedProps.contains(sourcePathPropName)) { addStringAttribute(strTable, elementProperties, sourcePathPropName, QStringLiteral("#Cube")); } - if (!theProperties.contains(startTimePropName)) + if (!fixedProps.contains(startTimePropName)) addIntAttribute(strTable, elementProperties, startTimePropName, parentStartTime); - if (!theProperties.contains(endTimePropName)) + if (!fixedProps.contains(endTimePropName)) addIntAttribute(strTable, elementProperties, endTimePropName, parentEndTime); - if (!theProperties.contains(eyeBallPropName)) + if (!fixedProps.contains(eyeBallPropName)) addBoolAttribute(strTable, elementProperties, eyeBallPropName, true); else - eyeBall = theProperties.value(eyeBallPropName).toBool(); + eyeBall = fixedProps.value(eyeBallPropName).toBool(); - QHashIterator<QString, QVariant> it(theProperties); + QHashIterator<QString, QVariant> it(fixedProps); while (it.hasNext()) { it.next(); switch (it.value().type()) { @@ -1105,11 +1107,15 @@ void CQmlEngineImpl::createElements(const QString &parentElementPath, const QStr } // Create new element + QString localElementPath = elementPaths[elementIndex]; + int colonIndex = localElementPath.indexOf(QLatin1Char(':')); + if (colonIndex != -1) + localElementPath = localElementPath.mid(colonIndex + 1); TElement &newElem = m_Application->GetElementAllocator().CreateElement( regName, metaType, elementSubType, toConstDataRef(elementProperties.data(), QT3DSU32(elementProperties.size())), presentation, parentElement, false); - newElem.m_Path = strTable.RegisterStr(elementPaths[elementIndex]); + newElem.m_Path = strTable.RegisterStr(localElementPath); // Insert the new element into the correct slide if (!slideSystem.addSlideElement(component, slideIndex, newElem, eyeBall)) { @@ -1131,7 +1137,7 @@ void CQmlEngineImpl::createElements(const QString &parentElementPath, const QStr toConstDataRef(matProperties.data(), QT3DSU32(matProperties.size())), presentation, &newElem, false); - QString matElemPath = elementPaths[elementIndex] + QLatin1String(".refmat"); + QString matElemPath = localElementPath + QLatin1String(".refmat"); newMatElem.m_Path = strTable.RegisterStr(matElemPath); if (!slideSystem.addSlideElement(component, slideIndex, newMatElem, eyeBall)) { @@ -1171,10 +1177,8 @@ void CQmlEngineImpl::createElements(const QString &parentElementPath, const QStr << "was not found. Trying to find a fallback material."; } if (firstChild) { - auto tr = static_cast<Qt3DSTranslator *>( - firstChild->GetAssociation()); - referencedMaterial = static_cast<SGraphObject *>( - &tr->RenderObject()); + auto tr = static_cast<Qt3DSTranslator *>(firstChild->GetAssociation()); + referencedMaterial = static_cast<SGraphObject *>(&tr->RenderObject()); } if (!referencedMaterial) { // We could create default material into the container in case there is @@ -1308,7 +1312,7 @@ void CQmlEngineImpl::createMaterials(const QString &elementPath, for (auto &materialInfo : materialInfos) materialNames << materialInfo->materialName; qDeleteAll(materialInfos); - notifyMaterialCreation(presentation, materialNames, error); + notifyMaterialCreation(materialNames, error); }; auto getMaterialInfos = [&]() { @@ -1327,8 +1331,7 @@ void CQmlEngineImpl::createMaterials(const QString &elementPath, if (!element) { error = QObject::tr("Invalid element: '%1'").arg(elementPath); - TElement *sceneElement = getTarget("Scene"); - presentation = static_cast<CPresentation *>(sceneElement->GetBelongedPresentation()); + presentation = m_Application->GetPrimaryPresentation(); presPath = QFileInfo(presentation->GetFilePath()).absolutePath(); projPath = presentation->getProjectPath(); getMaterialInfos(); @@ -2506,30 +2509,29 @@ QVector4D CQmlEngineImpl::parseFloat4Property(const QString &propValue) return retVal; } -void CQmlEngineImpl::notifyElementCreation(CPresentation *pres, const QStringList &elementNames, - const QString &error) +void CQmlEngineImpl::notifyElementCreation(const QStringList &elementNames, const QString &error) { // Notify presentation asynchronously to give renderer time to initialize the elements properly if (!error.isEmpty()) { qWarning() << "Warning: Element creation failed:" << error; QT3DS_ASSERT(false); } - QTimer::singleShot(0, [pres, elementNames, error]() { - pres->signalProxy()->SigElementsCreated(elementNames, error); + QTimer::singleShot(0, [this, elementNames, error]() { + m_Application->GetPrimaryPresentation()->signalProxy() + ->SigElementsCreated(elementNames, error); }); } -void CQmlEngineImpl::notifyMaterialCreation(CPresentation *pres, - const QStringList &materialNames, - const QString &error) +void CQmlEngineImpl::notifyMaterialCreation(const QStringList &materialNames, const QString &error) { // Notify presentation asynchronously to give renderer time to initialize the materials properly if (!error.isEmpty()) { qWarning() << "Warning: Material creation failed:" << materialNames << error; QT3DS_ASSERT(false); } - QTimer::singleShot(0, [pres, materialNames, error]() { - pres->signalProxy()->SigMaterialsCreated(materialNames, error); + QTimer::singleShot(0, [this, materialNames, error]() { + m_Application->GetPrimaryPresentation()->signalProxy() + ->SigMaterialsCreated(materialNames, error); }); } diff --git a/src/Runtime/Source/runtimerender/rendererimpl/Qt3DSRendererImpl.cpp b/src/Runtime/Source/runtimerender/rendererimpl/Qt3DSRendererImpl.cpp index 5b07b25a..0b3f6655 100644 --- a/src/Runtime/Source/runtimerender/rendererimpl/Qt3DSRendererImpl.cpp +++ b/src/Runtime/Source/runtimerender/rendererimpl/Qt3DSRendererImpl.cpp @@ -146,8 +146,17 @@ namespace render { void Qt3DSRendererImpl::ChildrenUpdated(SNode &inParent) { if (inParent.m_Type == GraphObjectTypes::Layer) { - TInstanceRenderMap::iterator theIter = - m_InstanceRenderMap.find(static_cast<SRenderInstanceId>(&inParent)); + TInstanceRenderMap::iterator theIter + = m_InstanceRenderMap.find(static_cast<SRenderInstanceId>(&inParent)); + if (theIter == m_InstanceRenderMap.end()) { + // The layer is not in main presentation, but it might be in subpresentation + theIter = m_InstanceRenderMap.begin(); + while (theIter != m_InstanceRenderMap.end()) { + if (static_cast<SNode *>(&theIter->second.mPtr->m_Layer) == &inParent) + break; + theIter++; + } + } if (theIter != m_InstanceRenderMap.end()) { theIter->second->m_CamerasAndLights.clear(); theIter->second->m_RenderableNodes.clear(); |