pythonmeshvtkpyvistatrimesh

How to stitch two meshes together along overlapping seams without altering other parts of the meshes?


I'm trying to join two meshes together into one single mesh. The boundary edges of both overlap perfectly, but they do not have the same spacing - thus, all faces touching the seams need to be deleted and then all the points from those faces (including those along the seam) need to be re-triangulated to close the gap.

See an example of the two meshes:

The blue area here is very fine mesh 1 Here the seam is exaggerated 2

There is a coarse mesh and a dense mesh as you can see from the first image. I need to stitch these two together along the seams.

The problem is that the seams can be very random and hard to generalize.

I also have the condition that I can't do a constrained delaunay and re-triangulate everything because there are parts of my mesh where z != F(x,y) , and this gets messed up by the delaunay. I can only modify the faces touching the seams.

Preferably a vtk based solution if anyone can help?

I've tried vtk.vtkDelaunay2D to re-mesh.

I also tried vtk.vtkFeatureEdges to extract the edges. Then tried to split the boundary points into segments, find which segments overlapping with the other mesh segments and using Delaunay on sets of segments something like this:

3

which didnt work since the seams are overlapping perfectly I think?

I got vtk.vtkDecimatePro to work fine but I don't want to actually modify the mesh. I only want to stitch the seams.

If anyone has any ideas, I'm running out.


Solution

  • I ended up modifying my approach, but hopefully it helps someone.

    The original goal here was to take a high resolution mesh, and pass over it with a predefined grid size - if cells in a given grid square pass a certain test, then the grid square is kept instead of the original cells. This way, after checking all the squares, a portion of the mesh can have a drastically reduced resolution.

    Whole goal here was to only reduce resolution in certain custom defined areas (not static areas either, but rule based).

    Most of the solution is not pertinent to this question so I will just describe:

    -group cells based on which grid squares their centroids land in

    -decide which grid squares to keep (and thus which original cells to downsample)

    -group together all the cells you want to downsample, and all the cells you want to keep (split the mesh into two parts)

    -use vtk.vtkDecimatePro on on the part you want to downsample, and make sure you turn off boundary vertex deletion

    -after downsampling, both meshes still have the same boundary so simply concatenate the meshes back together

    The relevant bits of code are:

    import vtk
    
    def decimate_polydata(polydata, 
                          reduction=0.5, 
                          error=0.01, 
                          accumulate_error=False,
                          degree=25,
                          feature=15,
                          splitting=True):
        '''
        Function to decimate a VTK polydata object
        '''
        deci = vtk.vtkDecimatePro()
        deci.SetTargetReduction(reduction)
        deci.PreserveTopologyOn()
        deci.SetFeatureAngle(feature)
        deci.SetSplitting(splitting)
        deci.SetErrorIsAbsolute(1)
        deci.SetAccumulateError(accumulate_error)
        deci.SetMaximumError(error)
        deci.SetDegree(degree)
        deci.BoundaryVertexDeletionOff() #this is the key!!
        deci.SetInputData(polydata)
        deci.Update()
        deci = deci.GetOutput()
        return deci
    
    def merge_polydata(polydatas):
        '''
        Function to append/merge two VTK polydata objects together
        pt and cell indexing is updated automatically
        '''
        poly = vtk.vtkAppendPolyData()
        for polydata in polydatas:
            poly.AddInputData(polydata)
        poly.Update()
        poly = poly.GetOutput()
        return poly
    

    The result is similar to what I had previously, but instead of there being squares in the coarse areas, it's just decimated:

    enter image description here enter image description here