I want to do stl file decimation in parallel, so I tried vtkBinnedDecimation
. The simplified fineness is bad than what using vtkQuadricDecimation
.
The origin STL file is 7.3M:
porsche.zip (3.0 MB)
Test using vtkBinnedDecimation
#define GLOG_NO_ABBREVIATED_SEVERITIES
#include <glog/logging.h>
#include <gtest/gtest.h>
#include <vtkBinnedDecimation.h>
#include <vtkSTLReader.h>
#include <vtkSTLWriter.h>
#include <vtkSmartPointer.h>
#include <boost/dll.hpp>
#include <chrono>
#include <cmath>
#include <filesystem>
namespace fs = std::filesystem;
TEST(VTK, binnedDecimation) {
const auto dir_path = boost::dll::program_location().parent_path();
const auto input_stl_path = fs::path(dir_path.string()) / "input.stl";
const auto output_stl_path = fs::path(dir_path.string()) / "output.stl";
const auto t0 = std::chrono::steady_clock::now();
const double decimation_ratio = 3;
// Read the input mesh
vtkSmartPointer<vtkSTLReader> reader = vtkSmartPointer<vtkSTLReader>::New();
reader->SetFileName(input_stl_path.c_str());
reader->Update();
vtkSmartPointer<vtkPolyData> inputMesh = reader->GetOutput();
const auto input_mesh_num = inputMesh->GetNumberOfCells();
const auto input_mesh_axis_num = std::pow(input_mesh_num, 1.0 / 3.0);
const auto dim = input_mesh_axis_num / std::pow(decimation_ratio, 1.0 / 3.0);
LOG(INFO) << "input mesh num: " << input_mesh_num << ". input mesh num per axis: " << input_mesh_axis_num << ". dim "
<< dim << std::endl;
// Create the decimation filter
auto mesh0 = vtkSmartPointer<vtkBinnedDecimation>::New();
mesh0->SetInputData(inputMesh);
mesh0->AutoAdjustNumberOfDivisionsOn();
mesh0->SetNumberOfDivisions(dim, dim, dim);
mesh0->ProducePointDataOn();
mesh0->ProduceCellDataOn();
mesh0->Update();
// Write the decimated mesh
vtkSmartPointer<vtkSTLWriter> writer = vtkSmartPointer<vtkSTLWriter>::New();
writer->SetFileName(output_stl_path.c_str());
writer->SetInputConnection(mesh0->GetOutputPort());
writer->Write();
const auto t1 = std::chrono::steady_clock::now();
const auto dur = std::chrono::duration_cast<std::chrono::milliseconds>(t1 - t0).count();
LOG(INFO) << "vtkQuadricDecimation time: " << dur << " ms\n";
}
The simplified stl file is 4.2M:
Test using vtkQuadricDecimation
#define GLOG_NO_ABBREVIATED_SEVERITIES
#include <glog/logging.h>
#include <gtest/gtest.h>
#include <vtkPolyData.h>
#include <vtkQuadricDecimation.h>
#include <vtkSTLReader.h>
#include <vtkSTLWriter.h>
#include <vtkSmartPointer.h>
#include <boost/dll.hpp>
#include <chrono>
#include <filesystem>
namespace fs = std::filesystem;
TEST(VTK, DECIMATION) {
const auto dir_path = boost::dll::program_location().parent_path();
const auto input_stl_path = fs::path(dir_path.string()) / "input.stl";
const auto t0 = std::chrono::steady_clock::now();
auto reader = vtkSmartPointer<vtkSTLReader>::New();
reader->SetFileName(input_stl_path.c_str());
reader->Update();
vtkSmartPointer<vtkPolyData> inputMesh = reader->GetOutput();
// 2. do decimation
vtkSmartPointer<vtkQuadricDecimation> decimationFilter = vtkSmartPointer<vtkQuadricDecimation>::New();
decimationFilter->SetInputData(inputMesh);
decimationFilter->SetTargetReduction(0.5); // Set the desired reduction factor
decimationFilter->Update();
vtkSmartPointer<vtkPolyData> outputMesh = decimationFilter->GetOutput();
// 3. output decimation meshes to output stl file
auto writer = vtkSmartPointer<vtkSTLWriter>::New();
const auto output_stl_path = fs::path(dir_path.string()) / "output.stl";
writer->SetFileName(output_stl_path.c_str());
writer->SetFileTypeToBinary();
writer->SetInputData(outputMesh);
writer->Write();
const auto t1 = std::chrono::steady_clock::now();
const auto dur = std::chrono::duration_cast<std::chrono::milliseconds>(t1 - t0).count();
LOG(INFO) << "vtkQuadricDecimation time: " << dur << " ms\n";
}
The simplified stl file is 3.7M:
Compare two simplified stl files
vtkBinnedDecimation
get less vertices / faces than vtkQuadricDecimation
, but the result stl file is large than what generated by vtkQuadricDecimation
.
Does any suggestions for the test code ?