Skip to content

Commit

Permalink
Backup node implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
JacksonCampolattaro committed Jun 15, 2020
1 parent 1b93e41 commit 032b0b4
Showing 1 changed file with 280 additions and 0 deletions.
280 changes: 280 additions & 0 deletions Octree/include/CGAL/Octree/Octree_node.h.deprecated
@@ -0,0 +1,280 @@
// Copyright (c) 2007-2008 INRIA (France).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org).
// You can redistribute it and/or modify it under the terms of the GNU
// General Public License as published by the Free Software Foundation,
// either version 3 of the License, or (at your option) any later version.
//
// Licensees holding a valid commercial license may use this file in
// accordance with the commercial license agreement provided with the software.
//
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//
// $URL$
// $Id$
// SPDX-License-Identifier: GPL-3.0+
//
//
// Author(s) : Tong Zhao, Cédric Portaneri

#ifndef OCTREE_OCTREE_NODE_H
#define OCTREE_OCTREE_NODE_H

#include <CGAL/bounding_box.h>
#include <boost/iterator/transform_iterator.hpp>
#include <CGAL/Aff_transformation_3.h>
#include <CGAL/aff_transformation_tags.h>

#include <CGAL/Orthogonal_k_neighbor_search.h>
#include <CGAL/Search_traits_3.h>
#include <CGAL/Search_traits_adapter.h>

/*
* These headers were not included here originally
* Adding them was necessary to make this header self sufficient
*/
#include <boost/function.hpp>
#include <boost/bind.hpp>
#include <iostream>
#include <fstream>

#include <stack>
#include <queue>
#include <vector>
#include <math.h>

namespace CGAL {

// TODO: Replace with std::array?
struct IntPoint_3 {
uint32_t m_coords[3] = {0, 0, 0};

IntPoint_3() {}

IntPoint_3(int x, int y, int z) {
m_coords[0] = x;
m_coords[1] = y;
m_coords[2] = z;
}

uint32_t &x() { return m_coords[0]; }

const uint32_t &x() const { return m_coords[0]; }

uint32_t &y() { return m_coords[1]; }

const uint32_t &y() const { return m_coords[1]; }

uint32_t &z() { return m_coords[2]; }

const uint32_t &z() const { return m_coords[2]; }

uint32_t &operator[](int i) {
assert(!(i < 0 || i > 2));
return m_coords[i];
}

const uint32_t &operator[](int i) const {
assert(i < 0 || i > 2);
return m_coords[i];
}

bool operator==(const IntPoint_3 &other) const {
return m_coords[0] == other.x() &&
m_coords[1] == other.y() &&
m_coords[2] == other.z();
}

bool operator<(const IntPoint_3 &other) const {
if (x() != other.x()) {
return (x() < other.x());
}
if (y() != other.y()) {
return (y() < other.y());
}
return (z() < other.z());
}
};

template<class Kernel,
class PointRange>
class Octree_node {
public: // types :
typedef Octree_node<Kernel, PointRange> Node;
typedef typename Kernel::FT FT;
typedef typename Kernel::Point_3 Point;
typedef IntPoint_3 IntPoint;
typedef typename Kernel::Vector_3 Vector;
typedef typename PointRange::const_iterator InputIterator;
typedef typename std::list<InputIterator> IterList;

private: // members :
Node *m_children; /* pointer the the 8 possible child nodes. Leaf if NULL */
Node *m_parent; /* pointer the the single parent node. Root if NULL */
IntPoint m_location; /* integer location of current node (x,y,z) on the current depth grid */
uint8_t m_depth; /* current depth inside the octree */
IterList m_points; /* list of iterators of the input pwn contained in the node */

public: // functions :
Octree_node() :
m_children(NULL),
m_parent(NULL),
m_location(IntPoint(0, 0, 0)),
m_depth(0) {}

~Octree_node() {
unsplit();
}

void unsplit() {
if (m_children != NULL) {
for (int i = 0; i < 8; i++)
m_children[i].unsplit();

delete[] m_children;
m_children = NULL;
}
}

void split() {
m_children = new Node[8];
for (int child_id = 0; child_id < 8; child_id++) {
m_children[child_id].set_parent(this);
m_children[child_id].depth() = m_depth + 1;

for (int j = 0; j < 3; j++) {
m_children[child_id].location()[j] = 2 * m_location[j] + ((child_id >> j) & 1);
}
}
}

bool is_leaf() const { return (m_children == NULL); }

Node *children() { return m_children; }

const Node *children() const { return m_children; }

Node *child(const unsigned int index) const {
if (m_children == NULL || index > 7)
return NULL;
else
return &(m_children[index]);
}

Node *parent() { return m_parent; }

const Node *parent() const { return m_parent; }

void set_parent(Node *parent) { m_parent = parent; }

IterList &points() { return m_points; }

const IterList &points() const { return m_points; }

void add_point(InputIterator point) { m_points.push_back(point); }

size_t num_points() const { return m_points.size(); }

bool is_empty() const { return (m_points.size() == 0); }

IntPoint &location() { return m_location; }

const IntPoint &location() const { return m_location; }

uint8_t &depth() { return m_depth; }

const uint8_t &depth() const { return m_depth; }

bool is_sibling(Node *neighbor) const {
return (m_parent == neighbor->parent());
}

// dir: LEFT = 000, RIGHT = 001, DOWN = 010, UP = 011, BACK = 100, FRONT= 101
Node *find_greater_or_equal_neighbor(int dir) const {
if (m_parent == NULL) return NULL;

unsigned int dir_axis = dir & 1; // 0, 1, 0, 1, 0, 1
unsigned int bit_axis = dir >> 1; // 0, 0, 1, 1, 2, 2
unsigned int dir_idx_offset = 1; // -1, 1, -2, 2, -4, 4
dir_idx_offset <<= bit_axis;
if (!dir_axis) dir_idx_offset = -dir_idx_offset;

for (int child_id = 0; child_id < 8; child_id++) {
// is 'this' an opposite 'dir' child?
if (((child_id >> bit_axis) & 1) != dir_axis && m_parent->child(child_id) == this) {
// return 'dir' sibling child
return m_parent->child(child_id + dir_idx_offset);
}
}

Node *parent_neighbor = m_parent->find_greater_or_equal_neighbor(dir);
if (parent_neighbor == NULL || parent_neighbor->is_leaf()) return parent_neighbor;
for (int child_id = 0; child_id < 8; child_id++) {
// 'this' is guaranted to be a 'dir' child
if (((child_id >> bit_axis) & 1) == dir_axis && m_parent->child(child_id) == this) {
// return opposite 'dir' neighbor child
return parent_neighbor->child(child_id - dir_idx_offset);
}
}

return NULL;
}

// dir: LEFT = 000, RIGHT = 001, DOWN = 010, UP = 011, BACK = 100, FRONT= 101
std::list<Node *> find_smaller_neighbors(Node *ge_neighbor, int dir) const {
std::list<Node *> le_neighbors;
unsigned int dir_axis = dir & 1; // 0, 1, 0, 1, 0, 1
unsigned int bit_axis = dir >> 1; // 0, 0, 1, 1, 2, 2

std::queue<Node *> possible_neighbors;
if (ge_neighbor != NULL) possible_neighbors.push(ge_neighbor);
while (!possible_neighbors.empty()) {
Node *node = possible_neighbors.front();

if (node->is_leaf()) {
le_neighbors.push_back(node);
} else {
for (int child_id = 0; child_id < 8; child_id++) {
if (((child_id >> bit_axis) & 1) != dir_axis) {
// add to queue the opposite 'dir' neighbor child
possible_neighbors.push(node->child(child_id));
}
}
}
possible_neighbors.pop();
}
return le_neighbors;
}

bool is_balanced() const {
for (int dir = 0; dir < 6; dir++) {
Node *ge_neighbor = find_greater_or_equal_neighbor(dir);
std::list<Node *> neighbors = find_smaller_neighbors(ge_neighbor, dir);
for (Node *neighbor : neighbors) {
if (neighbor != NULL && !is_sibling(neighbor)
&& (std::abs(this->depth() - neighbor->depth()) > 1)) {
return false;
}
}
}
return true;
}

std::list<Node *> find_unbalanced_neighbors_to_split() const {
std::list<Node *> neighbors_to_split;
for (int dir = 0; dir < 6; dir++) {
Node *neighbor = find_greater_or_equal_neighbor(dir);
if (neighbor != NULL && !is_sibling(neighbor) && neighbor->is_leaf()
&& ((this->depth() - neighbor->depth()) > 1)) {
neighbors_to_split.push_back(neighbor);
}
}
return neighbors_to_split;
}

}; // end class Octree_node
}

#endif //OCTREE_OCTREE_NODE_H

0 comments on commit 032b0b4

Please sign in to comment.