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