Cycles: Cleanup, split one gigantic function into two smaller ones
authorSergey Sharybin <sergey.vfx@gmail.com>
Fri, 20 Jan 2017 16:52:48 +0000 (17:52 +0100)
committerSergey Sharybin <sergey.vfx@gmail.com>
Fri, 20 Jan 2017 16:52:48 +0000 (17:52 +0100)
intern/cycles/bvh/bvh_build.cpp
intern/cycles/bvh/bvh_build.h

index 4abd686cc6eb470904820591a630542738b13fd0..9ff68333c805a738deda33653a8dfdec0cf90a50 100644 (file)
@@ -112,104 +112,214 @@ BVHBuild::~BVHBuild()
 
 /* Adding References */
 
-void BVHBuild::add_reference_mesh(BoundBox& root, BoundBox& center, Mesh *mesh, int i)
+void BVHBuild::add_reference_triangles(BoundBox& root, BoundBox& center, Mesh *mesh, int i)
 {
-       if(params.primitive_mask & PRIMITIVE_ALL_TRIANGLE) {
-               Attribute *attr_mP = NULL;
-
-               if(mesh->has_motion_blur())
-                       attr_mP = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
+       Attribute *attr_mP = NULL;
+       if(mesh->has_motion_blur()) {
+               attr_mP = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
+       }
+       const size_t num_triangles = mesh->num_triangles();
+       for(uint j = 0; j < num_triangles; j++) {
+               Mesh::Triangle t = mesh->get_triangle(j);
+               const float3 *verts = &mesh->verts[0];
+               if(attr_mP == NULL) {
+                       BoundBox bounds = BoundBox::empty;
+                       t.bounds_grow(verts, bounds);
+                       if(bounds.valid()) {
+                               references.push_back(BVHReference(bounds,
+                                                                 j,
+                                                                 i,
+                                                                 PRIMITIVE_TRIANGLE));
+                               root.grow(bounds);
+                               center.grow(bounds.center2());
+                       }
+               }
+               else if(params.num_motion_triangle_steps == 0 || params.use_spatial_split) {
+                       /* Motion triangles, simple case: single node for the whole
+                        * primitive. Lowest memory footprint and faster BVH build but
+                        * least optimal ray-tracing.
+                        */
+                       /* TODO(sergey): Support motion steps for spatially split BVH. */
+                       const size_t num_verts = mesh->verts.size();
+                       const size_t num_steps = mesh->motion_steps;
+                       const float3 *vert_steps = attr_mP->data_float3();
+                       BoundBox bounds = BoundBox::empty;
+                       t.bounds_grow(verts, bounds);
+                       for(size_t step = 0; step < num_steps - 1; step++) {
+                               t.bounds_grow(vert_steps + step*num_verts, bounds);
+                       }
+                       if(bounds.valid()) {
+                               references.push_back(
+                                       BVHReference(bounds,
+                                                    j,
+                                                    i,
+                                                    PRIMITIVE_MOTION_TRIANGLE));
+                               root.grow(bounds);
+                               center.grow(bounds.center2());
+                       }
+               }
+               else {
+                       /* Motion triangles, trace optimized case:  we split triangle
+                        * primitives into separate nodes for each of the time steps.
+                        * This way we minimize overlap of neighbor curve primitives.
+                        */
+                       const int num_bvh_steps = params.num_motion_curve_steps * 2 + 1;
+                       const float num_bvh_steps_inv_1 = 1.0f / (num_bvh_steps - 1);
+                       const size_t num_verts = mesh->verts.size();
+                       const size_t num_steps = mesh->motion_steps;
+                       const float3 *vert_steps = attr_mP->data_float3();
+                       /* Calculate bounding box of the previous time step.
+                        * Will be reused later to avoid duplicated work on
+                        * calculating BVH time step boundbox.
+                        */
+                       float3 prev_verts[3];
+                       t.motion_verts(verts,
+                                      vert_steps,
+                                      num_verts,
+                                      num_steps,
+                                      0.0f,
+                                      prev_verts);
+                       BoundBox prev_bounds = BoundBox::empty;
+                       prev_bounds.grow(prev_verts[0]);
+                       prev_bounds.grow(prev_verts[1]);
+                       prev_bounds.grow(prev_verts[2]);
+                       /* Create all primitive time steps, */
+                       for(int bvh_step = 1; bvh_step < num_bvh_steps; ++bvh_step) {
+                               const float curr_time = (float)(bvh_step) * num_bvh_steps_inv_1;
+                               float3 curr_verts[3];
+                               t.motion_verts(verts,
+                                              vert_steps,
+                                              num_verts,
+                                              num_steps,
+                                              curr_time,
+                                              curr_verts);
+                               BoundBox curr_bounds = BoundBox::empty;
+                               curr_bounds.grow(curr_verts[0]);
+                               curr_bounds.grow(curr_verts[1]);
+                               curr_bounds.grow(curr_verts[2]);
+                               BoundBox bounds = prev_bounds;
+                               bounds.grow(curr_bounds);
+                               if(bounds.valid()) {
+                                       const float prev_time = (float)(bvh_step - 1) * num_bvh_steps_inv_1;
+                                       references.push_back(
+                                               BVHReference(bounds,
+                                                            j,
+                                                            i,
+                                                            PRIMITIVE_MOTION_TRIANGLE,
+                                                            prev_time,
+                                                            curr_time));
+                                       root.grow(bounds);
+                                       center.grow(bounds.center2());
+                               }
+                               /* Current time boundbox becomes previous one for the
+                                * next time step.
+                                */
+                               prev_bounds = curr_bounds;
+                       }
+               }
+       }
+}
 
-               const size_t num_triangles = mesh->num_triangles();
-               for(uint j = 0; j < num_triangles; j++) {
-                       Mesh::Triangle t = mesh->get_triangle(j);
-                       const float3 *verts = &mesh->verts[0];
-                       if(attr_mP == NULL) {
+void BVHBuild::add_reference_curves(BoundBox& root, BoundBox& center, Mesh *mesh, int i)
+{
+       Attribute *curve_attr_mP = NULL;
+       if(mesh->has_motion_blur()) {
+               curve_attr_mP = mesh->curve_attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
+       }
+       size_t num_curves = mesh->num_curves();
+       for(uint j = 0; j < num_curves; j++) {
+               const Mesh::Curve curve = mesh->get_curve(j);
+               const float *curve_radius = &mesh->curve_radius[0];
+               for(int k = 0; k < curve.num_keys - 1; k++) {
+                       if(curve_attr_mP == NULL) {
+                               /* Really simple logic for static hair. */
                                BoundBox bounds = BoundBox::empty;
-                               t.bounds_grow(verts, bounds);
+                               curve.bounds_grow(k, &mesh->curve_keys[0], curve_radius, bounds);
                                if(bounds.valid()) {
-                                       references.push_back(BVHReference(bounds,
-                                                                         j,
-                                                                         i,
-                                                                         PRIMITIVE_TRIANGLE));
+                                       int packed_type = PRIMITIVE_PACK_SEGMENT(PRIMITIVE_CURVE, k);
+                                       references.push_back(BVHReference(bounds, j, i, packed_type));
                                        root.grow(bounds);
                                        center.grow(bounds.center2());
                                }
                        }
-                       else if(params.num_motion_triangle_steps == 0 || params.use_spatial_split) {
-                               /* Motion triangles, simple case: single node for the whole
-                                * primitive. Lowest memory footprint and faster BVH build but
-                                * least optimal ray-tracing.
+                       else if(params.num_motion_curve_steps == 0 || params.use_spatial_split) {
+                               /* Simple case of motion curves: single node for the while
+                                * shutter time. Lowest memory usage but less optimal
+                                * rendering.
                                 */
                                /* TODO(sergey): Support motion steps for spatially split BVH. */
-                               const size_t num_verts = mesh->verts.size();
-                               const size_t num_steps = mesh->motion_steps;
-                               const float3 *vert_steps = attr_mP->data_float3();
                                BoundBox bounds = BoundBox::empty;
-                               t.bounds_grow(verts, bounds);
+                               curve.bounds_grow(k, &mesh->curve_keys[0], curve_radius, bounds);
+                               const size_t num_keys = mesh->curve_keys.size();
+                               const size_t num_steps = mesh->motion_steps;
+                               const float3 *key_steps = curve_attr_mP->data_float3();
                                for(size_t step = 0; step < num_steps - 1; step++) {
-                                       t.bounds_grow(vert_steps + step*num_verts, bounds);
+                                       curve.bounds_grow(k,
+                                                         key_steps + step*num_keys,
+                                                         curve_radius,
+                                                         bounds);
                                }
                                if(bounds.valid()) {
-                                       references.push_back(
-                                               BVHReference(bounds,
-                                                            j,
-                                                            i,
-                                                            PRIMITIVE_MOTION_TRIANGLE));
+                                       int packed_type = PRIMITIVE_PACK_SEGMENT(PRIMITIVE_MOTION_CURVE, k);
+                                       references.push_back(BVHReference(bounds,
+                                                                         j,
+                                                                         i,
+                                                                         packed_type));
                                        root.grow(bounds);
                                        center.grow(bounds.center2());
                                }
                        }
                        else {
-                               /* Motion triangles, trace optimized case:  we split triangle
+                               /* Motion curves, trace optimized case:  we split curve keys
                                 * primitives into separate nodes for each of the time steps.
                                 * This way we minimize overlap of neighbor curve primitives.
                                 */
                                const int num_bvh_steps = params.num_motion_curve_steps * 2 + 1;
                                const float num_bvh_steps_inv_1 = 1.0f / (num_bvh_steps - 1);
-                               const size_t num_verts = mesh->verts.size();
                                const size_t num_steps = mesh->motion_steps;
-                               const float3 *vert_steps = attr_mP->data_float3();
+                               const float3 *curve_keys = &mesh->curve_keys[0];
+                               const float3 *key_steps = curve_attr_mP->data_float3();
+                               const size_t num_keys = mesh->curve_keys.size();
                                /* Calculate bounding box of the previous time step.
                                 * Will be reused later to avoid duplicated work on
                                 * calculating BVH time step boundbox.
                                 */
-                               float3 prev_verts[3];
-                               t.motion_verts(verts,
-                                              vert_steps,
-                                              num_verts,
-                                              num_steps,
-                                              0.0f,
-                                              prev_verts);
+                               float4 prev_keys[4];
+                               curve.cardinal_motion_keys(curve_keys,
+                                                          curve_radius,
+                                                          key_steps,
+                                                          num_keys,
+                                                          num_steps,
+                                                          0.0f,
+                                                          k - 1, k, k + 1, k + 2,
+                                                          prev_keys);
                                BoundBox prev_bounds = BoundBox::empty;
-                               prev_bounds.grow(prev_verts[0]);
-                               prev_bounds.grow(prev_verts[1]);
-                               prev_bounds.grow(prev_verts[2]);
+                               curve.bounds_grow(prev_keys, prev_bounds);
                                /* Create all primitive time steps, */
                                for(int bvh_step = 1; bvh_step < num_bvh_steps; ++bvh_step) {
                                        const float curr_time = (float)(bvh_step) * num_bvh_steps_inv_1;
-                                       float3 curr_verts[3];
-                                       t.motion_verts(verts,
-                                                      vert_steps,
-                                                      num_verts,
-                                                      num_steps,
-                                                      curr_time,
-                                                      curr_verts);
+                                       float4 curr_keys[4];
+                                       curve.cardinal_motion_keys(curve_keys,
+                                                                  curve_radius,
+                                                                  key_steps,
+                                                                  num_keys,
+                                                                  num_steps,
+                                                                  curr_time,
+                                                                  k - 1, k, k + 1, k + 2,
+                                                                  curr_keys);
                                        BoundBox curr_bounds = BoundBox::empty;
-                                       curr_bounds.grow(curr_verts[0]);
-                                       curr_bounds.grow(curr_verts[1]);
-                                       curr_bounds.grow(curr_verts[2]);
+                                       curve.bounds_grow(curr_keys, curr_bounds);
                                        BoundBox bounds = prev_bounds;
                                        bounds.grow(curr_bounds);
                                        if(bounds.valid()) {
                                                const float prev_time = (float)(bvh_step - 1) * num_bvh_steps_inv_1;
-                                               references.push_back(
-                                                       BVHReference(bounds,
-                                                                    j,
-                                                                    i,
-                                                                    PRIMITIVE_MOTION_TRIANGLE,
-                                                                    prev_time,
-                                                                    curr_time));
+                                               int packed_type = PRIMITIVE_PACK_SEGMENT(PRIMITIVE_MOTION_CURVE, k);
+                                               references.push_back(BVHReference(bounds,
+                                                                                 j,
+                                                                                 i,
+                                                                                 packed_type,
+                                                                                 prev_time,
+                                                                                 curr_time));
                                                root.grow(bounds);
                                                center.grow(bounds.center2());
                                        }
@@ -221,118 +331,15 @@ void BVHBuild::add_reference_mesh(BoundBox& root, BoundBox& center, Mesh *mesh,
                        }
                }
        }
+}
 
+void BVHBuild::add_reference_mesh(BoundBox& root, BoundBox& center, Mesh *mesh, int i)
+{
+       if(params.primitive_mask & PRIMITIVE_ALL_TRIANGLE) {
+               add_reference_triangles(root, center, mesh, i);
+       }
        if(params.primitive_mask & PRIMITIVE_ALL_CURVE) {
-               Attribute *curve_attr_mP = NULL;
-
-               if(mesh->has_motion_blur())
-                       curve_attr_mP = mesh->curve_attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
-
-               size_t num_curves = mesh->num_curves();
-               for(uint j = 0; j < num_curves; j++) {
-                       const Mesh::Curve curve = mesh->get_curve(j);
-                       const float *curve_radius = &mesh->curve_radius[0];
-                       for(int k = 0; k < curve.num_keys - 1; k++) {
-                               if(curve_attr_mP == NULL) {
-                                       /* Really simple logic for static hair. */
-                                       BoundBox bounds = BoundBox::empty;
-                                       curve.bounds_grow(k, &mesh->curve_keys[0], curve_radius, bounds);
-                                       if(bounds.valid()) {
-                                               int packed_type = PRIMITIVE_PACK_SEGMENT(PRIMITIVE_CURVE, k);
-                                               references.push_back(BVHReference(bounds, j, i, packed_type));
-                                               root.grow(bounds);
-                                               center.grow(bounds.center2());
-                                       }
-                               }
-                               else if(params.num_motion_curve_steps == 0 || params.use_spatial_split) {
-                                       /* Simple case of motion curves: single node for the while
-                                        * shutter time. Lowest memory usage but less optimal
-                                        * rendering.
-                                        */
-                                       /* TODO(sergey): Support motion steps for spatially split BVH. */
-                                       BoundBox bounds = BoundBox::empty;
-                                       curve.bounds_grow(k, &mesh->curve_keys[0], curve_radius, bounds);
-                                       const size_t num_keys = mesh->curve_keys.size();
-                                       const size_t num_steps = mesh->motion_steps;
-                                       const float3 *key_steps = curve_attr_mP->data_float3();
-                                       for(size_t step = 0; step < num_steps - 1; step++) {
-                                               curve.bounds_grow(k,
-                                                                 key_steps + step*num_keys,
-                                                                 curve_radius,
-                                                                 bounds);
-                                       }
-                                       if(bounds.valid()) {
-                                               int packed_type = PRIMITIVE_PACK_SEGMENT(PRIMITIVE_MOTION_CURVE, k);
-                                               references.push_back(BVHReference(bounds,
-                                                                                 j,
-                                                                                 i,
-                                                                                 packed_type));
-                                               root.grow(bounds);
-                                               center.grow(bounds.center2());
-                                       }
-                               }
-                               else {
-                                       /* Motion curves, trace optimized case:  we split curve keys
-                                        * primitives into separate nodes for each of the time steps.
-                                        * This way we minimize overlap of neighbor curve primitives.
-                                        */
-                                       const int num_bvh_steps = params.num_motion_curve_steps * 2 + 1;
-                                       const float num_bvh_steps_inv_1 = 1.0f / (num_bvh_steps - 1);
-                                       const size_t num_steps = mesh->motion_steps;
-                                       const float3 *curve_keys = &mesh->curve_keys[0];
-                                       const float3 *key_steps = curve_attr_mP->data_float3();
-                                       const size_t num_keys = mesh->curve_keys.size();
-                                       /* Calculate bounding box of the previous time step.
-                                        * Will be reused later to avoid duplicated work on
-                                        * calculating BVH time step boundbox.
-                                        */
-                                       float4 prev_keys[4];
-                                       curve.cardinal_motion_keys(curve_keys,
-                                                                  curve_radius,
-                                                                  key_steps,
-                                                                  num_keys,
-                                                                  num_steps,
-                                                                  0.0f,
-                                                                  k - 1, k, k + 1, k + 2,
-                                                                  prev_keys);
-                                       BoundBox prev_bounds = BoundBox::empty;
-                                       curve.bounds_grow(prev_keys, prev_bounds);
-                                       /* Create all primitive time steps, */
-                                       for(int bvh_step = 1; bvh_step < num_bvh_steps; ++bvh_step) {
-                                               const float curr_time = (float)(bvh_step) * num_bvh_steps_inv_1;
-                                               float4 curr_keys[4];
-                                               curve.cardinal_motion_keys(curve_keys,
-                                                                          curve_radius,
-                                                                          key_steps,
-                                                                          num_keys,
-                                                                          num_steps,
-                                                                          curr_time,
-                                                                          k - 1, k, k + 1, k + 2,
-                                                                          curr_keys);
-                                               BoundBox curr_bounds = BoundBox::empty;
-                                               curve.bounds_grow(curr_keys, curr_bounds);
-                                               BoundBox bounds = prev_bounds;
-                                               bounds.grow(curr_bounds);
-                                               if(bounds.valid()) {
-                                                       const float prev_time = (float)(bvh_step - 1) * num_bvh_steps_inv_1;
-                                                       int packed_type = PRIMITIVE_PACK_SEGMENT(PRIMITIVE_MOTION_CURVE, k);
-                                                       references.push_back(BVHReference(bounds,
-                                                                                         j,
-                                                                                         i,
-                                                                                         packed_type,
-                                                                                         prev_time,
-                                                                                         curr_time));
-                                                       root.grow(bounds);
-                                                       center.grow(bounds.center2());
-                                               }
-                                               /* Current time boundbox becomes previous one for the
-                                                * next time step.
-                                                */
-                                               prev_bounds = curr_bounds;
-                                       }
-                               }
-                       }
-               }
+               add_reference_curves(root, center, mesh, i);
        }
 }
 
index 64180349935f8c1382cae648f0af1afd305a3ae3..ee3cde66a2f139c85d506e283acabb906d29ed4e 100644 (file)
@@ -63,6 +63,8 @@ protected:
        friend class BVHObjectBinning;
 
        /* Adding references. */
+       void add_reference_triangles(BoundBox& root, BoundBox& center, Mesh *mesh, int i);
+       void add_reference_curves(BoundBox& root, BoundBox& center, Mesh *mesh, int i);
        void add_reference_mesh(BoundBox& root, BoundBox& center, Mesh *mesh, int i);
        void add_reference_object(BoundBox& root, BoundBox& center, Object *ob, int i);
        void add_references(BVHRange& root);