Add vtkSurfaceNetsAtlas
vtkSurfaceNetsAtlas is a new filter that consumes the polygonal output of any SurfaceNets filter
(vtkSurfaceNets2D, vtkSurfaceNets3D, or vtkGeneralizedSurfaceNets3D) and exposes it as a
queryable label atlas: a database of Regions (one per label) and Patches (one per adjacent label
pair) that can be efficiently re-queried without re-running upstream surface extraction.
The atlas is built once per input mesh change (gated on the input vtkPolyData MTime). Changing
extraction parameters does not trigger a rebuild, making iterative workflows (e.g. interactive label
visibility toggling) inexpensive.
Output
The filter produces a vtkPartitionedDataSetCollection with a vtkDataAssembly organized into two
subtrees: Regions (one PDS per label) and Patches (one PDS per adjacent label pair). Assembly
node names default to Label_N / Label_N_Label_M and are replaced by user-provided names when
set. Each node carries Name, Label, LID attributes (regions) or Name0, Name1, Label0,
Label1, LID0, LID1 (patches).
Each output partition carries identifying cell-data arrays so downstream consumers can work without the assembly:
- Region:
"BoundaryLabels"(2-component, active scalar; Label0 is always the region's own label so normals point outward),"Label"(vtkIdType, constant),"LID"(int, constant). Field data:"AdjacentLabels"(vtkIdType[]),"PatchIDs"(int[]). - Patch:
"BoundaryLabels"(2-component, active scalar; Label0 < Label1 by value, background last),"PatchID"(int, constant). - PDC field data:
"LIDToLabel"(vtkIdType[]),"PatchLIDs"(2-componentint),"PatchLabels"(2-componentvtkIdType). All three are always present.
Constant arrays are backed by vtkConstantArray (O(1) storage).
Extraction
GenerateRegions(default: on) emits one Region PDS per selected label.GeneratePatches(default: on) emits one Patch PDS per adjacent label pair where at least one label is selected.OutputStyle(default:Boundary) controls which cells appear in each Region:Boundary: only cells whose interface touches the background label. Combined withGeneratePatches, this forms an exact partition of the upstream output — no cell duplication, same total count.All: every cell of the region surface, so interior interface cells appear in both adjacent Region partitions.
ExtractionMode(default:EXTRACT_ALL) selects which labels are emitted:EXTRACT_ALL: every label in the input.EXTRACT_LABEL_SET: only labels in theSelectedLabelslist (empty list → empty output).
SelectedLabelsAPI:AddSelectedLabel,RemoveSelectedLabel,ClearSelectedLabels,SetSelectedLabel(i, label),GetSelectedLabel(i),SetSelectedLabels(vector),GetSelectedLabels(), andGetNumberOfSelectedLabels().GenerateSelectedLabels(numLabels, rangeStart, rangeEnd)populates the selection with evenly spaced integer labels (analogous tovtkContourValues::GenerateValues). The two-argument overloadGenerateSelectedLabels(rangeStart, rangeEnd)selects every integer in the range, covering the common case of sequential segmentation labels.
Label names
SetLabelName / AddLabelName / RemoveLabelName / ClearLabelNames / GetLabelName /
GetNumberOfLabelNames assign human-readable names to labels. Names are independent of the
SelectedLabels list and work with both extraction modes. They replace the default "Label_N" /
"Label_N_Label_M" assembly node names and are stored as "Name" / "Name0" / "Name1"
attributes on each node. Default names are filled in automatically at atlas build time for any label
without a user-provided name.
Topological queries
Post-Update() queries cover labelGetNumberOfLabels, HasLabel, GetLIDForLabel, GetLabelForLID, GetLabelForName,
AreAdjacent, GetAdjacentLabels, GetNumberOfPatches, GetPatchID, GetPatchLabels,
GetPatchCellCount, GetPatchesForLabel. All methods that accept a label value also have a
const std::string& name-based overload that resolves via GetLabelForName.
Optional post-processing
ResolveNonManifoldPoints splits non-manifold points in each output partition by local connected
component. If the input carries a NonManifoldTableIndices point-data array (produced by
vtkSurfaceNets3D), only candidate points are processed; otherwise all points are scanned. The
array is never forwarded to output partitions.
The following supporting changes were made:
-
vtkSurfaceNets3Ddeprecations:OUTPUT_STYLE_BOUNDARYandOUTPUT_STYLE_SELECTED, along with the associatedSelectedLabelsAPI, are deprecated in VTK 9.7 in favor of usingvtkSurfaceNetsAtlasdownstream. For backward compatibility these code paths now delegate internally to avtkSurfaceNetsAtlasinstance and merge the per-label partitions back into a singlevtkPolyDatausingvtkAppendPolyData. -
vtkGeneralizedSurfaceNets3Ddispatch: now dispatches over the concrete scalar type of the region-ids input array (viavtkArrayDispatch) instead of requiringvtkIntArray. Any integer array type (vtkShortArray,vtkIntArray,vtkLongArray, etc.) is handled natively without a copy. -
Consistent
"BoundaryLabels"convention:vtkSurfaceNets2DandvtkGeneralizedSurfaceNets3Dwere updated to name the boundary-label cell-data array"BoundaryLabels"and to use a consistent 2-tuple ordering (background label last; smaller label first when both are non-background), matchingvtkSurfaceNets3D.vtkGeneralizedSurfaceNets3Dalso reverses polygon winding when swapping labels to preserve outward-facing normals.