1 // Copyright (c) 2017-2021, Lawrence Livermore National Security, LLC and
2 // other Axom Project Developers. See the top-level LICENSE file for details.
3 //
4 // SPDX-License-Identifier: (BSD-3-Clause)
5
6 #ifndef AXOM_SPIN_LINEAR_BVH_VTKIO_HPP_
7 #define AXOM_SPIN_LINEAR_BVH_VTKIO_HPP_
8
9 #include "axom/primal/geometry/BoundingBox.hpp"
10
11 namespace axom
12 {
13 namespace spin
14 {
15 namespace internal
16 {
17 namespace linear_bvh
18 {
19 //------------------------------------------------------------------------------
20 template <typename FloatType>
write_box2d(const FloatType & xmin,const FloatType & ymin,const FloatType & xmax,const FloatType & ymax,int32 & numPoints,int32 & numBins,std::ostringstream & nodes,std::ostringstream & cells)21 void write_box2d(const FloatType& xmin,
22 const FloatType& ymin,
23 const FloatType& xmax,
24 const FloatType& ymax,
25 int32& numPoints,
26 int32& numBins,
27 std::ostringstream& nodes,
28 std::ostringstream& cells)
29 {
30 nodes << xmin << " " << ymin << " 0.0\n";
31 nodes << xmax << " " << ymin << " 0.0\n";
32 nodes << xmax << " " << ymax << " 0.0\n";
33 nodes << xmin << " " << ymax << " 0.0\n";
34
35 constexpr int32 NUM_NODES = 4;
36 int32 offset = numPoints;
37 cells << NUM_NODES << " ";
38 for(int32 i = 0; i < NUM_NODES; ++i)
39 {
40 cells << (offset + i) << " ";
41 }
42 cells << "\n";
43
44 numBins += 1;
45 numPoints += NUM_NODES;
46 }
47
48 //------------------------------------------------------------------------------
49 template <typename FloatType>
write_box3d(const FloatType & xmin,const FloatType & ymin,const FloatType & zmin,const FloatType & xmax,const FloatType & ymax,const FloatType & zmax,int32 & numPoints,int32 & numBins,std::ostringstream & nodes,std::ostringstream & cells)50 void write_box3d(const FloatType& xmin,
51 const FloatType& ymin,
52 const FloatType& zmin,
53 const FloatType& xmax,
54 const FloatType& ymax,
55 const FloatType& zmax,
56 int32& numPoints,
57 int32& numBins,
58 std::ostringstream& nodes,
59 std::ostringstream& cells)
60 {
61 nodes << xmin << " " << ymin << " " << zmin << std::endl;
62 nodes << xmax << " " << ymin << " " << zmin << std::endl;
63 nodes << xmax << " " << ymax << " " << zmin << std::endl;
64 nodes << xmin << " " << ymax << " " << zmin << std::endl;
65
66 nodes << xmin << " " << ymin << " " << zmax << std::endl;
67 nodes << xmax << " " << ymin << " " << zmax << std::endl;
68 nodes << xmax << " " << ymax << " " << zmax << std::endl;
69 nodes << xmin << " " << ymax << " " << zmax << std::endl;
70
71 constexpr int32 NUM_NODES = 8;
72 int32 offset = numPoints;
73 cells << NUM_NODES << " ";
74 for(int32 i = 0; i < NUM_NODES; ++i)
75 {
76 cells << (offset + i) << " ";
77 }
78 cells << "\n";
79
80 numBins += 1;
81 numPoints += NUM_NODES;
82 }
83
84 //------------------------------------------------------------------------------
85 template <typename FloatType, int NDIMS>
write_box(const primal::BoundingBox<FloatType,NDIMS> & box,int32 & numPoints,int32 & numBins,std::ostringstream & nodes,std::ostringstream & cells)86 void write_box(const primal::BoundingBox<FloatType, NDIMS>& box,
87 int32& numPoints,
88 int32& numBins,
89 std::ostringstream& nodes,
90 std::ostringstream& cells)
91 {
92 const FloatType& xmin = box.getMin()[0];
93 const FloatType& ymin = box.getMin()[1];
94
95 const FloatType& xmax = box.getMax()[0];
96 const FloatType& ymax = box.getMax()[1];
97
98 if(NDIMS == 2)
99 {
100 write_box2d(xmin, ymin, xmax, ymax, numPoints, numBins, nodes, cells);
101 }
102 else
103 {
104 const FloatType& zmin = box.getMin()[2];
105 const FloatType& zmax = box.getMax()[2];
106
107 write_box3d(xmin, ymin, zmin, xmax, ymax, zmax, numPoints, numBins, nodes, cells);
108 }
109 }
110
111 //------------------------------------------------------------------------------
112 template <typename FloatType>
write_root(const primal::BoundingBox<FloatType,2> & root,int32 & numPoints,int32 & numBins,std::ostringstream & nodes,std::ostringstream & cells,std::ostringstream & levels)113 void write_root(const primal::BoundingBox<FloatType, 2>& root,
114 int32& numPoints,
115 int32& numBins,
116 std::ostringstream& nodes,
117 std::ostringstream& cells,
118 std::ostringstream& levels)
119 {
120 write_box2d(root.getMin()[0],
121 root.getMin()[1],
122 root.getMax()[0],
123 root.getMax()[1],
124 numPoints,
125 numBins,
126 nodes,
127 cells);
128 levels << "0\n";
129 }
130
131 //------------------------------------------------------------------------------
132 template <typename FloatType>
write_root(const primal::BoundingBox<FloatType,3> & root,int32 & numPoints,int32 & numBins,std::ostringstream & nodes,std::ostringstream & cells,std::ostringstream & levels)133 void write_root(const primal::BoundingBox<FloatType, 3>& root,
134 int32& numPoints,
135 int32& numBins,
136 std::ostringstream& nodes,
137 std::ostringstream& cells,
138 std::ostringstream& levels)
139 {
140 write_box3d(root.getMin()[0],
141 root.getMin()[1],
142 root.getMin()[2],
143 root.getMax()[0],
144 root.getMax()[1],
145 root.getMax()[2],
146 numPoints,
147 numBins,
148 nodes,
149 cells);
150 levels << "0\n";
151 }
152
153 //------------------------------------------------------------------------------
154 template <typename FloatType, int NDIMS>
write_recursive(primal::BoundingBox<FloatType,NDIMS> * inner_nodes,int32 * inner_node_children,int32 current_node,int32 level,int32 & numPoints,int32 & numBins,std::ostringstream & nodes,std::ostringstream & cells,std::ostringstream & levels)155 void write_recursive(primal::BoundingBox<FloatType, NDIMS>* inner_nodes,
156 int32* inner_node_children,
157 int32 current_node,
158 int32 level,
159 int32& numPoints,
160 int32& numBins,
161 std::ostringstream& nodes,
162 std::ostringstream& cells,
163 std::ostringstream& levels)
164 {
165 // STEP 0: get the flat BVH bounding boxes
166 primal::BoundingBox<FloatType, NDIMS> l_box = inner_nodes[current_node + 0];
167 primal::BoundingBox<FloatType, NDIMS> r_box = inner_nodes[current_node + 1];
168
169 // STEP 1: extract children information
170 int32 l_child = inner_node_children[current_node + 0];
171 int32 r_child = inner_node_children[current_node + 1];
172
173 write_box<FloatType, NDIMS>(l_box, numPoints, numBins, nodes, cells);
174 levels << level << std::endl;
175 write_box<FloatType, NDIMS>(r_box, numPoints, numBins, nodes, cells);
176 levels << level << std::endl;
177
178 // STEP 2: check left
179 if(l_child > -1)
180 {
181 write_recursive<FloatType, NDIMS>(inner_nodes,
182 inner_node_children,
183 l_child,
184 level + 1,
185 numPoints,
186 numBins,
187 nodes,
188 cells,
189 levels);
190 }
191
192 // STEP 3: check right
193 if(r_child > -1)
194 {
195 write_recursive<FloatType, NDIMS>(inner_nodes,
196 inner_node_children,
197 r_child,
198 level + 1,
199 numPoints,
200 numBins,
201 nodes,
202 cells,
203 levels);
204 }
205 }
206
207 } /* namespace linear_bvh */
208 } /* namespace internal */
209 } /* namespace spin */
210 } /* namespace axom */
211
212 #endif /* AXOM_SPIN_LINEAR_BVH_VTKIO_HPP_ */
213