Skip to content

Segfault on render

It seems that trying to render a big point cloud (at least when doing it through Python) crashes with the segfault: Windows fatal exception: access violation.

The code I used to reproduce it below (you might need to adjust number of points based on your system).

Running with VTK Version: 9.4.2 and Python: 3.11.12.

I am not sure how to gracefully handle such situations on my end. I have enough RAM, so it seems that the issue is not really with the amount of memory.

Is this the expected behavior of VTK? Is there way to pre-check whether the render of some point cloud has enough resources (whatever causes the fatal exception...) so that the app which uses VTK does not silently crash?

import numpy as np
import vtk
from vtk.util import numpy_support
import gc
import sys
import os
import faulthandler 

faulthandler.enable()

def mre_large_points():
    """
    Attempt 1: Create a very large point cloud to trigger memory issues.
    This mimics your real-world scenario with massive datasets.
    """
    print("=== MRE Attempt 1: Large Point Cloud ===")
    
    # Create progressively larger point clouds until we hit the limit
    base_points = 10_000_000
    multipliers = [1, 5, 10, 20, 50, 100, 200]  # Scale up until crash
    
    for mult in multipliers:
        n_points = base_points * mult
        print(f"Testing with {n_points:,} points ({n_points * 3 * 8 / 1e9:.2f} GB for coordinates alone)")
        
        try:
            # Create random point cloud
            points = np.random.rand(n_points, 3).astype(np.float64) * 1000
            colors = np.random.randint(0, 255, (n_points, 3), dtype=np.uint8)
            intensity = np.random.rand(n_points).astype(np.float64)
            
            print(f"  Created arrays, RSS: {get_memory_mb():.1f}MB")
            
            # Create VTK objects
            vtk_points = vtk.vtkPoints()
            vtk_points.SetData(numpy_support.numpy_to_vtk(points, deep=True))
            
            intensity_vtk = numpy_support.numpy_to_vtk(intensity, deep=True)
            intensity_vtk.SetName("Intensity")
            
            rgb_vtk = numpy_support.numpy_to_vtk(colors, deep=True)
            rgb_vtk.SetNumberOfComponents(3)
            rgb_vtk.SetName("RGB")
            
            print(f"  Created VTK arrays, RSS: {get_memory_mb():.1f}MB")
            
            # Create polydata
            poly_data = vtk.vtkPolyData()
            poly_data.SetPoints(vtk_points)
            poly_data.GetPointData().AddArray(intensity_vtk)
            poly_data.GetPointData().SetScalars(rgb_vtk)
            
            print(f"  Created polydata, RSS: {get_memory_mb():.1f}MB")
            
            # Create vertex filter (this often crashes)
            vertex_filter = vtk.vtkVertexGlyphFilter()
            vertex_filter.SetInputData(poly_data)
            vertex_filter.Update()
            
            print(f"  Vertex filter done, RSS: {get_memory_mb():.1f}MB")
            
            # Create mapper and actor
            mapper = vtk.vtkPolyDataMapper()
            mapper.SetInputConnection(vertex_filter.GetOutputPort())
            
            actor = vtk.vtkActor()
            actor.SetMapper(mapper)
            
            print(f"  Actor created, RSS: {get_memory_mb():.1f}MB")
            
            # Try to render (this is where crashes often happen)
            renderer = vtk.vtkRenderer()
            render_window = vtk.vtkRenderWindow()
            render_window.SetOffScreenRendering(1)  # Don't need actual display
            render_window.AddRenderer(renderer)
            
            renderer.AddActor(actor)
            renderer.ResetCamera()
            
            print(f"  About to render...")
            render_window.Render()  # CRASH LIKELY HERE
            print(f"  Render successful! RSS: {get_memory_mb():.1f}MB")
            
            # Clean up
            del points, colors, intensity
            del vtk_points, intensity_vtk, rgb_vtk
            del poly_data, vertex_filter, mapper, actor
            del renderer, render_window
            gc.collect()
            
        except Exception as e:
            print(f"  CRASHED at {n_points:,} points: {e}")
            return n_points
        
    print("No crash occurred - your system is more robust than expected!")
    return None


def get_memory_mb():
    """Quick memory check."""
    import psutil
    return psutil.Process(os.getpid()).memory_info().rss / (1024**2)


def run_all_mre_attempts():
    """Run all MRE attempts to try to reproduce the crash."""
    print("Starting VTK crash MRE attempts...")
    print(f"Initial memory: {get_memory_mb():.1f}MB")
    print(f"VTK Version: {vtk.vtkVersion.GetVTKVersion()}")
    print(f"Python: {sys.version}")
    print("-" * 60)
    try:
        crash_point = mre_large_points()
    except Exception as e:
        print(f"\nUNEXPECTED ERROR in MRE: {e}")
        import traceback
        traceback.print_exc()


if __name__ == "__main__":
    run_all_mre_attempts()