31 template <
class dataTypeU,
class dataTypeV,
typename triangulationType>
32 inline int build(
const triangulationType *
const triangulation);
41 const bool &forSegmentation =
false)
const;
44 const std::pair<double, double> &p1,
45 std::vector<SimplexId> &cellList)
const;
71 inline void setRange(
const void *u,
const void *v) {
80 int stats(std::ostream &stream);
86 std::pair<std::pair<double, double>, std::pair<double, double>>
93 template <
class dataTypeU,
class dataTypeV>
94 int buildNode(
const std::vector<SimplexId> &cellList,
95 const std::array<std::pair<float, float>, 3> &domainBox,
96 const std::pair<std::pair<double, double>,
97 std::pair<double, double>> &rangeBox,
101 const std::pair<double, double> &p1,
103 std::vector<SimplexId> &cellList)
const;
106 const std::pair<double, double> &p1,
107 const std::pair<double, double> &q0,
108 const std::pair<double, double> &q1)
const;
121 std::vector<std::pair<std::pair<double, double>, std::pair<double, double>>>
131 const triangulationType *
const triangulation) {
135 const dataTypeU *u = (
const dataTypeU *)
u_;
136 const dataTypeV *v = (
const dataTypeV *)
v_;
151#ifdef TTK_ENABLE_OPENMP
152#pragma omp parallel for num_threads(threadNumber_)
156 for(
int j = 0; j < 3; j++) {
166 for(
int j = 0; j < 4; j++) {
172 triangulation->getCellVertex(i, j, vertexId);
173 }
else if(cell !=
nullptr) {
177 std::array<float, 3> p{};
179 triangulation->getVertexPoint(vertexId, p[0], p[1], p[2]);
233 std::array<std::pair<float, float>, 3> domainBox{};
234 std::pair<std::pair<double, double>, std::pair<double, double>> rangeBox;
239 std::array<float, 3> p{};
241 triangulation->getVertexPoint(i, p[0], p[1], p[2]);
248 for(
int j = 0; j < 3; j++) {
250 domainBox[j].first = domainBox[j].second = p[j];
252 if(p[j] < domainBox[j].first)
253 domainBox[j].first = p[j];
254 if(p[j] > domainBox[j].second)
255 domainBox[j].second = p[j];
260 rangeBox.first.first = rangeBox.first.second = u[i];
261 rangeBox.second.first = rangeBox.second.second = v[i];
263 if(u[i] < rangeBox.first.first)
264 rangeBox.first.first = u[i];
265 if(u[i] > rangeBox.first.second)
266 rangeBox.first.second = u[i];
268 if(v[i] < rangeBox.second.first)
269 rangeBox.second.first = v[i];
270 if(v[i] > rangeBox.second.second)
271 rangeBox.second.second = v[i];
275 rangeArea_ = (rangeBox.first.second - rangeBox.first.first)
276 * (rangeBox.second.second - rangeBox.second.first);
278 * (domainBox[1].second - domainBox[1].first)
279 * (domainBox[2].second - domainBox[2].first);
291 buildNode<dataTypeU, dataTypeV>(domain, domainBox, rangeBox,
rootId_);
304 const std::vector<SimplexId> &cellList,
305 const std::array<std::pair<float, float>, 3> &domainBox,
306 const std::pair<std::pair<double, double>, std::pair<double, double>>
310 nodeId = nodeList_.size();
312 nodeList_.emplace_back();
314 nodeList_.back().rangeBox_ = rangeBox;
315 nodeList_.back().domainBox_ = domainBox;
317 float const rangeArea = (rangeBox.first.second - rangeBox.first.first)
318 * (rangeBox.second.second - rangeBox.second.first);
320 float const domainVolume = (domainBox[0].second - domainBox[0].first)
321 * (domainBox[1].second - domainBox[1].first)
322 * (domainBox[2].second - domainBox[2].first);
324 if(((
SimplexId)cellList.size() > leafMinimumCellNumber_)
325 && (rangeArea > leafMinimumRangeAreaRatio_ * rangeArea_)
326 && (domainVolume > leafMinimumDomainVolumeRatio_ * domainVolume_)) {
328 nodeList_.back().childList_.resize(8);
330 std::array<std::array<std::pair<float, float>, 3>, 8> childDomainBox{};
331 std::array<std::pair<std::pair<dataTypeU, dataTypeU>,
332 std::pair<dataTypeV, dataTypeV>>,
335 std::array<std::vector<SimplexId>, 8> childCellList{};
338 = domainBox[0].first + (domainBox[0].second - domainBox[0].first) / 2.0;
340 = domainBox[1].first + (domainBox[1].second - domainBox[1].first) / 2.0;
342 = domainBox[2].first + (domainBox[2].second - domainBox[2].first) / 2.0;
345 childDomainBox[0][0].first = domainBox[0].first;
346 childDomainBox[0][0].second = midX;
347 childDomainBox[0][1].first = domainBox[1].first;
348 childDomainBox[0][1].second = midY;
349 childDomainBox[0][2].first = domainBox[2].first;
350 childDomainBox[0][2].second = midZ;
353 childDomainBox[1][0].first = domainBox[0].first;
354 childDomainBox[1][0].second = midX;
355 childDomainBox[1][1].first = domainBox[1].first;
356 childDomainBox[1][1].second = midY;
357 childDomainBox[1][2].first = midZ;
358 childDomainBox[1][2].second = domainBox[2].second;
361 childDomainBox[2][0].first = domainBox[0].first;
362 childDomainBox[2][0].second = midX;
363 childDomainBox[2][1].first = midY;
364 childDomainBox[2][1].second = domainBox[1].second;
365 childDomainBox[2][2].first = domainBox[2].first;
366 childDomainBox[2][2].second = midZ;
369 childDomainBox[3][0].first = domainBox[0].first;
370 childDomainBox[3][0].second = midX;
371 childDomainBox[3][1].first = midY;
372 childDomainBox[3][1].second = domainBox[1].second;
373 childDomainBox[3][2].first = midZ;
374 childDomainBox[3][2].second = domainBox[2].second;
377 childDomainBox[4][0].first = midX;
378 childDomainBox[4][0].second = domainBox[0].second;
379 childDomainBox[4][1].first = domainBox[1].first;
380 childDomainBox[4][1].second = midY;
381 childDomainBox[4][2].first = domainBox[2].first;
382 childDomainBox[4][2].second = midZ;
385 childDomainBox[5][0].first = midX;
386 childDomainBox[5][0].second = domainBox[0].second;
387 childDomainBox[5][1].first = domainBox[1].first;
388 childDomainBox[5][1].second = midY;
389 childDomainBox[5][2].first = midZ;
390 childDomainBox[5][2].second = domainBox[2].second;
393 childDomainBox[6][0].first = midX;
394 childDomainBox[6][0].second = domainBox[0].second;
395 childDomainBox[6][1].first = midY;
396 childDomainBox[6][1].second = domainBox[1].second;
397 childDomainBox[6][2].first = domainBox[2].first;
398 childDomainBox[6][2].second = midZ;
401 childDomainBox[7][0].first = midX;
402 childDomainBox[7][0].second = domainBox[0].second;
403 childDomainBox[7][1].first = midY;
404 childDomainBox[7][1].second = domainBox[1].second;
405 childDomainBox[7][2].first = midZ;
406 childDomainBox[7][2].second = domainBox[2].second;
412 for(
int j = 0; j < 8; j++) {
413 if((cellDomainBox_[cellList[i]][0].first >= childDomainBox[j][0].first)
414 && (cellDomainBox_[cellList[i]][0].first
415 < childDomainBox[j][0].second)
416 && (cellDomainBox_[cellList[i]][1].first
417 >= childDomainBox[j][1].first)
418 && (cellDomainBox_[cellList[i]][1].first
419 < childDomainBox[j][1].second)
420 && (cellDomainBox_[cellList[i]][2].first
421 >= childDomainBox[j][2].first)
422 && (cellDomainBox_[cellList[i]][2].first
423 < childDomainBox[j][2].second)) {
431 if(childCellList[childId].empty()) {
432 childRangeBox[childId].first.first
433 = cellRangeBox_[cellList[i]].first.first;
434 childRangeBox[childId].first.second
435 = cellRangeBox_[cellList[i]].first.second;
437 childRangeBox[childId].second.first
438 = cellRangeBox_[cellList[i]].second.first;
439 childRangeBox[childId].second.second
440 = cellRangeBox_[cellList[i]].second.second;
442 if(cellRangeBox_[cellList[i]].first.first
443 < childRangeBox[childId].first.first) {
444 childRangeBox[childId].first.first
445 = cellRangeBox_[cellList[i]].first.first;
447 if(cellRangeBox_[cellList[i]].first.second
448 > childRangeBox[childId].first.second) {
449 childRangeBox[childId].first.second
450 = cellRangeBox_[cellList[i]].first.second;
453 if(cellRangeBox_[cellList[i]].second.first
454 < childRangeBox[childId].second.first) {
455 childRangeBox[childId].second.first
456 = cellRangeBox_[cellList[i]].second.first;
458 if(cellRangeBox_[cellList[i]].second.second
459 > childRangeBox[childId].second.second) {
460 childRangeBox[childId].second.second
461 = cellRangeBox_[cellList[i]].second.second;
465 childCellList[childId].push_back(cellList[i]);
468 for(
int i = 0; i < 8; i++) {
469 buildNode<dataTypeU, dataTypeV>(childCellList[i], childDomainBox[i],
471 nodeList_[nodeId].childList_[i]);
475 nodeList_[nodeId].cellList_ = cellList;