【VTK】基于VTK的扩展ACVD实现网格重新划分网格Remeshing

07-10 1025阅读

很高兴在雪易的CSDN遇见你 

VTK技术爱好者 QQ:870202403      公众号:VTK忠粉


前言

本文分享基于VTK的扩展ACVD实现网格重新划分网格Remeshing,希望对各位小伙伴有所帮助!

感谢各位小伙伴的点赞+关注,小易会继续努力分享,一起进步!

你的点赞就是我的动力(^U^)ノ~YO

目录

前言

1. 重新划分网格Remeshing的效果

2. 基于VTK实现的ACVD

3. Remeshing源码分享

结论:


1. 重新划分网格Remeshing的效果

【VTK】基于VTK的扩展ACVD实现网格重新划分网格Remeshing

在3D图形处理时,通常需要进行网格的重新划分。医学图形处理时通常使用VTK作为图形处理和渲染显示的库。

分享过关于CGAL实现Remeshing的方法,详情见:

【CGAL系列】Remesh—1 Isotropic_remeshing_example_cgal remeshing-CSDN博客

这里,我们分享基于VTK如何进行网格重新划分Remeshing。 

2. 基于VTK实现的ACVD

网站链接:ACVD | Sébastien Valette (insa-lyon.fr)

源码:ACVD

 ACVD库基于VTK进行扩展,为三角形网格提供一种快速高效的网格简化/重采样方法。可以应用于非常复杂的网格(数百万个顶点)。这种方法基于变分框架内的输入网格单元的聚类。这种聚类方法类似于质心的分区Voronoi区域,其中每个区域具有相同的大小,因此表面的采样非常均匀,并且对生成的三角进行测量具有良好的纵横比。

这种方法对于重新划分网格程序也很有用。

基于斯坦福兔子的聚类方法

【VTK】基于VTK的扩展ACVD实现网格重新划分网格Remeshing

3. Remeshing源码分享

.h文件

#pragma once
#include 
#include 
class zxExampleRemeshing :
    public QObject
{
public:
    zxExampleRemeshing(QWidget* parent = nullptr);
    bool ValidateSurface(vtkPolyData* surface);
    vtkPolyData* Remesh(vtkPolyData* surface,
        int numVertices,
        double gradation,
        int subsampling,
        double edgeSplitting,
        int optimizationLevel,
        bool forceManifold,
        bool boundaryFixing);
    void Remeshing();
};

.cpp文件

#include "zxExampleRemeshing.h"
#include "vtkSTLReader.h"
#include "vtkSTLWriter.h"
#include "vtkTriangleFilter.h"
#include "vtkCellData.h"
#include "vtkPointData.h"
#include 
#include 
#include 
#include 
#include 
#include "vtkSurface.h"
#include "vtkIsotropicDiscreteRemeshing.h"
#include "vtkIsotropicMetricForClustering.h"
#include "vtkQuadricTools.h"
struct ClustersQuadrics final
{
    explicit ClustersQuadrics(size_t size)
        : Elements(size),
        Size(size)
    {
        for (auto& array : Elements)
            array.fill(0.0);
    }
    ~ClustersQuadrics() = default;
    ClustersQuadrics(const ClustersQuadrics&) = delete;
    ClustersQuadrics& operator=(const ClustersQuadrics&) = delete;
    std::vector Elements;
    size_t Size;
};
zxExampleRemeshing::zxExampleRemeshing(QWidget* parent)
{
}
bool zxExampleRemeshing::ValidateSurface(vtkPolyData* surface)
{
    if (nullptr == surface) return false;
    if (surface->GetNumberOfPoints() SetInputData(surface);
    tri->Update();
    surface->DeepCopy(tri->GetOutput());
    if (surface->GetNumberOfPolys() GetNumberOfPoints();
    }
    if (edgeSplitting != 0.0)
        mesh->SplitLongEdges(edgeSplitting);
    std::cout SetGradation(gradation);
    remesher->SetBoundaryFixing(boundaryFixing);
    remesher->SetConsoleOutput(1);
    remesher->SetForceManifold(forceManifold);
    remesher->SetInput(mesh);
    remesher->SetNumberOfClusters(numVertices);
    remesher->SetSubsamplingThreshold(subsampling);
    remesher->Remesh();
    std::cout GetInput();
        int clusteringType = remesher->GetClusteringType();
        int numItems = remesher->GetNumberOfItems();
        int numMisclassifiedItems = 0;
        for (int i = 0; i GetValue(i);
            if (cluster >= 0 && cluster GetVertexNeighbourFaces(i, faceList);
                    int numIds = static_cast(faceList->GetNumberOfIds());
                    for (int j = 0; j GetId(j), false);
                }
                else
                {
                    vtkQuadricTools::AddTriangleQuadric(clustersQuadrics.Elements[cluster].data(), remesherInput, i, false);
                }
            }
            else
            {
                ++numMisclassifiedItems;
            }
        }
        std::cout ComputePointNormalsOn();
    normals->ConsistencyOff();
    normals->FlipNormalsOff();
    normals->NonManifoldTraversalOff();
    normals->SplittingOff();
    normals->Update();
    auto remeshedSurface = vtkPolyData::New();
    remeshedSurface->DeepCopy(normals->GetOutput());
    std::cout  reader;
	reader->SetFileName("D:\\Data\\Remeshing\\implant.stl");
	reader->Update();
    vtkPolyData* polyData = vtkPolyData::New();
    polyData->DeepCopy(reader->GetOutput());
    std::cout GetCellData()->Initialize();
    mesh->GetPointData()->Initialize();
    mesh->DisplayMeshProperties();
    int density = 50;
    int numVertices = std::max(100, static_cast(polyData->GetNumberOfPoints() * density * 0.01));
    QString remeshingType = "Adaptive"; // Adaptive or Regular
    double gradation = remeshingType == QStringLiteral("Adaptive") ? 1.0 : 0.0;
    const QString quality = "Medium (fast)";
    int subsampling;
    if (QStringLiteral("High (slow)") == quality)
    {
        subsampling = 50;
    }
    else if (QStringLiteral("Maximum (very slow)") == quality)
    {
        subsampling = 500;
    }
    else // The default is "Medium (fast)".
    {
        subsampling = 10;
    }
    bool boundingFixing = true;
    double edgeSplitting = 0.;
    double optimizationLevel = 1.0;
    if (numVertices == 0)
    {
        numVertices = polyData->GetNumberOfPoints();
    }
    if (edgeSplitting != 0.0)
        mesh->SplitLongEdges(edgeSplitting);
    std::cout SetGradation(gradation);
    remesher->SetBoundaryFixing(boundingFixing);
    remesher->SetConsoleOutput(1);
    remesher->SetForceManifold(false);
    remesher->SetInput(mesh);
    remesher->SetNumberOfClusters(numVertices);
    remesher->SetSubsamplingThreshold(subsampling);
    remesher->Remesh();
    std::cout GetInput();
        int clusteringType = remesher->GetClusteringType();
        int numItems = remesher->GetNumberOfItems();
        int numMisclassifiedItems = 0;
        for (int i = 0; i GetValue(i);
            if (cluster >= 0 && cluster GetVertexNeighbourFaces(i, faceList);
                    int numIds = static_cast(faceList->GetNumberOfIds());
                    for (int j = 0; j GetId(j), false);
                }
                else
                {
                    vtkQuadricTools::AddTriangleQuadric(clustersQuadrics.Elements[cluster].data(), remesherInput, i, false);
                }
            }
            else
            {
                ++numMisclassifiedItems;
            }
        }
        std::cout ComputePointNormalsOn();
    normals->ConsistencyOff();
    normals->FlipNormalsOff();
    normals->NonManifoldTraversalOff();
    normals->SplittingOff();
    normals->Update();
    auto remeshedSurface = vtkPolyData::New();
    remeshedSurface->DeepCopy(normals->GetOutput());
    std::cout 
VPS购买请点击我

文章版权声明:除非注明,否则均为主机测评原创文章,转载或复制请以超链接形式并注明出处。

目录[+]