• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #include "scene_exporter.h"
16 
17 #include <scene/ext/intf_component.h>
18 #include <scene/ext/intf_internal_scene.h>
19 #include <scene/interface/intf_external_node.h>
20 #include <scene/interface/intf_mesh.h>
21 
22 #include <meta/api/metadata_util.h>
23 #include <meta/interface/property/construct_array_property.h>
24 #include <meta/interface/resource/intf_resource.h>
25 #include <meta/interface/serialization/intf_exporter.h>
26 
27 #include "scene_ser.h"
28 #include "util.h"
29 
30 SCENE_BEGIN_NAMESPACE()
31 
32 static void AddObjectProperties(const META_NS::IObject& node, const BASE_NS::string& head, META_NS::IMetadata& out);
33 
HandleReadOnlyProperty(const META_NS::IProperty::ConstPtr & p,const BASE_NS::string & head,META_NS::IMetadata & out)34 static void HandleReadOnlyProperty(
35     const META_NS::IProperty::ConstPtr& p, const BASE_NS::string& head, META_NS::IMetadata& out)
36 {
37     if (META_NS::ArrayPropertyLock arr { p }) {
38         for (size_t i = 0; i != arr->GetSize(); ++i) {
39             if (auto obj = interface_cast<META_NS::IObject>(META_NS::GetConstPointer(arr->GetAnyAt(i)))) {
40                 AddObjectProperties(
41                     *obj, head + "." + EscapeSerName(p->GetName()) + "[" + BASE_NS::to_string(i) + "]", out);
42             }
43         }
44     } else {
45         if (auto obj = META_NS::GetConstPointer<META_NS::IObject>(p)) {
46             AddObjectProperties(*obj, head + "." + EscapeSerName(p->GetName()), out);
47         }
48     }
49 }
50 
AddObjectProperties(const META_NS::IObject & obj,const BASE_NS::string & head,META_NS::IMetadata & out)51 static void AddObjectProperties(const META_NS::IObject& obj, const BASE_NS::string& head, META_NS::IMetadata& out)
52 {
53     if (auto i = interface_cast<META_NS::IMetadata>(&obj)) {
54         for (auto&& p : GetAllProperties(*i)) {
55             if (i->GetMetadata(META_NS::MetadataType::PROPERTY, p->GetName()).readOnly) {
56                 HandleReadOnlyProperty(p, head, out);
57             } else {
58                 META_NS::CloneToDefaultIfSet(p, out, head + "." + EscapeSerName(p->GetName()));
59             }
60         }
61     }
62 }
63 
AddObjectProperties(const META_NS::IObject & obj,META_NS::IMetadata & out)64 void AddObjectProperties(const META_NS::IObject& obj, META_NS::IMetadata& out)
65 {
66     AddObjectProperties(obj, "", out);
67 }
68 
AddObjectAttachments(const META_NS::IObject & node,ISceneNodeSer & out)69 static void AddObjectAttachments(const META_NS::IObject& node, ISceneNodeSer& out)
70 {
71     if (auto i = interface_cast<META_NS::IAttach>(&node)) {
72         BASE_NS::vector<META_NS::IObject::Ptr> vec;
73         for (auto&& att : i->GetAttachments()) {
74             if (!interface_cast<META_NS::IEvent>(att) && !interface_cast<META_NS::IFunction>(att) &&
75                 !interface_cast<META_NS::IProperty>(att) && !interface_cast<IComponent>(att) &&
76                 !interface_cast<IExternalNode>(att)) {
77                 vec.push_back(att);
78             }
79         }
80         out.SetAttachments(BASE_NS::move(vec));
81     }
82 }
83 
AddExternalAttachments(const META_NS::IObject & node,const BASE_NS::string & path,ISceneExternalNodeSer & out)84 static void AddExternalAttachments(
85     const META_NS::IObject& node, const BASE_NS::string& path, ISceneExternalNodeSer& out)
86 {
87     if (auto i = interface_cast<META_NS::IAttach>(&node)) {
88         BASE_NS::vector<META_NS::IObject::Ptr> vec;
89         for (auto&& att : i->GetAttachments()) {
90             if (!interface_cast<META_NS::IEvent>(att) && !interface_cast<META_NS::IFunction>(att) &&
91                 !interface_cast<META_NS::IProperty>(att) && !interface_cast<IComponent>(att) &&
92                 !interface_cast<IExternalNode>(att)) {
93                 out.AddAttachment(path, att);
94             }
95         }
96     }
97 }
98 
AddObjectData(const META_NS::IObject & node,const BASE_NS::string & head,META_NS::IMetadata & out)99 static void AddObjectData(const META_NS::IObject& node, const BASE_NS::string& head, META_NS::IMetadata& out)
100 {
101     if (auto ext = interface_cast<ISceneExternalNodeSer>(&out)) {
102         AddExternalAttachments(node, head, *ext);
103     }
104     AddObjectProperties(node, head, out);
105 }
106 
AddObjectDataRecursive(const META_NS::IObject & obj,const BASE_NS::string & head,META_NS::IMetadata & out)107 static void AddObjectDataRecursive(const META_NS::IObject& obj, const BASE_NS::string& head, META_NS::IMetadata& out)
108 {
109     AddObjectData(obj, head, out);
110 
111     META_NS::Internal::ConstIterate(
112         interface_cast<META_NS::IIterable>(&obj),
113         [&](META_NS::IObject::Ptr nodeObj) {
114             AddObjectDataRecursive(*nodeObj, head + "/" + EscapeSerName(nodeObj->GetName()), out);
115             return true;
116         },
117         META_NS::IterateStrategy { META_NS::TraversalType::NO_HIERARCHY });
118 }
119 
AddObjectDataRecursive(const META_NS::IObject & obj,META_NS::IMetadata & out)120 static void AddObjectDataRecursive(const META_NS::IObject& obj, META_NS::IMetadata& out)
121 {
122     AddObjectDataRecursive(obj, "", out);
123 }
124 
SetObjectData(const META_NS::IObject & node,ISceneNodeSer & out)125 static void SetObjectData(const META_NS::IObject& node, ISceneNodeSer& out)
126 {
127     if (auto outMeta = interface_cast<META_NS::IMetadata>(&out)) {
128         out.SetName(node.GetName());
129         out.SetId(node.GetClassId());
130         AddObjectAttachments(node, out);
131         AddObjectData(node, "", *outMeta);
132     }
133 }
134 
BuildExternalNode(const META_NS::IObject & node,const IExternalNode & ext)135 static META_NS::IObject::Ptr BuildExternalNode(const META_NS::IObject& node, const IExternalNode& ext)
136 {
137     auto obj = META_NS::GetObjectRegistry().Create<ISceneExternalNodeSer>(ClassId::SceneExternalNodeSer);
138     if (obj) {
139         obj->SetName(node.GetName());
140         obj->SetResourceId(ext.GetResourceId());
141         if (auto mout = interface_cast<META_NS::IMetadata>(obj)) {
142             AddObjectDataRecursive(node, *mout);
143         }
144     }
145     return interface_pointer_cast<META_NS::IObject>(obj);
146 }
147 
BuildObjectNode(const META_NS::IObject & node)148 static META_NS::IObject::Ptr BuildObjectNode(const META_NS::IObject& node)
149 {
150     auto cont = META_NS::GetObjectRegistry().Create<META_NS::IContainer>(ClassId::SceneNodeSer);
151     if (auto i = interface_cast<ISceneNodeSer>(cont)) {
152         SetObjectData(node, *i);
153     }
154     META_NS::Internal::ConstIterate(
155         interface_cast<META_NS::IIterable>(&node),
156         [&](META_NS::IObject::Ptr nodeObj) {
157             META_NS::IObject::Ptr obj;
158             if (auto att = interface_cast<META_NS::IAttach>(nodeObj)) {
159                 auto ext = att->GetAttachments<IExternalNode>();
160                 if (!ext.empty()) {
161                     obj = BuildExternalNode(*nodeObj, *ext.front());
162                 }
163             }
164             if (!obj) {
165                 obj = BuildObjectNode(*nodeObj);
166             }
167             cont->Add(obj);
168             return true;
169         },
170         META_NS::IterateStrategy { META_NS::TraversalType::NO_HIERARCHY });
171 
172     return interface_pointer_cast<META_NS::IObject>(cont);
173 }
174 
BuildObjectHierarchy(const IScene & scene)175 static META_NS::IObject::Ptr BuildObjectHierarchy(const IScene& scene)
176 {
177     META_NS::IObject::Ptr res = META_NS::GetObjectRegistry().Create(ClassId::SceneNodeSer);
178     if (res) {
179         if (auto obj = interface_cast<META_NS::IObject>(&scene)) {
180             if (auto ser = interface_cast<ISceneNodeSer>(res)) {
181                 SetObjectData(*obj, *ser);
182                 if (auto i = interface_cast<META_NS::IContainer>(res)) {
183                     if (auto root = interface_pointer_cast<META_NS::IObject>(scene.GetRootNode().GetResult())) {
184                         i->Add(BuildObjectNode(*root));
185                     }
186                 }
187             }
188         }
189     }
190     return res;
191 }
192 
CreateExporter(const IRenderContext::Ptr & r)193 static META_NS::IFileExporter::Ptr CreateExporter(const IRenderContext::Ptr& r)
194 {
195     META_NS::IFileExporter::Ptr exporter;
196     if (r) {
197         exporter = META_NS::GetObjectRegistry().Create<META_NS::IFileExporter>(META_NS::ClassId::JsonExporter);
198         exporter->SetResourceManager(r->GetResources());
199         exporter->SetMetadata(
200             META_NS::SerMetadataValues().SetVersion(SCENE_EXPORTER_VERSION).SetType(SCENE_EXPORTER_TYPE));
201     }
202     return exporter;
203 }
204 
ExportScene(CORE_NS::IFile & out,const IScene::ConstPtr & p)205 META_NS::ReturnError SceneExporter::ExportScene(CORE_NS::IFile& out, const IScene::ConstPtr& p)
206 {
207     META_NS::ReturnError res = META_NS::GenericError::FAIL;
208     if (auto scene = interface_cast<IScene>(p)) {
209         if (auto obj = BuildObjectHierarchy(*scene)) {
210             auto exporter = CreateExporter(scene->GetInternalScene()->GetContext());
211             res = exporter->Export(out, obj);
212         }
213     }
214     return res;
215 }
ExportNode(CORE_NS::IFile & out,const INode::ConstPtr & p)216 META_NS::ReturnError SceneExporter::ExportNode(CORE_NS::IFile& out, const INode::ConstPtr& p)
217 {
218     META_NS::ReturnError res = META_NS::GenericError::FAIL;
219     if (auto obj = BuildObjectNode(*interface_cast<META_NS::IObject>(p))) {
220         auto exporter = CreateExporter(p->GetScene()->GetInternalScene()->GetContext());
221         res = exporter->Export(out, obj);
222     }
223     return res;
224 }
225 
226 SCENE_END_NAMESPACE()
227