11 #include <tinyfiledialogs/tinyfiledialogs.h>
21 utility::LogInfo(
" Ctrl + S : Save current alignment session into a JSON file.");
22 utility::LogInfo(
" Ctrl + O : Load current alignment session from a JSON file.");
23 utility::LogInfo(
" Ctrl + A : Align point clouds based on manually annotations.");
25 utility::LogInfo(
" Ctrl + D : Run voxel downsample for both source and target.");
26 utility::LogInfo(
" Ctrl + K : Load a polygon from a JSON file and crop source.");
32 std::shared_ptr<ccPointCloud> source,
33 std::shared_ptr<ccPointCloud> target) {
45 GLFWwindow *window,
int key,
int scancode,
int action,
int mods) {
46 if (action == GLFW_PRESS && (mods & GLFW_MOD_CONTROL)) {
48 const char *pattern[1] = {
"*.json"};
58 std::string default_alignment =
62 "Alignment session", default_alignment.c_str(), 1,
63 pattern,
"JSON file (*.json)");
65 filename = default_alignment.c_str();
73 std::string default_alignment =
77 "Alignment session", default_alignment.c_str(), 1,
78 pattern,
"JSON file (*.json)", 0);
80 filename = default_alignment.c_str();
98 const char *str = tinyfd_inputBox(
100 "Set max correspondence distance for ICP (ignored "
101 "if it is non-positive)",
109 double l = std::strtod(str, &end);
110 if (errno == ERANGE &&
111 (l == HUGE_VAL || l == -HUGE_VAL)) {
113 "Illegal input, use default max "
114 "correspondence distance.");
122 "ICP with max correspondence distance {:.4f}.",
127 Eigen::Matrix4d::Identity(),
128 pipelines::registration::
129 TransformationEstimationPointToPoint(
true),
133 "Registration finished with fitness {:.4f} and "
136 if (
result.fitness_ > 0.0) {
145 "No ICP performed due to illegal max "
146 "correspondence distance.");
153 const char *str = tinyfd_inputBox(
155 "Set voxel size (ignored if it is non-positive)",
163 double l = std::strtod(str, &end);
164 if (errno == ERANGE &&
165 (l == HUGE_VAL || l == -HUGE_VAL)) {
167 "Illegal input, use default voxel size.");
181 "No voxel downsample performed due to illegal "
189 if (
const char *polygon_filename_chars =
190 tinyfd_openFileDialog(
191 "Bounding polygon",
"polygon.json",
192 0,
nullptr,
nullptr, 0)) {
194 std::string(polygon_filename_chars);
197 "Internal error: tinyfd_openFileDialog "
198 "returned nullptr.");
204 auto polygon_volume = std::make_shared<
216 std::string default_alignment =
220 "Alignment session", default_alignment.c_str(), 1,
221 pattern,
"JSON file (*.json)");
223 filename = default_alignment.c_str();
270 if (source_idx.empty() || target_idx.empty() ||
271 source_idx.size() != target_idx.size()) {
273 "# of picked points mismatch: {:d} in source, {:d} in "
275 (
int)source_idx.size(), (
int)target_idx.size());
281 for (
size_t i = 0; i < source_idx.size(); i++) {
318 std::string source_filename =
321 std::string target_filename =
324 std::string source_binname =
327 std::string target_binname =
341 fwrite(source_dis.data(),
sizeof(
double), source_dis.size(), f);
352 fwrite(target_dis.data(),
sizeof(
double), target_dis.size(), f);
filament::Texture::InternalFormat format
std::shared_ptr< ccPointCloud > source_ptr_
double max_correspondence_distance_
std::shared_ptr< ccPointCloud > target_ptr_
std::vector< size_t > source_indices_
Eigen::Matrix4d_u transformation_
std::vector< size_t > target_indices_
std::shared_ptr< ccPointCloud > target_copy_ptr_
bool LoadSessionFromFile(const std::string &filename)
visualization::VisualizerWithEditing & target_visualizer_
double max_correspondence_distance_
AlignmentSession alignment_session_
bool AlignWithManualAnnotation()
visualization::VisualizerWithEditing & source_visualizer_
bool AddSourceAndTarget(std::shared_ptr< ccPointCloud > source, std::shared_ptr< ccPointCloud > target)
std::string polygon_filename_
Eigen::Matrix4d transformation_
std::shared_ptr< ccPointCloud > source_copy_ptr_
void KeyPressCallback(GLFWwindow *window, int key, int scancode, int action, int mods) override
void EvaluateAlignmentAndSave(const std::string &filename)
void PrintVisualizerHelp() override
bool SaveSessionToFile(const std::string &filename)
void PrintTransformation()
std::string default_directory_
Class that defines the convergence criteria of ICP.
double point_size_
Point size for PointCloud.
Select a polygon volume for cropping.
std::vector< size_t > & GetPickedPoints()
virtual bool UpdateGeometry(std::shared_ptr< const ccHObject > geometry_ptr=nullptr)
Function to update geometry.
virtual void KeyPressCallback(GLFWwindow *window, int key, int scancode, int action, int mods)
RenderOption & GetRenderOption()
Function to retrieve the associated RenderOption.
virtual void UpdateRender()
Function to inform render needed to be updated.
void ResetViewPoint(bool reset_bounding_box=false)
Function to reset view point.
virtual bool AddGeometry(std::shared_ptr< const ccHObject > geometry_ptr, bool reset_bounding_box=true)
Function to add geometry to the scene and create corresponding shaders.
virtual void PrintVisualizerHelp()
bool WriteIJsonConvertible(const std::string &filename, const cloudViewer::utility::IJsonConvertible &object)
bool WritePointCloud(const std::string &filename, const ccPointCloud &pointcloud, const WritePointCloudOption ¶ms)
bool ReadIJsonConvertible(const std::string &filename, cloudViewer::utility::IJsonConvertible &object)
std::vector< Eigen::Vector2i > CorrespondenceSet
RegistrationResult RegistrationICP(const ccPointCloud &source, const ccPointCloud &target, double max_correspondence_distance, const Eigen::Matrix4d &init, const TransformationEstimation &estimation, const ICPConvergenceCriteria &criteria)
Functions for ICP registration.
std::string GetFileNameWithoutExtension(const std::string &filename)
bool FileExists(const std::string &filename)
FILE * FOpen(const std::string &filename, const std::string &mode)
Generic file read and write utility for python interface.
Eigen::Matrix< Index, 2, 1 > Vector2i