1 
2 //
3 // This source file is part of appleseed.
4 // Visit https://appleseedhq.net/ for additional information and resources.
5 //
6 // This software is released under the MIT license.
7 //
8 // Copyright (c) 2016-2018 Esteban Tovagliari, The appleseedhq Organization
9 //
10 // Permission is hereby granted, free of charge, to any person obtaining a copy
11 // of this software and associated documentation files (the "Software"), to deal
12 // in the Software without restriction, including without limitation the rights
13 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14 // copies of the Software, and to permit persons to whom the Software is
15 // furnished to do so, subject to the following conditions:
16 //
17 // The above copyright notice and this permission notice shall be included in
18 // all copies or substantial portions of the Software.
19 //
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
26 // THE SOFTWARE.
27 //
28 
29 // Interface header.
30 #include "archiveassembly.h"
31 
32 // Standard headers.
33 #include <string>
34 
35 // appleseed.renderer headers.
36 #include "renderer/modeling/project/project.h"
37 #include "renderer/modeling/project/projectfilereader.h"
38 #include "renderer/modeling/scene/scene.h"
39 #include "renderer/utility/paramarray.h"
40 
41 // appleseed.foundation headers.
42 #include "foundation/utility/api/apistring.h"
43 #include "foundation/utility/api/specializedapiarrays.h"
44 #include "foundation/utility/containers/dictionary.h"
45 #include "foundation/utility/foreach.h"
46 #include "foundation/utility/job/abortswitch.h"
47 #include "foundation/utility/searchpaths.h"
48 
49 // Standard headers.
50 #include <string>
51 
52 using namespace foundation;
53 using namespace std;
54 
55 namespace renderer
56 {
57 
58 //
59 // ArchiveAssembly class implementation.
60 //
61 
62 namespace
63 {
64     const char* Model = "archive_assembly";
65 }
66 
ArchiveAssembly(const char * name,const ParamArray & params)67 ArchiveAssembly::ArchiveAssembly(
68     const char*         name,
69     const ParamArray&   params)
70   : ProceduralAssembly(name, params)
71   , m_archive_opened(false)
72 {
73 }
74 
release()75 void ArchiveAssembly::release()
76 {
77     delete this;
78 }
79 
get_model() const80 const char* ArchiveAssembly::get_model() const
81 {
82     return Model;
83 }
84 
collect_asset_paths(StringArray & paths) const85 void ArchiveAssembly::collect_asset_paths(StringArray& paths) const
86 {
87     if (m_params.strings().exist("filename"))
88         paths.push_back(m_params.get("filename"));
89 }
90 
update_asset_paths(const StringDictionary & mappings)91 void ArchiveAssembly::update_asset_paths(const StringDictionary& mappings)
92 {
93     if (m_params.strings().exist("filename"))
94         m_params.set("filename", mappings.get(m_params.get("filename")));
95 }
96 
do_expand_contents(const Project & project,const Assembly * parent,IAbortSwitch * abort_switch)97 bool ArchiveAssembly::do_expand_contents(
98     const Project&      project,
99     const Assembly*     parent,
100     IAbortSwitch*       abort_switch)
101 {
102     if (!m_archive_opened)
103     {
104         // Establish and store the qualified path to the archive project.
105         const SearchPaths& search_paths = project.search_paths();
106         const string filepath =
107             to_string(search_paths.qualify(m_params.get_required<string>("filename", "")));
108 
109         ProjectFileReader reader;
110         auto_release_ptr<Assembly> assembly =
111             reader.read_archive(
112                 filepath.c_str(),
113                 nullptr,  // for now, we don't validate archives
114                 search_paths,
115                 ProjectFileReader::OmitProjectSchemaValidation);
116 
117         if (assembly.get())
118         {
119             swap_contents(*assembly);
120             m_archive_opened = true;
121         }
122     }
123 
124     return true;
125 }
126 
127 
128 //
129 // ArchiveAssemblyFactory class implementation.
130 //
131 
release()132 void ArchiveAssemblyFactory::release()
133 {
134     delete this;
135 }
136 
get_model() const137 const char* ArchiveAssemblyFactory::get_model() const
138 {
139     return Model;
140 }
141 
get_model_metadata() const142 Dictionary ArchiveAssemblyFactory::get_model_metadata() const
143 {
144     return
145         Dictionary()
146             .insert("name", Model)
147             .insert("label", "Archive Assembly");
148 }
149 
get_input_metadata() const150 DictionaryArray ArchiveAssemblyFactory::get_input_metadata() const
151 {
152     DictionaryArray metadata;
153 
154     metadata.push_back(
155         Dictionary()
156             .insert("name", "filename")
157             .insert("label", "File Path")
158             .insert("type", "file")
159             .insert("file_picker_mode", "open")
160             .insert("file_picker_type", "project")
161             .insert("use", "required"));
162 
163     return metadata;
164 }
165 
create(const char * name,const ParamArray & params) const166 auto_release_ptr<Assembly> ArchiveAssemblyFactory::create(
167     const char*         name,
168     const ParamArray&   params) const
169 {
170     return auto_release_ptr<Assembly>(new ArchiveAssembly(name, params));
171 }
172 
173 }   // namespace renderer
174