ClangFormat: apply to source, most of intern
[blender.git] / intern / cycles / render / mesh_subdivision.cpp
1 /*
2  * Copyright 2011-2016 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 "render/mesh.h"
18 #include "render/attribute.h"
19 #include "render/camera.h"
20
21 #include "subd/subd_split.h"
22 #include "subd/subd_patch.h"
23 #include "subd/subd_patch_table.h"
24
25 #include "util/util_foreach.h"
26 #include "util/util_algorithm.h"
27
28 CCL_NAMESPACE_BEGIN
29
30 #ifdef WITH_OPENSUBDIV
31
32 CCL_NAMESPACE_END
33
34 #  include <opensubdiv/far/topologyRefinerFactory.h>
35 #  include <opensubdiv/far/primvarRefiner.h>
36 #  include <opensubdiv/far/patchTableFactory.h>
37 #  include <opensubdiv/far/patchMap.h>
38
39 /* specializations of TopologyRefinerFactory for ccl::Mesh */
40
41 namespace OpenSubdiv {
42 namespace OPENSUBDIV_VERSION {
43 namespace Far {
44 template<>
45 bool TopologyRefinerFactory<ccl::Mesh>::resizeComponentTopology(TopologyRefiner &refiner,
46                                                                 ccl::Mesh const &mesh)
47 {
48   setNumBaseVertices(refiner, mesh.verts.size());
49   setNumBaseFaces(refiner, mesh.subd_faces.size());
50
51   const ccl::Mesh::SubdFace *face = mesh.subd_faces.data();
52
53   for (int i = 0; i < mesh.subd_faces.size(); i++, face++) {
54     setNumBaseFaceVertices(refiner, i, face->num_corners);
55   }
56
57   return true;
58 }
59
60 template<>
61 bool TopologyRefinerFactory<ccl::Mesh>::assignComponentTopology(TopologyRefiner &refiner,
62                                                                 ccl::Mesh const &mesh)
63 {
64   const ccl::Mesh::SubdFace *face = mesh.subd_faces.data();
65
66   for (int i = 0; i < mesh.subd_faces.size(); i++, face++) {
67     IndexArray face_verts = getBaseFaceVertices(refiner, i);
68
69     int *corner = &mesh.subd_face_corners[face->start_corner];
70
71     for (int j = 0; j < face->num_corners; j++, corner++) {
72       face_verts[j] = *corner;
73     }
74   }
75
76   return true;
77 }
78
79 template<>
80 bool TopologyRefinerFactory<ccl::Mesh>::assignComponentTags(TopologyRefiner &refiner,
81                                                             ccl::Mesh const &mesh)
82 {
83   const ccl::Mesh::SubdEdgeCrease *crease = mesh.subd_creases.data();
84
85   for (int i = 0; i < mesh.subd_creases.size(); i++, crease++) {
86     Index edge = findBaseEdge(refiner, crease->v[0], crease->v[1]);
87
88     if (edge != INDEX_INVALID) {
89       setBaseEdgeSharpness(refiner, edge, crease->crease * 10.0f);
90     }
91   }
92
93   for (int i = 0; i < mesh.verts.size(); i++) {
94     ConstIndexArray vert_edges = getBaseVertexEdges(refiner, i);
95
96     if (vert_edges.size() == 2) {
97       float sharpness = refiner.getLevel(0).getEdgeSharpness(vert_edges[0]);
98       sharpness = ccl::min(sharpness, refiner.getLevel(0).getEdgeSharpness(vert_edges[1]));
99
100       setBaseVertexSharpness(refiner, i, sharpness);
101     }
102   }
103
104   return true;
105 }
106
107 template<>
108 bool TopologyRefinerFactory<ccl::Mesh>::assignFaceVaryingTopology(TopologyRefiner & /*refiner*/,
109                                                                   ccl::Mesh const & /*mesh*/)
110 {
111   return true;
112 }
113
114 template<>
115 void TopologyRefinerFactory<ccl::Mesh>::reportInvalidTopology(TopologyError /*err_code*/,
116                                                               char const * /*msg*/,
117                                                               ccl::Mesh const & /*mesh*/)
118 {
119 }
120 } /* namespace Far */
121 } /* namespace OPENSUBDIV_VERSION */
122 } /* namespace OpenSubdiv */
123
124 CCL_NAMESPACE_BEGIN
125
126 using namespace OpenSubdiv;
127
128 /* struct that implements OpenSubdiv's vertex interface */
129
130 template<typename T> struct OsdValue {
131   T value;
132
133   OsdValue()
134   {
135   }
136
137   void Clear(void * = 0)
138   {
139     memset(&value, 0, sizeof(T));
140   }
141
142   void AddWithWeight(OsdValue<T> const &src, float weight)
143   {
144     value += src.value * weight;
145   }
146 };
147
148 template<> void OsdValue<uchar4>::AddWithWeight(OsdValue<uchar4> const &src, float weight)
149 {
150   for (int i = 0; i < 4; i++) {
151     value[i] += (uchar)(src.value[i] * weight);
152   }
153 }
154
155 /* class for holding OpenSubdiv data used during tessellation */
156
157 class OsdData {
158   Mesh *mesh;
159   vector<OsdValue<float3>> verts;
160   Far::TopologyRefiner *refiner;
161   Far::PatchTable *patch_table;
162   Far::PatchMap *patch_map;
163
164  public:
165   OsdData() : mesh(NULL), refiner(NULL), patch_table(NULL), patch_map(NULL)
166   {
167   }
168
169   ~OsdData()
170   {
171     delete refiner;
172     delete patch_table;
173     delete patch_map;
174   }
175
176   void build_from_mesh(Mesh *mesh_)
177   {
178     mesh = mesh_;
179
180     /* type and options */
181     Sdc::SchemeType type = Sdc::SCHEME_CATMARK;
182
183     Sdc::Options options;
184     options.SetVtxBoundaryInterpolation(Sdc::Options::VTX_BOUNDARY_EDGE_ONLY);
185
186     /* create refiner */
187     refiner = Far::TopologyRefinerFactory<Mesh>::Create(
188         *mesh, Far::TopologyRefinerFactory<Mesh>::Options(type, options));
189
190     /* adaptive refinement */
191     int max_isolation = calculate_max_isolation();
192     refiner->RefineAdaptive(Far::TopologyRefiner::AdaptiveOptions(max_isolation));
193
194     /* create patch table */
195     Far::PatchTableFactory::Options patch_options;
196     patch_options.endCapType = Far::PatchTableFactory::Options::ENDCAP_GREGORY_BASIS;
197
198     patch_table = Far::PatchTableFactory::Create(*refiner, patch_options);
199
200     /* interpolate verts */
201     int num_refiner_verts = refiner->GetNumVerticesTotal();
202     int num_local_points = patch_table->GetNumLocalPoints();
203
204     verts.resize(num_refiner_verts + num_local_points);
205     for (int i = 0; i < mesh->verts.size(); i++) {
206       verts[i].value = mesh->verts[i];
207     }
208
209     OsdValue<float3> *src = verts.data();
210     for (int i = 0; i < refiner->GetMaxLevel(); i++) {
211       OsdValue<float3> *dest = src + refiner->GetLevel(i).GetNumVertices();
212       Far::PrimvarRefiner(*refiner).Interpolate(i + 1, src, dest);
213       src = dest;
214     }
215
216     if (num_local_points) {
217       patch_table->ComputeLocalPointValues(&verts[0], &verts[num_refiner_verts]);
218     }
219
220     /* create patch map */
221     patch_map = new Far::PatchMap(*patch_table);
222   }
223
224   void subdivide_attribute(Attribute &attr)
225   {
226     Far::PrimvarRefiner primvar_refiner(*refiner);
227
228     if (attr.element == ATTR_ELEMENT_VERTEX) {
229       int num_refiner_verts = refiner->GetNumVerticesTotal();
230       int num_local_points = patch_table->GetNumLocalPoints();
231
232       attr.resize(num_refiner_verts + num_local_points);
233       attr.flags |= ATTR_FINAL_SIZE;
234
235       char *src = attr.buffer.data();
236
237       for (int i = 0; i < refiner->GetMaxLevel(); i++) {
238         char *dest = src + refiner->GetLevel(i).GetNumVertices() * attr.data_sizeof();
239
240         if (attr.same_storage(attr.type, TypeDesc::TypeFloat)) {
241           primvar_refiner.Interpolate(i + 1, (OsdValue<float> *)src, (OsdValue<float> *&)dest);
242         }
243         else if (attr.same_storage(attr.type, TypeFloat2)) {
244           primvar_refiner.Interpolate(i + 1, (OsdValue<float2> *)src, (OsdValue<float2> *&)dest);
245         }
246         else {
247           primvar_refiner.Interpolate(i + 1, (OsdValue<float4> *)src, (OsdValue<float4> *&)dest);
248         }
249
250         src = dest;
251       }
252
253       if (num_local_points) {
254         if (attr.same_storage(attr.type, TypeDesc::TypeFloat)) {
255           patch_table->ComputeLocalPointValues(
256               (OsdValue<float> *)&attr.buffer[0],
257               (OsdValue<float> *)&attr.buffer[num_refiner_verts * attr.data_sizeof()]);
258         }
259         else if (attr.same_storage(attr.type, TypeFloat2)) {
260           patch_table->ComputeLocalPointValues(
261               (OsdValue<float2> *)&attr.buffer[0],
262               (OsdValue<float2> *)&attr.buffer[num_refiner_verts * attr.data_sizeof()]);
263         }
264         else {
265           patch_table->ComputeLocalPointValues(
266               (OsdValue<float4> *)&attr.buffer[0],
267               (OsdValue<float4> *)&attr.buffer[num_refiner_verts * attr.data_sizeof()]);
268         }
269       }
270     }
271     else if (attr.element == ATTR_ELEMENT_CORNER || attr.element == ATTR_ELEMENT_CORNER_BYTE) {
272       // TODO(mai): fvar interpolation
273     }
274   }
275
276   int calculate_max_isolation()
277   {
278     /* loop over all edges to find longest in screen space */
279     const Far::TopologyLevel &level = refiner->GetLevel(0);
280     Transform objecttoworld = mesh->subd_params->objecttoworld;
281     Camera *cam = mesh->subd_params->camera;
282
283     float longest_edge = 0.0f;
284
285     for (size_t i = 0; i < level.GetNumEdges(); i++) {
286       Far::ConstIndexArray verts = level.GetEdgeVertices(i);
287
288       float3 a = mesh->verts[verts[0]];
289       float3 b = mesh->verts[verts[1]];
290
291       float edge_len;
292
293       if (cam) {
294         a = transform_point(&objecttoworld, a);
295         b = transform_point(&objecttoworld, b);
296
297         edge_len = len(a - b) / cam->world_to_raster_size((a + b) * 0.5f);
298       }
299       else {
300         edge_len = len(a - b);
301       }
302
303       longest_edge = max(longest_edge, edge_len);
304     }
305
306     /* calculate isolation level */
307     int isolation = (int)(log2f(max(longest_edge / mesh->subd_params->dicing_rate, 1.0f)) + 1.0f);
308
309     return min(isolation, 10);
310   }
311
312   friend struct OsdPatch;
313   friend class Mesh;
314 };
315
316 /* ccl::Patch implementation that uses OpenSubdiv for eval */
317
318 struct OsdPatch : Patch {
319   OsdData *osd_data;
320
321   OsdPatch(OsdData *data) : osd_data(data)
322   {
323   }
324
325   void eval(float3 *P, float3 *dPdu, float3 *dPdv, float3 *N, float u, float v)
326   {
327     const Far::PatchTable::PatchHandle *handle = osd_data->patch_map->FindPatch(patch_index, u, v);
328     assert(handle);
329
330     float p_weights[20], du_weights[20], dv_weights[20];
331     osd_data->patch_table->EvaluateBasis(*handle, u, v, p_weights, du_weights, dv_weights);
332
333     Far::ConstIndexArray cv = osd_data->patch_table->GetPatchVertices(*handle);
334
335     float3 du, dv;
336     if (P)
337       *P = make_float3(0.0f, 0.0f, 0.0f);
338     du = make_float3(0.0f, 0.0f, 0.0f);
339     dv = make_float3(0.0f, 0.0f, 0.0f);
340
341     for (int i = 0; i < cv.size(); i++) {
342       float3 p = osd_data->verts[cv[i]].value;
343
344       if (P)
345         *P += p * p_weights[i];
346       du += p * du_weights[i];
347       dv += p * dv_weights[i];
348     }
349
350     if (dPdu)
351       *dPdu = du;
352     if (dPdv)
353       *dPdv = dv;
354     if (N) {
355       *N = cross(du, dv);
356
357       float t = len(*N);
358       *N = (t != 0.0f) ? *N / t : make_float3(0.0f, 0.0f, 1.0f);
359     }
360   }
361
362   BoundBox bound()
363   {
364     return BoundBox::empty;
365   }
366 };
367
368 #endif
369
370 void Mesh::tessellate(DiagSplit *split)
371 {
372 #ifdef WITH_OPENSUBDIV
373   OsdData osd_data;
374   bool need_packed_patch_table = false;
375
376   if (subdivision_type == SUBDIVISION_CATMULL_CLARK) {
377     if (subd_faces.size()) {
378       osd_data.build_from_mesh(this);
379     }
380   }
381   else
382 #endif
383   {
384     /* force linear subdivision if OpenSubdiv is unavailable to avoid
385      * falling into catmull-clark code paths by accident
386      */
387     subdivision_type = SUBDIVISION_LINEAR;
388
389     /* force disable attribute subdivision for same reason as above */
390     foreach (Attribute &attr, subd_attributes.attributes) {
391       attr.flags &= ~ATTR_SUBDIVIDED;
392     }
393   }
394
395   int num_faces = subd_faces.size();
396
397   Attribute *attr_vN = subd_attributes.find(ATTR_STD_VERTEX_NORMAL);
398   float3 *vN = attr_vN->data_float3();
399
400   for (int f = 0; f < num_faces; f++) {
401     SubdFace &face = subd_faces[f];
402
403     if (face.is_quad()) {
404       /* quad */
405       QuadDice::SubPatch subpatch;
406
407       LinearQuadPatch quad_patch;
408 #ifdef WITH_OPENSUBDIV
409       OsdPatch osd_patch(&osd_data);
410
411       if (subdivision_type == SUBDIVISION_CATMULL_CLARK) {
412         osd_patch.patch_index = face.ptex_offset;
413
414         subpatch.patch = &osd_patch;
415       }
416       else
417 #endif
418       {
419         float3 *hull = quad_patch.hull;
420         float3 *normals = quad_patch.normals;
421
422         quad_patch.patch_index = face.ptex_offset;
423
424         for (int i = 0; i < 4; i++) {
425           hull[i] = verts[subd_face_corners[face.start_corner + i]];
426         }
427
428         if (face.smooth) {
429           for (int i = 0; i < 4; i++) {
430             normals[i] = vN[subd_face_corners[face.start_corner + i]];
431           }
432         }
433         else {
434           float3 N = face.normal(this);
435           for (int i = 0; i < 4; i++) {
436             normals[i] = N;
437           }
438         }
439
440         swap(hull[2], hull[3]);
441         swap(normals[2], normals[3]);
442
443         subpatch.patch = &quad_patch;
444       }
445
446       subpatch.patch->shader = face.shader;
447
448       /* Quad faces need to be split at least once to line up with split ngons, we do this
449        * here in this manner because if we do it later edge factors may end up slightly off.
450        */
451       subpatch.P00 = make_float2(0.0f, 0.0f);
452       subpatch.P10 = make_float2(0.5f, 0.0f);
453       subpatch.P01 = make_float2(0.0f, 0.5f);
454       subpatch.P11 = make_float2(0.5f, 0.5f);
455       split->split_quad(subpatch.patch, &subpatch);
456
457       subpatch.P00 = make_float2(0.5f, 0.0f);
458       subpatch.P10 = make_float2(1.0f, 0.0f);
459       subpatch.P01 = make_float2(0.5f, 0.5f);
460       subpatch.P11 = make_float2(1.0f, 0.5f);
461       split->split_quad(subpatch.patch, &subpatch);
462
463       subpatch.P00 = make_float2(0.0f, 0.5f);
464       subpatch.P10 = make_float2(0.5f, 0.5f);
465       subpatch.P01 = make_float2(0.0f, 1.0f);
466       subpatch.P11 = make_float2(0.5f, 1.0f);
467       split->split_quad(subpatch.patch, &subpatch);
468
469       subpatch.P00 = make_float2(0.5f, 0.5f);
470       subpatch.P10 = make_float2(1.0f, 0.5f);
471       subpatch.P01 = make_float2(0.5f, 1.0f);
472       subpatch.P11 = make_float2(1.0f, 1.0f);
473       split->split_quad(subpatch.patch, &subpatch);
474     }
475     else {
476       /* ngon */
477 #ifdef WITH_OPENSUBDIV
478       if (subdivision_type == SUBDIVISION_CATMULL_CLARK) {
479         OsdPatch patch(&osd_data);
480
481         patch.shader = face.shader;
482
483         for (int corner = 0; corner < face.num_corners; corner++) {
484           patch.patch_index = face.ptex_offset + corner;
485
486           split->split_quad(&patch);
487         }
488       }
489       else
490 #endif
491       {
492         float3 center_vert = make_float3(0.0f, 0.0f, 0.0f);
493         float3 center_normal = make_float3(0.0f, 0.0f, 0.0f);
494
495         float inv_num_corners = 1.0f / float(face.num_corners);
496         for (int corner = 0; corner < face.num_corners; corner++) {
497           center_vert += verts[subd_face_corners[face.start_corner + corner]] * inv_num_corners;
498           center_normal += vN[subd_face_corners[face.start_corner + corner]] * inv_num_corners;
499         }
500
501         for (int corner = 0; corner < face.num_corners; corner++) {
502           LinearQuadPatch patch;
503           float3 *hull = patch.hull;
504           float3 *normals = patch.normals;
505
506           patch.patch_index = face.ptex_offset + corner;
507
508           patch.shader = face.shader;
509
510           hull[0] =
511               verts[subd_face_corners[face.start_corner + mod(corner + 0, face.num_corners)]];
512           hull[1] =
513               verts[subd_face_corners[face.start_corner + mod(corner + 1, face.num_corners)]];
514           hull[2] =
515               verts[subd_face_corners[face.start_corner + mod(corner - 1, face.num_corners)]];
516           hull[3] = center_vert;
517
518           hull[1] = (hull[1] + hull[0]) * 0.5;
519           hull[2] = (hull[2] + hull[0]) * 0.5;
520
521           if (face.smooth) {
522             normals[0] =
523                 vN[subd_face_corners[face.start_corner + mod(corner + 0, face.num_corners)]];
524             normals[1] =
525                 vN[subd_face_corners[face.start_corner + mod(corner + 1, face.num_corners)]];
526             normals[2] =
527                 vN[subd_face_corners[face.start_corner + mod(corner - 1, face.num_corners)]];
528             normals[3] = center_normal;
529
530             normals[1] = (normals[1] + normals[0]) * 0.5;
531             normals[2] = (normals[2] + normals[0]) * 0.5;
532           }
533           else {
534             float3 N = face.normal(this);
535             for (int i = 0; i < 4; i++) {
536               normals[i] = N;
537             }
538           }
539
540           split->split_quad(&patch);
541         }
542       }
543     }
544   }
545
546   /* interpolate center points for attributes */
547   foreach (Attribute &attr, subd_attributes.attributes) {
548 #ifdef WITH_OPENSUBDIV
549     if (subdivision_type == SUBDIVISION_CATMULL_CLARK && attr.flags & ATTR_SUBDIVIDED) {
550       if (attr.element == ATTR_ELEMENT_CORNER || attr.element == ATTR_ELEMENT_CORNER_BYTE) {
551         /* keep subdivision for corner attributes disabled for now */
552         attr.flags &= ~ATTR_SUBDIVIDED;
553       }
554       else if (subd_faces.size()) {
555         osd_data.subdivide_attribute(attr);
556
557         need_packed_patch_table = true;
558         continue;
559       }
560     }
561 #endif
562
563     char *data = attr.data();
564     size_t stride = attr.data_sizeof();
565     int ngons = 0;
566
567     switch (attr.element) {
568       case ATTR_ELEMENT_VERTEX: {
569         for (int f = 0; f < num_faces; f++) {
570           SubdFace &face = subd_faces[f];
571
572           if (!face.is_quad()) {
573             char *center = data + (verts.size() - num_subd_verts + ngons) * stride;
574             attr.zero_data(center);
575
576             float inv_num_corners = 1.0f / float(face.num_corners);
577
578             for (int corner = 0; corner < face.num_corners; corner++) {
579               attr.add_with_weight(center,
580                                    data + subd_face_corners[face.start_corner + corner] * stride,
581                                    inv_num_corners);
582             }
583
584             ngons++;
585           }
586         }
587       } break;
588       case ATTR_ELEMENT_VERTEX_MOTION: {
589         // TODO(mai): implement
590       } break;
591       case ATTR_ELEMENT_CORNER: {
592         for (int f = 0; f < num_faces; f++) {
593           SubdFace &face = subd_faces[f];
594
595           if (!face.is_quad()) {
596             char *center = data + (subd_face_corners.size() + ngons) * stride;
597             attr.zero_data(center);
598
599             float inv_num_corners = 1.0f / float(face.num_corners);
600
601             for (int corner = 0; corner < face.num_corners; corner++) {
602               attr.add_with_weight(
603                   center, data + (face.start_corner + corner) * stride, inv_num_corners);
604             }
605
606             ngons++;
607           }
608         }
609       } break;
610       case ATTR_ELEMENT_CORNER_BYTE: {
611         for (int f = 0; f < num_faces; f++) {
612           SubdFace &face = subd_faces[f];
613
614           if (!face.is_quad()) {
615             uchar *center = (uchar *)data + (subd_face_corners.size() + ngons) * stride;
616
617             float inv_num_corners = 1.0f / float(face.num_corners);
618             float4 val = make_float4(0.0f, 0.0f, 0.0f, 0.0f);
619
620             for (int corner = 0; corner < face.num_corners; corner++) {
621               for (int i = 0; i < 4; i++) {
622                 val[i] += float(*(data + (face.start_corner + corner) * stride + i)) *
623                           inv_num_corners;
624               }
625             }
626
627             for (int i = 0; i < 4; i++) {
628               center[i] = uchar(min(max(val[i], 0.0f), 255.0f));
629             }
630
631             ngons++;
632           }
633         }
634       } break;
635       default:
636         break;
637     }
638   }
639
640 #ifdef WITH_OPENSUBDIV
641   /* pack patch tables */
642   if (need_packed_patch_table) {
643     delete patch_table;
644     patch_table = new PackedPatchTable;
645     patch_table->pack(osd_data.patch_table);
646   }
647 #endif
648 }
649
650 CCL_NAMESPACE_END