Cycles: relicense GNU GPL source code to Apache version 2.0.
[blender.git] / intern / cycles / subd / subd_split.cpp
1 /*
2  * Copyright 2011-2013 Blender Foundation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License
15  */
16
17 #include "camera.h"
18 #include "mesh.h"
19
20 #include "subd_dice.h"
21 #include "subd_patch.h"
22 #include "subd_split.h"
23
24 #include "util_debug.h"
25 #include "util_math.h"
26 #include "util_types.h"
27
28 CCL_NAMESPACE_BEGIN
29
30 /* DiagSplit */
31
32 DiagSplit::DiagSplit()
33 {
34         test_steps = 3;
35         split_threshold = 1;
36         dicing_rate = 0.1f;
37         camera = NULL;
38 }
39
40 void DiagSplit::dispatch(QuadDice::SubPatch& sub, QuadDice::EdgeFactors& ef)
41 {
42         subpatches_quad.push_back(sub);
43         edgefactors_quad.push_back(ef);
44 }
45
46 void DiagSplit::dispatch(TriangleDice::SubPatch& sub, TriangleDice::EdgeFactors& ef)
47 {
48         subpatches_triangle.push_back(sub);
49         edgefactors_triangle.push_back(ef);
50 }
51
52 float3 DiagSplit::project(Patch *patch, float2 uv)
53 {
54         float3 P;
55
56         patch->eval(&P, NULL, NULL, uv.x, uv.y);
57         if(camera)
58                 P = transform_perspective(&camera->worldtoraster, P);
59
60         return P;
61 }
62
63 int DiagSplit::T(Patch *patch, float2 Pstart, float2 Pend)
64 {
65         float3 Plast = make_float3(0.0f, 0.0f, 0.0f);
66         float Lsum = 0.0f;
67         float Lmax = 0.0f;
68
69         for(int i = 0; i < test_steps; i++) {
70                 float t = i/(float)(test_steps-1);
71
72                 float3 P = project(patch, Pstart + t*(Pend - Pstart));
73
74                 if(i > 0) {
75                         float L = len(P - Plast);
76                         Lsum += L;
77                         Lmax = max(L, Lmax);
78                 }
79
80                 Plast = P;
81         }
82
83         int tmin = (int)ceil(Lsum/dicing_rate);
84         int tmax = (int)ceil((test_steps-1)*Lmax/dicing_rate); // XXX paper says N instead of N-1, seems wrong?
85
86         if(tmax - tmin > split_threshold)
87                 return DSPLIT_NON_UNIFORM;
88         
89         return tmax;
90 }
91
92 void DiagSplit::partition_edge(Patch *patch, float2 *P, int *t0, int *t1, float2 Pstart, float2 Pend, int t)
93 {
94         if(t == DSPLIT_NON_UNIFORM) {
95                 *P = (Pstart + Pend)*0.5f;
96                 *t0 = T(patch, Pstart, *P);
97                 *t1 = T(patch, *P, Pend);
98         }
99         else {
100                 int I = floor(t*0.5f);
101                 *P = interp(Pstart, Pend, (t == 0)? 0: I/(float)t); /* XXX is t faces or verts */
102                 *t0 = I;
103                 *t1 = t - I;
104         }
105 }
106
107 void DiagSplit::split(TriangleDice::SubPatch& sub, TriangleDice::EdgeFactors& ef, int depth)
108 {
109         assert(ef.tu == T(sub.patch, sub.Pv, sub.Pw));
110         assert(ef.tv == T(sub.patch, sub.Pw, sub.Pu));
111         assert(ef.tw == T(sub.patch, sub.Pu, sub.Pv));
112
113         if(depth == 0) {
114                 dispatch(sub, ef);
115                 return;
116         }
117
118         if(ef.tu == DSPLIT_NON_UNIFORM) {
119                 /* partition edges */
120                 TriangleDice::EdgeFactors ef0, ef1;
121                 float2 Psplit;
122
123                 partition_edge(sub.patch,
124                         &Psplit, &ef1.tu, &ef0.tu, sub.Pv, sub.Pw, ef.tu);
125
126                 /* split */
127                 int tsplit = T(sub.patch, sub.Pu, Psplit);
128                 ef0.tv = ef.tv;
129                 ef0.tw = tsplit;
130
131                 ef1.tv = tsplit;
132                 ef1.tw = ef.tw;
133
134                 /* create subpatches */
135                 TriangleDice::SubPatch sub0 = {sub.patch, sub.Pu, Psplit, sub.Pw};
136                 TriangleDice::SubPatch sub1 = {sub.patch, sub.Pu, sub.Pv, Psplit};
137
138                 split(sub0, ef0, depth+1);
139                 split(sub1, ef1, depth+1);
140         }
141         else if(ef.tv == DSPLIT_NON_UNIFORM) {
142                 /* partition edges */
143                 TriangleDice::EdgeFactors ef0, ef1;
144                 float2 Psplit;
145
146                 partition_edge(sub.patch,
147                         &Psplit, &ef1.tu, &ef0.tu, sub.Pw, sub.Pu, ef.tv);
148
149                 /* split */
150                 int tsplit = T(sub.patch, sub.Pv, Psplit);
151                 ef0.tv = ef.tw;
152                 ef0.tw = tsplit;
153
154                 ef1.tv = tsplit;
155                 ef1.tw = ef.tu;
156
157                 /* create subpatches */
158                 TriangleDice::SubPatch sub0 = {sub.patch, sub.Pv, Psplit, sub.Pu};
159                 TriangleDice::SubPatch sub1 = {sub.patch, sub.Pv, sub.Pw, Psplit};
160
161                 split(sub0, ef0, depth+1);
162                 split(sub1, ef1, depth+1);
163         }
164         else if(ef.tw == DSPLIT_NON_UNIFORM) {
165                 /* partition edges */
166                 TriangleDice::EdgeFactors ef0, ef1;
167                 float2 Psplit;
168
169                 partition_edge(sub.patch,
170                         &Psplit, &ef1.tu, &ef0.tu, sub.Pu, sub.Pv, ef.tw);
171
172                 /* split */
173                 int tsplit = T(sub.patch, sub.Pw, Psplit);
174                 ef0.tv = ef.tu;
175                 ef0.tw = tsplit;
176
177                 ef1.tv = tsplit;
178                 ef1.tw = ef.tv;
179
180                 /* create subpatches */
181                 TriangleDice::SubPatch sub0 = {sub.patch, sub.Pw, Psplit, sub.Pv};
182                 TriangleDice::SubPatch sub1 = {sub.patch, sub.Pw, sub.Pu, Psplit};
183
184                 split(sub0, ef0, depth+1);
185                 split(sub1, ef1, depth+1);
186         }
187         else
188                 dispatch(sub, ef);
189 }
190
191 void DiagSplit::split(QuadDice::SubPatch& sub, QuadDice::EdgeFactors& ef, int depth)
192 {
193         if((ef.tu0 == DSPLIT_NON_UNIFORM || ef.tu1 == DSPLIT_NON_UNIFORM)) {
194                 /* partition edges */
195                 QuadDice::EdgeFactors ef0, ef1;
196                 float2 Pu0, Pu1;
197
198                 partition_edge(sub.patch,
199                         &Pu0, &ef0.tu0, &ef1.tu0, sub.P00, sub.P10, ef.tu0);
200                 partition_edge(sub.patch,
201                         &Pu1, &ef0.tu1, &ef1.tu1, sub.P01, sub.P11, ef.tu1);
202
203                 /* split */
204                 int tsplit = T(sub.patch, Pu0, Pu1);
205                 ef0.tv0 = ef.tv0;
206                 ef0.tv1 = tsplit;
207
208                 ef1.tv0 = tsplit;
209                 ef1.tv1 = ef.tv1;
210
211                 /* create subpatches */
212                 QuadDice::SubPatch sub0 = {sub.patch, sub.P00, Pu0, sub.P01, Pu1};
213                 QuadDice::SubPatch sub1 = {sub.patch, Pu0, sub.P10, Pu1, sub.P11};
214
215                 split(sub0, ef0, depth+1);
216                 split(sub1, ef1, depth+1);
217         }
218         else if(ef.tv0 == DSPLIT_NON_UNIFORM || ef.tv1 == DSPLIT_NON_UNIFORM) {
219                 /* partition edges */
220                 QuadDice::EdgeFactors ef0, ef1;
221                 float2 Pv0, Pv1;
222
223                 partition_edge(sub.patch,
224                         &Pv0, &ef0.tv0, &ef1.tv0, sub.P00, sub.P01, ef.tv0);
225                 partition_edge(sub.patch,
226                         &Pv1, &ef0.tv1, &ef1.tv1, sub.P10, sub.P11, ef.tv1);
227
228                 /* split */
229                 int tsplit = T(sub.patch, Pv0, Pv1);
230                 ef0.tu0 = ef.tu0;
231                 ef0.tu1 = tsplit;
232
233                 ef1.tu0 = tsplit;
234                 ef1.tu1 = ef.tu1;
235
236                 /* create subpatches */
237                 QuadDice::SubPatch sub0 = {sub.patch, sub.P00, sub.P10, Pv0, Pv1};
238                 QuadDice::SubPatch sub1 = {sub.patch, Pv0, Pv1, sub.P01, sub.P11};
239
240                 split(sub0, ef0, depth+1);
241                 split(sub1, ef1, depth+1);
242         }
243         else
244                 dispatch(sub, ef);
245 }
246
247 void DiagSplit::split_triangle(Mesh *mesh, Patch *patch, int shader, bool smooth)
248 {
249         TriangleDice::SubPatch sub_split;
250         TriangleDice::EdgeFactors ef_split;
251
252         sub_split.patch = patch;
253         sub_split.Pu = make_float2(1.0f, 0.0f);
254         sub_split.Pv = make_float2(0.0f, 1.0f);
255         sub_split.Pw = make_float2(0.0f, 0.0f);
256
257         ef_split.tu = T(patch, sub_split.Pv, sub_split.Pw);
258         ef_split.tv = T(patch, sub_split.Pw, sub_split.Pu);
259         ef_split.tw = T(patch, sub_split.Pu, sub_split.Pv);
260
261         split(sub_split, ef_split);
262
263         TriangleDice dice(mesh, shader, smooth, dicing_rate);
264         dice.camera = camera;
265
266         for(size_t i = 0; i < subpatches_triangle.size(); i++) {
267                 TriangleDice::SubPatch& sub = subpatches_triangle[i];
268                 TriangleDice::EdgeFactors& ef = edgefactors_triangle[i];
269
270                 ef.tu = 4;
271                 ef.tv = 4;
272                 ef.tw = 4;
273
274                 ef.tu = max(ef.tu, 1);
275                 ef.tv = max(ef.tv, 1);
276                 ef.tw = max(ef.tw, 1);
277
278                 dice.dice(sub, ef);
279         }
280
281         subpatches_triangle.clear();
282         edgefactors_triangle.clear();
283 }
284
285 void DiagSplit::split_quad(Mesh *mesh, Patch *patch, int shader, bool smooth)
286 {
287         QuadDice::SubPatch sub_split;
288         QuadDice::EdgeFactors ef_split;
289
290         sub_split.patch = patch;
291         sub_split.P00 = make_float2(0.0f, 0.0f);
292         sub_split.P10 = make_float2(1.0f, 0.0f);
293         sub_split.P01 = make_float2(0.0f, 1.0f);
294         sub_split.P11 = make_float2(1.0f, 1.0f);
295
296         ef_split.tu0 = T(patch, sub_split.P00, sub_split.P10);
297         ef_split.tu1 = T(patch, sub_split.P01, sub_split.P11);
298         ef_split.tv0 = T(patch, sub_split.P00, sub_split.P01);
299         ef_split.tv1 = T(patch, sub_split.P10, sub_split.P11);
300
301         split(sub_split, ef_split);
302
303         QuadDice dice(mesh, shader, smooth, dicing_rate);
304         dice.camera = camera;
305
306         for(size_t i = 0; i < subpatches_quad.size(); i++) {
307                 QuadDice::SubPatch& sub = subpatches_quad[i];
308                 QuadDice::EdgeFactors& ef = edgefactors_quad[i];
309
310                 ef.tu0 = max(ef.tu0, 1);
311                 ef.tu1 = max(ef.tu1, 1);
312                 ef.tv0 = max(ef.tv0, 1);
313                 ef.tv1 = max(ef.tv1, 1);
314
315                 dice.dice(sub, ef);
316         }
317
318         subpatches_quad.clear();
319         edgefactors_quad.clear();
320 }
321
322 CCL_NAMESPACE_END
323