The post shows a way to remesh a model to make uneven triangles on the mesh to be more uniform.

#include <iostream>
#include <vtkSmartPointer.h>
#include <vtkSphereSource.h>
#include <vtkActor.h>
#include <vtkConeSource.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkPolyDataMapper.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkSTLReader.h>
#include <vtkCleanPolyData.h>
#include <vtkPolyDataToImageStencil.h>
#include <vtkImageData.h>
#include <vtkImageStencil.h>
#include <vtkImageMarchingCubes.h>
#include <vtkFillHolesFilter.h>
#include <vtkPolyDataNormals.h>
#include <vtkPointData.h>
#include <vtkXMLPolyDataWriter.h>

#define vtkSPtr vtkSmartPointer
#define vtkSPtrNew(Var, Type) vtkSPtr<Type> Var = vtkSPtr<Type>::New();

using namespace std;

vtkSPtr<vtkPolyData> GetRemeshPd(vtkSPtr<vtkPolyData> polydata)
{
    if( nullptr == polydata )
    {
        return nullptr;
    }
    // --------------------- polydata to image -----------------------
    double spacingVal = 0.2;
    int togetherExtentSize = 3;
    unsigned char imageInVal = 255;
    unsigned char imageOutVal = 0;
    double bounds[6];
    polydata->GetBounds(bounds);


    int dim[3];
    for (int i = 0; i < 3; i++)
    {
        dim[i] = static_cast<int>( ceil((bounds[2 * i + 1] - bounds[2 * i]) / spacingVal) ) + togetherExtentSize;
    }
    double origin[3];
    origin[0] = bounds[0] - spacingVal * togetherExtentSize / 2;
    origin[1] = bounds[2] - spacingVal * togetherExtentSize / 2;
    origin[2] = bounds[4] - spacingVal * togetherExtentSize / 2;


    vtkSPtrNew(imageData, vtkImageData);
    imageData->SetSpacing(spacingVal, spacingVal, spacingVal);
    imageData->SetDimensions(dim);
    imageData->SetOrigin(origin);
    imageData->AllocateScalars(VTK_UNSIGNED_CHAR, 1);
    imageData->GetPointData()->GetScalars()->Fill(imageInVal);


    // polygonal data --> imageData stencil:
    vtkSPtrNew(pd2stenc, vtkPolyDataToImageStencil);
    pd2stenc->SetInputData(polydata);
    pd2stenc->SetOutputOrigin(origin);
    pd2stenc->SetOutputSpacing(spacingVal, spacingVal, spacingVal);
    pd2stenc->SetOutputWholeExtent(imageData->GetExtent());
    pd2stenc->Update();


    // cut the corresponding white imageData and set the background:
    vtkSPtrNew(imgstenc, vtkImageStencil);
    imgstenc->SetInputData(imageData);
    imgstenc->SetStencilConnection(pd2stenc->GetOutputPort());
    imgstenc->ReverseStencilOff();
    imgstenc->SetBackgroundValue( imageOutVal );
    imgstenc->Update();


    imageData->DeepCopy(imgstenc->GetOutput());


    // -------------------------- image to polydata --------------------------------
    vtkSPtrNew( marchingCubes, vtkImageMarchingCubes );
    marchingCubes->SetInputData( imageData );
    marchingCubes->SetValue( 0, (imageInVal + imageOutVal)/2 );
marchingCubes->SetComputeNormals(0);
marchingCubes->SetComputeGradients(0);
    marchingCubes->SetNumberOfContours( 1 );
    marchingCubes->Update();


    // Fill the holes
    vtkSPtrNew( fillHoles, vtkFillHolesFilter );
    fillHoles->SetInputData( marchingCubes->GetOutput() );
    fillHoles->SetHoleSize( 1000000 );
    fillHoles->Update();

    vtkSPtrNew( cleanFilter, vtkCleanPolyData );
    cleanFilter->SetInputData( fillHoles->GetOutput() );
    cleanFilter->Update();

    // Make the triangle winding order consistent
    vtkSPtrNew( normals, vtkPolyDataNormals );
    normals->SetInputData( cleanFilter->GetOutput() );
    normals->ConsistencyOn();
    normals->SplittingOff();
    normals->GetOutput()->GetPointData()->SetNormals(
        marchingCubes->GetOutput()->GetPointData()->GetNormals());
    normals->Update();


    vtkSPtrNew( result, vtkPolyData );
    result->DeepCopy( normals->GetOutput() );

    return result;
}

int main()
{
    vtkSPtrNew( reader, vtkSTLReader );
    reader->SetFileName( "locker.stl" );
    reader->Update();

    auto inputData = reader->GetOutput();
    auto newData = GetRemeshPd( inputData );

    vtkSPtrNew(writer1, vtkXMLPolyDataWriter);
    writer1->SetInputData( newData );
    writer1->SetFileName("newData.vtp");
    writer1->Write();

    return 0;
}

The 3D model file locker.stl can be downloaded at the page:
https://www.weiy.city/downloads/3d-model-simple-lock/ .

Compare the original mesh and the new data in paraview:

Categories: VTK

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Inline Feedbacks
View all comments

Tex To PDF
: convert the Latex file which suffix is tex to a PDF file

X
0
Would love your thoughts, please comment.x
()
x