From 0f7f273f0d7a0430898bd1529d561c0f9ba9e4d4 Mon Sep 17 00:00:00 2001 From: Thomas Krijnen Date: Mon, 13 May 2024 16:43:56 +0200 Subject: [PATCH] count_neighbours() voxel operation --- voxec.cpp | 1 + voxec.h | 58 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+) diff --git a/voxec.cpp b/voxec.cpp index 15b46c9..264b0b8 100644 --- a/voxec.cpp +++ b/voxec.cpp @@ -68,6 +68,7 @@ voxel_operation_map::map_t& voxel_operation_map::map() { m.insert(std::make_pair(std::string("dimensionality_estimate"), &instantiate)); m.insert(std::make_pair(std::string("segment"), &instantiate)); m.insert(std::make_pair(std::string("keep_neighbours"), &instantiate)); + m.insert(std::make_pair(std::string("count_neighbours"), &instantiate)); m.insert(std::make_pair(std::string("free"), &instantiate)); m.insert(std::make_pair(std::string("assert"), &instantiate)); m.insert(std::make_pair(std::string("set"), &instantiate)); diff --git a/voxec.h b/voxec.h index 0a678f2..2ec44ce 100644 --- a/voxec.h +++ b/voxec.h @@ -2837,6 +2837,64 @@ class op_keep_neighbours : public voxel_operation { } }; + +class op_count_neighbours : public voxel_operation { +public: + const std::vector& arg_names() const { + static std::vector nm_ = { { true, "input", "voxels" }, { true, "connectivity", "integer" } }; + return nm_; + } + symbol_value invoke(const scope_map& scope) const { + auto voxels = (regular_voxel_storage*)scope.get_value("input"); + voxel_uint32_t u32; + auto result = (regular_voxel_storage*)voxels->empty_copy_as(&u32); + const auto connectivity = scope.get_value("connectivity"); + auto extents = voxels->extents().as(); + + for (auto it = voxels->begin(); it != voxels->end(); ++it) { + uint32_t num = 0; + + if (connectivity == 6) { + + for (size_t f = 0; f < 6; ++f) { + vec_n<3, long> n; + size_t normal = f / 2; + size_t o0 = (normal + 1) % 3; + size_t o1 = (normal + 2) % 3; + size_t side = f % 2; + n.get(normal) = side ? 1 : -1; + if (it.neighbour(n)) { + ++num; + } + } + + } else { + + for (long i = -1; i <= 1; ++i) { + for (long j = -1; j <= 1; ++j) { + for (long k = -1; k <= 1; ++k) { + if (i == 0 && j == 0 && k == 0) { + continue; + } + auto ijk2 = (*it).as() + make_vec(i, j, k); + if ((ijk2 >= 0).all() && (ijk2 < extents).all()) { + if (voxels->Get(ijk2.as())) { + ++num; + } + } + } + } + } + + } + + result->Set(*it, &num); + } + + return result; + } +}; + class op_set : public voxel_operation { public: const std::vector& arg_names() const {