40 prim_type(prim_type_),
41 prim_index(prim_index_),
42 prim_object(prim_object_),
43 prim_time(prim_time_),
46 progress_start_time(0.0),
47 unaligned_heuristic(objects_)
69 for (
uint j = 0; j < num_triangles; j++) {
72 if (attr_mP ==
NULL) {
87 const size_t num_verts =
mesh->verts.
size();
88 const size_t num_steps =
mesh->motion_steps;
92 for (
size_t step = 0; step < num_steps - 1; step++) {
93 t.bounds_grow(vert_steps + step * num_verts,
bounds);
107 const float num_bvh_steps_inv_1 = 1.0f / (num_bvh_steps - 1);
108 const size_t num_verts =
mesh->verts.
size();
109 const size_t num_steps =
mesh->motion_steps;
116 t.motion_verts(
verts, vert_steps, num_verts, num_steps, 0.0f, prev_verts);
118 prev_bounds.
grow(prev_verts[0]);
119 prev_bounds.
grow(prev_verts[1]);
120 prev_bounds.
grow(prev_verts[2]);
122 for (
int bvh_step = 1; bvh_step < num_bvh_steps; ++bvh_step) {
123 const float curr_time = (
float)(bvh_step)*num_bvh_steps_inv_1;
125 t.motion_verts(
verts, vert_steps, num_verts, num_steps, curr_time, curr_verts);
127 curr_bounds.
grow(curr_verts[0]);
128 curr_bounds.
grow(curr_verts[1]);
129 curr_bounds.
grow(curr_verts[2]);
133 const float prev_time = (
float)(bvh_step - 1) * num_bvh_steps_inv_1;
142 prev_bounds = curr_bounds;
158 for (
uint j = 0; j < num_curves; j++) {
160 const float *curve_radius = &hair->get_curve_radius()[0];
161 for (
int k = 0; k <
curve.num_keys - 1; k++) {
162 if (curve_attr_mP ==
NULL) {
165 curve.bounds_grow(k, &hair->get_curve_keys()[0], curve_radius,
bounds);
180 curve.bounds_grow(k, &hair->get_curve_keys()[0], curve_radius,
bounds);
181 const size_t num_keys = hair->get_curve_keys().size();
182 const size_t num_steps = hair->get_motion_steps();
184 for (
size_t step = 0; step < num_steps - 1; step++) {
185 curve.bounds_grow(k, key_steps + step * num_keys, curve_radius,
bounds);
200 const float num_bvh_steps_inv_1 = 1.0f / (num_bvh_steps - 1);
201 const size_t num_steps = hair->get_motion_steps();
202 const float3 *curve_keys = &hair->get_curve_keys()[0];
204 const size_t num_keys = hair->get_curve_keys().size();
210 curve.cardinal_motion_keys(curve_keys,
222 curve.bounds_grow(prev_keys, prev_bounds);
224 for (
int bvh_step = 1; bvh_step < num_bvh_steps; ++bvh_step) {
225 const float curr_time = (
float)(bvh_step)*num_bvh_steps_inv_1;
227 curve.cardinal_motion_keys(curve_keys,
239 curve.bounds_grow(curr_keys, curr_bounds);
243 const float prev_time = (
float)(bvh_step - 1) * num_bvh_steps_inv_1;
253 prev_bounds = curr_bounds;
270 const float3 *points_data = &pointcloud->points[0];
271 const float *radius_data = &pointcloud->radius[0];
272 const size_t num_points = pointcloud->
num_points();
274 const size_t num_steps = pointcloud->get_motion_steps();
276 if (point_attr_mP ==
NULL) {
278 for (
uint j = 0; j < num_points; j++) {
281 point.bounds_grow(points_data, radius_data,
bounds);
295 for (
uint j = 0; j < num_points; j++) {
298 point.bounds_grow(points_data, radius_data,
bounds);
299 for (
size_t step = 0; step < num_steps - 1; step++) {
300 point.bounds_grow(motion_data + step * num_points, radius_data,
bounds);
315 const float num_bvh_steps_inv_1 = 1.0f / (num_bvh_steps - 1);
317 for (
uint j = 0; j < num_points; j++) {
319 const size_t num_steps = pointcloud->get_motion_steps();
327 points_data, radius_data, point_steps, num_points, num_steps, 0.0f, j);
329 point.bounds_grow(prev_key, prev_bounds);
331 for (
int bvh_step = 1; bvh_step < num_bvh_steps; ++bvh_step) {
332 const float curr_time = (
float)(bvh_step)*num_bvh_steps_inv_1;
334 points_data, radius_data, point_steps, num_points, num_steps, curr_time, j);
336 point.bounds_grow(curr_key, curr_bounds);
340 const float prev_time = (
float)(bvh_step - 1) * num_bvh_steps_inv_1;
349 prev_bounds = curr_bounds;
365 Hair *hair =
static_cast<Hair *
>(geom);
383 size_t num = 0, num_curves = hair->
num_curves();
385 for (
size_t i = 0; i < num_curves; i++)
398 Hair *hair =
static_cast<Hair *
>(geom);
412 size_t num_alloc_references = 0;
419 if (!ob->get_geometry()->is_instanced()) {
423 num_alloc_references++;
443 if (!ob->get_geometry()->is_instanced())
492 double build_start_time;
539 if (rootnode !=
NULL) {
541 <<
" Build time: " <<
time_dt() - build_start_time <<
"\n"
542 <<
" Total number of nodes: "
545 <<
" Number of inner nodes: "
548 <<
" Number of leaf nodes: "
551 <<
" Number of unaligned nodes: "
554 <<
" Allocation slop factor: "
558 <<
" Maximum depth: "
575 "Building BVH %.0f%%, duplicates %.0f%%", progress_start * 100.0, duplicates * 100.0);
633 if (
size > max_leaf_size)
636 size_t num_triangles = 0;
637 size_t num_motion_triangles = 0;
638 size_t num_curves = 0;
639 size_t num_motion_curves = 0;
640 size_t num_points = 0;
641 size_t num_motion_points = 0;
643 for (
int i = 0; i <
size; i++) {
656 num_motion_triangles++;
700 float unalignedSplitSAH = FLT_MAX;
701 float unalignedLeafSAH = FLT_MAX;
703 bool do_unalinged_split =
false;
712 if (unalignedLeafSAH < unalignedSplitSAH && unalignedSplitSAH < splitSAH &&
718 if (unalignedSplitSAH < splitSAH) {
719 do_unalinged_split =
true;
725 if (do_unalinged_split) {
733 if (do_unalinged_split) {
757 if (do_unalinged_split) {
793 if (
split.no_split) {
803 float unalignedSplitSAH = FLT_MAX;
806 bool do_unalinged_split =
false;
816 if (unalignedSplitSAH < splitSAH) {
817 do_unalinged_split =
true;
823 if (do_unalinged_split) {
833 if (do_unalinged_split) {
869 task_pool.
push([=, refs = std::move(left_references)]()
mutable {
872 task_pool.
push([=, refs = std::move(right_references)]()
mutable {
877 if (do_unalinged_split) {
940 typedef StackAllocator<256, int> LeafStackAllocator;
941 typedef StackAllocator<256, float2> LeafTimeStackAllocator;
942 typedef StackAllocator<256, BVHReference> LeafReferenceStackAllocator;
958 int num_new_prims = 0;
960 for (
int i = 0; i < range.
size(); i++) {
964 p_ref[type_index].push_back(ref);
965 p_type[type_index].push_back(ref.
prim_type());
966 p_index[type_index].push_back(ref.
prim_index());
975 object_references.push_back(ref);
991 size_t start_index = 0;
994 local_prim_type.resize(num_new_prims);
995 local_prim_index.resize(num_new_prims);
996 local_prim_object.resize(num_new_prims);
998 local_prim_time.resize(num_new_prims);
1001 int num = (int)p_type[i].
size();
1003 assert(p_type[i].
size() == p_index[i].
size());
1004 assert(p_type[i].
size() == p_object[i].
size());
1006 bool alignment_found =
false;
1007 for (
int j = 0; j < num; ++j) {
1008 const int index = start_index + j;
1009 local_prim_type[index] = p_type[i][j];
1010 local_prim_index[index] = p_index[i][j];
1011 local_prim_object[index] = p_object[i][j];
1013 local_prim_time[index] = p_time[i][j];
1021 float time_from = 1.0f, time_to = 0.0f;
1022 for (
int j = 0; j < num; ++j) {
1030 if (alignment_found) {
1033 for (
int j = 0; j < num; ++j) {
1042 leaves[num_leaves++] = leaf_node;
1047 const int num_new_leaf_data = start_index;
1048 const size_t new_leaf_data_size =
sizeof(int) * num_new_leaf_data;
1061 const size_t range_end = start_index + range.
size();
1069 const size_t reserve = (size_t)(range_end + (
float)range_end * factor);
1086 if (new_leaf_data_size > 0) {
1087 memcpy(&
prim_type[start_index], &local_prim_type[0], new_leaf_data_size);
1088 memcpy(&
prim_index[start_index], &local_prim_index[0], new_leaf_data_size);
1089 memcpy(&
prim_object[start_index], &local_prim_object[0], new_leaf_data_size);
1091 memcpy(&
prim_time[start_index], &local_prim_time[0],
sizeof(
float2) * num_new_leaf_data);
1101 start_index = range.
start();
1102 if (new_leaf_data_size > 0) {
1103 memcpy(&
prim_type[start_index], &local_prim_type[0], new_leaf_data_size);
1104 memcpy(&
prim_index[start_index], &local_prim_index[0], new_leaf_data_size);
1105 memcpy(&
prim_object[start_index], &local_prim_object[0], new_leaf_data_size);
1107 memcpy(&
prim_time[start_index], &local_prim_time[0],
sizeof(
float2) * num_new_leaf_data);
1116 for (
int i = 0; i < num_leaves; ++i) {
1118 leaf->
lo += start_index;
1119 leaf->
hi += start_index;
1123 if (num_leaves == 0 || ob_num) {
1135 if (num_leaves == 1) {
1142 else if (num_leaves == 2) {
1145 else if (num_leaves == 3) {
1152 assert(num_leaves <= 5);
1159 if (num_leaves == 5) {
1165 #undef MAX_ITEMS_PER_LEAF
1175 for (
int i = 0; i < iterations; i++)
1182 if (
node->is_leaf() || max_depth < 0)
1188 for (
size_t c = 0;
c < 2;
c++)
1201 float best_cost = FLT_MAX;
1202 int best_child = -1, best_target = -1, best_other = -1;
1204 for (
size_t c = 0;
c < 2;
c++) {
1210 BoundBox &other = (
c == 0) ? bounds1 : bounds0;
1220 if (
min(cost0, cost1) < best_cost) {
1221 best_child = (int)
c;
1222 best_other = (int)(1 -
c);
1224 if (cost0 < cost1) {
1239 assert(best_child == 0 || best_child == 1);
1240 assert(best_target != -1);
typedef float(TangentPoint)[2]
typedef double(DMatrix)[4][4]
NSNotificationCenter * center
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble right
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble w _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat w _GL_VOID_RET _GL_VOID GLint GLint GLint w _GL_VOID_RET _GL_VOID GLshort GLshort GLshort w _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble y2 _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat y2 _GL_VOID_RET _GL_VOID GLint GLint GLint y2 _GL_VOID_RET _GL_VOID GLshort GLshort GLshort y2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLuint *buffer _GL_VOID_RET _GL_VOID GLdouble t _GL_VOID_RET _GL_VOID GLfloat t _GL_VOID_RET _GL_VOID GLint t _GL_VOID_RET _GL_VOID GLshort t _GL_VOID_RET _GL_VOID GLdouble t
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 Sky Generate a procedural sky texture Noise Generate fractal Perlin noise Wave Generate procedural bands or rings with noise 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
__forceinline BoundBox merge(const BoundBox &bbox, const float3 &pt)
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
static btDbvtVolume bounds(btDbvtNode **leaves, int count)
static size_t count_primitives(Geometry *geom)
static size_t count_curve_segments(Hair *hair)
@ BVH_STAT_UNALIGNED_COUNT
Attribute * find(ustring name) const
BVHNode * create_object_leaf_nodes(const BVHReference *ref, int start, int num)
BVHNode * create_leaf_node(const BVHRange &range, const vector< BVHReference > &references)
void thread_build_spatial_split_node(InnerNode *node, int child, const BVHRange &range, vector< BVHReference > &references, int level)
BVHBuild(const vector< Object * > &objects, array< int > &prim_type, array< int > &prim_index, array< int > &prim_object, array< float2 > &prim_time, const BVHParams ¶ms, Progress &progress)
bool range_within_max_leaf_size(const BVHRange &range, const vector< BVHReference > &references) const
thread_spin_lock spatial_spin_lock
void add_references(BVHRange &root)
void add_reference_object(BoundBox &root, BoundBox ¢er, Object *ob, int i)
BVHNode * build_node(const BVHRange &range, vector< BVHReference > &references, int level, BVHSpatialStorage *storage)
void add_reference_curves(BoundBox &root, BoundBox ¢er, Hair *hair, int i)
size_t spatial_free_index
BVHUnaligned unaligned_heuristic
void add_reference_geometry(BoundBox &root, BoundBox ¢er, Geometry *geom, int i)
friend class BVHObjectBinning
array< float2 > & prim_time
vector< Object * > objects
array< int > & prim_index
void rotate(BVHNode *node, int max_depth)
enumerable_thread_specific< BVHSpatialStorage > spatial_storage
size_t progress_original_total
void thread_build_node(InnerNode *node, int child, const BVHObjectBinning &range, int level)
float spatial_min_overlap
double progress_start_time
array< int > & prim_object
void add_reference_points(BoundBox &root, BoundBox ¢er, PointCloud *pointcloud, int i)
friend class BVHMixedSplit
vector< BVHReference > references
void add_reference_triangles(BoundBox &root, BoundBox ¢er, Mesh *mesh, int i)
__forceinline void split(BVHBuild *builder, BVHRange &left, BVHRange &right, const BVHRange &range)
void split(BVHReference *prims, BVHObjectBinning &left_o, BVHObjectBinning &right_o) const
__forceinline const BoundBox & unaligned_bounds()
int max_triangle_leaf_size
int num_motion_triangle_steps
float spatial_split_alpha
__forceinline bool small_enough_for_leaf(int size, int level)
int max_motion_curve_leaf_size
int max_motion_point_leaf_size
int max_motion_triangle_leaf_size
int num_motion_point_steps
float unaligned_split_threshold
int num_motion_curve_steps
__forceinline int size() const
__forceinline int start() const
__forceinline const BoundBox & bounds() const
__forceinline int prim_type() const
__forceinline int prim_object() const
__forceinline const BoundBox & bounds() const
__forceinline float time_from() const
__forceinline float time_to() const
__forceinline int prim_index() const
Transform compute_aligned_space(const BVHObjectBinning &range, const BVHReference *references) const
BoundBox compute_aligned_boundbox(const BVHObjectBinning &range, const BVHReference *references, const Transform &aligned_space, BoundBox *cent_bounds=NULL) const
BoundBox compute_aligned_prim_boundbox(const BVHReference &prim, const Transform &aligned_space) const
bool has_motion_blur() const
Curve get_curve(size_t i) const
size_t num_curves() const
PrimitiveType primitive_type() const override
BVHNode * children[kNumMaxChildren]
void set_substatus(const string &substatus_)
T * resize(size_t newsize)
void reserve(size_t newcapacity)
#define CCL_NAMESPACE_END
#define PRIMITIVE_PACK_SEGMENT(type, segment)
@ ATTR_STD_MOTION_VERTEX_POSITION
#define PRIMITIVE_INDEX(type)
ccl_device_inline float3 zero_float3()
void split(const std::string &s, const char delim, std::vector< std::string > &tokens)
string string_human_readable_number(size_t num)
CCL_NAMESPACE_BEGIN string string_printf(const char *format,...)
int getSubtreeSize(BVH_STAT stat=BVH_STAT_NODE_COUNT) const
virtual bool is_leaf() const =0
void set_aligned_space(const Transform &aligned_space)
__forceinline float half_area() const
__forceinline float safe_area() const
__forceinline void grow(const float3 &pt)
__forceinline float3 center2() const
Triangle get_triangle(size_t i) const
size_t num_triangles() const
PrimitiveType primitive_type() const override
NODE_DECLARE BoundBox bounds
bool is_traceable() const
Point get_point(int i) const
size_t num_points() const
void push(TaskRunFunction &&task)
void wait_work(Summary *stats=NULL)
std::unique_lock< std::mutex > thread_scoped_lock
CCL_NAMESPACE_BEGIN double time_dt()