ReUseX  0.0.5
3D Point Cloud Processing for Building Reuse
Loading...
Searching...
No Matches
filter_expression.hpp
Go to the documentation of this file.
1// SPDX-FileCopyrightText: 2025 Povl Filip Sonne-Frederiksen
2// SPDX-License-Identifier: GPL-3.0-or-later
3
4#pragma once
5
6#include <memory>
7#include <reusex/types.hpp>
8#include <string>
9#include <unordered_set>
10#include <vector>
11
12namespace reusex {
13// Forward declaration
14class ProjectDB;
15} // namespace reusex
16
17namespace reusex::core {
18
23 std::string cloud_name_;
24 CloudLConstPtr label_cloud_;
25
26 public:
28 : cloud_name_(std::move(name)), label_cloud_(std::move(labels)) {}
29
30 auto labels() const -> const CloudLConstPtr & { return label_cloud_; }
31 auto name() const -> const std::string & { return cloud_name_; }
32 auto size() const -> size_t { return label_cloud_->size(); }
33};
34
40 public:
41 virtual ~FilterNode() = default;
42
47 virtual auto evaluate(const std::vector<CloudReferenceNode> &clouds,
48 size_t point_idx) const -> bool = 0;
49};
50
53inline int32_t cloud_label_at(const std::vector<CloudReferenceNode> &clouds,
54 size_t cloud_idx, size_t point_idx) {
55 if (cloud_idx >= clouds.size()) {
56 return -1;
57 }
58 const auto &cloud = clouds[cloud_idx];
59 if (point_idx >= cloud.size()) {
60 return -1;
61 }
62 return cloud.labels()->points[point_idx].label;
63}
64
66class EqualNode : public FilterNode {
67 size_t cloud_idx_;
68 int32_t value_;
69
70 public:
71 EqualNode(size_t cloud_idx, int32_t value)
72 : cloud_idx_(cloud_idx), value_(value) {}
73 auto evaluate(const std::vector<CloudReferenceNode> &clouds,
74 size_t point_idx) const -> bool override {
75 return cloud_label_at(clouds, cloud_idx_, point_idx) == value_;
76 }
77};
78
80class NotEqualNode : public FilterNode {
81 size_t cloud_idx_;
82 int32_t value_;
83
84 public:
85 NotEqualNode(size_t cloud_idx, int32_t value)
86 : cloud_idx_(cloud_idx), value_(value) {}
87 auto evaluate(const std::vector<CloudReferenceNode> &clouds,
88 size_t point_idx) const -> bool override {
89 return cloud_label_at(clouds, cloud_idx_, point_idx) != value_;
90 }
91};
92
94class InNode : public FilterNode {
95 size_t cloud_idx_;
96 std::unordered_set<int32_t> values_;
97
98 public:
99 InNode(size_t cloud_idx, std::vector<int32_t> values)
100 : cloud_idx_(cloud_idx), values_(values.begin(), values.end()) {}
101 auto evaluate(const std::vector<CloudReferenceNode> &clouds,
102 size_t point_idx) const -> bool override {
103 return values_.count(cloud_label_at(clouds, cloud_idx_, point_idx)) > 0;
104 }
105};
106
108class CompareNode : public FilterNode {
109 public:
110 enum class Op { GT, GE, LT, LE };
111
112 private:
113 size_t cloud_idx_;
114 Op op_;
115 int32_t value_;
116
117 public:
118 CompareNode(size_t cloud_idx, Op op, int32_t value)
119 : cloud_idx_(cloud_idx), op_(op), value_(value) {}
120 auto evaluate(const std::vector<CloudReferenceNode> &clouds,
121 size_t point_idx) const -> bool override {
122 const int32_t label = cloud_label_at(clouds, cloud_idx_, point_idx);
123 switch (op_) {
124 case Op::GT:
125 return label > value_;
126 case Op::GE:
127 return label >= value_;
128 case Op::LT:
129 return label < value_;
130 case Op::LE:
131 return label <= value_;
132 }
133 return false;
134 }
135};
136
138class AndNode : public FilterNode {
139 std::unique_ptr<FilterNode> left_;
140 std::unique_ptr<FilterNode> right_;
141
142 public:
143 AndNode(std::unique_ptr<FilterNode> left, std::unique_ptr<FilterNode> right)
144 : left_(std::move(left)), right_(std::move(right)) {}
145 auto evaluate(const std::vector<CloudReferenceNode> &clouds,
146 size_t point_idx) const -> bool override {
147 return left_->evaluate(clouds, point_idx) &&
148 right_->evaluate(clouds, point_idx);
149 }
150};
151
153class OrNode : public FilterNode {
154 std::unique_ptr<FilterNode> left_;
155 std::unique_ptr<FilterNode> right_;
156
157 public:
158 OrNode(std::unique_ptr<FilterNode> left, std::unique_ptr<FilterNode> right)
159 : left_(std::move(left)), right_(std::move(right)) {}
160 auto evaluate(const std::vector<CloudReferenceNode> &clouds,
161 size_t point_idx) const -> bool override {
162 return left_->evaluate(clouds, point_idx) ||
163 right_->evaluate(clouds, point_idx);
164 }
165};
166
169 std::unique_ptr<FilterNode> root;
170 std::vector<CloudReferenceNode> clouds;
171
175 auto evaluate_point(size_t idx) const -> bool;
176};
177
183auto parse_filter_expression(const std::string &expression, ProjectDB &db)
184 -> std::unique_ptr<FilterExpression>;
185
190auto evaluate_filter(const FilterExpression &expr, size_t cloud_size)
191 -> IndicesPtr;
192
193} // namespace reusex::core
auto evaluate(const std::vector< CloudReferenceNode > &clouds, size_t point_idx) const -> bool override
Evaluate this node for a specific point.
AndNode(std::unique_ptr< FilterNode > left, std::unique_ptr< FilterNode > right)
auto labels() const -> const CloudLConstPtr &
auto name() const -> const std::string &
CloudReferenceNode(std::string name, CloudLConstPtr labels)
auto evaluate(const std::vector< CloudReferenceNode > &clouds, size_t point_idx) const -> bool override
Evaluate this node for a specific point.
CompareNode(size_t cloud_idx, Op op, int32_t value)
auto evaluate(const std::vector< CloudReferenceNode > &clouds, size_t point_idx) const -> bool override
Evaluate this node for a specific point.
EqualNode(size_t cloud_idx, int32_t value)
Base AST node for filter expressions.
virtual ~FilterNode()=default
virtual auto evaluate(const std::vector< CloudReferenceNode > &clouds, size_t point_idx) const -> bool=0
Evaluate this node for a specific point.
auto evaluate(const std::vector< CloudReferenceNode > &clouds, size_t point_idx) const -> bool override
Evaluate this node for a specific point.
InNode(size_t cloud_idx, std::vector< int32_t > values)
NotEqualNode(size_t cloud_idx, int32_t value)
auto evaluate(const std::vector< CloudReferenceNode > &clouds, size_t point_idx) const -> bool override
Evaluate this node for a specific point.
auto evaluate(const std::vector< CloudReferenceNode > &clouds, size_t point_idx) const -> bool override
Evaluate this node for a specific point.
OrNode(std::unique_ptr< FilterNode > left, std::unique_ptr< FilterNode > right)
auto evaluate_filter(const FilterExpression &expr, size_t cloud_size) -> IndicesPtr
Evaluate filter expression against all points, generate Indices.
int32_t cloud_label_at(const std::vector< CloudReferenceNode > &clouds, size_t cloud_idx, size_t point_idx)
Helper for leaf nodes: read the label for point_idx from cloud cloud_idx, returning -1 if the index i...
auto parse_filter_expression(const std::string &expression, ProjectDB &db) -> std::unique_ptr< FilterExpression >
Parse filter expression and resolve label cloud references from ProjectDB.
typename CloudL::ConstPtr CloudLConstPtr
Definition types.hpp:36
pcl::IndicesPtr IndicesPtr
Definition types.hpp:23
Parsed filter expression with resolved label cloud references.
std::vector< CloudReferenceNode > clouds
Referenced label clouds.
auto evaluate_point(size_t idx) const -> bool
Evaluate filter for a point index.
std::unique_ptr< FilterNode > root
AST root.