-
Notifications
You must be signed in to change notification settings - Fork 2.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
VTK based implementation of extract trianglemesh #6648
base: main
Are you sure you want to change the base?
Changes from all commits
90b6b39
631908d
9a60f78
b70ee45
0c4795b
b37a8e1
2890ec9
3b6d9a4
8cb8894
e1743dc
f8c94a1
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -16,6 +16,22 @@ | |
#include "open3d/utility/Helper.h" | ||
#include "open3d/utility/Parallel.h" | ||
|
||
#include <vtkPolyData.h> | ||
#include <vtkSmartPointer.h> | ||
#include <vtkFlyingEdges3D.h> | ||
#include <vtkMarchingCubes.h> | ||
#include "open3d/t/geometry/VtkUtils.h" | ||
|
||
#include <vtkPolyData.h> | ||
#include <vtkImageData.h> | ||
#include <vtkPointData.h> | ||
#include <vtkFloatArray.h> | ||
#include <vtkSmartPointer.h> | ||
#include <vtkFlyingEdges3D.h> | ||
#include <vtkMarchingCubes.h> | ||
#include <vtkInformation.h> | ||
#include <vtkPolyDataConnectivityFilter.h> | ||
|
||
namespace open3d { | ||
namespace pipelines { | ||
namespace integration { | ||
|
@@ -138,6 +154,64 @@ std::shared_ptr<geometry::PointCloud> UniformTSDFVolume::ExtractPointCloud() { | |
return pointcloud; | ||
} | ||
|
||
std::shared_ptr<geometry::TriangleMesh> | ||
UniformTSDFVolume::ExtractTriangleMesh_v2() { | ||
auto mesh = std::make_shared<geometry::TriangleMesh>(); | ||
//float *image_array = new float[resolution_ * resolution_ * resolution_]; | ||
//const long r_sq = resolution_ * resolution_; | ||
int dims[] = {resolution_, resolution_, resolution_}; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Use std::array or modern containers, or explicitly declare array size. |
||
float ***values = new float **[dims[0]]; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. All pointers are allocated but not released. It's better to allocate a flattened std::vector and unroll the indices. |
||
for(int i = 0; i <= dims[1]; ++i) { | ||
values[i] = new float *[dims[2]]; | ||
for (int j = 0; j <= dims[1]; ++j) { | ||
values[i][j] = new float[dims[2]]; | ||
} | ||
} | ||
|
||
for (int x = 0; x < resolution_ - 1; x++) { | ||
for (int y = 0; y < resolution_ - 1; y++) { | ||
for (int z = 0; z < resolution_ - 1; z++) { | ||
Eigen::Vector3i idx0(x, y, z); | ||
const float f = voxels_[IndexOf(idx0)].tsdf_; | ||
values[x][y][z] = f; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Only TSDF is used here, weights are not handled, see the original implementation. This is known to provide problematic mesh especially around boundaries. |
||
} | ||
} | ||
} | ||
vtkIdType totalSize = (vtkIdType)dims[0] * (vtkIdType) dims[1] * (vtkIdType) dims[2]; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Use static_cast. |
||
vtkNew<vtkFloatArray> array; | ||
array->SetArray(**values, totalSize, 1); | ||
vtkNew<vtkInformation> info; | ||
vtkNew<vtkImageData> imageData; | ||
imageData->GetPointData()->SetScalars(array); | ||
imageData->SetDimensions(dims); | ||
imageData->SetScalarType(VTK_UNSIGNED_SHORT, info); | ||
imageData->SetSpacing(1.0, 1.0, 1.0); | ||
imageData->SetOrigin(0.0, 0.0, 0.0); | ||
|
||
#ifdef USE_FLYING_EDGES | ||
vtkNew<vtkFlyingEdges3D> surface; | ||
#else | ||
vtkNew<vtkMarchingCubes> surface; | ||
#endif | ||
surface->SetInputData(imageData); | ||
surface->ComputeNormalsOn(); | ||
const double isoValue = 0.0; | ||
surface->SetValue(0, isoValue); | ||
|
||
//// To remain largest region. | ||
//// vtkNew<vtkPolyDataConnectivityFilter> confilter; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Either remove unused code or add a flag to run the code. |
||
//// confilter->SetInputConnection(surface->GetOutputPort()); | ||
//// confilter->SetExtractionModeToLargestRegion(); | ||
//// vtkPolyData *pdata = confilter->GetOutput(); | ||
//// cout << "pdata: " << pdata << std::endl; | ||
vtkPolyData *sdata = surface->GetOutput(); | ||
auto tmesh = open3d::t::geometry::vtkutils::CreateTriangleMeshFromVtkPolyData(sdata); | ||
auto lmesh = tmesh.ToLegacy(); | ||
std::shared_ptr<geometry::TriangleMesh> pmesh(new geometry::TriangleMesh(lmesh.vertices_, lmesh.triangles_)); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Memory is copied twice in the conversion. It is also unsafe to use new to initialize a shared_ptr. Please use std::make_shared and reduce redundant memory copy. |
||
return pmesh; | ||
} | ||
|
||
|
||
std::shared_ptr<geometry::TriangleMesh> | ||
UniformTSDFVolume::ExtractTriangleMesh() { | ||
// implementation of marching cubes, based on | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -52,6 +52,8 @@ class UniformTSDFVolume : public TSDFVolume { | |
const Eigen::Matrix4d &extrinsic) override; | ||
std::shared_ptr<geometry::PointCloud> ExtractPointCloud() override; | ||
std::shared_ptr<geometry::TriangleMesh> ExtractTriangleMesh() override; | ||
/// Temporary function will be deleted/"merged" with ExtractTriangleMesh | ||
std::shared_ptr<geometry::TriangleMesh> ExtractTriangleMesh_v2(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It would be better to inject the implementation as an option in |
||
|
||
/// Debug function to extract the voxel data into a VoxelGrid | ||
std::shared_ptr<geometry::PointCloud> ExtractVoxelPointCloud() const; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -136,6 +136,8 @@ In SIGGRAPH, 1996)"); | |
"Debug function to inject the voxel TSDF data.", "tsdf"_a) | ||
.def("inject_volume_color", &UniformTSDFVolume::InjectVolumeColor, | ||
"Debug function to inject the voxel Color data.", "color"_a) | ||
// TODO remove after debugging | ||
.def("extract_triangle_mesh_v2", &UniformTSDFVolume::ExtractTriangleMesh_v2) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same, do not duplicate API. |
||
.def_readwrite("length", &UniformTSDFVolume::length_, | ||
"Total length, where ``voxel_length = length / " | ||
"resolution``.") | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove unused comments.