Skip to content

Fix vtkCutter and add test for ContourLoopExtraction - #3637

Open
Jo-Byr wants to merge 3 commits into
Kitware:masterfrom
Jo-Byr:fix-cutter
Open

Jo-Byr wants to merge 3 commits into
Kitware:masterfrom
Jo-Byr:fix-cutter

Conversation

@Jo-Byr

@Jo-Byr Jo-Byr commented Sep 7, 2026

Copy link
Copy Markdown
Contributor

Context

vtkCutter yields invalid results if the plane intersects a point of the cut mesh. This is visible on vtkContourLoopExtraction's example where the loop extraction returns 8 loops (visibly 3: pink, green, pink but each actually has multiple layers under).

Screenshot 2026-09-07 154550

Results

By properly handling cases where the plane intersects a point, we can fix the issue and have only 2 loops (red and green):

image

Changes

Properly differentiate the 3 cases: negative sign, null sign (on plane) and positive sign

Dedupe points, result of a same point being counted twice.

image

For the green triangle, intersected in one of its vertices by the red plane, 2 edges will be counted as intersected on the same position.

Added a non-regression test on ContourLoopExtraction

Modified ContourLoopExtraction example's parameters to fit with the model's bounds.

PR Checklist

  • GitHub Actions CI passed: semantic-release commit messages, lint, and tests
  • Test coverage added
  • Documentation and TypeScript definitions are updated to match these changes

@Jo-Byr
Jo-Byr requested a review from finetjul September 7, 2026 13:58
@Jo-Byr Jo-Byr self-assigned this Sep 7, 2026
Comment thread Sources/Filters/Core/Cutter/index.js Outdated
Comment thread Sources/Filters/Core/Cutter/index.js Outdated
Comment thread Sources/Filters/Core/Cutter/index.js Outdated
@finetjul

finetjul commented Sep 7, 2026

Copy link
Copy Markdown
Member

Does it mean the VTK C++ implementation also has the problem ? If so, please report a bug in VTK

Fix bug in vtkCutter where the output would be invalid if the cutting
plane intersecting a point of the input mesh
Change initial values and bounds of example's parameters to allow
exploring the mesh properly
@Jo-Byr

Jo-Byr commented Sep 8, 2026

Copy link
Copy Markdown
Contributor Author

Does it mean the VTK C++ implementation also has the problem ? If so, please report a bug in VTK

I didn't look into the C++ implementation but it does not produce this invalid result, I used a local python vtk as a truth test.

@sankhesh sankhesh left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM with a couple of questions

Comment thread Sources/Filters/General/ContourLoopExtraction/test/testContourLoopExtraction.js Outdated
for (let i = 1; i < it.cell.length; i++) {
const sideCurrentPoint = cellPointsScalars[i] > 0;
for (let i = 0; i < it.cell.length; i++) {
if (i === firstPointIdx) {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This new sign()-based crossing detection is definitely better than what we had before but I'm curious what would happen if all points of the cell are exactly on the cut plane? I'd assume firstPointIdx remains null. It might be a good test case too.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tested with a cube and it works fine with a cut plane in the same plane as one of the faces since their points will be discovered when testing the intersection of other cells that share these points.

The only case where I can see it failing is a single cell whose points are not shared with any other cell, that is colinear to the plane. But even if we added a fallback firstPointIdx = firstPointIdx ?? 0 it would get caught by allPointsSameSide.

@finetjul

finetjul commented Sep 9, 2026

Copy link
Copy Markdown
Member

Does it mean the VTK C++ implementation also has the problem ? If so, please report a bug in VTK

I didn't look into the C++ implementation but it does not produce this invalid result, I used a local python vtk as a truth test.

Isn't the vtkCutter JS implementation a port of the VTK C++ implementation ? Maybe it would be wise to check how it differs...

@Jo-Byr

Jo-Byr commented Sep 10, 2026

Copy link
Copy Markdown
Contributor Author

Isn't the vtkCutter JS implementation a port of the VTK C++ implementation ? Maybe it would be wise to check how it differs...

From my understanding of the C++ implementation, it has a special implementation for plane cutting with vtkPlaneCutter, itself going into vtkPolyDataPlaneCutter if the inputData is a polydata, and a generic DatasetCutter method for cutting a vtkPolyData by something else than a plane.

This method itself uses vtkContourHelper to get the contour out of the evaluated cutter function on every point of the input data that indirectly falls back to vtkTriangle::Contour that finds intersection points along edges and draws a line between them.

It all relies on the cut scalars indirectly. For plane cutter it uses a triple state too:

// Point is either above(=2), below(=1), or on(=0) the plane.
// NOLINTNEXTLINE(readability-avoid-nested-conditional-operator)
*inOutItr = (eval > zero ? 2 : (eval < zero ? 1 : 0));

I don't know if it's generic in C++ but it seems a natural approach to me.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants