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) 2010-2013 Francois Beaune, Jupiter Jazz Limited
9 // Copyright (c) 2014-2018 Francois Beaune, The appleseedhq Organization
10 //
11 // Permission is hereby granted, free of charge, to any person obtaining a copy
12 // of this software and associated documentation files (the "Software"), to deal
13 // in the Software without restriction, including without limitation the rights
14 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15 // copies of the Software, and to permit persons to whom the Software is
16 // furnished to do so, subject to the following conditions:
17 //
18 // The above copyright notice and this permission notice shall be included in
19 // all copies or substantial portions of the Software.
20 //
21 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
27 // THE SOFTWARE.
28 //
29 
30 // Interface header.
31 #include "basegroup.h"
32 
33 // appleseed.renderer headers.
34 #include "renderer/kernel/shading/oslshadingsystem.h"
35 #include "renderer/modeling/color/colorentity.h"
36 #include "renderer/modeling/scene/assembly.h"
37 #include "renderer/modeling/scene/assemblyinstance.h"
38 #include "renderer/modeling/scene/textureinstance.h"
39 #include "renderer/modeling/shadergroup/shadergroup.h"
40 #include "renderer/modeling/texture/texture.h"
41 
42 // appleseed.foundation headers.
43 #include "foundation/utility/job/abortswitch.h"
44 
45 using namespace foundation;
46 
47 namespace renderer
48 {
49 
50 struct BaseGroup::Impl
51 {
52     ColorContainer              m_colors;
53     TextureContainer            m_textures;
54     TextureInstanceContainer    m_texture_instances;
55     ShaderGroupContainer        m_shader_groups;
56     AssemblyContainer           m_assemblies;
57     AssemblyInstanceContainer   m_assembly_instances;
58 
Implrenderer::BaseGroup::Impl59     explicit Impl(Entity* parent)
60       : m_colors(parent)
61       , m_textures(parent)
62       , m_texture_instances(parent)
63       , m_shader_groups(parent)
64       , m_assemblies(parent)
65       , m_assembly_instances(parent)
66     {
67     }
68 };
69 
BaseGroup(Entity * parent)70 BaseGroup::BaseGroup(Entity* parent)
71   : impl(new Impl(parent))
72 {
73 }
74 
~BaseGroup()75 BaseGroup::~BaseGroup()
76 {
77     delete impl;
78 }
79 
colors() const80 ColorContainer& BaseGroup::colors() const
81 {
82     return impl->m_colors;
83 }
84 
textures() const85 TextureContainer& BaseGroup::textures() const
86 {
87     return impl->m_textures;
88 }
89 
texture_instances() const90 TextureInstanceContainer& BaseGroup::texture_instances() const
91 {
92     return impl->m_texture_instances;
93 }
94 
shader_groups() const95 ShaderGroupContainer& BaseGroup::shader_groups() const
96 {
97     return impl->m_shader_groups;
98 }
99 
clear()100 void BaseGroup::clear()
101 {
102     impl->m_colors.clear();
103     impl->m_textures.clear();
104     impl->m_texture_instances.clear();
105     impl->m_shader_groups.clear();
106     impl->m_assemblies.clear();
107     impl->m_assembly_instances.clear();
108 }
109 
create_optimized_osl_shader_groups(OSLShadingSystem & shading_system,const ShaderCompiler * shader_compiler,IAbortSwitch * abort_switch)110 bool BaseGroup::create_optimized_osl_shader_groups(
111     OSLShadingSystem&           shading_system,
112     const ShaderCompiler*       shader_compiler,
113     IAbortSwitch*               abort_switch)
114 {
115     for (Assembly& assembly : assemblies())
116     {
117         if (is_aborted(abort_switch))
118             return false;
119 
120         if (!assembly.create_optimized_osl_shader_groups(
121                 shading_system,
122                 shader_compiler,
123                 abort_switch))
124             return false;
125     }
126 
127     for (ShaderGroup& shader_group : shader_groups())
128     {
129         if (is_aborted(abort_switch))
130             return false;
131 
132         if (!shader_group.create_optimized_osl_shader_group(
133                 shading_system,
134                 shader_compiler,
135                 abort_switch))
136             return false;
137     }
138 
139     return true;
140 }
141 
release_optimized_osl_shader_groups()142 void BaseGroup::release_optimized_osl_shader_groups()
143 {
144     for (Assembly& assembly : assemblies())
145         assembly.release_optimized_osl_shader_groups();
146 
147     for (ShaderGroup& shader_group : shader_groups())
148         shader_group.release_optimized_osl_shader_group();
149 }
150 
assemblies() const151 AssemblyContainer& BaseGroup::assemblies() const
152 {
153     return impl->m_assemblies;
154 }
155 
assembly_instances() const156 AssemblyInstanceContainer& BaseGroup::assembly_instances() const
157 {
158     return impl->m_assembly_instances;
159 }
160 
collect_asset_paths(StringArray & paths) const161 void BaseGroup::collect_asset_paths(StringArray& paths) const
162 {
163     invoke_collect_asset_paths(colors(), paths);
164     invoke_collect_asset_paths(textures(), paths);
165     invoke_collect_asset_paths(texture_instances(), paths);
166     invoke_collect_asset_paths(shader_groups(), paths);
167     invoke_collect_asset_paths(assemblies(), paths);
168     invoke_collect_asset_paths(assembly_instances(), paths);
169 }
170 
update_asset_paths(const StringDictionary & mappings)171 void BaseGroup::update_asset_paths(const StringDictionary& mappings)
172 {
173     invoke_update_asset_paths(colors(), mappings);
174     invoke_update_asset_paths(textures(), mappings);
175     invoke_update_asset_paths(texture_instances(), mappings);
176     invoke_update_asset_paths(shader_groups(), mappings);
177     invoke_update_asset_paths(assemblies(), mappings);
178     invoke_update_asset_paths(assembly_instances(), mappings);
179 }
180 
on_render_begin(const Project & project,const BaseGroup * parent,OnRenderBeginRecorder & recorder,IAbortSwitch * abort_switch)181 bool BaseGroup::on_render_begin(
182     const Project&              project,
183     const BaseGroup*            parent,
184     OnRenderBeginRecorder&      recorder,
185     IAbortSwitch*               abort_switch)
186 {
187     bool success = true;
188     success = success && invoke_on_render_begin(colors(), project, this, recorder, abort_switch);
189     success = success && invoke_on_render_begin(textures(), project, this, recorder, abort_switch);
190     success = success && invoke_on_render_begin(texture_instances(), project, this, recorder, abort_switch);
191     success = success && invoke_on_render_begin(shader_groups(), project, this, recorder, abort_switch);
192     success = success && invoke_on_render_begin(assemblies(), project, this, recorder, abort_switch);
193     success = success && invoke_on_render_begin(assembly_instances(), project, this, recorder, abort_switch);
194     return success;
195 }
196 
on_frame_begin(const Project & project,const BaseGroup * parent,OnFrameBeginRecorder & recorder,IAbortSwitch * abort_switch)197 bool BaseGroup::on_frame_begin(
198     const Project&              project,
199     const BaseGroup*            parent,
200     OnFrameBeginRecorder&       recorder,
201     IAbortSwitch*               abort_switch)
202 {
203     bool success = true;
204     success = success && invoke_on_frame_begin(colors(), project, this, recorder, abort_switch);
205     success = success && invoke_on_frame_begin(textures(), project, this, recorder, abort_switch);
206     success = success && invoke_on_frame_begin(texture_instances(), project, this, recorder, abort_switch);
207     success = success && invoke_on_frame_begin(shader_groups(), project, this, recorder, abort_switch);
208     success = success && invoke_on_frame_begin(assemblies(), project, this, recorder, abort_switch);
209     success = success && invoke_on_frame_begin(assembly_instances(), project, this, recorder, abort_switch);
210     return success;
211 }
212 
213 }   // namespace renderer
214