diff options
author | Miikka Heikkinen <miikka.heikkinen@qt.io> | 2019-04-30 14:09:34 +0300 |
---|---|---|
committer | Miikka Heikkinen <miikka.heikkinen@qt.io> | 2019-05-07 08:47:09 +0000 |
commit | ee62a1cd82e7f6dc3b16d9935fc148f3c48c8f46 (patch) | |
tree | fe117785f310373976c74300e4c440af3a640d49 /src/Runtime | |
parent | 988f62c763eef90e4dafe9ecf6bb05629279278e (diff) |
Add deleteElement to C++ API
Add possibility to delete elements that have been added with
createElement.
Task-number: QT3DS-3374
Change-Id: I701e565241d18294171cd63ef934083f627b89aa
Reviewed-by: Tomi Korpipää <tomi.korpipaa@qt.io>
Diffstat (limited to 'src/Runtime')
-rw-r--r-- | src/Runtime/Source/engine/Qt3DSRenderRuntimeBindingImpl.h | 4 | ||||
-rw-r--r-- | src/Runtime/Source/engine/Qt3DSRuntimeView.cpp | 16 | ||||
-rw-r--r-- | src/Runtime/Source/engine/Qt3DSRuntimeView.h | 1 | ||||
-rw-r--r-- | src/Runtime/Source/runtime/Qt3DSIScriptBridge.h | 2 | ||||
-rw-r--r-- | src/Runtime/Source/runtime/Qt3DSQmlEngine.cpp | 76 | ||||
-rw-r--r-- | src/Runtime/Source/runtime/Qt3DSSlideSystem.cpp | 41 | ||||
-rw-r--r-- | src/Runtime/Source/runtime/Qt3DSSlideSystem.h | 2 | ||||
-rw-r--r-- | src/Runtime/Source/viewer/Qt3DSViewerApp.cpp | 8 | ||||
-rw-r--r-- | src/Runtime/Source/viewer/Qt3DSViewerApp.h | 1 |
9 files changed, 144 insertions, 7 deletions
diff --git a/src/Runtime/Source/engine/Qt3DSRenderRuntimeBindingImpl.h b/src/Runtime/Source/engine/Qt3DSRenderRuntimeBindingImpl.h index c174d4a7..92cb8658 100644 --- a/src/Runtime/Source/engine/Qt3DSRenderRuntimeBindingImpl.h +++ b/src/Runtime/Source/engine/Qt3DSRenderRuntimeBindingImpl.h @@ -190,8 +190,8 @@ namespace render { static Qt3DSTranslator *GetTranslatorFromGraphNode(SGraphObject &inObject); static Qt3DSTranslator *CreateTranslatorForElement(Q3DStudio::TElement &inElement, - SGraphObject &inGraphObject, - NVAllocatorCallback &inAlloc); + SGraphObject &inGraphObject, + NVAllocatorCallback &inAlloc); static Q3DStudio::IPresentation * GetPresentationFromPresentation(SPresentation &inPresentation); static void InitializePointerTags(IStringTable &inTable); diff --git a/src/Runtime/Source/engine/Qt3DSRuntimeView.cpp b/src/Runtime/Source/engine/Qt3DSRuntimeView.cpp index abff8f09..9863031d 100644 --- a/src/Runtime/Source/engine/Qt3DSRuntimeView.cpp +++ b/src/Runtime/Source/engine/Qt3DSRuntimeView.cpp @@ -217,6 +217,7 @@ public: void createElement(const QString &parentElementPath, const QString &slideName, const QHash<QString, QVariant> &properties) override; + void deleteElement(const QString &elementPath) override; void SetAttribute(const char *elementPath, const char *attributeName, const char *value) override; bool GetAttribute(const char *elementPath, const char *attributeName, void *value) override; @@ -615,7 +616,7 @@ float CRuntimeView::dataInputMin(const QString &name) const } void CRuntimeView::createElement(const QString &parentElementPath, const QString &slideName, - const QHash<QString, QVariant> &properties) + const QHash<QString, QVariant> &properties) { if (m_Application) { Q3DStudio::CQmlEngine &theBridgeEngine @@ -625,7 +626,18 @@ void CRuntimeView::createElement(const QString &parentElementPath, const QString } } -void CRuntimeView::SetAttribute(const char *elementPath, const char *attributeName, const char *value) +void CRuntimeView::deleteElement(const QString &elementPath) +{ + if (m_Application) { + Q3DStudio::CQmlEngine &theBridgeEngine + = static_cast<Q3DStudio::CQmlEngine &>(m_RuntimeFactoryCore->GetScriptEngineQml()); + theBridgeEngine.deleteElement(elementPath, + &m_RuntimeFactory->GetQt3DSRenderContext().GetRenderer()); + } +} + +void CRuntimeView::SetAttribute(const char *elementPath, const char *attributeName, + const char *value) { if (m_Application) { if (!elementPath || !attributeName || !value) diff --git a/src/Runtime/Source/engine/Qt3DSRuntimeView.h b/src/Runtime/Source/engine/Qt3DSRuntimeView.h index 3626fd52..776fbea2 100644 --- a/src/Runtime/Source/engine/Qt3DSRuntimeView.h +++ b/src/Runtime/Source/engine/Qt3DSRuntimeView.h @@ -191,6 +191,7 @@ public: virtual float dataInputMin(const QString &name) const = 0; virtual void createElement(const QString &parentElementPath, const QString &slideName, const QHash<QString, QVariant> &properties) = 0; + virtual void deleteElement(const QString &elementPath) = 0; virtual void SetAttribute(const char *elementPath, const char *attributeName, const char *value) = 0; virtual bool GetAttribute(const char *elementPath, const char *attributeName, void *value) = 0; diff --git a/src/Runtime/Source/runtime/Qt3DSIScriptBridge.h b/src/Runtime/Source/runtime/Qt3DSIScriptBridge.h index 3b26abd2..2aa59339 100644 --- a/src/Runtime/Source/runtime/Qt3DSIScriptBridge.h +++ b/src/Runtime/Source/runtime/Qt3DSIScriptBridge.h @@ -161,6 +161,8 @@ public: // Elements virtual void createElement(const QString &parentElementPath, const QString &slideName, const QHash<QString, QVariant> &properties, qt3ds::render::IQt3DSRenderer *renderer) = 0; + virtual void deleteElement(const QString &elementPath, + qt3ds::render::IQt3DSRenderer *renderer) = 0; public: // Components virtual void GotoSlide(const char *component, const char *slideName, diff --git a/src/Runtime/Source/runtime/Qt3DSQmlEngine.cpp b/src/Runtime/Source/runtime/Qt3DSQmlEngine.cpp index 23a097a7..86f68bdd 100644 --- a/src/Runtime/Source/runtime/Qt3DSQmlEngine.cpp +++ b/src/Runtime/Source/runtime/Qt3DSQmlEngine.cpp @@ -420,6 +420,8 @@ public: void createElement(const QString &parentElementPath, const QString &slideName, const QHash<QString, QVariant> &properties, qt3ds::render::IQt3DSRenderer *renderer) override; + void deleteElement(const QString &elementPath, + qt3ds::render::IQt3DSRenderer *renderer) override; //void createMaterial() override; // TODO (QT3DS-3377) //void createMesh() override; // TODO (QT3DS-3378) @@ -1042,7 +1044,6 @@ void CQmlEngineImpl::createElement(const QString &parentElementPath, const QStri return; } - // First check if we can resolve the referenced material before creating any graph objects // Find a match in material container // If the specified material is not available in original presentation, or was not specified, @@ -1086,7 +1087,7 @@ void CQmlEngineImpl::createElement(const QString &parentElementPath, const QStri } } - // Create new SGraphObject (SNode) + // Create model SGraphObject NVAllocatorCallback &allocator = presentation->GetScene()->allocator(); qt3ds::render::SModel *newObject = QT3DS_NEW(allocator, qt3ds::render::SModel)(); newObject->m_Id = strTable.RegisterStr((QByteArrayLiteral("_newObject_") @@ -1124,6 +1125,77 @@ void CQmlEngineImpl::createElement(const QString &parentElementPath, const QStri renderer->ChildrenUpdated(parentObject); } +// Only supports deleting element types that can be added via createElement. +void CQmlEngineImpl::deleteElement(const QString &elementPath, + qt3ds::render::IQt3DSRenderer *renderer) +{ + // Resolve element + QByteArray thePath = elementPath.toUtf8(); + TElement *element = getTarget(thePath.constData()); + + if (!element) { + qWarning() << __FUNCTION__ << "Invalid element:" << elementPath; + return; + } + + // Remove element recursively from slide system + IPresentation *presentation = element->GetBelongedPresentation(); + TElement &component = element->GetComponentParent(); + ISlideSystem &slideSystem = presentation->GetSlideSystem(); + slideSystem.removeElement(component, *element); + + TElement *parentElement = element->GetParent(); + Q_ASSERT(parentElement); + + NVAllocatorCallback &allocator = presentation->GetScene()->allocator(); + + // Recursive deleter for translators and graph objects + std::function<void(TElement *)> deleteRenderObjects; + deleteRenderObjects = [&](TElement *elem) { + TElement *child = elem->m_Child; + while (child) { + TElement *sibling = child->m_Sibling; + deleteRenderObjects(child); + child = sibling; + } + + auto translator = static_cast<qt3ds::render::Qt3DSTranslator *>(elem->GetAssociation()); + if (translator) { + if (translator->GetUIPType() == qt3ds::render::GraphObjectTypes::Model) { + auto model = static_cast<qt3ds::render::SModel *>(&translator->RenderObject()); + // Delete material + if (model->m_FirstMaterial) { + auto material = static_cast<qt3ds::render::SReferencedMaterial *>( + model->m_FirstMaterial); + QT3DS_FREE(allocator, material); + } + QT3DS_FREE(allocator, model); + } + QT3DS_FREE(allocator, translator); + } + }; + + qt3ds::render::SNode *node = nullptr; + qt3ds::render::SNode *parentNode = nullptr; + auto translator = static_cast<qt3ds::render::Qt3DSTranslator *>(element->GetAssociation()); + + if (translator) { + node = &static_cast<qt3ds::render::SNode &>(translator->RenderObject()); + auto parentTranslator = static_cast<qt3ds::render::Qt3DSTranslator *>( + parentElement->GetAssociation()); + if (parentTranslator) { + parentNode = &static_cast<qt3ds::render::SNode &>(parentTranslator->RenderObject()); + parentNode->RemoveChild(*node); + renderer->ChildrenUpdated(*parentNode); + } + // Release child element graph objects/translators + deleteRenderObjects(element); + } + + // Remove element recursively + m_Application->GetElementAllocator().ReleaseElement(*element, true); +} + void CQmlEngineImpl::GotoSlide(const char *component, const char *slideName, const SScriptEngineGotoSlideArgs &inArgs) { diff --git a/src/Runtime/Source/runtime/Qt3DSSlideSystem.cpp b/src/Runtime/Source/runtime/Qt3DSSlideSystem.cpp index 3e2f95c2..33c7544d 100644 --- a/src/Runtime/Source/runtime/Qt3DSSlideSystem.cpp +++ b/src/Runtime/Source/runtime/Qt3DSSlideSystem.cpp @@ -255,7 +255,6 @@ struct SSlideSystem : public ISlideSystem } } - // The parent element must be found from target slide. // Elements cannot be added to the master slide. bool addSlideElement(element::SElement &inComponent, int slideIndex, @@ -314,6 +313,46 @@ struct SSlideSystem : public ISlideSystem return true; } + void removeElementRecursive(SSlide *slide, element::SElement &inElement) + { + element::SElement *child = inElement.m_Child; + while (child) { + removeElementRecursive(slide, *child); + child = child->m_Sibling; + } + + SSlideElement *slideElement = slide->m_FirstElement; + SSlideElement *previousElement = nullptr; + while (slideElement) { + if (slideElement->m_ElementHandle == inElement.m_Handle) { + if (slide->m_FirstElement == slideElement) + slide->m_FirstElement = slideElement->m_NextElement; + if (slide->m_lastElement == slideElement) + slide->m_lastElement = previousElement; + if (previousElement) + previousElement->m_NextElement = slideElement->m_NextElement; + m_SlideElements.deallocate(slideElement); + break; + } + previousElement = slideElement; + slideElement = slideElement->m_NextElement; + } + } + + // Removes element and its children from all slides + void removeElement(element::SElement &inComponent, element::SElement &inElement) override + { + TComponentSlideHash::const_iterator theFindResult = m_Slides.find(&inComponent); + if (theFindResult == m_Slides.end()) { + qWarning() << __FUNCTION__ << "Could not find slides for component"; + return; + } + + SSlide *slide = theFindResult->second; + for (; slide; slide = slide->m_NextSlide) + removeElementRecursive(slide, inElement); + } + void AddSlideAttribute(Q3DStudio::SAttributeKey inKey, Q3DStudio::UVariant inValue) override { if (m_CurrentSlideElement) { diff --git a/src/Runtime/Source/runtime/Qt3DSSlideSystem.h b/src/Runtime/Source/runtime/Qt3DSSlideSystem.h index 3aa2a011..d3accbd3 100644 --- a/src/Runtime/Source/runtime/Qt3DSSlideSystem.h +++ b/src/Runtime/Source/runtime/Qt3DSSlideSystem.h @@ -128,6 +128,8 @@ namespace runtime { virtual void AddSlideElement(element::SElement &inElement, bool inActive) = 0; virtual bool addSlideElement(element::SElement &inComponent, int slideIndex, element::SElement &inElement, bool eyeBall) = 0; + virtual void removeElement(element::SElement &inComponent, + element::SElement &inElement) = 0; virtual void AddSlideAttribute(Q3DStudio::SAttributeKey inKey, Q3DStudio::UVariant inValue) = 0; virtual SSlideAnimAction *AddSlideAnimAction(bool inAnimation, QT3DSI32 inIndex, diff --git a/src/Runtime/Source/viewer/Qt3DSViewerApp.cpp b/src/Runtime/Source/viewer/Qt3DSViewerApp.cpp index 005eedcd..4dd5dbd9 100644 --- a/src/Runtime/Source/viewer/Qt3DSViewerApp.cpp +++ b/src/Runtime/Source/viewer/Qt3DSViewerApp.cpp @@ -803,6 +803,14 @@ void Q3DSViewerApp::createElement(const QString &parentElementPath, const QStrin m_Impl.m_view->createElement(parentElementPath, slideName, properties); } +void Q3DSViewerApp::deleteElement(const QString &elementPath) +{ + if (!m_Impl.m_view) + return; + + m_Impl.m_view->deleteElement(elementPath); +} + Q3DSViewerApp &Q3DSViewerApp::Create(void *glContext, Q3DStudio::IAudioPlayer *inAudioPlayer, QElapsedTimer *startupTimer) { diff --git a/src/Runtime/Source/viewer/Qt3DSViewerApp.h b/src/Runtime/Source/viewer/Qt3DSViewerApp.h index a4bdc2e3..66a40e76 100644 --- a/src/Runtime/Source/viewer/Qt3DSViewerApp.h +++ b/src/Runtime/Source/viewer/Qt3DSViewerApp.h @@ -361,6 +361,7 @@ public: void createElement(const QString &parentElementPath, const QString &slideName, const QHash<QString, QVariant> &properties); + void deleteElement(const QString &elementPath); QString error(); |