@@ -2837,6 +2837,64 @@ class op_keep_neighbours : public voxel_operation {
28372837 }
28382838};
28392839
2840+
2841+ class op_count_neighbours : public voxel_operation {
2842+ public:
2843+ const std::vector<argument_spec>& arg_names () const {
2844+ static std::vector<argument_spec> nm_ = { { true , " input" , " voxels" }, { true , " connectivity" , " integer" } };
2845+ return nm_;
2846+ }
2847+ symbol_value invoke (const scope_map& scope) const {
2848+ auto voxels = (regular_voxel_storage*)scope.get_value <abstract_voxel_storage*>(" input" );
2849+ voxel_uint32_t u32 ;
2850+ auto result = (regular_voxel_storage*)voxels->empty_copy_as (&u32 );
2851+ const auto connectivity = scope.get_value <int >(" connectivity" );
2852+ auto extents = voxels->extents ().as <long >();
2853+
2854+ for (auto it = voxels->begin (); it != voxels->end (); ++it) {
2855+ uint32_t num = 0 ;
2856+
2857+ if (connectivity == 6 ) {
2858+
2859+ for (size_t f = 0 ; f < 6 ; ++f) {
2860+ vec_n<3 , long > n;
2861+ size_t normal = f / 2 ;
2862+ size_t o0 = (normal + 1 ) % 3 ;
2863+ size_t o1 = (normal + 2 ) % 3 ;
2864+ size_t side = f % 2 ;
2865+ n.get (normal) = side ? 1 : -1 ;
2866+ if (it.neighbour (n)) {
2867+ ++num;
2868+ }
2869+ }
2870+
2871+ } else {
2872+
2873+ for (long i = -1 ; i <= 1 ; ++i) {
2874+ for (long j = -1 ; j <= 1 ; ++j) {
2875+ for (long k = -1 ; k <= 1 ; ++k) {
2876+ if (i == 0 && j == 0 && k == 0 ) {
2877+ continue ;
2878+ }
2879+ auto ijk2 = (*it).as <long >() + make_vec<long >(i, j, k);
2880+ if ((ijk2 >= 0 ).all () && (ijk2 < extents).all ()) {
2881+ if (voxels->Get (ijk2.as <size_t >())) {
2882+ ++num;
2883+ }
2884+ }
2885+ }
2886+ }
2887+ }
2888+
2889+ }
2890+
2891+ result->Set (*it, &num);
2892+ }
2893+
2894+ return result;
2895+ }
2896+ };
2897+
28402898class op_set : public voxel_operation {
28412899public:
28422900 const std::vector<argument_spec>& arg_names () const {
0 commit comments