ACloudViewer  3.9.4
A Modern Library for 3D Data Processing
LineSetFactory.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 
8 #include <Helper.h>
9 
10 #include <Eigen/Dense>
11 #include <unordered_set>
12 
13 #include "LineSet.h"
14 #include "ecvBBox.h"
15 #include "ecvMesh.h"
16 #include "ecvOrientedBBox.h"
17 #include "ecvPointCloud.h"
18 #include "ecvTetraMesh.h"
19 
20 namespace cloudViewer {
21 namespace geometry {
22 
24  const ccPointCloud &cloud0,
25  const ccPointCloud &cloud1,
26  const std::vector<std::pair<int, int>> &correspondences) {
27  auto lineset_ptr = std::make_shared<LineSet>();
28  unsigned int point0_size = cloud0.size();
29  unsigned int point1_size = cloud1.size();
30  lineset_ptr->points_.resize(point0_size + point1_size);
31  for (unsigned int i = 0; i < point0_size; i++)
32  lineset_ptr->points_[i] = cloud0.getEigenPoint(i);
33  for (unsigned int i = 0; i < point1_size; i++)
34  lineset_ptr->points_[point0_size + i] = cloud1.getEigenPoint(i);
35 
36  size_t corr_size = correspondences.size();
37  lineset_ptr->lines_.resize(corr_size);
38  for (size_t i = 0; i < corr_size; i++)
39  lineset_ptr->lines_[i] =
40  Eigen::Vector2i(correspondences[i].first,
41  point0_size + correspondences[i].second);
42  return lineset_ptr;
43 }
44 
45 std::shared_ptr<LineSet> LineSet::CreateFromTriangleMesh(const ccMesh &mesh) {
46  auto line_set = std::make_shared<LineSet>();
47  line_set->points_ = mesh.getEigenVertices();
48 
49  std::unordered_set<Eigen::Vector2i,
51  inserted_edges;
52  auto InsertEdge = [&](int vidx0, int vidx1) {
53  Eigen::Vector2i edge(std::min(vidx0, vidx1), std::max(vidx0, vidx1));
54  if (inserted_edges.count(edge) == 0) {
55  inserted_edges.insert(edge);
56  line_set->lines_.push_back(Eigen::Vector2i(vidx0, vidx1));
57  }
58  };
59 
60  for (unsigned int i = 0; i < mesh.size(); ++i) {
61  const cloudViewer::VerticesIndexes *tri =
62  mesh.getTriangleVertIndexes(i);
63  InsertEdge(tri->i1, tri->i2);
64  InsertEdge(tri->i2, tri->i3);
65  InsertEdge(tri->i3, tri->i1);
66  }
67 
68  return line_set;
69 }
70 
71 std::shared_ptr<LineSet> LineSet::CreateFromOrientedBoundingBox(
72  const ecvOrientedBBox &box) {
73  auto line_set = std::make_shared<LineSet>();
74  line_set->points_ = box.GetBoxPoints();
75  line_set->lines_.push_back(Eigen::Vector2i(0, 1));
76  line_set->lines_.push_back(Eigen::Vector2i(1, 7));
77  line_set->lines_.push_back(Eigen::Vector2i(7, 2));
78  line_set->lines_.push_back(Eigen::Vector2i(2, 0));
79  line_set->lines_.push_back(Eigen::Vector2i(3, 6));
80  line_set->lines_.push_back(Eigen::Vector2i(6, 4));
81  line_set->lines_.push_back(Eigen::Vector2i(4, 5));
82  line_set->lines_.push_back(Eigen::Vector2i(5, 3));
83  line_set->lines_.push_back(Eigen::Vector2i(0, 3));
84  line_set->lines_.push_back(Eigen::Vector2i(1, 6));
85  line_set->lines_.push_back(Eigen::Vector2i(7, 4));
86  line_set->lines_.push_back(Eigen::Vector2i(2, 5));
87  line_set->PaintUniformColor(box.GetColor());
88  return line_set;
89 }
90 
92  const ccBBox &box) {
93  auto line_set = std::make_shared<LineSet>();
94  line_set->points_ = box.GetBoxPoints();
95  line_set->lines_.push_back(Eigen::Vector2i(0, 1));
96  line_set->lines_.push_back(Eigen::Vector2i(1, 7));
97  line_set->lines_.push_back(Eigen::Vector2i(7, 2));
98  line_set->lines_.push_back(Eigen::Vector2i(2, 0));
99  line_set->lines_.push_back(Eigen::Vector2i(3, 6));
100  line_set->lines_.push_back(Eigen::Vector2i(6, 4));
101  line_set->lines_.push_back(Eigen::Vector2i(4, 5));
102  line_set->lines_.push_back(Eigen::Vector2i(5, 3));
103  line_set->lines_.push_back(Eigen::Vector2i(0, 3));
104  line_set->lines_.push_back(Eigen::Vector2i(1, 6));
105  line_set->lines_.push_back(Eigen::Vector2i(7, 4));
106  line_set->lines_.push_back(Eigen::Vector2i(2, 5));
107  line_set->PaintUniformColor(box.GetColor());
108  return line_set;
109 }
110 
111 std::shared_ptr<LineSet> LineSet::CreateFromTetraMesh(const TetraMesh &mesh) {
112  auto line_set = std::make_shared<LineSet>();
113  line_set->points_ = mesh.vertices_;
114 
115  std::unordered_set<Eigen::Vector2i,
117  inserted_edges;
118  auto InsertEdge = [&](int vidx0, int vidx1) {
119  Eigen::Vector2i edge(std::min(vidx0, vidx1), std::max(vidx0, vidx1));
120  if (inserted_edges.count(edge) == 0) {
121  inserted_edges.insert(edge);
122  line_set->lines_.push_back(Eigen::Vector2i(vidx0, vidx1));
123  }
124  };
125  for (const auto &tetra : mesh.tetras_) {
126  InsertEdge(tetra(0), tetra(1));
127  InsertEdge(tetra(1), tetra(2));
128  InsertEdge(tetra(2), tetra(0));
129  InsertEdge(tetra(3), tetra(0));
130  InsertEdge(tetra(3), tetra(1));
131  InsertEdge(tetra(3), tetra(2));
132  }
133 
134  return line_set;
135 }
136 
137 std::shared_ptr<LineSet> LineSet::CreateCameraVisualization(
138  int view_width_px,
139  int view_height_px,
140  const Eigen::Matrix3d &intrinsic,
141  const Eigen::Matrix4d &extrinsic,
142  double scale) {
143  Eigen::Matrix4d intrinsic4;
144  intrinsic4 << intrinsic(0, 0), intrinsic(0, 1), intrinsic(0, 2), 0.0,
145  intrinsic(1, 0), intrinsic(1, 1), intrinsic(1, 2), 0.0,
146  intrinsic(2, 0), intrinsic(2, 1), intrinsic(2, 2), 0.0, 0.0, 0.0,
147  0.0, 1.0;
148  Eigen::Matrix4d m = (intrinsic4 * extrinsic).inverse();
149  auto lines = std::make_shared<geometry::LineSet>();
150 
151  auto mult = [](const Eigen::Matrix4d &m,
152  const Eigen::Vector3d &v) -> Eigen::Vector3d {
153  Eigen::Vector4d v4(v.x(), v.y(), v.z(), 1.0);
154  auto result = m * v4;
155  return Eigen::Vector3d{result.x() / result.w(), result.y() / result.w(),
156  result.z() / result.w()};
157  };
158  double w = double(view_width_px);
159  double h = double(view_height_px);
160  // Matrix m transforms from homogeneous pixel coordinates to world
161  // coordinates so x and y need to be multiplied by z. In the case of the
162  // first point, the eye point, z=0, so x and y will be zero, too regardless
163  // of their initial values as the center.
164  lines->points_.push_back(mult(m, Eigen::Vector3d{0.0, 0.0, 0.0}));
165  lines->points_.push_back(mult(m, Eigen::Vector3d{0.0, 0.0, scale}));
166  lines->points_.push_back(mult(m, Eigen::Vector3d{w * scale, 0.0, scale}));
167  lines->points_.push_back(
168  mult(m, Eigen::Vector3d{w * scale, h * scale, scale}));
169  lines->points_.push_back(mult(m, Eigen::Vector3d{0.0, h * scale, scale}));
170 
171  lines->lines_.push_back({0, 1});
172  lines->lines_.push_back({0, 2});
173  lines->lines_.push_back({0, 3});
174  lines->lines_.push_back({0, 4});
175  lines->lines_.push_back({1, 2});
176  lines->lines_.push_back({2, 3});
177  lines->lines_.push_back({3, 4});
178  lines->lines_.push_back({4, 1});
179  lines->PaintUniformColor({0.0f, 0.0f, 1.0f});
180 
181  // Add XYZ axes
182  lines->points_.push_back(
183  mult(m, Eigen::Vector3d{intrinsic(0, 0) * scale, 0.0, 0.0}));
184  lines->points_.push_back(
185  mult(m, Eigen::Vector3d{0.0, intrinsic(1, 1) * scale, 0.0}));
186  lines->points_.push_back(
187  mult(m, Eigen::Vector3d{intrinsic(0, 2) * scale,
188  intrinsic(1, 2) * scale, scale}));
189 
190  // Add lines for the axes
191  lines->lines_.push_back({0, 5}); // X axis (red)
192  lines->lines_.push_back({0, 6}); // Y axis (green)
193  lines->lines_.push_back({0, 7}); // Z axis (blue)
194 
195  // Set colors for the axes
196  lines->colors_.push_back({1.0f, 0.0f, 0.0f}); // Red
197  lines->colors_.push_back({0.0f, 1.0f, 0.0f}); // Green
198  lines->colors_.push_back({0.0f, 0.0f, 1.0f}); // Blue
199 
200  return lines;
201 }
202 
203 } // namespace geometry
204 } // namespace cloudViewer
geometry::LineSet * lineset_ptr
Definition: LineSetIO.cpp:25
core::Tensor result
Definition: VtkUtils.cpp:76
Bounding box structure.
Definition: ecvBBox.h:25
std::vector< Eigen::Vector3d > GetBoxPoints() const
Returns the eight points that define the bounding box.
Definition: ecvBBox.cpp:119
Triangular mesh.
Definition: ecvMesh.h:35
virtual unsigned size() const override
Returns the number of triangles.
Definition: ecvMesh.cpp:2143
std::vector< Eigen::Vector3d > getEigenVertices() const
Definition: ecvMesh.cpp:2368
cloudViewer::VerticesIndexes * getTriangleVertIndexes(unsigned triangleIndex) override
Returns the indexes of the vertices of a given triangle.
Definition: ecvMesh.cpp:2599
A 3D cloud and its associated features (color, normals, scalar fields, etc.)
Eigen::Vector3d GetColor() const
Gets the bounding box color.
Definition: BoundingBox.h:267
std::vector< Eigen::Vector3d > GetBoxPoints() const
const Eigen::Vector3d & GetColor() const
Gets the bounding box color.
unsigned size() const override
Definition: PointCloudTpl.h:38
Eigen::Vector3d getEigenPoint(size_t index) const
static std::shared_ptr< LineSet > CreateFromTetraMesh(const TetraMesh &mesh)
static std::shared_ptr< LineSet > CreateFromOrientedBoundingBox(const ecvOrientedBBox &box)
Factory function to create a LineSet from an OrientedBoundingBox.
static std::shared_ptr< LineSet > CreateFromPointCloudCorrespondences(const ccPointCloud &cloud0, const ccPointCloud &cloud1, const std::vector< std::pair< int, int >> &correspondences)
Factory function to create a LineSet from two PointClouds (cloud0, cloud1) and a correspondence set.
static std::shared_ptr< LineSet > CreateFromTriangleMesh(const ccMesh &mesh)
static std::shared_ptr< LineSet > CreateCameraVisualization(int view_width_px, int view_height_px, const Eigen::Matrix3d &intrinsic, const Eigen::Matrix4d &extrinsic, double scale=1.0)
static std::shared_ptr< LineSet > CreateFromAxisAlignedBoundingBox(const ccBBox &box)
Factory function to create a LineSet from an ccBBox.
Tetra mesh contains vertices and tetrahedra represented by the indices to the vertices.
Definition: ecvTetraMesh.h:29
std::vector< Eigen::Vector4i, cloudViewer::utility::Vector4i_allocator > tetras_
List of tetras denoted by the index of points forming the tetra.
Definition: ecvTetraMesh.h:108
std::vector< Eigen::Vector3d > vertices_
Vertex coordinates.
Definition: ecvMeshBase.h:132
Generic file read and write utility for python interface.
Eigen::Matrix< Index, 2, 1 > Vector2i
Definition: knncpp.h:29
Triangle described by the indexes of its 3 vertices.