Blender V4.3
bvh/split.h
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2009-2010 NVIDIA Corporation
2 * SPDX-FileCopyrightText: 2011-2022 Blender Foundation
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 *
6 * Adapted code from NVIDIA Corporation. */
7
8#ifndef __BVH_SPLIT_H__
9#define __BVH_SPLIT_H__
10
11#include "bvh/build.h"
12#include "bvh/params.h"
13
15
16class BVHBuild;
17class Hair;
18class Mesh;
19class PointCloud;
20struct Transform;
21
22/* Object Split */
23
25 public:
26 float sah;
27 int dim;
31
33 BVHObjectSplit(BVHBuild *builder,
34 BVHSpatialStorage *storage,
35 const BVHRange &range,
36 vector<BVHReference> &references,
37 float nodeSAH,
38 const BVHUnaligned *unaligned_heuristic = NULL,
39 const Transform *aligned_space = NULL);
40
41 void split(BVHRange &left, BVHRange &right, const BVHRange &range);
42
43 protected:
48
50 {
51 if (aligned_space_ == NULL) {
52 return prim.bounds();
53 }
54 else {
56 }
57 }
58};
59
60/* Spatial Split */
61
63 public:
64 float sah;
65 int dim;
66 float pos;
67
69 BVHSpatialSplit(const BVHBuild &builder,
70 BVHSpatialStorage *storage,
71 const BVHRange &range,
72 vector<BVHReference> &references,
73 float nodeSAH,
74 const BVHUnaligned *unaligned_heuristic = NULL,
75 const Transform *aligned_space = NULL);
76
77 void split(BVHBuild *builder, BVHRange &left, BVHRange &right, const BVHRange &range);
78
79 void split_reference(const BVHBuild &builder,
80 BVHReference &left,
81 BVHReference &right,
82 const BVHReference &ref,
83 int dim,
84 float pos);
85
86 protected:
91
92 /* Lower-level functions which calculates boundaries of left and right nodes
93 * needed for spatial split.
94 *
95 * Operates directly with primitive specified by its index, reused by higher
96 * level splitting functions.
97 */
98 void split_triangle_primitive(const Mesh *mesh,
99 const Transform *tfm,
100 int prim_index,
101 int dim,
102 float pos,
103 BoundBox &left_bounds,
104 BoundBox &right_bounds);
105 void split_curve_primitive(const Hair *hair,
106 const Transform *tfm,
107 int prim_index,
108 int segment_index,
109 int dim,
110 float pos,
111 BoundBox &left_bounds,
112 BoundBox &right_bounds);
113 void split_point_primitive(const PointCloud *pointcloud,
114 const Transform *tfm,
115 int prim_index,
116 int dim,
117 float pos,
118 BoundBox &left_bounds,
119 BoundBox &right_bounds);
120
121 /* Lower-level functions which calculates boundaries of left and right nodes
122 * needed for spatial split.
123 *
124 * Operates with BVHReference, internally uses lower level API functions.
125 */
127 const Mesh *mesh,
128 int dim,
129 float pos,
130 BoundBox &left_bounds,
131 BoundBox &right_bounds);
132 void split_curve_reference(const BVHReference &ref,
133 const Hair *hair,
134 int dim,
135 float pos,
136 BoundBox &left_bounds,
137 BoundBox &right_bounds);
138 void split_point_reference(const BVHReference &ref,
139 const PointCloud *pointcloud,
140 int dim,
141 float pos,
142 BoundBox &left_bounds,
143 BoundBox &right_bounds);
145 const Object *object, int dim, float pos, BoundBox &left_bounds, BoundBox &right_bounds);
146
148 {
149 if (aligned_space_ == NULL) {
150 return prim.bounds();
151 }
152 else {
154 }
155 }
156
158 {
159 if (aligned_space_ == NULL) {
160 return point;
161 }
162 else {
163 return transform_point(aligned_space_, point);
164 }
165 }
166};
167
168/* Mixed Object-Spatial Split */
169
171 public:
174
175 float leafSAH;
176 float nodeSAH;
177 float minSAH;
178
180
182
184
186 BVHSpatialStorage *storage,
187 const BVHRange &range,
188 vector<BVHReference> &references,
189 int level,
190 const BVHUnaligned *unaligned_heuristic = NULL,
191 const Transform *aligned_space = NULL)
192 {
193 if (aligned_space == NULL) {
194 bounds = range.bounds();
195 }
196 else {
197 bounds = unaligned_heuristic->compute_aligned_boundbox(
198 range, &references.at(0), *aligned_space);
199 }
200 /* find split candidates. */
201 float area = bounds.safe_area();
202
203 leafSAH = area * builder->params.primitive_cost(range.size());
204 nodeSAH = area * builder->params.node_cost(2);
205
206 object = BVHObjectSplit(
207 builder, storage, range, references, nodeSAH, unaligned_heuristic, aligned_space);
208
209 if (builder->params.use_spatial_split && level < BVHParams::MAX_SPATIAL_DEPTH) {
210 BoundBox overlap = object.left_bounds;
211 overlap.intersect(object.right_bounds);
212
213 if (overlap.safe_area() >= builder->spatial_min_overlap) {
215 *builder, storage, range, references, nodeSAH, unaligned_heuristic, aligned_space);
216 }
217 }
218
219 /* leaf SAH is the lowest => create leaf. */
220 minSAH = min(min(leafSAH, object.sah), spatial.sah);
221 no_split = (minSAH == leafSAH && builder->range_within_max_leaf_size(range, references));
222 }
223
225 BVHRange &left,
226 BVHRange &right,
227 const BVHRange &range)
228 {
229 if (builder->params.use_spatial_split && minSAH == spatial.sah)
230 spatial.split(builder, left, right, range);
231 if (!left.size() || !right.size())
232 object.split(left, right, range);
233 }
234};
235
237
238#endif /* __BVH_SPLIT_H__ */
in reality light always falls off quadratically Particle Retrieve the data of the particle that spawned the object for example to give variation to multiple instances of an object Point Retrieve information about points in a point cloud Retrieve the edges of an object as it appears to Cycles topology will always appear triangulated Convert a blackbody temperature to an RGB value Normal Generate a perturbed normal from an RGB normal map image Typically used for faking highly detailed surfaces Generate an OSL shader from a file or text data block Image Sample an image file as a texture Gabor Generate Gabor noise Gradient Generate interpolated color and intensity values based on the input vector Magic Generate a psychedelic color texture Voronoi Generate Worley noise based on the distance to random points Typically used to generate textures such as or biological cells Brick Generate a procedural texture producing bricks Texture Retrieve multiple types of texture coordinates nTypically used as inputs for texture nodes Vector Convert a point
bool range_within_max_leaf_size(const BVHRange &range, const vector< BVHReference > &references) const
Definition build.cpp:636
BVHParams params
Definition build.h:110
float spatial_min_overlap
Definition build.h:120
BVHSpatialSplit spatial
Definition bvh/split.h:173
__forceinline void split(BVHBuild *builder, BVHRange &left, BVHRange &right, const BVHRange &range)
Definition bvh/split.h:224
__forceinline BVHMixedSplit(BVHBuild *builder, BVHSpatialStorage *storage, const BVHRange &range, vector< BVHReference > &references, int level, const BVHUnaligned *unaligned_heuristic=NULL, const Transform *aligned_space=NULL)
Definition bvh/split.h:185
BVHObjectSplit object
Definition bvh/split.h:172
BoundBox bounds
Definition bvh/split.h:181
BVHSpatialStorage * storage_
Definition bvh/split.h:44
vector< BVHReference > * references_
Definition bvh/split.h:45
BoundBox left_bounds
Definition bvh/split.h:29
BoundBox right_bounds
Definition bvh/split.h:30
__forceinline BoundBox get_prim_bounds(const BVHReference &prim) const
Definition bvh/split.h:49
void split(BVHRange &left, BVHRange &right, const BVHRange &range)
Definition bvh/split.cpp:87
const Transform * aligned_space_
Definition bvh/split.h:47
const BVHUnaligned * unaligned_heuristic_
Definition bvh/split.h:46
__forceinline float node_cost(int n) const
Definition params.h:159
bool use_spatial_split
Definition params.h:61
@ MAX_SPATIAL_DEPTH
Definition params.h:112
__forceinline float primitive_cost(int n) const
Definition params.h:154
__forceinline const BoundBox & bounds() const
Definition params.h:205
void split_point_primitive(const PointCloud *pointcloud, const Transform *tfm, int prim_index, int dim, float pos, BoundBox &left_bounds, BoundBox &right_bounds)
void split_curve_primitive(const Hair *hair, const Transform *tfm, int prim_index, int segment_index, int dim, float pos, BoundBox &left_bounds, BoundBox &right_bounds)
const BVHUnaligned * unaligned_heuristic_
Definition bvh/split.h:89
void split_curve_reference(const BVHReference &ref, const Hair *hair, int dim, float pos, BoundBox &left_bounds, BoundBox &right_bounds)
void split_triangle_primitive(const Mesh *mesh, const Transform *tfm, int prim_index, int dim, float pos, BoundBox &left_bounds, BoundBox &right_bounds)
__forceinline float3 get_unaligned_point(const float3 &point) const
Definition bvh/split.h:157
__forceinline BoundBox get_prim_bounds(const BVHReference &prim) const
Definition bvh/split.h:147
BVHSpatialStorage * storage_
Definition bvh/split.h:87
void split_object_reference(const Object *object, int dim, float pos, BoundBox &left_bounds, BoundBox &right_bounds)
const Transform * aligned_space_
Definition bvh/split.h:90
vector< BVHReference > * references_
Definition bvh/split.h:88
void split_triangle_reference(const BVHReference &ref, const Mesh *mesh, int dim, float pos, BoundBox &left_bounds, BoundBox &right_bounds)
void split_point_reference(const BVHReference &ref, const PointCloud *pointcloud, int dim, float pos, BoundBox &left_bounds, BoundBox &right_bounds)
void split_reference(const BVHBuild &builder, BVHReference &left, BVHReference &right, const BVHReference &ref, int dim, float pos)
void split(BVHBuild *builder, BVHRange &left, BVHRange &right, const BVHRange &range)
BoundBox compute_aligned_prim_boundbox(const BVHReference &prim, const Transform &aligned_space) const
Definition unaligned.cpp:76
Definition hair.h:14
#define CCL_NAMESPACE_END
#define NULL
#define __forceinline
#define min(a, b)
Definition sort.c:32
#define FLT_MAX
Definition stdcycles.h:14
__forceinline void intersect(const BoundBox &bbox)
Definition boundbox.h:86
__forceinline float safe_area() const
Definition boundbox.h:93
CCL_NAMESPACE_END CCL_NAMESPACE_BEGIN ccl_device_inline float3 transform_point(ccl_private const Transform *t, const float3 a)
Definition transform.h:63