57 num_tris_allocated(0),
58 num_vertices_allocated(0),
59 num_vertex_updated(0) {}
63 num_tris(other.num_tris),
64 num_vertices(other.num_vertices),
65 build_state(other.build_state),
66 num_tris_allocated(other.num_tris),
67 num_vertices_allocated(other.num_vertices) {
86 if (other_ptr ==
nullptr)
return false;
92 if (!result)
return false;
98 const std::vector<Triangle>& tri_indices_ = *(
tri_indices);
99 const std::vector<Triangle>& other_tri_indices_ = *(other.
tri_indices);
100 for (
size_t k = 0; k < static_cast<size_t>(
num_tris); ++k)
101 if (tri_indices_[k] != other_tri_indices_[k])
return false;
108 const std::vector<Vec3s>& vertices_ = *(
vertices);
109 const std::vector<Vec3s>& other_vertices_ = *(other.
vertices);
110 for (
size_t k = 0; k < static_cast<size_t>(
num_vertices); ++k)
111 if (vertices_[k] != other_vertices_[k])
return false;
119 const std::vector<Vec3s>& other_prev_vertices_ = *(other.
prev_vertices);
120 for (
size_t k = 0; k < static_cast<size_t>(
num_vertices); ++k) {
121 if (prev_vertices_[k] != other_prev_vertices_[k])
return false;
130 std::cerr <<
"BVH Error in `buildConvexRepresentation`! The BVHModel has "
136 std::cerr <<
"BVH Error in `buildConvexRepresentation`! The BVHModel has "
143 std::shared_ptr<std::vector<Vec3s>> points =
vertices;
144 std::shared_ptr<std::vector<Triangle>> polygons =
tri_indices;
146 points.reset(
new std::vector<Vec3s>(*(
vertices)));
147 polygons.reset(
new std::vector<Triangle>(*(
tri_indices)));
155 const char* qhullCommand) {
161 template <
typename BV>
164 bv_splitter(other.bv_splitter),
165 bv_fitter(other.bv_fitter) {
173 if (other.
bvs.get()) {
180 unsigned int num_vertices_) {
191 if (num_tris_ <= 0) num_tris_ = 8;
192 if (num_vertices_ <= 0) num_vertices_ = 8;
200 std::cerr <<
"BVH Error! Out of memory for tri_indices array on "
212 <<
"BVH Error! Out of memory for vertices array on BeginModel() call!"
223 <<
"BVH Warning! Calling beginModel() on a BVHModel that is not empty. "
224 "This model was cleared and previous triangles/vertices were lost."
237 std::cerr <<
"BVH Warning! Call addVertex() in a wrong order. addVertex() "
238 "was ignored. Must do a beginModel() to clear the model for "
239 "addition of new vertices."
245 std::shared_ptr<std::vector<Vec3s>> temp(
249 <<
"BVH Error! Out of memory for vertices array on addVertex() call!"
255 (*temp)[i] = (*vertices)[i];
269 std::cerr <<
"BVH Warning! Call addSubModel() in a wrong order. "
270 "addSubModel() was ignored. Must do a beginModel() to clear "
271 "the model for addition of new vertices."
276 const unsigned int num_tris_to_add = (
unsigned int)triangles.rows();
279 std::shared_ptr<std::vector<Triangle>> temp(
282 std::cerr <<
"BVH Error! Out of memory for tri_indices array on "
283 "addSubModel() call!"
288 for (
size_t i = 0; i <
num_tris; ++i) {
289 (*temp)[i] = (*tri_indices)[i];
295 std::vector<Triangle>& tri_indices_ = *
tri_indices;
296 for (Eigen::DenseIndex i = 0; i < triangles.rows(); ++i) {
297 const Matrixx3i::ConstRowXpr triangle = triangles.row(i);
309 std::cerr <<
"BVH Warning! Call addVertex() in a wrong order. "
310 "addVertices() was ignored. Must do a beginModel() to clear "
311 "the model for addition of new vertices."
318 std::shared_ptr<std::vector<Vec3s>> temp(
322 <<
"BVH Error! Out of memory for vertices array on addVertex() call!"
328 (*temp)[i] = (*vertices)[i];
333 std::vector<Vec3s>& vertices_ = *
vertices;
334 for (Eigen::DenseIndex
id = 0;
id < points.rows(); ++id)
343 std::cerr <<
"BVH Warning! Call addTriangle() in a wrong order. "
344 "addTriangle() was ignored. Must do a beginModel() to clear "
345 "the model for addition of new triangles."
351 std::shared_ptr<std::vector<Vec3s>> temp(
354 std::cerr <<
"BVH Error! Out of memory for vertices array on "
355 "addTriangle() call!"
361 (*temp)[i] = (*vertices)[i];
377 std::shared_ptr<std::vector<Triangle>> temp(
380 std::cerr <<
"BVH Error! Out of memory for tri_indices array on "
381 "addTriangle() call!"
386 for (
size_t i = 0; i <
num_tris; ++i) {
387 (*temp)[i] = (*tri_indices)[i];
403 std::cerr <<
"BVH Warning! Calling addSubModel() in a wrong order. "
404 "addSubModel() was ignored. Must do a beginModel() to clear "
405 "the model for addition of new vertices."
410 const unsigned int num_vertices_to_add = (
unsigned int)ps.size();
413 std::shared_ptr<std::vector<Vec3s>> temp(
new std::vector<Vec3s>(
416 std::cerr <<
"BVH Error! Out of memory for vertices array on "
417 "addSubModel() call!"
423 (*temp)[i] = (*vertices)[i];
430 std::vector<Vec3s>& vertices_ = *
vertices;
431 for (
size_t i = 0; i < (size_t)num_vertices_to_add; ++i) {
440 const std::vector<Triangle>& ts) {
442 std::cerr <<
"BVH Warning! Calling addSubModel() in a wrong order. "
443 "addSubModel() was ignored. Must do a beginModel() to clear "
444 "the model for addition of new vertices."
449 const unsigned int num_vertices_to_add = (
unsigned int)ps.size();
452 std::shared_ptr<std::vector<Vec3s>> temp(
new std::vector<Vec3s>(
455 std::cerr <<
"BVH Error! Out of memory for vertices array on "
456 "addSubModel() call!"
462 (*temp)[i] = (*vertices)[i];
471 std::vector<Vec3s>& vertices_ = *
vertices;
472 for (
size_t i = 0; i < (size_t)num_vertices_to_add; ++i) {
477 const unsigned int num_tris_to_add = (
unsigned int)
ts.size();
480 std::shared_ptr<std::vector<Triangle>> temp(
new std::vector<Triangle>(
483 std::cerr <<
"BVH Error! Out of memory for tri_indices array on "
484 "addSubModel() call!"
489 for (
size_t i = 0; i <
num_tris; ++i) {
490 (*temp)[i] = (*tri_indices)[i];
496 std::vector<Triangle>& tri_indices_ = *
tri_indices;
497 for (
size_t i = 0; i < (size_t)num_tris_to_add; ++i) {
499 tri_indices_[
num_tris].set(
t[0] + (
size_t)offset,
t[1] + (size_t)offset,
500 t[2] + (
size_t)offset);
509 std::cerr <<
"BVH Warning! Call endModel() in wrong order. endModel() was "
516 std::cerr <<
"BVH Error! endModel() called on model with no triangles and "
524 std::shared_ptr<std::vector<Triangle>> new_tris(
525 new std::vector<Triangle>(
num_tris));
526 if (!(new_tris.get())) {
527 std::cerr <<
"BVH Error! Out of memory for tri_indices array in "
533 for (
size_t i = 0; i <
num_tris; ++i) {
534 (*new_tris)[i] = (*tri_indices)[i];
546 std::shared_ptr<std::vector<Vec3s>> new_vertices(
548 if (!(new_vertices.get())) {
550 <<
"BVH Error! Out of memory for vertices array in endModel() call!"
556 (*new_vertices)[i] = (*vertices)[i];
579 std::cerr <<
"BVH Error! Call beginReplaceModel() on a BVHModel that has "
596 std::cerr <<
"BVH Warning! Call replaceVertex() in a wrong order. "
597 "replaceVertex() was ignored. Must do a beginReplaceModel() "
598 "for initialization."
612 std::cerr <<
"BVH Warning! Call replaceTriangle() in a wrong order. "
613 "replaceTriangle() was ignored. Must do a beginReplaceModel() "
614 "for initialization."
630 std::cerr <<
"BVH Warning! Call replaceSubModel() in a wrong order. "
631 "replaceSubModel() was ignored. Must do a beginReplaceModel() "
632 "for initialization."
637 std::vector<Vec3s>& vertices_ = *
vertices;
638 for (
unsigned int i = 0; i < ps.size(); ++i) {
647 std::cerr <<
"BVH Warning! Call endReplaceModel() in a wrong order. "
648 "endReplaceModel() was ignored. "
654 std::cerr <<
"BVH Error! The replaced model should have the same number of "
655 "vertices as the old model."
676 std::cerr <<
"BVH Error! Call beginUpdatemodel() on a BVHModel that has no "
701 <<
"BVH Warning! Call updateVertex() in a wrong order. updateVertex() "
702 "was ignored. Must do a beginUpdateModel() for initialization."
716 std::cerr <<
"BVH Warning! Call updateTriangle() in a wrong order. "
717 "updateTriangle() was ignored. Must do a beginUpdateModel() "
718 "for initialization."
734 std::cerr <<
"BVH Warning! Call updateSubModel() in a wrong order. "
735 "updateSubModel() was ignored. Must do a beginUpdateModel() "
736 "for initialization."
741 std::vector<Vec3s>& vertices_ = *
vertices;
742 for (
unsigned int i = 0; i < ps.size(); ++i) {
751 std::cerr <<
"BVH Warning! Call endUpdateModel() in a wrong order. "
752 "endUpdateModel() was ignored. "
758 std::cerr <<
"BVH Error! The updated model should have the same number of "
759 "vertices as the old model."
783 const std::vector<Vec3s>& vertices_ = *
vertices;
785 aabb_ += vertices_[i];
802 template <
typename BV>
807 num_bvs_allocated(0),
810 template <
typename BV>
813 primitive_indices.reset();
814 num_bvs_allocated = num_bvs = 0;
817 template <
typename BV>
820 unsigned int num_bvs_to_be_allocated = 0;
822 num_bvs_to_be_allocated = 2 * num_vertices - 1;
824 num_bvs_to_be_allocated = 2 * num_tris - 1;
827 primitive_indices.reset(
828 new std::vector<unsigned int>(num_bvs_to_be_allocated));
829 if (!(bvs.get()) || !(primitive_indices.get())) {
830 std::cerr <<
"BVH Error! Out of memory for BV array in endModel()!"
834 num_bvs_allocated = num_bvs_to_be_allocated;
839 template <
typename BV>
841 unsigned int mem_bv_list = (
unsigned int)
sizeof(BV) * num_bvs;
842 unsigned int mem_tri_list = (
unsigned int)
sizeof(
Triangle) * num_tris;
843 unsigned int mem_vertex_list = (
unsigned int)
sizeof(
Vec3s) * num_vertices;
845 unsigned int total_mem = mem_bv_list + mem_tri_list + mem_vertex_list +
848 std::cerr <<
"Total for model " << total_mem <<
" bytes." << std::endl;
849 std::cerr <<
"BVs: " << num_bvs <<
" allocated." << std::endl;
850 std::cerr <<
"Tris: " << num_tris <<
" allocated." << std::endl;
851 std::cerr <<
"Vertices: " << num_vertices <<
" allocated." << std::endl;
854 return static_cast<int>(total_mem);
857 template <
typename BV>
860 Vec3s* vertices_ = vertices.get() ? vertices->data() : NULL;
861 Triangle* tri_indices_ = tri_indices.get() ? tri_indices->data() : NULL;
862 bv_fitter->
set(vertices_, tri_indices_, getModelType());
864 bv_splitter->set(vertices_, tri_indices_, getModelType());
868 unsigned int num_primitives = 0;
869 switch (getModelType()) {
871 num_primitives = (
unsigned int)num_tris;
874 num_primitives = (
unsigned int)num_vertices;
877 std::cerr <<
"BVH Error: Model type not supported!" << std::endl;
881 std::vector<unsigned int>& primitive_indices_ = *primitive_indices;
882 for (
unsigned int i = 0; i < num_primitives; ++i) primitive_indices_[i] = i;
883 recursiveBuildTree(0, 0, num_primitives);
886 bv_splitter->clear();
891 template <
typename BV>
893 unsigned int num_primitives) {
896 unsigned int* cur_primitive_indices =
897 primitive_indices->data() + first_primitive;
900 BV bv = bv_fitter->fit(cur_primitive_indices, num_primitives);
901 bv_splitter->computeRule(bv, cur_primitive_indices, num_primitives);
907 if (num_primitives == 1) {
908 bvnode->
first_child = -((int)(*cur_primitive_indices) + 1);
914 const std::vector<Vec3s>& vertices_ = *vertices;
915 const std::vector<Triangle>& tri_indices_ = *tri_indices;
916 for (
unsigned int i = 0; i < num_primitives; ++i) {
919 p = vertices_[cur_primitive_indices[i]];
921 const Triangle&
t = tri_indices_[cur_primitive_indices[i]];
923 const Vec3s& p2 = vertices_[
t[1]];
924 const Vec3s& p3 = vertices_[
t[2]];
926 p = (
p1 + p2 + p3) / 3.;
928 std::cerr <<
"BVH Error: Model type not supported!" << std::endl;
938 if (bv_splitter->apply(p))
942 unsigned int temp = cur_primitive_indices[i];
943 cur_primitive_indices[i] = cur_primitive_indices[c1];
944 cur_primitive_indices[c1] = temp;
949 if ((c1 == 0) || (c1 == num_primitives)) c1 = num_primitives / 2;
951 const unsigned int num_first_half = c1;
953 recursiveBuildTree(bvnode->
leftChild(), first_primitive, num_first_half);
954 recursiveBuildTree(bvnode->
rightChild(), first_primitive + num_first_half,
955 num_primitives - num_first_half);
961 template <
typename BV>
964 return refitTree_bottomup();
966 return refitTree_topdown();
969 template <
typename BV>
976 int res = recursiveRefitTree_bottomup(0);
982 template <
typename BV>
991 if (prev_vertices.get()) {
993 v[0] = (*prev_vertices)[
static_cast<size_t>(primitive_id)];
994 v[1] = (*vertices)[
static_cast<size_t>(primitive_id)];
997 fit(vertices->data() + primitive_id, 1, bv);
1003 (*tri_indices)[
static_cast<size_t>(primitive_id)];
1005 if (prev_vertices.get()) {
1008 v[i] = (*prev_vertices)[triangle[i]];
1009 v[i + 3] = (*vertices)[triangle[i]];
1019 for (
int i = 0; i < 3; ++i) {
1028 std::cerr <<
"BVH Error: Model type not supported!" << std::endl;
1032 recursiveRefitTree_bottomup(bvnode->
leftChild());
1033 recursiveRefitTree_bottomup(bvnode->
rightChild());
1034 bvnode->
bv = (*bvs)[
static_cast<size_t>(bvnode->
leftChild())].bv +
1035 (*bvs)[
static_cast<size_t>(bvnode->
rightChild())].bv;
1045 template <
typename BV>
1047 Vec3s* vertices_ = vertices.get() ? vertices->data() : NULL;
1048 Vec3s* prev_vertices_ = prev_vertices.get() ? prev_vertices->data() : NULL;
1049 Triangle* tri_indices_ = tri_indices.get() ? tri_indices->data() : NULL;
1050 bv_fitter->
set(vertices_, prev_vertices_, tri_indices_, getModelType());
1052 unsigned int* primitive_indices_ = primitive_indices->data();
1053 for (
unsigned int i = 0; i < num_bvs; ++i) {
1054 BV bv = bv_fitter->fit(primitive_indices_ + bvs_[i].first_primitive,
1055 bvs_[i].num_primitives);
1066 const Vec3s& parent_c) {
1068 OBB&
obb = bvs_[
static_cast<size_t>(bv_id)].bv;
1069 if (!bvs_[
static_cast<size_t>(bv_id)].isLeaf()) {
1070 makeParentRelativeRecurse(bvs_[
static_cast<size_t>(bv_id)].first_child,
1073 makeParentRelativeRecurse(bvs_[
static_cast<size_t>(bv_id)].first_child + 1,
1079 obb.axes.applyOnTheLeft(parent_axes.transpose());
1082 obb.To.noalias() = parent_axes.transpose() *
t;
1087 const Vec3s& parent_c) {
1089 RSS& rss = bvs_[
static_cast<size_t>(bv_id)].bv;
1090 if (!bvs_[
static_cast<size_t>(bv_id)].isLeaf()) {
1091 makeParentRelativeRecurse(bvs_[
static_cast<size_t>(bv_id)].first_child,
1094 makeParentRelativeRecurse(bvs_[
static_cast<size_t>(bv_id)].first_child + 1,
1100 rss.
axes.applyOnTheLeft(parent_axes.transpose());
1103 rss.
Tr.noalias() = parent_axes.transpose() *
t;
1109 const Vec3s& parent_c) {
1111 OBB&
obb = bvs_[
static_cast<size_t>(bv_id)].bv.obb;
1112 RSS& rss = bvs_[
static_cast<size_t>(bv_id)].bv.rss;
1113 if (!bvs_[
static_cast<size_t>(bv_id)].isLeaf()) {
1114 makeParentRelativeRecurse(bvs_[
static_cast<size_t>(bv_id)].first_child,
1117 makeParentRelativeRecurse(bvs_[
static_cast<size_t>(bv_id)].first_child + 1,
1122 rss.axes.noalias() = parent_axes.transpose() *
obb.axes;
1123 obb.axes = rss.axes;
1126 obb.To.noalias() = parent_axes.transpose() *
t;