diff --git a/blobtree_structure/include/aabb.hpp b/blobtree_structure/include/aabb.hpp deleted file mode 100644 index 17120ce..0000000 --- a/blobtree_structure/include/aabb.hpp +++ /dev/null @@ -1,33 +0,0 @@ -#pragma once - -#include "primitive_descriptor.h" - -#include "utils/eigen_alias.hpp" - -struct aabb_t { - Eigen::Vector3d min{std::numeric_limits::max(), - std::numeric_limits::max(), - std::numeric_limits::max()}; - Eigen::Vector3d max{std::numeric_limits::min(), - std::numeric_limits::min(), - std::numeric_limits::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; - } - -}; \ No newline at end of file diff --git a/blobtree_structure/include/globals.hpp b/blobtree_structure/include/globals.hpp index 7ab1afb..e7fd729 100644 --- a/blobtree_structure/include/globals.hpp +++ b/blobtree_structure/include/globals.hpp @@ -6,9 +6,7 @@ #include #include "blobtree.h" - -#include "aabb.hpp" -#include "node_operation.hpp" +#include "internal_structs.hpp" struct blobtree_t { std::vector> nodes{}; diff --git a/blobtree_structure/interface/internal_api.hpp b/blobtree_structure/interface/internal_api.hpp index 20f43e6..66ab519 100644 --- a/blobtree_structure/interface/internal_api.hpp +++ b/blobtree_structure/interface/internal_api.hpp @@ -6,6 +6,11 @@ #include #include "blobtree.h" +#include "internal_structs.hpp" + +// ====================================================================================================== +// Debugging +// ====================================================================================================== #ifdef _DEBUG #include @@ -13,6 +18,10 @@ void output_blobtree(virtual_node_t node); #endif +// ====================================================================================================== +// APIs +// ====================================================================================================== + BPE_API double evaluate(const constant_descriptor_t& desc, const Eigen::Ref& point); BPE_API double evaluate(const plane_descriptor_t& desc, const Eigen::Ref& point); BPE_API double evaluate(const sphere_descriptor_t& desc, const Eigen::Ref& point); @@ -22,232 +31,53 @@ BPE_API double evaluate(const box_descriptor_t& desc, const Eigen::Ref& point); BPE_API double evaluate(const extrude_descriptor_t& desc, const Eigen::Ref& point); -BPE_API double evaluate(const primitive_node_t& node, const raw_vector3d_t& point); - // Basic Operations -/** - * @brief Get all primitive nodes - * @return Primitive array - */ -BPE_API std::vector>& get_primitives() noexcept; +BPE_API std::vector> blobtree_get_leaf_nodes_primitive_mapping(uint32_t index) noexcept; + +BPE_API size_t get_primitive_count() noexcept; +BPE_API const primitive_node_t& get_primitive_node(uint32_t index) noexcept; +BPE_API const aabb_t& get_aabb(uint32_t index) noexcept; BPE_API void free_sub_blobtree(uint32_t index) noexcept; // Geometry Generation -/** - * @brief Create a new empty body - * @param[in] desc The empty descriptor - * @return The virtual node - */ BPE_API virtual_node_t blobtree_new_virtual_node(const constant_descriptor_t& desc); - -/** - * @brief Create a new plane body - * @param[in] desc The plane descriptor - * @return The virtual node - */ BPE_API virtual_node_t blobtree_new_virtual_node(const plane_descriptor_t& desc); - -/** - * @brief Create a new sphere body - * @param[in] desc The sphere descriptor - * @return The virtual node - */ BPE_API virtual_node_t blobtree_new_virtual_node(const sphere_descriptor_t& desc); - -/** - * @brief Create a new cylinder body - * @param[in] desc The cylinder descriptor - * @return The virtual node - */ BPE_API virtual_node_t blobtree_new_virtual_node(const cylinder_descriptor_t& desc); - -/** - * @brief Create a new cone body - * @param[in] desc The cone descriptor - * @return The virtual node - */ BPE_API virtual_node_t blobtree_new_virtual_node(const cone_descriptor_t& desc); - -/** - * @brief Create a new box body - * @param[in] desc The box descriptor - * @return The virtual node - */ BPE_API virtual_node_t blobtree_new_virtual_node(const box_descriptor_t& desc); - -/** - * @brief Create a new mesh body - * @param[in] desc The mesh descriptor - * @return The virtual node - */ BPE_API virtual_node_t blobtree_new_virtual_node(const mesh_descriptor_t& desc); - -/** - * @brief Create a new extrude body - * @param[in] desc The extrude descriptor - * @return The virtual node - */ BPE_API virtual_node_t blobtree_new_virtual_node(const extrude_descriptor_t& desc); -/** - * @brief Free a virtual node - * @param[in] node The virtual node to be released - */ -BPE_API void blobtree_free_virtual_node(virtual_node_t* node); +BPE_API void blobtree_free_virtual_node(const virtual_node_t& node); // Geometry Operations -/** - * @brief Union two virtual node, result will be writen to first node - * @param[in] node1 The first virtual node - * @param[in] node2 The second virtual node - */ -BPE_API void virtual_node_boolean_union(virtual_node_t* node1, virtual_node_t* node2); - -/** - * @brief Intersect two virtual node, result will be writen to first node - * @param[in] node1 The first virtual node - * @param[in] node2 The second virtual node - */ -BPE_API void virtual_node_boolean_intersect(virtual_node_t* node1, virtual_node_t* node2); - -/** - * @brief Difference two virtual node, result will be writen to first node - * @param[in] node1 The first virtual node - * @param[in] node2 The second virtual node - */ -BPE_API void virtual_node_boolean_difference(virtual_node_t* node1, virtual_node_t* node2); - -/** - * @brief Offset a body - * @param[in] node The virtual node - * @param[in] directrion The offset direction - * @param[in] length The offset length - */ -BPE_API void virtual_node_offset(virtual_node_t* node, const raw_vector3d_t& direction, const double length); - -/** - * @brief Offset a body - * @param[in] node The virtual node - * @param[in] offset The offset direction and length - */ -BPE_API void virtual_node_offset(virtual_node_t* node, const raw_vector3d_t& offset); - -/** - * @brief Split a body - * @param[in] node The virtual node - * @param[in] basePoint The base point of the split face - * @param[in] normal The normal of the split face - */ -BPE_API void virtual_node_split(virtual_node_t* node, raw_vector3d_t base_point, raw_vector3d_t normal); +BPE_API void virtual_node_boolean_union(virtual_node_t& node1, const virtual_node_t& node2); +BPE_API void virtual_node_boolean_intersect(virtual_node_t& node1, const virtual_node_t& node2); +BPE_API void virtual_node_boolean_difference(virtual_node_t& node1, const virtual_node_t& node2); +BPE_API void virtual_node_offset(virtual_node_t& node, const raw_vector3d_t& direction, const double length); +BPE_API void virtual_node_offset(virtual_node_t& node, const raw_vector3d_t& offset); +BPE_API void virtual_node_split(virtual_node_t& node, raw_vector3d_t base_point, raw_vector3d_t normal); // Tree Node Operations -/** - * @brief Sets the parent of a virtual node, a validity check will be performed - * @param[in] node The virtual node whose parent is waiting to be set - * @param[in] parent The parent virtual node - * @return True if the operation is successful - */ -BPE_API bool virtual_node_set_parent(virtual_node_t* node, virtual_node_t* parent); - -/** - * @brief Sets the left node of a virtual node, a validity check will be performed - * @param[in] node The virtual node whose left child is waiting to be set - * @param[in] child The child virtual node - * @return True if the operation is successful - */ -BPE_API bool virtual_node_set_left_child(virtual_node_t* node, virtual_node_t* child); - -/** - * @brief Sets the right node of a virtual node, a validity check will be performed - * @param[in] node The virtual node whose right child is waiting to be set - * @param[in] child The child virtual node - * @return True if the operation is successful - */ -BPE_API bool virtual_node_set_right_child(virtual_node_t* node, virtual_node_t* child); - -/** - * @brief Add a child node of given virtual node, a validity check will be performed - * @param[in] node The virtual node whose child is waiting to be added - * @param[in] child The child virtual node - * @return True if the operation is successful - */ -BPE_API bool virtual_node_add_child(virtual_node_t* node, virtual_node_t* child); - -/** - * @brief Remove a child node of given virtual node, a validity check will be performed - * @param[in] node The virtual node whose child is waiting to be removed - * @param[in] child The child virtual node - * @return True if the operation is successful - */ -BPE_API bool virtual_node_remove_child(virtual_node_t* node, virtual_node_t* child); +BPE_API bool virtual_node_set_parent(const virtual_node_t& node, const virtual_node_t& parent); +BPE_API bool virtual_node_set_left_child(const virtual_node_t& node, const virtual_node_t& child); +BPE_API bool virtual_node_set_right_child(const virtual_node_t& node, const virtual_node_t& child); +BPE_API bool virtual_node_add_child(const virtual_node_t& node, const virtual_node_t& child); +BPE_API bool virtual_node_remove_child(const virtual_node_t& node, const virtual_node_t& child); // Node Replacement Operation -/** - * @brief Replace a primitive node to constant, a validity check will be performed - * @param[in] node The virtual node which points to primitive node - * @param[in] desc The new descriptor - * @return True if the operation is successful - */ -BPE_API bool virtual_node_replace_primitive(virtual_node_t* node, const constant_descriptor_t& desc); - -/** - * @brief Replace a primitive node to plane, a validity check will be performed - * @param[in] node The virtual node which points to primitive node - * @param[in] desc The new descriptor - * @return True if the operation is successful - */ -BPE_API bool virtual_node_replace_primitive(virtual_node_t* node, const plane_descriptor_t& desc); - -/** - * @brief Replace a primitive node to sphere, a validity check will be performed - * @param[in] node The virtual node which points to primitive node - * @param[in] desc The new descriptor - * @return True if the operation is successful - */ -BPE_API bool virtual_node_replace_primitive(virtual_node_t* node, const sphere_descriptor_t& desc); - -/** - * @brief Replace a primitive node to cylinder, a validity check will be performed - * @param[in] node The virtual node which points to primitive node - * @param[in] desc The new descriptor - * @return True if the operation is successful - */ -BPE_API bool virtual_node_replace_primitive(virtual_node_t* node, const cylinder_descriptor_t& desc); - -/** - * @brief Replace a primitive node to cone, a validity check will be performed - * @param[in] node The virtual node which points to primitive node - * @param[in] desc The new descriptor - * @return True if the operation is successful - */ -BPE_API bool virtual_node_replace_primitive(virtual_node_t* node, const cone_descriptor_t& desc); - -/** - * @brief Replace a primitive node to box, a validity check will be performed - * @param[in] node The virtual node which points to primitive node - * @param[in] desc The new descriptor - * @return True if the operation is successful - */ -BPE_API bool virtual_node_replace_primitive(virtual_node_t* node, const box_descriptor_t& desc); - -/** - * @brief Replace a primitive node to mesh, a validity check will be performed - * @param[in] node The virtual node which points to primitive node - * @param[in] desc The new descriptor - * @return True if the operation is successful - */ -BPE_API bool virtual_node_replace_primitive(virtual_node_t* node, const mesh_descriptor_t& desc); - -/** - * @brief Replace a primitive node to extrude, a validity check will be performed - * @param[in] node The virtual node which points to primitive node - * @param[in] desc The new descriptor - * @return True if the operation is successful - */ -BPE_API bool virtual_node_replace_primitive(virtual_node_t* node, const extrude_descriptor_t& desc); +BPE_API bool virtual_node_replace_primitive(const virtual_node_t& node, const constant_descriptor_t& desc); +BPE_API bool virtual_node_replace_primitive(const virtual_node_t& node, const plane_descriptor_t& desc); +BPE_API bool virtual_node_replace_primitive(const virtual_node_t& node, const sphere_descriptor_t& desc); +BPE_API bool virtual_node_replace_primitive(const virtual_node_t& node, const cylinder_descriptor_t& desc); +BPE_API bool virtual_node_replace_primitive(const virtual_node_t& node, const cone_descriptor_t& desc); +BPE_API bool virtual_node_replace_primitive(const virtual_node_t& node, const box_descriptor_t& desc); +BPE_API bool virtual_node_replace_primitive(const virtual_node_t& node, const mesh_descriptor_t& desc); +BPE_API bool virtual_node_replace_primitive(const virtual_node_t& node, const extrude_descriptor_t& desc); diff --git a/blobtree_structure/include/node_operation.hpp b/blobtree_structure/interface/internal_structs.hpp similarity index 87% rename from blobtree_structure/include/node_operation.hpp rename to blobtree_structure/interface/internal_structs.hpp index 3449357..8d849ba 100644 --- a/blobtree_structure/include/node_operation.hpp +++ b/blobtree_structure/interface/internal_structs.hpp @@ -1,6 +1,41 @@ #pragma once -#include +#include + +// ====================================================================== +// AABB +// ====================================================================== + +struct aabb_t { + Eigen::Vector3d min{std::numeric_limits::max(), + std::numeric_limits::max(), + std::numeric_limits::max()}; + Eigen::Vector3d max{std::numeric_limits::min(), + std::numeric_limits::min(), + std::numeric_limits::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; + } +}; + +// ====================================================================== +// Node +// ====================================================================== struct node_t { uint64_t data[2]; diff --git a/blobtree_structure/src/blobtree.cpp b/blobtree_structure/src/blobtree.cpp index 798274a..17701ce 100644 --- a/blobtree_structure/src/blobtree.cpp +++ b/blobtree_structure/src/blobtree.cpp @@ -1,10 +1,9 @@ #include +#include #include "internal_api.hpp" #include "globals.hpp" -#include "aabb.hpp" -#include "node_operation.hpp" /* internal global variables for blobtree */ std::vector> structures{}; @@ -16,7 +15,34 @@ std::stack>> free_st * basic functionalities * ============================================================================================= */ -BPE_API std::vector>& get_primitives() noexcept { return primitives; } +BPE_API std::vector> blobtree_get_leaf_nodes_primitive_mapping(uint32_t index) noexcept +{ + std::vector> mapping(primitives.size(), std::numeric_limits::max()); + for (const auto& leaf_node_index : structures[index].leaf_index) { + const uint32_t primitive_index = node_fetch_primitive_index(structures[index].nodes[leaf_node_index]); + mapping[primitive_index] = leaf_node_index; + } + + return mapping; +} + +BPE_API size_t get_primitive_count() noexcept +{ + assert(primitives.size() == aabbs.size()); + return primitives.size(); +} + +BPE_API const primitive_node_t& get_primitive_node(uint32_t index) noexcept +{ + assert(index < primitives.size()); + return primitives[index]; +} + +BPE_API const aabb_t& get_aabb(uint32_t index) noexcept +{ + assert(index < aabbs.size()); + return aabbs[index]; +} void shrink_primitives() { primitives.shrink_to_fit(); } @@ -47,61 +73,6 @@ virtual_node_t copy(virtual_node_t old_node, virtual_node_t new_node) return virtual_node_t{new_node.main_index, old_node.inner_index + size}; } -void offset_primitive(primitive_node_t& node, const Eigen::Vector3d& offset) -{ - auto offset_point = [](raw_vector3d_t& point, const Eigen::Vector3d& offset) { - Eigen::Map point_map(&point.x); - point_map += offset; - }; - - auto type = node.type; - switch (type) { - case PRIMITIVE_TYPE_CONSTANT: { - break; - } - case PRIMITIVE_TYPE_PLANE: { - auto desc = static_cast(node.desc); - offset_point(desc->point, offset); - break; - } - case PRIMITIVE_TYPE_SPHERE: { - auto desc = static_cast(node.desc); - offset_point(desc->center, offset); - break; - } - case PRIMITIVE_TYPE_CYLINDER: { - auto desc = static_cast(node.desc); - offset_point(desc->bottom_origion, offset); - break; - } - case PRIMITIVE_TYPE_CONE: { - auto desc = static_cast(node.desc); - offset_point(desc->top_point, offset); - offset_point(desc->bottom_point, offset); - break; - } - case PRIMITIVE_TYPE_BOX: { - auto desc = static_cast(node.desc); - offset_point(desc->center, offset); - - break; - } - case PRIMITIVE_TYPE_MESH: { - auto desc = static_cast(node.desc); - for (int i = 0; i < desc->point_number; i++) { offset_point(desc->points[i], offset); } - break; - } - case PRIMITIVE_TYPE_EXTRUDE: { - auto desc = static_cast(node.desc); - for (int i = 0; i < desc->edges_number; i++) { offset_point(desc->points[i], offset); } - break; - } - default: { - break; - } - } -} - BPE_API void free_sub_blobtree(uint32_t index) noexcept { // 这里尽量打标记,延迟修改和删除 @@ -167,24 +138,24 @@ bool upward_propagation(blobtree_t& tree, const int leaf_node_index, const int r } } -eNodeLocation evaluate(const virtual_node_t& node, const raw_vector3d_t& point) -{ - auto temp = structures[node.main_index]; - - auto& leaf_index = temp.leaf_index; - for (size_t i = 0; i < leaf_index.size(); i++) { - auto sdf = evaluate(primitives[leaf_index[i]], point); - auto leaf_node_in_out = node_fetch_in_out(temp.nodes[leaf_index[i]]); - if (sdf <= 0.0) - leaf_node_in_out = eNodeLocation::in; - else - leaf_node_in_out = eNodeLocation::out; - - if (upward_propagation(temp, leaf_index[i], node.inner_index)) { break; } - } +// eNodeLocation evaluate(const virtual_node_t& node, const raw_vector3d_t& point) +// { +// auto temp = structures[node.main_index]; + +// auto& leaf_index = temp.leaf_index; +// for (size_t i = 0; i < leaf_index.size(); i++) { +// auto sdf = evaluate(primitives[leaf_index[i]], point); +// auto leaf_node_in_out = node_fetch_in_out(temp.nodes[leaf_index[i]]); +// if (sdf <= 0.0) +// leaf_node_in_out = eNodeLocation::in; +// else +// leaf_node_in_out = eNodeLocation::out; + +// if (upward_propagation(temp, leaf_index[i], node.inner_index)) { break; } +// } - return node_fetch_in_out(temp.nodes[node.inner_index]); -} +// return node_fetch_in_out(temp.nodes[node.inner_index]); +// } aabb_t get_aabb(const virtual_node_t& node) { @@ -248,17 +219,17 @@ aabb_t get_aabb(const virtual_node_t& node) * tree node operations * ============================================================================================= */ -BPE_API bool virtual_node_set_parent(virtual_node_t* node, virtual_node_t* parent) +BPE_API bool virtual_node_set_parent(const virtual_node_t& node, const virtual_node_t& parent) { - auto& node_in_tree = structures[node->main_index].nodes[node->inner_index]; + auto& node_in_tree = structures[node.main_index].nodes[node.inner_index]; // The node's parent is not empty if (!node_is_parent_null(node_in_tree)) { return false; } - auto& parent_in_tree = structures[parent->main_index].nodes[parent->inner_index]; - auto parent_inner_index = parent->inner_index; + auto& parent_in_tree = structures[parent.main_index].nodes[parent.inner_index]; + auto parent_inner_index = parent.inner_index; // not on the same tree - if (node->main_index != parent->main_index) { - auto new_parent = copy(*parent, *node); + if (node.main_index != parent.main_index) { + auto new_parent = copy(parent, node); parent_in_tree = structures[new_parent.main_index].nodes[new_parent.inner_index]; parent_inner_index = new_parent.inner_index; } @@ -270,21 +241,21 @@ BPE_API bool virtual_node_set_parent(virtual_node_t* node, virtual_node_t* paren // The parent's left child is empty if (node_is_left_child_null(node_in_tree)) { - parent_left_child = node->inner_index; + parent_left_child = node.inner_index; return true; } // The parent's right child is empty else if (node_is_right_child_null(node_in_tree)) { - parent_right_child = node->inner_index; + parent_right_child = node.inner_index; return true; } return false; } -BPE_API bool virtual_node_set_left_child(virtual_node_t* node, virtual_node_t* child) +BPE_API bool virtual_node_set_left_child(const virtual_node_t& node, virtual_node_t& child) { - auto& node_in_tree = structures[node->main_index].nodes[node->inner_index]; + auto& node_in_tree = structures[node.main_index].nodes[node.inner_index]; // The child's parent is not empty if (!node_is_parent_null(node_in_tree)) { return false; } @@ -296,23 +267,23 @@ BPE_API bool virtual_node_set_left_child(virtual_node_t* node, virtual_node_t* c auto node_right_child = node_fetch_right_child_index(node_in_tree); // On the same tree - if (node->main_index == child->main_index) { - auto& child_in_tree = structures[child->main_index].nodes[child->inner_index]; - node_fetch_parent_index(child_in_tree) = node->inner_index; - node_left_child = child->inner_index; + if (node.main_index == child.main_index) { + auto& child_in_tree = structures[child.main_index].nodes[child.inner_index]; + node_fetch_parent_index(child_in_tree) = node.inner_index; + node_left_child = child.inner_index; } else { - auto new_child = copy(*child, *node); + auto new_child = copy(child, node); auto& child_in_tree = structures[new_child.main_index].nodes[new_child.inner_index]; - node_fetch_parent_index(child_in_tree) = node->inner_index; + node_fetch_parent_index(child_in_tree) = node.inner_index; node_left_child = new_child.inner_index; } return true; } -BPE_API bool virtual_node_set_right_child(virtual_node_t* node, virtual_node_t* child) +BPE_API bool virtual_node_set_right_child(const virtual_node_t& node, virtual_node_t& child) { - auto& node_in_tree = structures[node->main_index].nodes[node->inner_index]; + auto& node_in_tree = structures[node.main_index].nodes[node.inner_index]; // The child's parent is not empty if (!node_is_parent_null(node_in_tree)) { return false; } @@ -324,21 +295,21 @@ BPE_API bool virtual_node_set_right_child(virtual_node_t* node, virtual_node_t* auto node_right_child = node_fetch_right_child_index(node_in_tree); // On the same tree - if (node->main_index == child->main_index) { - auto& child_in_tree = structures[child->main_index].nodes[child->inner_index]; - node_fetch_parent_index(child_in_tree) = node->inner_index; - node_right_child = child->inner_index; + if (node.main_index == child.main_index) { + auto& child_in_tree = structures[child.main_index].nodes[child.inner_index]; + node_fetch_parent_index(child_in_tree) = node.inner_index; + node_right_child = child.inner_index; } else { - auto new_child = copy(*child, *node); + auto new_child = copy(child, node); auto& child_in_tree = structures[new_child.main_index].nodes[new_child.inner_index]; - node_fetch_parent_index(child_in_tree) = node->inner_index; + node_fetch_parent_index(child_in_tree) = node.inner_index; node_right_child = new_child.inner_index; } return true; } -BPE_API bool virtual_node_add_child(virtual_node_t* node, virtual_node_t* child) +BPE_API bool virtual_node_add_child(const virtual_node_t& node, virtual_node_t& child) { if (virtual_node_set_left_child(node, child)) { return true; @@ -349,19 +320,19 @@ BPE_API bool virtual_node_add_child(virtual_node_t* node, virtual_node_t* child) return false; } -BPE_API bool virtual_node_remove_child(virtual_node_t* node, virtual_node_t* child) +BPE_API bool virtual_node_remove_child(const virtual_node_t& node, virtual_node_t& child) { - if (node->main_index != child->main_index) { return false; } + if (node.main_index != child.main_index) { return false; } - auto& node_in_tree = structures[node->main_index].nodes[node->inner_index]; + auto& node_in_tree = structures[node.main_index].nodes[node.inner_index]; auto node_left_child = node_fetch_left_child_index(node_in_tree); auto node_right_child = node_fetch_right_child_index(node_in_tree); - if (node_left_child == child->inner_index) { + if (node_left_child == child.inner_index) { node_left_child = 0xFFFFFFFFu; blobtree_free_virtual_node(child); return true; - } else if (node_right_child == child->inner_index) { + } else if (node_right_child == child.inner_index) { node_right_child = 0xFFFFFFFFu; blobtree_free_virtual_node(child); return true; @@ -376,52 +347,107 @@ BPE_API bool virtual_node_remove_child(virtual_node_t* node, virtual_node_t* chi static constexpr node_t standard_new_node = {(uint64_t)0xFFFFFFFFFFFFFFFFu, (uint64_t)0xFFFFFFFFFFFFFFFFu}; -static inline void virtual_node_boolean_op(virtual_node_t* node1, virtual_node_t* node2, eNodeOperation op) +static inline void virtual_node_boolean_op(virtual_node_t& node1, const virtual_node_t& node2, eNodeOperation op) { - auto new_node2 = copy(*node2, *node1); + auto new_node2 = copy(node2, node1); - auto& inserted_node = structures[node1->main_index].nodes.emplace_back(standard_new_node); + auto& inserted_node = structures[node1.main_index].nodes.emplace_back(standard_new_node); node_fetch_is_primitive(inserted_node) = false; // weird bug: need to force cast, or it will be treated as uint32_t instead of eNodeOperation node_fetch_operation(inserted_node) = (eNodeOperation)op; - node_fetch_left_child_index(inserted_node) = node1->inner_index; + node_fetch_left_child_index(inserted_node) = node1.inner_index; node_fetch_right_child_index(inserted_node) = new_node2.inner_index; - uint32_t parent_index = structures[node1->main_index].nodes.size() - 1; - node_fetch_parent_index(structures[node1->main_index].nodes[node1->inner_index]) = parent_index; + uint32_t parent_index = structures[node1.main_index].nodes.size() - 1; + node_fetch_parent_index(structures[node1.main_index].nodes[node1.inner_index]) = parent_index; node_fetch_parent_index(structures[new_node2.main_index].nodes[new_node2.inner_index]) = parent_index; - node1->inner_index = parent_index; + node1.inner_index = parent_index; } -BPE_API void virtual_node_boolean_union(virtual_node_t* node1, virtual_node_t* node2) +BPE_API void virtual_node_boolean_union(virtual_node_t& node1, const virtual_node_t& node2) { virtual_node_boolean_op(node1, node2, eNodeOperation::unionOp); } -BPE_API void virtual_node_boolean_intersect(virtual_node_t* node1, virtual_node_t* node2) +BPE_API void virtual_node_boolean_intersect(virtual_node_t& node1, const virtual_node_t& node2) { virtual_node_boolean_op(node1, node2, eNodeOperation::intersectionOp); } -BPE_API void virtual_node_boolean_difference(virtual_node_t* node1, virtual_node_t* node2) +BPE_API void virtual_node_boolean_difference(virtual_node_t& node1, const virtual_node_t& node2) { virtual_node_boolean_op(node1, node2, eNodeOperation::differenceOp); } -BPE_API void virtual_node_offset(virtual_node_t* node, const raw_vector3d_t& direction, const double length) +void offset_primitive(primitive_node_t& node, const Eigen::Vector3d& offset) +{ + auto offset_point = [](raw_vector3d_t& point, const Eigen::Vector3d& offset) { + Eigen::Map point_map(&point.x); + point_map += offset; + }; + + auto type = node.type; + switch (type) { + case PRIMITIVE_TYPE_CONSTANT: { + break; + } + case PRIMITIVE_TYPE_PLANE: { + auto desc = static_cast(node.desc); + offset_point(desc->point, offset); + break; + } + case PRIMITIVE_TYPE_SPHERE: { + auto desc = static_cast(node.desc); + offset_point(desc->center, offset); + break; + } + case PRIMITIVE_TYPE_CYLINDER: { + auto desc = static_cast(node.desc); + offset_point(desc->bottom_origion, offset); + break; + } + case PRIMITIVE_TYPE_CONE: { + auto desc = static_cast(node.desc); + offset_point(desc->top_point, offset); + offset_point(desc->bottom_point, offset); + break; + } + case PRIMITIVE_TYPE_BOX: { + auto desc = static_cast(node.desc); + offset_point(desc->center, offset); + + break; + } + case PRIMITIVE_TYPE_MESH: { + auto desc = static_cast(node.desc); + for (int i = 0; i < desc->point_number; i++) { offset_point(desc->points[i], offset); } + break; + } + case PRIMITIVE_TYPE_EXTRUDE: { + auto desc = static_cast(node.desc); + for (int i = 0; i < desc->edges_number; i++) { offset_point(desc->points[i], offset); } + break; + } + default: { + break; + } + } +} + +BPE_API void virtual_node_offset(virtual_node_t& node, const raw_vector3d_t& direction, const double length) { raw_vector3d_t offset = {direction.x * length, direction.y * length, direction.z * length}; virtual_node_offset(node, offset); } -BPE_API void virtual_node_offset(virtual_node_t* node, const raw_vector3d_t& offset) +BPE_API void virtual_node_offset(virtual_node_t& node, const raw_vector3d_t& offset) { Eigen::Map offset_(&offset.x); - auto& all_leaf = structures[node->main_index].leaf_index; - for (const auto& leaf_index : structures[node->main_index].leaf_index) { - auto& primitive_node = structures[node->main_index].nodes[leaf_index]; + auto& all_leaf = structures[node.main_index].leaf_index; + for (const auto& leaf_index : structures[node.main_index].leaf_index) { + auto& primitive_node = structures[node.main_index].nodes[leaf_index]; const uint32_t primitive_index = node_fetch_primitive_index(primitive_node); offset_primitive(primitives[primitive_index], offset_); @@ -429,12 +455,12 @@ BPE_API void virtual_node_offset(virtual_node_t* node, const raw_vector3d_t& off } } -BPE_API void virtual_node_split(virtual_node_t* node, raw_vector3d_t base_point, raw_vector3d_t normal) +BPE_API void virtual_node_split(virtual_node_t& node, raw_vector3d_t base_point, raw_vector3d_t normal) { plane_descriptor_t descriptor; descriptor.normal = raw_vector3d_t{normal.x * -1, normal.y * -1, normal.z * -1}; descriptor.point = base_point; auto plane = blobtree_new_virtual_node(descriptor); - virtual_node_boolean_intersect(node, &plane); + virtual_node_boolean_intersect(node, plane); } \ No newline at end of file diff --git a/blobtree_structure/src/evaluation.cpp b/blobtree_structure/src/evaluation.cpp index 2c595dc..13f6e45 100644 --- a/blobtree_structure/src/evaluation.cpp +++ b/blobtree_structure/src/evaluation.cpp @@ -211,45 +211,4 @@ BPE_API double evaluate(const extrude_descriptor_t& desc, const Eigen::Ref(node.desc); - return evaluate(*desc, vec3d_conversion(point)); - } - case PRIMITIVE_TYPE_SPHERE: { - auto desc = static_cast(node.desc); - return evaluate(*desc, vec3d_conversion(point)); - } - case PRIMITIVE_TYPE_CYLINDER: { - auto desc = static_cast(node.desc); - return evaluate(*desc, vec3d_conversion(point)); - } - case PRIMITIVE_TYPE_CONE: { - auto desc = static_cast(node.desc); - return evaluate(*desc, vec3d_conversion(point)); - } - case PRIMITIVE_TYPE_BOX: { - auto desc = static_cast(node.desc); - return evaluate(*desc, vec3d_conversion(point)); - } - case PRIMITIVE_TYPE_MESH: { - auto desc = static_cast(node.desc); - return evaluate(*desc, vec3d_conversion(point)); - } - case PRIMITIVE_TYPE_EXTRUDE: { - auto desc = static_cast(node.desc); - return evaluate(*desc, vec3d_conversion(point)); - } - default: { - return 0.0; - } - } -} +} \ No newline at end of file diff --git a/blobtree_structure/src/primitive_node_build.cpp b/blobtree_structure/src/primitive_node_build.cpp index dde8047..42a55d9 100644 --- a/blobtree_structure/src/primitive_node_build.cpp +++ b/blobtree_structure/src/primitive_node_build.cpp @@ -1,8 +1,6 @@ #include "internal_api.hpp" #include "globals.hpp" -#include "aabb.hpp" -#include "node_operation.hpp" /* Geometry Generation */ diff --git a/blobtree_structure/src/primitive_node_replace.cpp b/blobtree_structure/src/primitive_node_replace.cpp index f7c390e..b294314 100644 --- a/blobtree_structure/src/primitive_node_replace.cpp +++ b/blobtree_structure/src/primitive_node_replace.cpp @@ -1,12 +1,10 @@ #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) +BPE_API bool virtual_node_replace_primitive(const virtual_node_t& node, const constant_descriptor_t& desc) { - auto& node_in_tree = structures[node->main_index].nodes[node->inner_index]; + auto& node_in_tree = structures[node.main_index].nodes[node.inner_index]; if (!node_fetch_is_primitive(node_in_tree)) { return false; } @@ -18,9 +16,9 @@ BPE_API bool virtual_node_replace_primitive(virtual_node_t* node, const constant return true; } -BPE_API bool virtual_node_replace_primitive(virtual_node_t* node, const plane_descriptor_t& desc) +BPE_API bool virtual_node_replace_primitive(const virtual_node_t& node, const plane_descriptor_t& desc) { - auto& node_in_tree = structures[node->main_index].nodes[node->inner_index]; + auto& node_in_tree = structures[node.main_index].nodes[node.inner_index]; if (!node_fetch_is_primitive(node_in_tree)) { return false; } @@ -32,9 +30,9 @@ BPE_API bool virtual_node_replace_primitive(virtual_node_t* node, const plane_de return true; } -BPE_API bool virtual_node_replace_primitive(virtual_node_t* node, const sphere_descriptor_t& desc) +BPE_API bool virtual_node_replace_primitive(const virtual_node_t& node, const sphere_descriptor_t& desc) { - auto& node_in_tree = structures[node->main_index].nodes[node->inner_index]; + auto& node_in_tree = structures[node.main_index].nodes[node.inner_index]; if (!node_fetch_is_primitive(node_in_tree)) { return false; } @@ -51,9 +49,9 @@ BPE_API bool virtual_node_replace_primitive(virtual_node_t* node, const sphere_d return true; } -BPE_API bool virtual_node_replace_primitive(virtual_node_t* node, const cylinder_descriptor_t& desc) +BPE_API bool virtual_node_replace_primitive(const virtual_node_t& node, const cylinder_descriptor_t& desc) { - auto& node_in_tree = structures[node->main_index].nodes[node->inner_index]; + auto& node_in_tree = structures[node.main_index].nodes[node.inner_index]; if (!node_fetch_is_primitive(node_in_tree)) { return false; } @@ -74,9 +72,9 @@ BPE_API bool virtual_node_replace_primitive(virtual_node_t* node, const cylinder return true; } -BPE_API bool virtual_node_replace_primitive(virtual_node_t* node, const cone_descriptor_t& desc) +BPE_API bool virtual_node_replace_primitive(const virtual_node_t& node, const cone_descriptor_t& desc) { - auto& node_in_tree = structures[node->main_index].nodes[node->inner_index]; + auto& node_in_tree = structures[node.main_index].nodes[node.inner_index]; if (!node_fetch_is_primitive(node_in_tree)) { return false; } @@ -97,9 +95,9 @@ BPE_API bool virtual_node_replace_primitive(virtual_node_t* node, const cone_des return true; } -BPE_API bool virtual_node_replace_primitive(virtual_node_t* node, const box_descriptor_t& desc) +BPE_API bool virtual_node_replace_primitive(const virtual_node_t& node, const box_descriptor_t& desc) { - auto& node_in_tree = structures[node->main_index].nodes[node->inner_index]; + auto& node_in_tree = structures[node.main_index].nodes[node.inner_index]; if (!node_fetch_is_primitive(node_in_tree)) { return false; } @@ -116,9 +114,9 @@ BPE_API bool virtual_node_replace_primitive(virtual_node_t* node, const box_desc return true; } -BPE_API bool virtual_node_replace_primitive(virtual_node_t* node, const mesh_descriptor_t& desc) +BPE_API bool virtual_node_replace_primitive(const virtual_node_t& node, const mesh_descriptor_t& desc) { - auto& node_in_tree = structures[node->main_index].nodes[node->inner_index]; + auto& node_in_tree = structures[node.main_index].nodes[node.inner_index]; if (!node_fetch_is_primitive(node_in_tree)) { return false; } @@ -134,9 +132,9 @@ BPE_API bool virtual_node_replace_primitive(virtual_node_t* node, const mesh_des return true; } -BPE_API bool virtual_node_replace_primitive(virtual_node_t* node, const extrude_descriptor_t& desc) +BPE_API bool virtual_node_replace_primitive(const virtual_node_t& node, const extrude_descriptor_t& desc) { - auto& node_in_tree = structures[node->main_index].nodes[node->inner_index]; + auto& node_in_tree = structures[node.main_index].nodes[node.inner_index]; if (!node_fetch_is_primitive(node_in_tree)) { return false; } diff --git a/blobtree_structure/xmake.lua b/blobtree_structure/xmake.lua index b65637f..6580e9f 100644 --- a/blobtree_structure/xmake.lua +++ b/blobtree_structure/xmake.lua @@ -13,4 +13,7 @@ internal_library("blobtree_structure", "BPE") add_rules("config.indirect_predicates.flags") add_deps("shared_module") add_defines("RELEASE_BRANCH") - add_packages("eigen-latest", {public = true}) \ No newline at end of file + add_packages("eigen-latest", {public = true}) + after_build(function (target) + os.cp("$(scriptdir)/interface/*.h", target:targetdir()) + end) \ No newline at end of file diff --git a/frontend/distribute_header/environment.h b/frontend/distribute_header/environment.h new file mode 100644 index 0000000..14b2306 --- /dev/null +++ b/frontend/distribute_header/environment.h @@ -0,0 +1,11 @@ +#pragma once + +#include + +typedef struct sSetting { + uint32_t resolution; +} setting_descriptor; + +extern "C" __declspec(dllimport) void update_setting(const setting_descriptor desc); +// apply updated settings to the environment +extern "C" __declspec(dllimport) void update_environment(); \ No newline at end of file diff --git a/frontend/distribute_header/execution.h b/frontend/distribute_header/execution.h new file mode 100644 index 0000000..b3429d4 --- /dev/null +++ b/frontend/distribute_header/execution.h @@ -0,0 +1,25 @@ +#pragma once + +#include + +#include + +typedef struct { + raw_vector3d_t* vertices; + uint32_t* faces; // indices of vertices in each face + uint32_t* vertex_counts; // number of vertices in each face + uint32_t num_vertices; + uint32_t num_faces; +} polymesh_t; + +typedef struct { + polymesh_t mesh; + double surf_int_result; + double vol_int_result; + bool success; +} solve_result_t; + +extern "C" __declspec(dllimport) solve_result_t execute_solver(const virtual_node_t* tree_node); +// output time usage statistics to console +extern "C" __declspec(dllimport) void print_statistics(); +extern "C" __declspec(dllimport) void clear_statistics(); \ No newline at end of file diff --git a/frontend/distribute_header/io.h b/frontend/distribute_header/io.h new file mode 100644 index 0000000..9a311e8 --- /dev/null +++ b/frontend/distribute_header/io.h @@ -0,0 +1,113 @@ +#pragma once + +#include + +#include + +/** + * @brief Create a new primitive body + * @param[in] desc The descriptor of the primitive, must be consistent with the type + * @param[in] type The type of the primitive + * @return The virtual node (indices) pointing to the created primitive node + */ +extern "C" __declspec(dllimport) virtual_node_t blobtree_new_node(const void* desc, primitive_type type); + +/** + * @brief Union two virtual node, result will be writen to first node + * @param[in] node1 The first virtual node + * @param[in] node2 The second virtual node + */ +extern "C" __declspec(dllimport) void virtual_node_boolean_union(virtual_node_t* node1, const virtual_node_t* node2); + +/** + * @brief Intersect two virtual node, result will be writen to first node + * @param[in] node1 The first virtual node + * @param[in] node2 The second virtual node + */ +extern "C" __declspec(dllimport) void virtual_node_boolean_intersect(virtual_node_t* node1, const virtual_node_t* node2); + +/** + * @brief Difference two virtual node, result will be writen to first node + * @param[in] node1 The first virtual node + * @param[in] node2 The second virtual node + */ +extern "C" __declspec(dllimport) void virtual_node_boolean_difference(virtual_node_t* node1, const virtual_node_t* node2); + +/** + * @brief Offset a body + * @param[in] node The virtual node + * @param[in] directrion The offset direction + * @param[in] length The offset length + */ +extern "C" __declspec(dllimport) void virtual_node_offset(virtual_node_t* node, + const raw_vector3d_t& direction, + const double length); + +/** + * @brief Offset a body + * @param[in] node The virtual node + * @param[in] offset The offset direction and length + */ +extern "C" __declspec(dllimport) void virtual_node_offset_directly(virtual_node_t* node, const raw_vector3d_t& offset); + +/** + * @brief Split a body + * @param[in] node The virtual node + * @param[in] basePoint The base point of the split face + * @param[in] normal The normal of the split face + */ +extern "C" __declspec(dllimport) void virtual_node_split(virtual_node_t* node, + raw_vector3d_t base_point, + raw_vector3d_t normal); + +// Tree Node Operations + +/** + * @brief Sets the parent of a virtual node, a validity check will be performed + * @param[in] node The virtual node whose parent is waiting to be set + * @param[in] parent The parent virtual node + * @return True if the operation is successful + */ +extern "C" __declspec(dllimport) bool virtual_node_set_parent(const virtual_node_t* node, const virtual_node_t* parent); + +/** + * @brief Sets the left node of a virtual node, a validity check will be performed + * @param[in] node The virtual node whose left child is waiting to be set + * @param[in] child The child virtual node + * @return True if the operation is successful + */ +extern "C" __declspec(dllimport) bool virtual_node_set_left_child(const virtual_node_t* node, const virtual_node_t* child); + +/** + * @brief Sets the right node of a virtual node, a validity check will be performed + * @param[in] node The virtual node whose right child is waiting to be set + * @param[in] child The child virtual node + * @return True if the operation is successful + */ +extern "C" __declspec(dllimport) bool virtual_node_set_right_child(const virtual_node_t* node, const virtual_node_t* child); + +/** + * @brief Add a child node of given virtual node, a validity check will be performed + * @param[in] node The virtual node whose child is waiting to be added + * @param[in] child The child virtual node + * @return True if the operation is successful + */ +extern "C" __declspec(dllimport) bool virtual_node_add_child(const virtual_node_t* node, const virtual_node_t* child); + +/** + * @brief Remove a child node of given virtual node, a validity check will be performed + * @param[in] node The virtual node whose child is waiting to be removed + * @param[in] child The child virtual node + * @return True if the operation is successful + */ +extern "C" __declspec(dllimport) bool virtual_node_remove_child(const virtual_node_t* node, const virtual_node_t* child); + +/** + * @brief Replace a primitive node to a new one, a validity check will be performed + * @param[in] node The virtual node which points to primitive node + * @param[in] desc The new descriptor + * @return True if the operation is successful + */ +extern "C" __declspec(dllimport) bool virtual_node_replace_primitive(const virtual_node_t* node, + const void* desc, + primitive_type type); \ No newline at end of file diff --git a/frontend/distribute_header/todo.md b/frontend/distribute_header/todo.md new file mode 100644 index 0000000..3bce833 --- /dev/null +++ b/frontend/distribute_header/todo.md @@ -0,0 +1,5 @@ +use lua+regex match to automatically generate the precompiled header file, steps: + +1. get precompiled header file from the project +2. clear all '''#include ''' +3. replace '''__declspec(dllexport)''' with '''__declspec(dllimport)''' \ No newline at end of file diff --git a/frontend/include/implicit_surface_network_processor.hpp b/frontend/include/implicit_surface_network_processor.hpp index fdfeb20..b5ead18 100644 --- a/frontend/include/implicit_surface_network_processor.hpp +++ b/frontend/include/implicit_surface_network_processor.hpp @@ -1,8 +1,7 @@ #pragma once #include -#include -#include +#include "execution.h" #include "background_mesh_manager.hpp" #include "patch_integrator.hpp" @@ -11,7 +10,7 @@ struct ImplicitSurfaceNetworkProcessor { void update_background_mesh(const Eigen::Ref& aabb_min, const Eigen::Ref& aabb_max) noexcept; void clear() noexcept; - bool run(labelled_timers_manager& timers_manager) noexcept; + solve_result_t run(const virtual_node_t& tree_node) noexcept; /* adaptors */ BackgroundMeshManager background_mesh_manager{}; @@ -32,9 +31,4 @@ struct ImplicitSurfaceNetworkProcessor { ///< opposite orientation with respect to the shell. stl_vector_mp> arrangement_cells{}; ///< A 3D region partitioned by the surface network; encoded by a vector of shell indices - stl_vector_mp> - cell_function_labels{}; ///< A 2D boolean array for the signs of each pair of a function and an arrangement cell - // integration results - stl_vector_mp surf_int_of_patch{}; - stl_vector_mp vol_int_of_patch{}; }; \ No newline at end of file diff --git a/frontend/interface/environment.h b/frontend/interface/environment.h index 122c0fe..1bbab32 100644 --- a/frontend/interface/environment.h +++ b/frontend/interface/environment.h @@ -9,5 +9,5 @@ typedef struct sSetting { } setting_descriptor; EXTERN_C API void update_setting(const setting_descriptor desc); -EXTERN_C API void update_scene(); +// apply updated settings to the environment EXTERN_C API void update_environment(); \ No newline at end of file diff --git a/frontend/interface/execution.h b/frontend/interface/execution.h index 8f40d6d..eb78e40 100644 --- a/frontend/interface/execution.h +++ b/frontend/interface/execution.h @@ -1,7 +1,26 @@ #pragma once +#include + #include +#include + +typedef struct { + raw_vector3d_t* vertices; + uint32_t* faces; // indices of vertices in each face + uint32_t* vertex_counts; // number of vertices in each face + uint32_t num_vertices; + uint32_t num_faces; +} polymesh_t; + +typedef struct { + polymesh_t mesh; + double surf_int_result; + double vol_int_result; + bool success; +} solve_result_t; -EXTERN_C API bool execute_solver(); -EXTERN_C API void clear_statistics(); -EXTERN_C API void print_statistics(); \ No newline at end of file +EXTERN_C API solve_result_t execute_solver(const virtual_node_t* tree_node); +// output time usage statistics to console +EXTERN_C API void print_statistics(); +EXTERN_C API void clear_statistics(); \ No newline at end of file diff --git a/frontend/interface/io.h b/frontend/interface/io.h index 9fb071d..ac62e92 100644 --- a/frontend/interface/io.h +++ b/frontend/interface/io.h @@ -1,10 +1,112 @@ #pragma once +#include + #include #include EXTERN_C_BEGIN +/** + * @brief Create a new primitive body + * @param[in] desc The descriptor of the primitive, must be consistent with the type + * @param[in] type The type of the primitive + * @return The virtual node (indices) pointing to the created primitive node + */ API virtual_node_t blobtree_new_node(const void* desc, primitive_type type); +/** + * @brief Union two virtual node, result will be writen to first node + * @param[in] node1 The first virtual node + * @param[in] node2 The second virtual node + */ +API void virtual_node_boolean_union(virtual_node_t* node1, const virtual_node_t* node2); + +/** + * @brief Intersect two virtual node, result will be writen to first node + * @param[in] node1 The first virtual node + * @param[in] node2 The second virtual node + */ +API void virtual_node_boolean_intersect(virtual_node_t* node1, const virtual_node_t* node2); + +/** + * @brief Difference two virtual node, result will be writen to first node + * @param[in] node1 The first virtual node + * @param[in] node2 The second virtual node + */ +API void virtual_node_boolean_difference(virtual_node_t* node1, const virtual_node_t* node2); + +/** + * @brief Offset a body + * @param[in] node The virtual node + * @param[in] directrion The offset direction + * @param[in] length The offset length + */ +API void virtual_node_offset(virtual_node_t* node, const raw_vector3d_t& direction, const double length); + +/** + * @brief Offset a body + * @param[in] node The virtual node + * @param[in] offset The offset direction and length + */ +API void virtual_node_offset_directly(virtual_node_t* node, const raw_vector3d_t& offset); + +/** + * @brief Split a body + * @param[in] node The virtual node + * @param[in] basePoint The base point of the split face + * @param[in] normal The normal of the split face + */ +API void virtual_node_split(virtual_node_t* node, raw_vector3d_t base_point, raw_vector3d_t normal); + +// Tree Node Operations + +/** + * @brief Sets the parent of a virtual node, a validity check will be performed + * @param[in] node The virtual node whose parent is waiting to be set + * @param[in] parent The parent virtual node + * @return True if the operation is successful + */ +API bool virtual_node_set_parent(const virtual_node_t* node, const virtual_node_t* parent); + +/** + * @brief Sets the left node of a virtual node, a validity check will be performed + * @param[in] node The virtual node whose left child is waiting to be set + * @param[in] child The child virtual node + * @return True if the operation is successful + */ +API bool virtual_node_set_left_child(const virtual_node_t* node, const virtual_node_t* child); + +/** + * @brief Sets the right node of a virtual node, a validity check will be performed + * @param[in] node The virtual node whose right child is waiting to be set + * @param[in] child The child virtual node + * @return True if the operation is successful + */ +API bool virtual_node_set_right_child(const virtual_node_t* node, const virtual_node_t* child); + +/** + * @brief Add a child node of given virtual node, a validity check will be performed + * @param[in] node The virtual node whose child is waiting to be added + * @param[in] child The child virtual node + * @return True if the operation is successful + */ +API bool virtual_node_add_child(const virtual_node_t* node, const virtual_node_t* child); + +/** + * @brief Remove a child node of given virtual node, a validity check will be performed + * @param[in] node The virtual node whose child is waiting to be removed + * @param[in] child The child virtual node + * @return True if the operation is successful + */ +API bool virtual_node_remove_child(const virtual_node_t* node, const virtual_node_t* child); + +/** + * @brief Replace a primitive node to a new one, a validity check will be performed + * @param[in] node The virtual node which points to primitive node + * @param[in] desc The new descriptor + * @return True if the operation is successful + */ +API bool virtual_node_replace_primitive(const virtual_node_t* node, const void* desc, primitive_type type); + EXTERN_C_END \ No newline at end of file diff --git a/frontend/src/api.cpp b/frontend/src/api.cpp index 17adce6..0312c36 100644 --- a/frontend/src/api.cpp +++ b/frontend/src/api.cpp @@ -1,6 +1,6 @@ #include "implicit_arrangement.hpp" -#include "integrator.hpp" -#include "statistics.hpp" +#include "globals.hpp" + #include "environment.h" #include "execution.h" @@ -12,20 +12,12 @@ EXTERN_C API void update_setting(const setting_descriptor desc) load_lut(); } -EXTERN_C API void update_scene() { g_integrator.update_scene(); } - EXTERN_C API void update_environment() { g_integrator.update_background_mesh(-Eigen::Vector3d::Ones(), Eigen::Vector3d::Ones()); } -EXTERN_C API bool execute_solver() -{ - if (!g_integrator.run(g_timers_manager)) return false; - g_integrator.compute(g_timers_manager); - - return true; -} +EXTERN_C API solve_result_t execute_solver(const virtual_node_t* tree_node) { return g_integrator.run(*tree_node); } EXTERN_C API void clear_statistics() { g_timers_manager.clear(); } diff --git a/frontend/src/io.cpp b/frontend/src/io.cpp index 82d4bf0..46f1990 100644 --- a/frontend/src/io.cpp +++ b/frontend/src/io.cpp @@ -18,4 +18,73 @@ API virtual_node_t blobtree_new_node(const void* desc, primitive_type type) } } +API void virtual_node_boolean_union(virtual_node_t* node1, const virtual_node_t* node2) +{ + virtual_node_boolean_union(*node1, *node2); +} + +API void virtual_node_boolean_intersect(virtual_node_t* node1, const virtual_node_t* node2) +{ + virtual_node_boolean_intersect(*node1, *node2); +} + +API void virtual_node_boolean_difference(virtual_node_t* node1, const virtual_node_t* node2) +{ + virtual_node_boolean_difference(*node1, *node2); +} + +API void virtual_node_offset(virtual_node_t* node, const raw_vector3d_t& direction, const double length) +{ + virtual_node_offset(*node, direction, length); +} + +API void virtual_node_offset_directly(virtual_node_t* node, const raw_vector3d_t& offset) +{ + virtual_node_offset(*node, offset); +} + +API void virtual_node_split(virtual_node_t* node, raw_vector3d_t base_point, raw_vector3d_t normal) +{ + virtual_node_split(*node, base_point, normal); +} + +API bool virtual_node_set_parent(const virtual_node_t* node, const virtual_node_t* parent) +{ + return virtual_node_set_parent(*node, *parent); +} + +API bool virtual_node_set_left_child(const virtual_node_t* node, const virtual_node_t* child) +{ + return virtual_node_set_left_child(*node, *child); +} + +API bool virtual_node_set_right_child(const virtual_node_t* node, const virtual_node_t* child) +{ + return virtual_node_set_right_child(*node, *child); +} + +API bool virtual_node_add_child(const virtual_node_t* node, const virtual_node_t* child) +{ + return virtual_node_add_child(*node, *child); +} + +API bool virtual_node_remove_child(const virtual_node_t* node, const virtual_node_t* child) +{ + return virtual_node_remove_child(*node, *child); +} + +API bool virtual_node_replace_primitive(const virtual_node_t* node, const void* desc, primitive_type type) +{ + switch (type) { + case PRIMITIVE_TYPE_CONSTANT: return virtual_node_replace_primitive(*node, *(const constant_descriptor_t*)desc); + case PRIMITIVE_TYPE_PLANE: return virtual_node_replace_primitive(*node, *(const plane_descriptor_t*)desc); + case PRIMITIVE_TYPE_SPHERE: return virtual_node_replace_primitive(*node, *(const sphere_descriptor_t*)desc); + case PRIMITIVE_TYPE_CYLINDER: return virtual_node_replace_primitive(*node, *(const cylinder_descriptor_t*)desc); + case PRIMITIVE_TYPE_CONE: return virtual_node_replace_primitive(*node, *(const cone_descriptor_t*)desc); + case PRIMITIVE_TYPE_BOX: return virtual_node_replace_primitive(*node, *(const box_descriptor_t*)desc); + case PRIMITIVE_TYPE_MESH: return virtual_node_replace_primitive(*node, *(const mesh_descriptor_t*)desc); + case PRIMITIVE_TYPE_EXTRUDE: return virtual_node_replace_primitive(*node, *(const extrude_descriptor_t*)desc); + } +} + EXTERN_C_END \ No newline at end of file diff --git a/frontend/xmake.lua b/frontend/xmake.lua index 5ae8977..a68dfb8 100644 --- a/frontend/xmake.lua +++ b/frontend/xmake.lua @@ -1,4 +1,7 @@ exposed_library("frontend") add_rules("config.indirect_predicates.flags") add_deps("implicit_surface_network_process", "blobtree_structure", "shared_module") - add_defines("RELEASE_BRANCH") \ No newline at end of file + add_defines("RELEASE_BRANCH") + after_build(function (target) + os.cp("$(scriptdir)/interface/*.h", target:targetdir()) + end) \ No newline at end of file