ACloudViewer  3.9.4
A Modern Library for 3D Data Processing
Visualization.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 
11 
12 namespace cloudViewer {
13 namespace t {
14 namespace pipelines {
15 namespace slac {
16 
17 static const Eigen::Vector3d kSourceColor = Eigen::Vector3d(0, 1, 0);
18 static const Eigen::Vector3d kTargetColor = Eigen::Vector3d(1, 0, 0);
19 static const Eigen::Vector3d kCorresColor = Eigen::Vector3d(0, 0, 1);
20 
21 static Eigen::Vector3d Jet(double v, double vmin, double vmax) {
22  Eigen::Vector3d c(1, 1, 1);
23  double dv;
24 
25  if (v < vmin) v = vmin;
26  if (v > vmax) v = vmax;
27  dv = vmax - vmin;
28 
29  if (v < (vmin + 0.25 * dv)) {
30  c(0) = 0;
31  c(1) = 4 * (v - vmin) / dv;
32  } else if (v < (vmin + 0.5 * dv)) {
33  c(0) = 0;
34  c(2) = 1 + 4 * (vmin + 0.25 * dv - v) / dv;
35  } else if (v < (vmin + 0.75 * dv)) {
36  c(0) = 4 * (v - vmin - 0.5 * dv) / dv;
37  c(2) = 0;
38  } else {
39  c(1) = 1 + 4 * (vmin + 0.75 * dv - v) / dv;
40  c(2) = 0;
41  }
42 
43  return c;
44 }
45 
47  const t::geometry::PointCloud& tpcd_j,
48  const core::Tensor correspondences,
49  const core::Tensor& T_ij) {
50  Eigen::Matrix4d flip;
51  flip << 1, 0, 0, 0, 0, -1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 1;
52 
53  core::Tensor correspondences_host =
54  correspondences.To(core::Device("CPU:0"));
55 
56  auto pcd_i_corres = std::make_shared<cloudViewer::geometry::PointCloud>(
57  tpcd_i.Clone().Transform(T_ij).ToLegacy());
58  pcd_i_corres->PaintUniformColor(kSourceColor);
59  pcd_i_corres->Transform(flip);
60 
61  auto pcd_j_corres = std::make_shared<cloudViewer::geometry::PointCloud>(
62  tpcd_j.ToLegacy());
63  pcd_j_corres->PaintUniformColor(kTargetColor);
64  pcd_j_corres->Transform(flip);
65 
66  std::vector<std::pair<int, int>> corres_lines;
67  for (int i = 0; i < correspondences_host.GetLength(); ++i) {
68  corres_lines.push_back(
69  std::make_pair(correspondences_host[i][0].Item<int64_t>(),
70  correspondences_host[i][1].Item<int64_t>()));
71  }
72  auto lineset =
74  *pcd_i_corres, *pcd_j_corres, corres_lines);
75  lineset->PaintUniformColor(kCorresColor);
76 
77  visualization::DrawGeometries({pcd_i_corres, pcd_j_corres, lineset});
78 }
79 
81  ControlGrid& ctr_grid,
82  bool show_lines) {
83  Eigen::Matrix4d flip;
84  flip << 1, 0, 0, 0, 0, -1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 1;
85 
86  // Prepare all ctr grid point cloud for lineset
87  auto pcd = std::make_shared<cloudViewer::geometry::PointCloud>(
88  tpcd_param.ToLegacy());
89  pcd->Transform(flip);
90 
91  t::geometry::PointCloud tpcd_grid(
92  ctr_grid.GetCurrPositions().Slice(0, 0, ctr_grid.Size()));
93  auto pcd_grid = std::make_shared<cloudViewer::geometry::PointCloud>(
94  tpcd_grid.ToLegacy());
95  pcd_grid->Transform(flip);
96 
97  // Prepare nb point cloud for visualization
99  .To(core::Device("CPU:0"), core::Int64);
100  t::geometry::PointCloud tpcd_grid_nb(
101  tpcd_grid.GetPointPositions().IndexGet({corres.View({-1})}));
102 
103  auto pcd_grid_nb = std::make_shared<cloudViewer::geometry::PointCloud>(
104  tpcd_grid_nb.ToLegacy());
105  pcd_grid_nb->PaintUniformColor(kSourceColor);
106  pcd_grid_nb->Transform(flip);
107 
108  visualization::DrawGeometries({pcd, pcd_grid_nb}, "Point cloud embedding");
109 
110  // Prepare n x 8 corres for visualization
111  std::vector<std::pair<int, int>> corres_lines;
112  for (int64_t i = 0; i < corres.GetLength(); ++i) {
113  for (int k = 0; k < 8; ++k) {
114  std::pair<int, int> pair = {i, corres[i][k].Item<int64_t>()};
115  corres_lines.push_back(pair);
116  }
117  }
118  auto lineset =
120  *pcd, *pcd_grid, corres_lines);
121 
122  core::Tensor corres_interp =
123  tpcd_param.GetPointAttr(ControlGrid::kGrid8NbVertexInterpRatios)
124  .To(core::Device("CPU:0"));
125  for (int64_t i = 0; i < corres.GetLength(); ++i) {
126  for (int k = 0; k < 8; ++k) {
127  float ratio = corres_interp[i][k].Item<float>();
128  Eigen::Vector3d color = Jet(ratio, 0, 0.5);
129  lineset->colors_.push_back(color);
130  }
131  }
132 
133  // Ensure raw pcd is visible
134  pcd->PaintUniformColor({0, 0, 0});
135  visualization::DrawGeometries({lineset, pcd, pcd_grid_nb},
136  "Point cloud embedding");
137 }
138 
140  ControlGrid& ctr_grid) {
141  Eigen::Matrix4d flip;
142  flip << 1, 0, 0, 0, 0, -1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 1;
143 
144  core::Tensor corres = tpcd_param.GetPointAttr(ControlGrid::kGrid8NbIndices)
145  .To(core::Device("CPU:0"), core::Int64)
146  .View({-1});
147 
148  core::Tensor prev = ctr_grid.GetInitPositions().IndexGet({corres});
149  core::Tensor curr = ctr_grid.GetCurrPositions().IndexGet({corres});
150 
151  t::geometry::PointCloud tpcd_init_grid(prev);
152  auto pcd_init_grid = std::make_shared<cloudViewer::geometry::PointCloud>(
153  tpcd_init_grid.ToLegacy());
154  pcd_init_grid->PaintUniformColor({0, 1, 0});
155  pcd_init_grid->Transform(flip);
156 
157  auto pcd = std::make_shared<cloudViewer::geometry::PointCloud>(
158  tpcd_param.ToLegacy());
159  pcd->PaintUniformColor({0, 1, 0});
160  pcd->Transform(flip);
161 
162  t::geometry::PointCloud tpcd_curr_grid(curr);
163  auto pcd_curr_grid = std::make_shared<cloudViewer::geometry::PointCloud>(
164  tpcd_curr_grid.ToLegacy());
165  pcd_curr_grid->PaintUniformColor({1, 0, 0});
166  pcd_curr_grid->Transform(flip);
167 
168  auto tpcd_warped = ctr_grid.Deform(tpcd_param);
169  auto pcd_warped = std::make_shared<cloudViewer::geometry::PointCloud>(
170  tpcd_warped.ToLegacy());
171  pcd_warped->PaintUniformColor({1, 0, 0});
172  pcd_warped->Transform(flip);
173 
174  std::vector<std::pair<int, int>> deform_lines;
175  for (size_t i = 0; i < pcd_init_grid->size(); ++i) {
176  deform_lines.push_back(std::make_pair(i, i));
177  }
178  auto lineset =
180  *pcd_init_grid, *pcd_curr_grid, deform_lines);
181 
183  {pcd, pcd_warped, pcd_init_grid, pcd_curr_grid, lineset},
184  "Point cloud deformation");
185 }
186 
188  core::Tensor indices, indices_nb, masks_nb;
189  std::tie(indices, indices_nb, masks_nb) = cgrid.GetNeighborGridMap();
190 
191  core::Device host("CPU:0");
192  indices = indices.To(host);
193  indices_nb = indices_nb.To(host);
194  masks_nb = masks_nb.To(host);
195 
196  int64_t n = cgrid.Size();
197  core::Tensor prev = cgrid.GetInitPositions().Slice(0, 0, n);
198  core::Tensor curr = cgrid.GetCurrPositions().Slice(0, 0, n);
199 
200  t::geometry::PointCloud tpcd_init_grid(prev);
201  auto pcd_init_grid = std::make_shared<cloudViewer::geometry::PointCloud>(
202  tpcd_init_grid.ToLegacy());
203  pcd_init_grid->PaintUniformColor({0, 1, 0});
204 
205  t::geometry::PointCloud tpcd_curr_grid(curr);
206  auto pcd_curr_grid = std::make_shared<cloudViewer::geometry::PointCloud>(
207  tpcd_curr_grid.ToLegacy());
208  pcd_curr_grid->PaintUniformColor({1, 0, 0});
209 
210  std::vector<std::pair<int, int>> nb_lines;
211  for (int64_t i = 0; i < indices.GetLength(); ++i) {
212  for (int j = 0; j < 6; ++j) {
213  if (masks_nb[i][j].Item<bool>()) {
214  nb_lines.push_back(std::make_pair(
215  indices[i].Item<int>(), indices_nb[i][j].Item<int>()));
216  }
217  }
218  }
219 
220  {
221  auto lineset_init = cloudViewer::geometry::LineSet::
223  *pcd_init_grid, nb_lines);
224  auto lineset_curr = cloudViewer::geometry::LineSet::
226  *pcd_curr_grid, nb_lines);
228  {pcd_init_grid, pcd_curr_grid, lineset_init, lineset_curr},
229  "Grid Deformation");
230  }
231 }
232 
233 } // namespace slac
234 } // namespace pipelines
235 } // namespace t
236 } // namespace cloudViewer
math::float4 color
int64_t GetLength() const
Definition: Tensor.h:1125
Tensor IndexGet(const std::vector< Tensor > &index_tensors) const
Advanced indexing getter. This will always allocate a new Tensor.
Definition: Tensor.cpp:905
Tensor Slice(int64_t dim, int64_t start, int64_t stop, int64_t step=1) const
Definition: Tensor.cpp:857
Tensor To(Dtype dtype, bool copy=false) const
Definition: Tensor.cpp:739
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.
A point cloud contains a list of 3D points.
Definition: PointCloud.h:82
core::Tensor & GetPointPositions()
Get the value of the "positions" attribute. Convenience function.
Definition: PointCloud.h:124
cloudViewer::geometry::PointCloud ToLegacy() const
Convert to a legacy CloudViewer PointCloud.
PointCloud Clone() const
Returns copy of the point cloud on the same device.
Definition: PointCloud.cpp:123
const TensorMap & GetPointAttr() const
Getter for point_attr_ TensorMap. Used in Pybind.
Definition: PointCloud.h:111
PointCloud & Transform(const core::Tensor &transformation)
Transforms the PointPositions and PointNormals (if exist) of the PointCloud.
Definition: PointCloud.cpp:171
static const std::string kGrid8NbVertexInterpRatios
8 neighbor grid interpolation ratio for vertex per point.
Definition: ControlGrid.h:36
static const std::string kGrid8NbIndices
Definition: ControlGrid.h:34
geometry::PointCloud Deform(const geometry::PointCloud &pcd)
Non-rigidly deform a point cloud using the control grid.
core::Tensor GetInitPositions()
Get control grid original positions directly from tensor keys.
Definition: ControlGrid.h:104
std::tuple< core::Tensor, core::Tensor, core::Tensor > GetNeighborGridMap()
const Dtype Int64
Definition: Dtype.cpp:47
CLOUDVIEWER_HOST_DEVICE Pair< First, Second > make_pair(const First &_first, const Second &_second)
Definition: SlabTraits.h:49
static const Eigen::Vector3d kCorresColor
void VisualizePointCloudEmbedding(t::geometry::PointCloud &tpcd_param, ControlGrid &ctr_grid, bool show_lines)
void VisualizePointCloudCorrespondences(const t::geometry::PointCloud &tpcd_i, const t::geometry::PointCloud &tpcd_j, const core::Tensor correspondences, const core::Tensor &T_ij)
Visualize pairs with correspondences.
static const Eigen::Vector3d kTargetColor
void VisualizeGridDeformation(ControlGrid &cgrid)
void VisualizePointCloudDeformation(const geometry::PointCloud &tpcd_param, ControlGrid &ctr_grid)
static const Eigen::Vector3d kSourceColor
static Eigen::Vector3d Jet(double v, double vmin, double vmax)
bool DrawGeometries(const std::vector< std::shared_ptr< const ccHObject >> &geometry_ptrs, const std::string &window_name, int width, int height, int left, int top, bool point_show_normal, bool mesh_show_wireframe, bool mesh_show_back_face, Eigen::Vector3d *lookat, Eigen::Vector3d *up, Eigen::Vector3d *front, double *zoom)
Function to draw a list of geometry objects.
Generic file read and write utility for python interface.