bwoodsend/vtkplotlib

Display overlapping meshes

Closed this issue · 2 comments

I am trying to display a mesh and "highlight" a part of the mesh in a different color.
The highlighted part of the mesh has been anotated as a separate STL file.

When I run the following code,

import vtkplotlib as vpl
from stl.mesh import Mesh

# path = "if you have an STL file then put it's path here."
# Otherwise vtkplotlib comes with a small STL file for demos/testing.
path = vpl.data.get_rabbit_stl()

# Read the STL using numpy-stl
mesh = Mesh.from_file(path)


mesh2 = Mesh.from_file(r"\path\to\part_of_stl.stl")

# Plot the mesh
vpl.mesh_plot(mesh)
vpl.mesh_plot(mesh2, color="orange")

# Show the figure
vpl.show()

it produces the result captured in this screenshot

Capture d’écran 2021-01-22 144610

I understand that VTK tries to display both meshes on top of each other and since they have the same coordinates there is a display artefact.

How would you implement a method to avoid such problems?

Many thanks

Additionnal info

Python: 3.7.0
vtkplotlib : 1.4.0
VTK : 9.0.1
numpy : 1.19.5

I use anaconda but I installed vtkplotlib with pip
Tested on Windows 10

If you want to reporduce the bug, the file part_of_stl.stl is the following :
https://github.com/redoules/vtkplotlib/raw/master/part_of_stl.stl

There's some strange coincident topology VTK API but I've never gotten it to work. If I understand the VTK docs correctly it only applies to lines coinciding with facets anyway.

I've always done it manually by either sucking in or pushing out the facets slightly. It's not ideal but visually, it does the trick.

import numpy as np
from stl.mesh import Mesh
import vtkplotlib as vpl

# Load the rabbit.
mesh = Mesh.from_file(vpl.data.get_rabbit_stl())
# And copy half of it into another mesh.
subsample = Mesh(mesh.data[mesh.y[:, 0] > mesh.y.mean()])

# Plot the whole mesh slightly sucked in by subtracting its
# normal multplied by a small scalar (0.01).
vpl.mesh_plot(mesh.vectors - mesh.units[:, np.newaxis] * .01)
# Plot the submesh as is.
vpl.mesh_plot(subsample, color="r")

vpl.show()

Bear in mind that most of the work will be done using 32-bit floats so don't go nuts and set the scaling factor to 1e-12.

Thanks for the reply.

Indeed it does the trick.

For futur reference, I tried a method where I removed the coincident triangles of the mesh but it required and extra dependence (numpy-indexed)

import numpy_indexed as npi

def remove_coincident(mesh1, mesh2):
    """
    returns a mesh similar to mesh1 but with the coincident triangles between mesh1 and mesh2 removed
    """
    
    mesh = Mesh(np.zeros(npi.difference(mesh1.points, mesh2.points).shape[0], dtype=Mesh.dtype))
    mesh.points = npi.difference(mesh1.points, mesh2.points)
    return mesh