ACloudViewer  3.9.4
A Modern Library for 3D Data Processing
SelectionPolygonVolume.cpp
Go to the documentation of this file.
1 // ----------------------------------------------------------------------------
2 // - CloudViewer: www.cloudViewer.org -
3 // ----------------------------------------------------------------------------
4 // Copyright (c) 2018-2024 www.cloudViewer.org
5 // SPDX-License-Identifier: MIT
6 // ----------------------------------------------------------------------------
7 
9 
10 #include <Logging.h>
11 #include <ecvMesh.h>
12 #include <ecvPointCloud.h>
13 #include <json/json.h>
14 
15 namespace cloudViewer {
16 namespace visualization {
17 using namespace cloudViewer;
18 
19 bool SelectionPolygonVolume::ConvertToJsonValue(Json::Value &value) const {
20  Json::Value polygon_array;
21  for (const auto &point : bounding_polygon_) {
22  Json::Value point_object;
23  if (!EigenVector3dToJsonArray(point, point_object)) {
24  return false;
25  }
26  polygon_array.append(point_object);
27  }
28  value["class_name"] = "SelectionPolygonVolume";
29  value["version_major"] = 1;
30  value["version_minor"] = 0;
31  value["bounding_polygon"] = polygon_array;
32  value["orthogonal_axis"] = orthogonal_axis_;
33  value["axis_min"] = axis_min_;
34  value["axis_max"] = axis_max_;
35  return true;
36 }
37 
38 bool SelectionPolygonVolume::ConvertFromJsonValue(const Json::Value &value) {
39  if (!value.isObject()) {
41  "SelectionPolygonVolume read JSON failed: unsupported json "
42  "format.");
43  return false;
44  }
45  if (value.get("class_name", "").asString() != "SelectionPolygonVolume" ||
46  value.get("version_major", 1).asInt() != 1 ||
47  value.get("version_minor", 0).asInt() != 0) {
49  "SelectionPolygonVolume read JSON failed: unsupported json "
50  "format.");
51  return false;
52  }
53  orthogonal_axis_ = value.get("orthogonal_axis", "").asString();
54  axis_min_ = value.get("axis_min", 0.0).asDouble();
55  axis_max_ = value.get("axis_max", 0.0).asDouble();
56  const Json::Value &polygon_array = value["bounding_polygon"];
57  if (polygon_array.size() == 0) {
59  "SelectionPolygonVolume read JSON failed: empty trajectory.");
60  return false;
61  }
62  bounding_polygon_.resize(polygon_array.size());
63  for (int i = 0; i < (int)polygon_array.size(); i++) {
64  const Json::Value &point_object = polygon_array[i];
65  if (!EigenVector3dFromJsonArray(bounding_polygon_[i], point_object)) {
66  return false;
67  }
68  }
69  return true;
70 }
71 
72 std::shared_ptr<ccPointCloud> SelectionPolygonVolume::CropPointCloud(
73  const ccPointCloud &input) const {
74  if (orthogonal_axis_ == "" || bounding_polygon_.empty())
75  return std::make_shared<ccPointCloud>();
76  return CropPointCloudInPolygon(input);
77 }
78 
79 std::shared_ptr<ccPointCloud> SelectionPolygonVolume::CropPointCloudInPolygon(
80  const ccPointCloud &input) const {
81  return input.SelectByIndex(CropInPolygon(input.getPoints()));
82 }
83 
85  const ccMesh &input) const {
86  if (orthogonal_axis_ == "" || bounding_polygon_.empty())
87  return std::make_shared<ccMesh>(nullptr);
88  if (!input.getAssociatedCloud() && input.size() == 0) {
90  "ccMesh contains vertices, but no triangles; "
91  "cropping will always yield an empty "
92  "ccMesh.");
93  return std::make_shared<ccMesh>(nullptr);
94  }
95  return CropTriangleMeshInPolygon(input);
96 }
97 
98 std::shared_ptr<ccMesh> SelectionPolygonVolume::CropTriangleMeshInPolygon(
99  const ccMesh &input) const {
100  return input.SelectByIndex(CropInPolygon(input.getVertices()));
101 }
102 
104  const ccPointCloud &input) const {
105  return CropInPolygon(input.getPoints());
106 }
107 
108 std::vector<size_t> SelectionPolygonVolume::CropInPolygon(
109  const std::vector<Eigen::Vector3d> &input) const {
111 }
112 
113 std::vector<size_t> SelectionPolygonVolume::CropInPolygon(
114  const std::vector<CCVector3> &input) const {
115  std::vector<size_t> output_index;
116  int u, v, w;
117  if (orthogonal_axis_ == "x" || orthogonal_axis_ == "X") {
118  u = 1;
119  v = 2;
120  w = 0;
121  } else if (orthogonal_axis_ == "y" || orthogonal_axis_ == "Y") {
122  u = 0;
123  v = 2;
124  w = 1;
125  } else {
126  u = 0;
127  v = 1;
128  w = 2;
129  }
130  std::vector<double> nodes;
131  utility::ConsoleProgressBar progress_bar((int64_t)input.size(),
132  "Cropping geometry: ");
133  for (size_t k = 0; k < input.size(); k++) {
134  ++progress_bar;
135  const auto &point = input[k];
136  if (point(w) < axis_min_ || point(w) > axis_max_) continue;
137  nodes.clear();
138  for (size_t i = 0; i < bounding_polygon_.size(); i++) {
139  size_t j = (i + 1) % bounding_polygon_.size();
140  if ((bounding_polygon_[i](v) < point(v) &&
141  bounding_polygon_[j](v) >= point(v)) ||
142  (bounding_polygon_[j](v) < point(v) &&
143  bounding_polygon_[i](v) >= point(v))) {
144  nodes.push_back(bounding_polygon_[i](u) +
145  (point(v) - bounding_polygon_[i](v)) /
146  (bounding_polygon_[j](v) -
147  bounding_polygon_[i](v)) *
148  (bounding_polygon_[j](u) -
149  bounding_polygon_[i](u)));
150  }
151  }
152  std::sort(nodes.begin(), nodes.end());
153  auto loc = std::lower_bound(nodes.begin(), nodes.end(), point(u));
154  if (std::distance(nodes.begin(), loc) % 2 == 1) {
155  output_index.push_back(k);
156  }
157  }
158  return output_index;
159 }
160 
161 } // namespace visualization
162 } // namespace cloudViewer
utility::CountingProgressReporter * progress_bar
static std::vector< Eigen::Matrix< double, 3, 1 > > fromArrayContainer(const std::vector< Vector3Tpl< PointCoordinateType >> &container)
Definition: CVGeom.h:301
Triangular mesh.
Definition: ecvMesh.h:35
std::shared_ptr< ccMesh > SelectByIndex(const std::vector< size_t > &indices, bool cleanup=true) const
const std::vector< CCVector3 > & getVertices() const
ccGenericPointCloud * getAssociatedCloud() const override
Returns the vertices cloud.
Definition: ecvMesh.h:143
virtual unsigned size() const override
Returns the number of triangles.
A 3D cloud and its associated features (color, normals, scalar fields, etc.)
std::shared_ptr< ccPointCloud > SelectByIndex(const std::vector< size_t > &indices, bool invert=false) const
Function to select points from input ccPointCloud into output ccPointCloud.
std::vector< CCVector3 > & getPoints()
static bool EigenVector3dFromJsonArray(Eigen::Vector3d &vec, const Json::Value &value)
static bool EigenVector3dToJsonArray(const Eigen::Vector3d &vec, Json::Value &value)
std::vector< Eigen::Vector3d > bounding_polygon_
Bounding polygon boundary.
bool ConvertToJsonValue(Json::Value &value) const override
std::vector< size_t > CropInPolygon(const ccPointCloud &input) const
bool ConvertFromJsonValue(const Json::Value &value) override
std::shared_ptr< ccPointCloud > CropPointCloud(const ccPointCloud &input) const
std::shared_ptr< ccMesh > CropTriangleMesh(const ccMesh &input) const
#define LogWarning(...)
Definition: Logging.h:72
Generic file read and write utility for python interface.
Definition: lsd.c:149