add BLI_strcpy_rlen, replace strcat, which was used in misleading way.
[blender.git] / intern / cycles / render / integrator.cpp
1 /*
2  * Copyright 2011, Blender Foundation.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  */
18
19 #include "device.h"
20 #include "integrator.h"
21 #include "light.h"
22 #include "scene.h"
23 #include "sobol.h"
24
25 #include "util_foreach.h"
26 #include "util_hash.h"
27
28 CCL_NAMESPACE_BEGIN
29
30 Integrator::Integrator()
31 {
32         min_bounce = 2;
33         max_bounce = 7;
34
35         max_diffuse_bounce = max_bounce;
36         max_glossy_bounce = max_bounce;
37         max_transmission_bounce = max_bounce;
38         probalistic_termination = true;
39
40         transparent_min_bounce = min_bounce;
41         transparent_max_bounce = max_bounce;
42         transparent_probalistic = true;
43         transparent_shadows = false;
44
45         no_caustics = false;
46         filter_glossy = 0.0f;
47         seed = 0;
48         layer_flag = ~0;
49         sample_clamp = 0.0f;
50         motion_blur = false;
51
52         aa_samples = 0;
53         diffuse_samples = 1;
54         glossy_samples = 1;
55         transmission_samples = 1;
56         ao_samples = 1;
57         mesh_light_samples = 1;
58         subsurface_samples = 1;
59         progressive = true;
60
61         sampling_pattern = SAMPLING_PATTERN_SOBOL;
62
63         need_update = true;
64 }
65
66 Integrator::~Integrator()
67 {
68 }
69
70 void Integrator::device_update(Device *device, DeviceScene *dscene, Scene *scene)
71 {
72         if(!need_update)
73                 return;
74
75         device_free(device, dscene);
76
77         KernelIntegrator *kintegrator = &dscene->data.integrator;
78
79         /* integrator parameters */
80         kintegrator->max_bounce = max_bounce + 1;
81         if(probalistic_termination)
82                 kintegrator->min_bounce = min_bounce + 1;
83         else
84                 kintegrator->min_bounce = kintegrator->max_bounce;
85
86         kintegrator->max_diffuse_bounce = max_diffuse_bounce + 1;
87         kintegrator->max_glossy_bounce = max_glossy_bounce + 1;
88         kintegrator->max_transmission_bounce = max_transmission_bounce + 1;
89
90         kintegrator->transparent_max_bounce = transparent_max_bounce + 1;
91         if(transparent_probalistic)
92                 kintegrator->transparent_min_bounce = transparent_min_bounce + 1;
93         else
94                 kintegrator->transparent_min_bounce = kintegrator->transparent_max_bounce;
95
96         kintegrator->transparent_shadows = transparent_shadows;
97
98         kintegrator->no_caustics = no_caustics;
99         kintegrator->filter_glossy = (filter_glossy == 0.0f)? FLT_MAX: 1.0f/filter_glossy;
100
101         kintegrator->seed = hash_int(seed);
102         kintegrator->layer_flag = layer_flag << PATH_RAY_LAYER_SHIFT;
103
104         kintegrator->use_ambient_occlusion =
105                 ((dscene->data.film.pass_flag & PASS_AO) || dscene->data.background.ao_factor != 0.0f);
106         
107         kintegrator->sample_clamp = (sample_clamp == 0.0f)? FLT_MAX: sample_clamp*3.0f;
108
109         kintegrator->progressive = progressive;
110         kintegrator->aa_samples = aa_samples;
111         kintegrator->diffuse_samples = diffuse_samples;
112         kintegrator->glossy_samples = glossy_samples;
113         kintegrator->transmission_samples = transmission_samples;
114         kintegrator->ao_samples = ao_samples;
115         kintegrator->mesh_light_samples = mesh_light_samples;
116         kintegrator->subsurface_samples = subsurface_samples;
117
118         kintegrator->sampling_pattern = sampling_pattern;
119
120         /* sobol directions table */
121         int max_samples = 1;
122
123         if(!progressive) {
124                 foreach(Light *light, scene->lights)
125                         max_samples = max(max_samples, light->samples);
126
127                 max_samples = max(max_samples, max(diffuse_samples, max(glossy_samples, transmission_samples)));
128                 max_samples = max(max_samples, max(ao_samples, max(mesh_light_samples, subsurface_samples)));
129         }
130
131         max_samples *= (max_bounce + transparent_max_bounce + 2);
132
133         int dimensions = PRNG_BASE_NUM + max_samples*PRNG_BOUNCE_NUM;
134         dimensions = min(dimensions, SOBOL_MAX_DIMENSIONS);
135
136         uint *directions = dscene->sobol_directions.resize(SOBOL_BITS*dimensions);
137
138         sobol_generate_direction_vectors((uint(*)[SOBOL_BITS])directions, dimensions);
139
140         device->tex_alloc("__sobol_directions", dscene->sobol_directions);
141
142         need_update = false;
143 }
144
145 void Integrator::device_free(Device *device, DeviceScene *dscene)
146 {
147         device->tex_free(dscene->sobol_directions);
148         dscene->sobol_directions.clear();
149 }
150
151 bool Integrator::modified(const Integrator& integrator)
152 {
153         return !(min_bounce == integrator.min_bounce &&
154                 max_bounce == integrator.max_bounce &&
155                 max_diffuse_bounce == integrator.max_diffuse_bounce &&
156                 max_glossy_bounce == integrator.max_glossy_bounce &&
157                 max_transmission_bounce == integrator.max_transmission_bounce &&
158                 probalistic_termination == integrator.probalistic_termination &&
159                 transparent_min_bounce == integrator.transparent_min_bounce &&
160                 transparent_max_bounce == integrator.transparent_max_bounce &&
161                 transparent_probalistic == integrator.transparent_probalistic &&
162                 transparent_shadows == integrator.transparent_shadows &&
163                 no_caustics == integrator.no_caustics &&
164                 filter_glossy == integrator.filter_glossy &&
165                 layer_flag == integrator.layer_flag &&
166                 seed == integrator.seed &&
167                 sample_clamp == integrator.sample_clamp &&
168                 progressive == integrator.progressive &&
169                 aa_samples == integrator.aa_samples &&
170                 diffuse_samples == integrator.diffuse_samples &&
171                 glossy_samples == integrator.glossy_samples &&
172                 transmission_samples == integrator.transmission_samples &&
173                 ao_samples == integrator.ao_samples &&
174                 mesh_light_samples == integrator.mesh_light_samples &&
175                 subsurface_samples == integrator.subsurface_samples &&
176                 motion_blur == integrator.motion_blur &&
177                 sampling_pattern == integrator.sampling_pattern);
178 }
179
180 void Integrator::tag_update(Scene *scene)
181 {
182         need_update = true;
183 }
184
185 CCL_NAMESPACE_END
186