15 changed files with 1051 additions and 974 deletions
			
			
		@ -0,0 +1,33 @@ | 
				
			|||
#pragma once | 
				
			|||
 | 
				
			|||
#include "primitive_descriptor.h" | 
				
			|||
 | 
				
			|||
#include "utils/eigen_alias.hpp" | 
				
			|||
 | 
				
			|||
struct aabb_t { | 
				
			|||
    Eigen::Vector3d min{std::numeric_limits<double>::max(), | 
				
			|||
                        std::numeric_limits<double>::max(), | 
				
			|||
                        std::numeric_limits<double>::max()}; | 
				
			|||
    Eigen::Vector3d max{std::numeric_limits<double>::min(), | 
				
			|||
                        std::numeric_limits<double>::min(), | 
				
			|||
                        std::numeric_limits<double>::min()}; | 
				
			|||
 | 
				
			|||
    void extend(const Eigen::Vector3d& point) | 
				
			|||
    { | 
				
			|||
        min = min.cwiseMin(point); | 
				
			|||
        max = max.cwiseMax(point); | 
				
			|||
    } | 
				
			|||
 | 
				
			|||
    void extend(const aabb_t& aabb) | 
				
			|||
    { | 
				
			|||
        min = min.cwiseMin(aabb.min); | 
				
			|||
        max = max.cwiseMax(aabb.max); | 
				
			|||
    } | 
				
			|||
 | 
				
			|||
    void offset(const Eigen::Vector3d& offset) | 
				
			|||
    { | 
				
			|||
        min = min + offset; | 
				
			|||
        max = max + offset; | 
				
			|||
    } | 
				
			|||
 | 
				
			|||
}; | 
				
			|||
@ -0,0 +1,21 @@ | 
				
			|||
#pragma once | 
				
			|||
 | 
				
			|||
#include <vector> | 
				
			|||
#include <stack> | 
				
			|||
 | 
				
			|||
#include <tbb/tbb.h> | 
				
			|||
 | 
				
			|||
#include "blobtree.h" | 
				
			|||
 | 
				
			|||
#include "aabb.hpp" | 
				
			|||
#include "node_operation.hpp" | 
				
			|||
 | 
				
			|||
struct blobtree_t { | 
				
			|||
    std::vector<node_t, tbb::tbb_allocator<node_t>>     nodes{}; | 
				
			|||
    std::vector<uint32_t, tbb::tbb_allocator<uint32_t>> leaf_index{}; | 
				
			|||
}; | 
				
			|||
 | 
				
			|||
extern std::vector<blobtree_t, tbb::tbb_allocator<blobtree_t>>                  structures; | 
				
			|||
extern std::vector<aabb_t, tbb::tbb_allocator<aabb_t>>                          aabbs; | 
				
			|||
extern std::vector<primitive_node_t, tbb::tbb_allocator<primitive_node_t>>      primitives; | 
				
			|||
extern std::stack<uint32_t, std::deque<uint32_t, tbb::tbb_allocator<uint32_t>>> free_structure_list; | 
				
			|||
@ -0,0 +1,236 @@ | 
				
			|||
#pragma once | 
				
			|||
 | 
				
			|||
#include <type_traits> | 
				
			|||
 | 
				
			|||
struct node_t { | 
				
			|||
    uint64_t data[2]; | 
				
			|||
 | 
				
			|||
    constexpr node_t() : data{0, 0} {} | 
				
			|||
 | 
				
			|||
    constexpr node_t(const uint64_t n1, const uint64_t n2) : data{n1, n2} {} | 
				
			|||
 | 
				
			|||
    template <typename T, typename = std::enable_if_t<sizeof(T) <= sizeof(uint64_t)>> | 
				
			|||
    constexpr node_t(T value) | 
				
			|||
    { | 
				
			|||
        data[0] = 0; | 
				
			|||
        data[1] = static_cast<uint64_t>(value); | 
				
			|||
    } | 
				
			|||
 | 
				
			|||
    template <typename T, typename = std::enable_if_t<sizeof(T) <= sizeof(uint64_t)>> | 
				
			|||
    constexpr operator T() const | 
				
			|||
    { | 
				
			|||
        return static_cast<T>(data[1]); | 
				
			|||
    } | 
				
			|||
 | 
				
			|||
    node_t operator>>(const uint32_t shift) const | 
				
			|||
    { | 
				
			|||
        if (shift == 0) { return *this; } | 
				
			|||
 | 
				
			|||
        node_t result = *this; | 
				
			|||
 | 
				
			|||
        if (shift >= 128) { | 
				
			|||
            result.data[0] = 0; | 
				
			|||
            result.data[1] = 0; | 
				
			|||
        } else if (shift >= 64) { | 
				
			|||
            result.data[1] = this->data[0] >> (shift - 64); | 
				
			|||
            result.data[0] = 0; | 
				
			|||
        } else { | 
				
			|||
            result.data[1] = (this->data[1] >> shift) | (this->data[0] << (64 - shift)); | 
				
			|||
            result.data[0] = this->data[0] >> shift; | 
				
			|||
        } | 
				
			|||
 | 
				
			|||
        return result; | 
				
			|||
    } | 
				
			|||
 | 
				
			|||
    node_t operator<<(const uint32_t shift) const | 
				
			|||
    { | 
				
			|||
        if (shift == 0) { return *this; } | 
				
			|||
 | 
				
			|||
        node_t result = *this; | 
				
			|||
 | 
				
			|||
        if (shift >= 128) { | 
				
			|||
            result.data[0] = 0; | 
				
			|||
            result.data[1] = 0; | 
				
			|||
        } else if (shift >= 64) { | 
				
			|||
            result.data[0] = this->data[1] << (shift - 64); | 
				
			|||
            result.data[1] = 0; | 
				
			|||
        } else { | 
				
			|||
            result.data[0] = (this->data[0] << shift) | (this->data[1] >> (64 - shift)); | 
				
			|||
            result.data[1] = this->data[1] << shift; | 
				
			|||
        } | 
				
			|||
 | 
				
			|||
        return result; | 
				
			|||
    } | 
				
			|||
 | 
				
			|||
    const node_t operator&(const node_t& other) const | 
				
			|||
    { | 
				
			|||
        node_t result   = *this; | 
				
			|||
        result.data[0] &= other.data[0]; | 
				
			|||
        result.data[1] &= other.data[1]; | 
				
			|||
        return result; | 
				
			|||
    } | 
				
			|||
 | 
				
			|||
    friend const node_t operator&(node_t, const uint32_t&); | 
				
			|||
 | 
				
			|||
    const node_t operator|(const node_t& other) const | 
				
			|||
    { | 
				
			|||
        node_t result   = *this; | 
				
			|||
        result.data[0] |= other.data[0]; | 
				
			|||
        result.data[1] |= other.data[1]; | 
				
			|||
        return result; | 
				
			|||
    } | 
				
			|||
 | 
				
			|||
    friend const node_t operator|(node_t, const uint32_t&); | 
				
			|||
 | 
				
			|||
    const node_t operator~() const | 
				
			|||
    { | 
				
			|||
        node_t result  = *this; | 
				
			|||
        result.data[0] = ~result.data[0]; | 
				
			|||
        result.data[1] = ~result.data[1]; | 
				
			|||
        return result; | 
				
			|||
    } | 
				
			|||
}; | 
				
			|||
 | 
				
			|||
inline const node_t operator&(node_t lhs, const uint32_t& rhs) | 
				
			|||
{ | 
				
			|||
    lhs.data[1] &= rhs; | 
				
			|||
    return lhs; | 
				
			|||
} | 
				
			|||
 | 
				
			|||
inline const node_t operator|(node_t lhs, const uint32_t& rhs) | 
				
			|||
{ | 
				
			|||
    lhs.data[1] |= rhs; | 
				
			|||
    return lhs; | 
				
			|||
} | 
				
			|||
 | 
				
			|||
enum class eNodeLocation : uint32_t { in = 0, out = 1, edge = 2, unset = 3 }; | 
				
			|||
enum class eNodeOperation : uint32_t { unionOp = 0, intersectionOp = 1, differenceOp = 2, unsetOp = 3 }; | 
				
			|||
 | 
				
			|||
/* getter/setter for node_t */ | 
				
			|||
template <typename _Tp> | 
				
			|||
struct node_proxy { | 
				
			|||
    constexpr node_proxy() = default; | 
				
			|||
 | 
				
			|||
    constexpr node_proxy(node_t& _data, uint32_t _offset, node_t _mask) : data(&_data), offset(_offset), mask(_mask) {} | 
				
			|||
 | 
				
			|||
    void reinit(node_t& _data, uint32_t _offset, node_t _mask) | 
				
			|||
    { | 
				
			|||
        data   = &_data; | 
				
			|||
        offset = _offset; | 
				
			|||
        mask   = _mask; | 
				
			|||
    } | 
				
			|||
 | 
				
			|||
    void reinit(node_proxy&& other) | 
				
			|||
    { | 
				
			|||
        data   = std::move(other.data); | 
				
			|||
        offset = std::move(other.offset); | 
				
			|||
        mask   = std::move(other.mask); | 
				
			|||
    } | 
				
			|||
 | 
				
			|||
    node_proxy(const node_proxy&) = delete; | 
				
			|||
    node_proxy(node_proxy&&)      = delete; | 
				
			|||
 | 
				
			|||
    constexpr node_proxy& operator=(const node_proxy& other) | 
				
			|||
    { | 
				
			|||
        const auto _mask = mask << offset; | 
				
			|||
        *data            = (*data & ~_mask) | (other.data & _mask); | 
				
			|||
        return *this; | 
				
			|||
    } | 
				
			|||
 | 
				
			|||
    constexpr node_proxy& operator=(node_proxy&& other) | 
				
			|||
    { | 
				
			|||
        const auto _mask = mask << offset; | 
				
			|||
        *data            = (*data & ~_mask) | (std::forward(other.data) & _mask); | 
				
			|||
        return *this; | 
				
			|||
    } | 
				
			|||
 | 
				
			|||
    template <typename _Fp, typename = std::enable_if_t<!std::is_same_v<_Fp, node_proxy>>> | 
				
			|||
    constexpr node_proxy& operator=(_Fp&& other) | 
				
			|||
    { | 
				
			|||
        const auto _mask = mask << offset; | 
				
			|||
        if constexpr (std::is_enum_v<_Fp>) { | 
				
			|||
            const auto offset_value = static_cast<std::underlying_type_t<_Fp>>(std::forward<_Fp>(other)) << offset; | 
				
			|||
            *data                   = (*data & ~_mask) | (_mask & offset_value); | 
				
			|||
        } else if constexpr (std::is_same_v<_Fp, bool>) { | 
				
			|||
            const auto offset_value = static_cast<uint32_t>(std::forward<_Fp>(other)) << offset; | 
				
			|||
            *data                   = (*data & ~_mask) | (_mask & offset_value); | 
				
			|||
        } else { | 
				
			|||
            const auto offset_value = std::forward<_Fp>(other) << offset; | 
				
			|||
            *data                   = (*data & ~_mask) | (_mask & offset_value); | 
				
			|||
        } | 
				
			|||
        return *this; | 
				
			|||
    } | 
				
			|||
 | 
				
			|||
    template <typename _Fp, | 
				
			|||
              typename = std::enable_if_t<!std::is_same_v<_Fp, node_proxy> && //
 | 
				
			|||
                                          !std::is_enum_v<_Fp> &&             //
 | 
				
			|||
                                          !std::is_same_v<_Fp, bool>>> | 
				
			|||
    constexpr node_proxy& operator+=(_Fp&& other) | 
				
			|||
    { | 
				
			|||
        const auto _mask      = mask << offset; | 
				
			|||
        const _Fp  low_data   = (*data) >> offset; | 
				
			|||
        const auto low_result = std::forward<_Fp>(other) + low_data; | 
				
			|||
        *data                 = (*data & ~_mask) | (_mask & (low_result << offset)); | 
				
			|||
        return *this; | 
				
			|||
    } | 
				
			|||
 | 
				
			|||
    constexpr operator _Tp() const { return static_cast<_Tp>(((*data) >> offset) & mask); } | 
				
			|||
 | 
				
			|||
protected: | 
				
			|||
    node_t*  data; | 
				
			|||
    uint32_t offset{}; | 
				
			|||
    node_t   mask{}; | 
				
			|||
}; | 
				
			|||
 | 
				
			|||
template <typename _Tp> | 
				
			|||
struct const_node_proxy { | 
				
			|||
    constexpr const_node_proxy(const node_t& _data, uint32_t _offset, node_t _mask) : data(&_data), offset(_offset), mask(_mask) | 
				
			|||
    { | 
				
			|||
    } | 
				
			|||
 | 
				
			|||
    const_node_proxy(const const_node_proxy&) = delete; | 
				
			|||
    const_node_proxy(const_node_proxy&&)      = delete; | 
				
			|||
 | 
				
			|||
    constexpr operator _Tp() const { return static_cast<_Tp>(((*data) >> offset) & mask); } | 
				
			|||
 | 
				
			|||
protected: | 
				
			|||
    const node_t* data; | 
				
			|||
    uint32_t      offset{}; | 
				
			|||
    node_t        mask{}; | 
				
			|||
}; | 
				
			|||
 | 
				
			|||
// 0 for internal node, 1 for primitive node
 | 
				
			|||
static constexpr inline auto node_fetch_is_primitive(node_t& node) { return node_proxy<bool>(node, 127u, 0x01u); } | 
				
			|||
 | 
				
			|||
// 0 for union, 1 for intersection, 2 for difference, 3 for unset
 | 
				
			|||
static constexpr inline auto node_fetch_operation(node_t& node) { return node_proxy<eNodeOperation>(node, 125u, 0x03u); } | 
				
			|||
 | 
				
			|||
// 0 for in, 1 for out, 2 for on edge, 3 for unset
 | 
				
			|||
static constexpr inline auto node_fetch_in_out(node_t& node) { return node_proxy<eNodeLocation>(node, 123u, 0x03u); } | 
				
			|||
 | 
				
			|||
// If primitive node, the index to the primitive information
 | 
				
			|||
static constexpr inline auto node_fetch_primitive_index(node_t& node) { return node_proxy<uint32_t>(node, 96u, 0xFFFFFFu); } | 
				
			|||
 | 
				
			|||
static constexpr inline auto node_is_parent_null(const node_t& node) | 
				
			|||
{ | 
				
			|||
    return const_node_proxy<uint32_t>(node, 96u, 0xFFFFFFu) == 0xFFFFFFFFu; | 
				
			|||
} | 
				
			|||
 | 
				
			|||
// Parent node index
 | 
				
			|||
static constexpr inline auto node_fetch_parent_index(node_t& node) { return node_proxy<uint32_t>(node, 64u, 0xFFFFFFFFu); } | 
				
			|||
 | 
				
			|||
// Left child node index
 | 
				
			|||
static constexpr inline auto node_fetch_left_child_index(node_t& node) { return node_proxy<uint32_t>(node, 32u, 0xFFFFFFFFu); } | 
				
			|||
 | 
				
			|||
static constexpr inline auto node_is_left_child_null(const node_t& node) | 
				
			|||
{ | 
				
			|||
    return const_node_proxy<uint32_t>(node, 32u, 0xFFFFFFFFu) == 0xFFFFFFFFu; | 
				
			|||
} | 
				
			|||
 | 
				
			|||
// Right child node index
 | 
				
			|||
static constexpr inline auto node_fetch_right_child_index(node_t& node) { return node_proxy<uint32_t>(node, 0u, 0xFFFFFFFFu); } | 
				
			|||
 | 
				
			|||
static constexpr inline auto node_is_right_child_null(const node_t& node) | 
				
			|||
{ | 
				
			|||
    return const_node_proxy<uint32_t>(node, 0u, 0xFFFFFFFFu) == 0xFFFFFFFFu; | 
				
			|||
} | 
				
			|||
								
									
										File diff suppressed because it is too large
									
								
							
						
					@ -0,0 +1,169 @@ | 
				
			|||
#include <iostream> | 
				
			|||
 | 
				
			|||
#include "primitive_descriptor.h" | 
				
			|||
 | 
				
			|||
#include "globals.hpp" | 
				
			|||
 | 
				
			|||
#ifdef _DEBUG | 
				
			|||
 | 
				
			|||
void output_primitive_node(const primitive_node_t& node) | 
				
			|||
{ | 
				
			|||
    auto output_point = [](const raw_vector3d_t& point) { | 
				
			|||
        std::cout << "( " << point.x << ", " << point.y << ", " << point.z << " )" << std::endl; | 
				
			|||
    }; | 
				
			|||
 | 
				
			|||
    auto type = node.type; | 
				
			|||
    switch (type) { | 
				
			|||
        case PRIMITIVE_TYPE_CONSTANT: { | 
				
			|||
            auto desc = static_cast<constant_descriptor_t*>(node.desc); | 
				
			|||
            std::cout << "constant:" << std::endl; | 
				
			|||
            std::cout << "\tvalue: " << desc->value << std::endl << std::endl; | 
				
			|||
            break; | 
				
			|||
        } | 
				
			|||
        case PRIMITIVE_TYPE_PLANE: { | 
				
			|||
            auto desc = static_cast<plane_descriptor_t*>(node.desc); | 
				
			|||
            std::cout << "plane:" << std::endl; | 
				
			|||
            std::cout << "\tbase point: "; | 
				
			|||
            output_point(desc->point); | 
				
			|||
            std::cout << "\tnormal: "; | 
				
			|||
            output_point(desc->normal); | 
				
			|||
            std::cout << std::endl; | 
				
			|||
            break; | 
				
			|||
        } | 
				
			|||
        case PRIMITIVE_TYPE_SPHERE: { | 
				
			|||
            auto desc = static_cast<sphere_descriptor_t*>(node.desc); | 
				
			|||
            std::cout << "sphere:" << std::endl; | 
				
			|||
            std::cout << "\tcenter: "; | 
				
			|||
            output_point(desc->center); | 
				
			|||
            std::cout << "\tradius: " << desc->radius << std::endl << std::endl; | 
				
			|||
            break; | 
				
			|||
        } | 
				
			|||
        case PRIMITIVE_TYPE_CYLINDER: { | 
				
			|||
            auto desc = static_cast<cylinder_descriptor_t*>(node.desc); | 
				
			|||
            std::cout << "cylinder:" << std::endl; | 
				
			|||
            std::cout << "\tbottom point: "; | 
				
			|||
            output_point(desc->bottom_origion); | 
				
			|||
            std::cout << "\tradius: " << desc->radius << std::endl << std::endl; | 
				
			|||
            std::cout << "\toffset: "; | 
				
			|||
            output_point(desc->offset); | 
				
			|||
            break; | 
				
			|||
        } | 
				
			|||
        case PRIMITIVE_TYPE_CONE: { | 
				
			|||
            auto desc = static_cast<cone_descriptor_t*>(node.desc); | 
				
			|||
            std::cout << "cone:" << std::endl; | 
				
			|||
            std::cout << "\tbottom point: "; | 
				
			|||
            output_point(desc->bottom_point); | 
				
			|||
            std::cout << "\ttop point: "; | 
				
			|||
            output_point(desc->top_point); | 
				
			|||
            std::cout << "\tradius1: " << desc->radius1 << std::endl; | 
				
			|||
            std::cout << "\tradius2: " << desc->radius2 << std::endl << std::endl; | 
				
			|||
            break; | 
				
			|||
        } | 
				
			|||
        case PRIMITIVE_TYPE_BOX: { | 
				
			|||
            auto desc = static_cast<box_descriptor_t*>(node.desc); | 
				
			|||
            std::cout << "box:" << std::endl; | 
				
			|||
            std::cout << "\tcenter: "; | 
				
			|||
            output_point(desc->center); | 
				
			|||
            std::cout << "\thalf_size "; | 
				
			|||
            output_point(desc->half_size); | 
				
			|||
            break; | 
				
			|||
        } | 
				
			|||
        case PRIMITIVE_TYPE_MESH: { | 
				
			|||
            auto desc = static_cast<mesh_descriptor_t*>(node.desc); | 
				
			|||
            std::cout << "mesh:" << std::endl; | 
				
			|||
            std::cout << "\tpoint number: " << desc->point_number << std::endl; | 
				
			|||
            for (int i = 0; i < desc->point_number; i++) { | 
				
			|||
                std::cout << "\t\t( " << desc->points[i].x << ", " << desc->points[i].y << ", " << desc->points[i].z << " )" | 
				
			|||
                          << std::endl; | 
				
			|||
            } | 
				
			|||
 | 
				
			|||
            std::cout << "\tfaces number: " << desc->face_number << std::endl; | 
				
			|||
            for (int i = 0; i < desc->face_number; i++) { | 
				
			|||
                auto begin  = desc->faces[i][0]; | 
				
			|||
                auto length = desc->faces[i][1]; | 
				
			|||
                std::cout << "\t\t<" << begin << ", " << length << "> : "; | 
				
			|||
                for (int j = begin; j < begin + length; j++) { std::cout << desc->indexs[j] << " "; } | 
				
			|||
                std::cout << std::endl; | 
				
			|||
            } | 
				
			|||
            break; | 
				
			|||
        } | 
				
			|||
        case PRIMITIVE_TYPE_EXTRUDE: { | 
				
			|||
            auto desc = static_cast<extrude_descriptor_t*>(node.desc); | 
				
			|||
            std::cout << "extrude:" << std::endl; | 
				
			|||
            std::cout << "\tedges number: " << desc->edges_number << std::endl; | 
				
			|||
            std::cout << "\textusion: "; | 
				
			|||
            output_point(desc->extusion); | 
				
			|||
 | 
				
			|||
            std::cout << "\tpoints: " << std::endl; | 
				
			|||
            for (int i = 0; i < desc->edges_number; i++) { | 
				
			|||
                std::cout << "\t\t( " << desc->points[i].x << ", " << desc->points[i].y << ", " << desc->points[i].z << " )" | 
				
			|||
                          << std::endl; | 
				
			|||
            } | 
				
			|||
 | 
				
			|||
            std::cout << "\tbulges: " << std::endl; | 
				
			|||
            for (int i = 0; i < desc->edges_number; i++) { std::cout << "\t\t" << desc->bulges[i] << std::endl; } | 
				
			|||
            break; | 
				
			|||
        } | 
				
			|||
        default: { | 
				
			|||
            break; | 
				
			|||
        } | 
				
			|||
    } | 
				
			|||
} | 
				
			|||
 | 
				
			|||
void output_blobtree(virtual_node_t node) | 
				
			|||
{ | 
				
			|||
    std::map<int, std::string> index; | 
				
			|||
    index[0] = "constant"; | 
				
			|||
    index[1] = "plane"; | 
				
			|||
    index[2] = "sphere"; | 
				
			|||
    index[3] = "cylinder"; | 
				
			|||
    index[4] = "cone"; | 
				
			|||
    index[5] = "box"; | 
				
			|||
    index[6] = "mesh"; | 
				
			|||
    index[7] = "extrude"; | 
				
			|||
 | 
				
			|||
    auto               root = structures[node.main_index].nodes[node.inner_index]; | 
				
			|||
    std::queue<node_t> now, next; | 
				
			|||
    now.push(root); | 
				
			|||
 | 
				
			|||
    std::vector<primitive_node_t> temp; | 
				
			|||
 | 
				
			|||
    while (!now.empty()) { | 
				
			|||
        auto begin = now.front(); | 
				
			|||
        now.pop(); | 
				
			|||
 | 
				
			|||
        if (is_primitive_node(begin)) { | 
				
			|||
            std::cout << index[primitives[node_fetch_primitive_index(begin)].type] << "\t\t"; | 
				
			|||
            temp.push_back(primitives[node_fetch_primitive_index(begin)]); | 
				
			|||
        } else { | 
				
			|||
            auto op = (uint32_t)node_fetch_operation(begin); | 
				
			|||
            if (op == 0) { | 
				
			|||
                std::cout << "or" | 
				
			|||
                          << "\t\t"; | 
				
			|||
            } else if (op == 1) { | 
				
			|||
                std::cout << "and" | 
				
			|||
                          << "\t\t"; | 
				
			|||
            } else if (op == 2) { | 
				
			|||
                std::cout << "sub" | 
				
			|||
                          << "\t\t"; | 
				
			|||
            } | 
				
			|||
        } | 
				
			|||
 | 
				
			|||
        if (!node_is_left_child_null(begin)) { | 
				
			|||
            next.push(structures[node.main_index].nodes[node_fetch_left_child_index(begin)]); | 
				
			|||
        } | 
				
			|||
        if (!node_is_right_child_null(begin)) { | 
				
			|||
            next.push(structures[node.main_index].nodes[node_fetch_right_child_index(begin)]); | 
				
			|||
        } | 
				
			|||
 | 
				
			|||
        if (now.empty()) { | 
				
			|||
            now = next; | 
				
			|||
            while (!next.empty()) { next.pop(); } | 
				
			|||
            std::cout << std::endl; | 
				
			|||
        } | 
				
			|||
    } | 
				
			|||
    std::cout << std::endl; | 
				
			|||
 | 
				
			|||
    for (int i = 0; i < temp.size(); i++) { output_primitive_node(temp[i]); } | 
				
			|||
} | 
				
			|||
#endif // _DEBUG
 | 
				
			|||
@ -0,0 +1,130 @@ | 
				
			|||
#include "internal_api.hpp" | 
				
			|||
 | 
				
			|||
#include "globals.hpp" | 
				
			|||
#include "aabb.hpp" | 
				
			|||
#include "node_operation.hpp" | 
				
			|||
 | 
				
			|||
/* Geometry Generation */ | 
				
			|||
 | 
				
			|||
static constexpr node_t standard_new_node = {(uint64_t)0xFFFFFFFFFFFFFFFFu, (uint64_t)0xFFFFFFFFFFFFFFFFu}; | 
				
			|||
 | 
				
			|||
virtual_node_t push_primitive_node(primitive_node_t&& primitive_node, const aabb_t&& aabb) | 
				
			|||
{ | 
				
			|||
    aabbs.emplace_back(aabb); | 
				
			|||
    primitives.emplace_back(primitive_node); | 
				
			|||
 | 
				
			|||
    node_t node                      = standard_new_node; | 
				
			|||
    node_fetch_primitive_index(node) = static_cast<uint32_t>(primitives.size() - 1); | 
				
			|||
 | 
				
			|||
    blobtree_t tree; | 
				
			|||
    tree.nodes.emplace_back(node); | 
				
			|||
    tree.leaf_index.push_back(0); | 
				
			|||
 | 
				
			|||
    structures.push_back(tree); | 
				
			|||
 | 
				
			|||
    return virtual_node_t{static_cast<uint32_t>(structures.size() - 1), 0}; | 
				
			|||
} | 
				
			|||
 | 
				
			|||
BPE_API virtual_node_t blobtree_new_virtual_node(const constant_descriptor_t& desc) | 
				
			|||
{ | 
				
			|||
    primitive_node_t node{PRIMITIVE_TYPE_CONSTANT, malloc(sizeof(constant_descriptor_t))}; | 
				
			|||
    *((constant_descriptor_t*)node.desc) = std::move(desc); | 
				
			|||
 | 
				
			|||
    aabb_t aabb{}; | 
				
			|||
    return push_primitive_node(std::move(node), std::move(aabb)); | 
				
			|||
} | 
				
			|||
 | 
				
			|||
BPE_API virtual_node_t blobtree_new_virtual_node(const plane_descriptor_t& desc) | 
				
			|||
{ | 
				
			|||
    primitive_node_t node{PRIMITIVE_TYPE_PLANE, malloc(sizeof(plane_descriptor_t))}; | 
				
			|||
    *((plane_descriptor_t*)node.desc) = std::move(desc); | 
				
			|||
 | 
				
			|||
    aabb_t aabb{}; | 
				
			|||
    return push_primitive_node(std::move(node), std::move(aabb)); | 
				
			|||
} | 
				
			|||
 | 
				
			|||
BPE_API virtual_node_t blobtree_new_virtual_node(const sphere_descriptor_t& desc) | 
				
			|||
{ | 
				
			|||
    primitive_node_t node{PRIMITIVE_TYPE_SPHERE, malloc(sizeof(sphere_descriptor_t))}; | 
				
			|||
 | 
				
			|||
    Eigen::Map<const Eigen::Vector3d> center(&desc.center.x); | 
				
			|||
 | 
				
			|||
    aabb_t aabb{center.array() - desc.radius, center.array() + desc.radius}; | 
				
			|||
 | 
				
			|||
    *((sphere_descriptor_t*)node.desc) = std::move(desc); | 
				
			|||
    return push_primitive_node(std::move(node), std::move(aabb)); | 
				
			|||
} | 
				
			|||
 | 
				
			|||
BPE_API virtual_node_t blobtree_new_virtual_node(const cylinder_descriptor_t& desc) | 
				
			|||
{ | 
				
			|||
    primitive_node_t node{PRIMITIVE_TYPE_CYLINDER, malloc(sizeof(cylinder_descriptor_t))}; | 
				
			|||
 | 
				
			|||
    // NOTE: A rough AABB bounding box
 | 
				
			|||
    aabb_t                            aabb{}; | 
				
			|||
    Eigen::Map<const Eigen::Vector3d> bottom_center(&desc.bottom_origion.x), offset(&desc.offset.x); | 
				
			|||
    aabb.extend(bottom_center.array() + desc.radius); | 
				
			|||
    aabb.extend(bottom_center.array() - desc.radius); | 
				
			|||
    aabb.extend(bottom_center.array() + offset.array() + desc.radius); | 
				
			|||
    aabb.extend(bottom_center.array() + offset.array() - desc.radius); | 
				
			|||
 | 
				
			|||
    *((cylinder_descriptor_t*)node.desc) = std::move(desc); | 
				
			|||
    return push_primitive_node(std::move(node), std::move(aabb)); | 
				
			|||
} | 
				
			|||
 | 
				
			|||
BPE_API virtual_node_t blobtree_new_virtual_node(const cone_descriptor_t& desc) | 
				
			|||
{ | 
				
			|||
    primitive_node_t node{PRIMITIVE_TYPE_CONE, malloc(sizeof(cone_descriptor_t))}; | 
				
			|||
 | 
				
			|||
    // NOTE: A rough AABB bounding box
 | 
				
			|||
    aabb_t                            aabb{}; | 
				
			|||
    Eigen::Map<const Eigen::Vector3d> top_point(&desc.top_point.x), bottom_point(&desc.bottom_point.x); | 
				
			|||
    aabb.extend(top_point.array() + desc.radius1); | 
				
			|||
    aabb.extend(top_point.array() - desc.radius1); | 
				
			|||
    aabb.extend(bottom_point.array() + desc.radius2); | 
				
			|||
    aabb.extend(bottom_point.array() - desc.radius2); | 
				
			|||
 | 
				
			|||
    *((cone_descriptor_t*)node.desc) = std::move(desc); | 
				
			|||
    return push_primitive_node(std::move(node), std::move(aabb)); | 
				
			|||
} | 
				
			|||
 | 
				
			|||
BPE_API virtual_node_t blobtree_new_virtual_node(const box_descriptor_t& desc) | 
				
			|||
{ | 
				
			|||
    primitive_node_t node{PRIMITIVE_TYPE_BOX, malloc(sizeof(box_descriptor_t))}; | 
				
			|||
 | 
				
			|||
    Eigen::Map<const Eigen::Vector3d> center(&desc.center.x), half_size(&desc.half_size.x); | 
				
			|||
 | 
				
			|||
    aabb_t aabb{center - half_size, center + half_size}; | 
				
			|||
 | 
				
			|||
    *((box_descriptor_t*)node.desc) = std::move(desc); | 
				
			|||
    return push_primitive_node(std::move(node), std::move(aabb)); | 
				
			|||
} | 
				
			|||
 | 
				
			|||
BPE_API virtual_node_t blobtree_new_virtual_node(const mesh_descriptor_t& desc) | 
				
			|||
{ | 
				
			|||
    primitive_node_t node{PRIMITIVE_TYPE_MESH, malloc(sizeof(mesh_descriptor_t))}; | 
				
			|||
 | 
				
			|||
    aabb_t aabb{}; | 
				
			|||
    for (int i = 0; i < desc.point_number; i++) { aabb.extend(Eigen::Map<const Eigen::Vector3d>(&desc.points[i].x)); } | 
				
			|||
 | 
				
			|||
    *((mesh_descriptor_t*)node.desc) = std::move(desc); | 
				
			|||
    return push_primitive_node(std::move(node), std::move(aabb)); | 
				
			|||
} | 
				
			|||
 | 
				
			|||
BPE_API virtual_node_t blobtree_new_virtual_node(const extrude_descriptor_t& desc) | 
				
			|||
{ | 
				
			|||
    primitive_node_t node{PRIMITIVE_TYPE_EXTRUDE, malloc(sizeof(extrude_descriptor_t))}; | 
				
			|||
 | 
				
			|||
    aabb_t                            aabb{}; | 
				
			|||
    Eigen::Map<const Eigen::Vector3d> e(&desc.extusion.x); | 
				
			|||
    // NOTE: Currently only straight edges are considered
 | 
				
			|||
    for (int i = 0; i < desc.edges_number; i++) { | 
				
			|||
        Eigen::Map<const Eigen::Vector3d> p(&desc.points[i].x); | 
				
			|||
        aabb.extend(p); | 
				
			|||
        aabb.extend(p + e); | 
				
			|||
    } | 
				
			|||
 | 
				
			|||
    *((extrude_descriptor_t*)node.desc) = std::move(desc); | 
				
			|||
    return push_primitive_node(std::move(node), std::move(aabb)); | 
				
			|||
} | 
				
			|||
 | 
				
			|||
BPE_API void blobtree_free_virtual_node(virtual_node_t* node) { free_sub_blobtree(node->main_index); } | 
				
			|||
@ -0,0 +1,159 @@ | 
				
			|||
#include "internal_api.hpp" | 
				
			|||
 | 
				
			|||
#include "globals.hpp" | 
				
			|||
#include "aabb.hpp" | 
				
			|||
#include "node_operation.hpp" | 
				
			|||
 | 
				
			|||
BPE_API bool virtual_node_replace_primitive(virtual_node_t* node, const constant_descriptor_t& desc) | 
				
			|||
{ | 
				
			|||
    auto& node_in_tree = structures[node->main_index].nodes[node->inner_index]; | 
				
			|||
 | 
				
			|||
    if (!node_fetch_is_primitive(node_in_tree)) { return false; } | 
				
			|||
 | 
				
			|||
    const uint32_t primitive_index                              = node_fetch_primitive_index(node_in_tree); | 
				
			|||
    *((constant_descriptor_t*)primitives[primitive_index].desc) = std::move(desc); | 
				
			|||
    primitives[primitive_index].type                            = PRIMITIVE_TYPE_CONSTANT; | 
				
			|||
    aabbs[primitive_index]                                      = aabb_t{}; | 
				
			|||
 | 
				
			|||
    return true; | 
				
			|||
} | 
				
			|||
 | 
				
			|||
BPE_API bool virtual_node_replace_primitive(virtual_node_t* node, const plane_descriptor_t& desc) | 
				
			|||
{ | 
				
			|||
    auto& node_in_tree = structures[node->main_index].nodes[node->inner_index]; | 
				
			|||
 | 
				
			|||
    if (!node_fetch_is_primitive(node_in_tree)) { return false; } | 
				
			|||
 | 
				
			|||
    const uint32_t primitive_index                           = node_fetch_primitive_index(node_in_tree); | 
				
			|||
    *((plane_descriptor_t*)primitives[primitive_index].desc) = std::move(desc); | 
				
			|||
    primitives[primitive_index].type                         = PRIMITIVE_TYPE_PLANE; | 
				
			|||
    aabbs[primitive_index]                                   = aabb_t{}; | 
				
			|||
 | 
				
			|||
    return true; | 
				
			|||
} | 
				
			|||
 | 
				
			|||
BPE_API bool virtual_node_replace_primitive(virtual_node_t* node, const sphere_descriptor_t& desc) | 
				
			|||
{ | 
				
			|||
    auto& node_in_tree = structures[node->main_index].nodes[node->inner_index]; | 
				
			|||
 | 
				
			|||
    if (!node_fetch_is_primitive(node_in_tree)) { return false; } | 
				
			|||
 | 
				
			|||
    const uint32_t primitive_index = node_fetch_primitive_index(node_in_tree); | 
				
			|||
 | 
				
			|||
    Eigen::Map<const Eigen::Vector3d> center(&desc.center.x); | 
				
			|||
 | 
				
			|||
    aabb_t aabb{center.array() - desc.radius, center.array() + desc.radius}; | 
				
			|||
 | 
				
			|||
    *((sphere_descriptor_t*)primitives[primitive_index].desc) = std::move(desc); | 
				
			|||
    primitives[primitive_index].type                          = PRIMITIVE_TYPE_SPHERE; | 
				
			|||
    aabbs[primitive_index]                                    = std::move(aabb); | 
				
			|||
 | 
				
			|||
    return true; | 
				
			|||
} | 
				
			|||
 | 
				
			|||
BPE_API bool virtual_node_replace_primitive(virtual_node_t* node, const cylinder_descriptor_t& desc) | 
				
			|||
{ | 
				
			|||
    auto& node_in_tree = structures[node->main_index].nodes[node->inner_index]; | 
				
			|||
 | 
				
			|||
    if (!node_fetch_is_primitive(node_in_tree)) { return false; } | 
				
			|||
 | 
				
			|||
    const uint32_t primitive_index = node_fetch_primitive_index(node_in_tree); | 
				
			|||
 | 
				
			|||
    // NOTE: A rough AABB bounding box
 | 
				
			|||
    aabb_t                            aabb{}; | 
				
			|||
    Eigen::Map<const Eigen::Vector3d> bottom_center(&desc.bottom_origion.x), offset(&desc.offset.x); | 
				
			|||
    aabb.extend(bottom_center.array() + desc.radius); | 
				
			|||
    aabb.extend(bottom_center.array() - desc.radius); | 
				
			|||
    aabb.extend(bottom_center.array() + offset.array() + desc.radius); | 
				
			|||
    aabb.extend(bottom_center.array() + offset.array() - desc.radius); | 
				
			|||
 | 
				
			|||
    *((cylinder_descriptor_t*)primitives[primitive_index].desc) = std::move(desc); | 
				
			|||
    primitives[primitive_index].type                            = PRIMITIVE_TYPE_CYLINDER; | 
				
			|||
    aabbs[primitive_index]                                      = std::move(aabb); | 
				
			|||
 | 
				
			|||
    return true; | 
				
			|||
} | 
				
			|||
 | 
				
			|||
BPE_API bool virtual_node_replace_primitive(virtual_node_t* node, const cone_descriptor_t& desc) | 
				
			|||
{ | 
				
			|||
    auto& node_in_tree = structures[node->main_index].nodes[node->inner_index]; | 
				
			|||
 | 
				
			|||
    if (!node_fetch_is_primitive(node_in_tree)) { return false; } | 
				
			|||
 | 
				
			|||
    const uint32_t primitive_index = node_fetch_primitive_index(node_in_tree); | 
				
			|||
 | 
				
			|||
    // NOTE: A rough AABB bounding box
 | 
				
			|||
    aabb_t                            aabb{}; | 
				
			|||
    Eigen::Map<const Eigen::Vector3d> top_point(&desc.top_point.x), bottom_point(&desc.bottom_point.x); | 
				
			|||
    aabb.extend(top_point.array() + desc.radius1); | 
				
			|||
    aabb.extend(top_point.array() - desc.radius1); | 
				
			|||
    aabb.extend(bottom_point.array() + desc.radius2); | 
				
			|||
    aabb.extend(bottom_point.array() - desc.radius2); | 
				
			|||
 | 
				
			|||
    *((cone_descriptor_t*)primitives[primitive_index].desc) = std::move(desc); | 
				
			|||
    primitives[primitive_index].type                        = PRIMITIVE_TYPE_CONE; | 
				
			|||
    aabbs[primitive_index]                                  = std::move(aabb); | 
				
			|||
 | 
				
			|||
    return true; | 
				
			|||
} | 
				
			|||
 | 
				
			|||
BPE_API bool virtual_node_replace_primitive(virtual_node_t* node, const box_descriptor_t& desc) | 
				
			|||
{ | 
				
			|||
    auto& node_in_tree = structures[node->main_index].nodes[node->inner_index]; | 
				
			|||
 | 
				
			|||
    if (!node_fetch_is_primitive(node_in_tree)) { return false; } | 
				
			|||
 | 
				
			|||
    const uint32_t primitive_index = node_fetch_primitive_index(node_in_tree); | 
				
			|||
 | 
				
			|||
    Eigen::Map<const Eigen::Vector3d> center(&desc.center.x), half_size(&desc.half_size.x); | 
				
			|||
 | 
				
			|||
    aabb_t aabb{center - half_size, center + half_size}; | 
				
			|||
 | 
				
			|||
    *((box_descriptor_t*)primitives[primitive_index].desc) = std::move(desc); | 
				
			|||
    primitives[primitive_index].type                       = PRIMITIVE_TYPE_BOX; | 
				
			|||
    aabbs[primitive_index]                                 = std::move(aabb); | 
				
			|||
 | 
				
			|||
    return true; | 
				
			|||
} | 
				
			|||
 | 
				
			|||
BPE_API bool virtual_node_replace_primitive(virtual_node_t* node, const mesh_descriptor_t& desc) | 
				
			|||
{ | 
				
			|||
    auto& node_in_tree = structures[node->main_index].nodes[node->inner_index]; | 
				
			|||
 | 
				
			|||
    if (!node_fetch_is_primitive(node_in_tree)) { return false; } | 
				
			|||
 | 
				
			|||
    const uint32_t primitive_index = node_fetch_primitive_index(node_in_tree); | 
				
			|||
 | 
				
			|||
    aabb_t aabb{}; | 
				
			|||
    for (int i = 0; i < desc.point_number; i++) { aabb.extend(Eigen::Map<const Eigen::Vector3d>(&desc.points[i].x)); } | 
				
			|||
 | 
				
			|||
    *((mesh_descriptor_t*)primitives[primitive_index].desc) = std::move(desc); | 
				
			|||
    primitives[primitive_index].type                        = PRIMITIVE_TYPE_MESH; | 
				
			|||
    aabbs[primitive_index]                                  = std::move(aabb); | 
				
			|||
 | 
				
			|||
    return true; | 
				
			|||
} | 
				
			|||
 | 
				
			|||
BPE_API bool virtual_node_replace_primitive(virtual_node_t* node, const extrude_descriptor_t& desc) | 
				
			|||
{ | 
				
			|||
    auto& node_in_tree = structures[node->main_index].nodes[node->inner_index]; | 
				
			|||
 | 
				
			|||
    if (!node_fetch_is_primitive(node_in_tree)) { return false; } | 
				
			|||
 | 
				
			|||
    const uint32_t primitive_index = node_fetch_primitive_index(node_in_tree); | 
				
			|||
 | 
				
			|||
    aabb_t                            aabb{}; | 
				
			|||
    Eigen::Map<const Eigen::Vector3d> e(&desc.extusion.x); | 
				
			|||
    // NOTE: Currently only straight edges are considered
 | 
				
			|||
    for (int i = 0; i < desc.edges_number; i++) { | 
				
			|||
        Eigen::Map<const Eigen::Vector3d> p(&desc.points[i].x); | 
				
			|||
        aabb.extend(p); | 
				
			|||
        aabb.extend(p + e); | 
				
			|||
    } | 
				
			|||
 | 
				
			|||
    *((extrude_descriptor_t*)primitives[primitive_index].desc) = std::move(desc); | 
				
			|||
    primitives[primitive_index].type                           = PRIMITIVE_TYPE_EXTRUDE; | 
				
			|||
    aabbs[primitive_index]                                     = std::move(aabb); | 
				
			|||
 | 
				
			|||
    return true; | 
				
			|||
} | 
				
			|||
					Loading…
					
					
				
		Reference in new issue