Repository navigation
Deterministic vtkSMPTools clustering; input polydata left untouched - #55
JensMunkHansen wants to merge 2 commits into
Conversation
Threaded clustering (vtkThreadedClustering, used by ACVDP / ACVDQP / AnisotropicRemeshingQP) now runs on vtkSMPTools instead of a vtkMultiThreader pool. Each loop runs the regions in greedy rounds (region index order) whose regions share no cluster and no edge, then the edges between regions alone. The schedule no longer depends on measured run times or on the number of threads, and the per-cluster mutexes are gone, so the result is the same for every backend and thread count. The region count is items / max(ItemsPerRegion, 8 x cluster size); ItemsPerRegion (default 512) replaces PoolingRatio (ACVDQP: -ipr replaces -p). The per-edge calls of the clustering loop are static instead of virtual: the most-derived class is passed down as a template parameter (Derived) through vtkSurfaceClustering / vtkDiscreteRemeshing to vtkThreadedClustering. vtkIsotropicDiscreteRemeshing, vtkQIsotropicDiscreteRemeshing and vtkAnisotropicDiscreteRemeshing pass themselves; the AnisotropicRemeshing tools use a small VerticesRemeshing<Metric> class for the same purpose. vtkUniformClustering::ReComputeStatistics and the polynomial fitting in vtkCurvatureMeasure use vtkSMPTools instead of OpenMP / vtkMultiThreader (vtkCurvatureMeasure::SetNumberOfThreads is removed). No OpenMP is left; the examples no longer look for it. The tools select the STDThread backend (VTK builds default to Sequential, and TBB is often not available); -np sets the vtkSMPTools thread count. vtkSurfaceBase::CreateFromPolyData always copies the polygons. They were shared with the caller's polydata through the shallow copy whenever they were already in 64-bit storage, and CheckNormals() reoriented the caller's cells in place. Checked (tooth 32k vertices and a lower jaw scan, 3000 vertices, gradation 1.5): - ACVDP, ACVDQP, AnisotropicRemeshingQP: byte-identical output over the Sequential, STDThread and TBB backends and 1, 4, 16 threads (upstream ACVDQP gives a different mesh on every run). Jaw ACVDQP 3.7 s at 1 thread, 1.0 s at 16. - ACVD, ACVDQ, AnisotropicRemeshing, AnisotropicRemeshingQ: byte-identical to the unmodified tools. - A polydata with flipped triangles passed to CreateFromPolyData and remeshed: connectivity changed before, points and connectivity unchanged now. Note, not addressed here: AnisotropicRemeshing and AnisotropicRemeshingQ segfault on the tooth mesh (1000 vertices, gradation 1.5 or 0) in vtkUniformClustering<vtkAnisotropicMetricForClustering>::ReComputeStatistics, called from MinimizeEnergy. The unmodified upstream tools crash the same way (the jaw scan runs fine with both), so this predates this change. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
I kept your I/O stuff inside some classes (I do not have stuff like this). But without it, you tests couldn't execute. It is now deterministic, it is using SMPTools and input are not overwritten. |
Found with valgrind --leak-check=full on ACVD, ACVDQ, ACVDP and ACVDQP (tooth mesh, 3000 vertices, gradation 1.5); all four now report 0 bytes lost and 0 errors, with byte-identical output. - vtkQEMetricForClustering never freed Items (allocated in BuildMetric; 3.3 MB on the tooth). It is now initialised to 0 and deleted in the destructor, as vtkIsotropicMetricForClustering does. - vtkSinglePolynomialMeasure allocated SecondMember[i] with new double and freed it with delete [] (1600 mismatched frees per run). - vtkThreadedClustering::ComputeEdgesLayout never freed its EdgesLayout array; it is now a std::vector moved into EdgesProcess. - vtkSurface::WriteToFile never deleted its writer. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Thank you for this PR. I will probably pull the memory leak fixes, but I have some questions:
Mesh with 10000000 polygons, 4999996 points, 15000000 edges Computing Curvature ........
Could you split the modifications in different PRs? The threading code does not seem mature enough to be pulled right now anyway. |
|
One could also allocate differently. The issue was a new / delete mismatch.
…On Thu, Nov 5, 2026 at 1:15 PM Sébastien Valette ***@***.***> wrote:
*valette* left a comment (valette/ACVD#55)
<#55 (comment)>
Thank you for this PR. I will probably pull the memory leak fixes, but I
have some questions:
1. What is this fix for?
- SecondMember[i]= new double;
- SecondMember[i]= new double[1];
2. on my box (14 cores, 64GB RAM), processing a large mesh crashes
(OOM):
bin/ACVDQP ~/data/meshes/xyzrgb_statuette.ply 200000 1.5
load : /home/valette/data/meshes/xyzrgb_statuette.ply
------------------------------
Mesh with 10000000 polygons, 4999996 points, 15000000 edges
Bounding Box: [-117.973, -190.474, -99.8223]
[117.251, 205.567, 103.339]
The mesh is made only of 10000000 triangles
0 non-manifold edges and 0 boundary edges
The mesh has 1 connected components
Vertex valence entropy: 1.93073
0 disconnected vertices, 5e+06 connected vertices
55.5547 percent of irregular vertices
Mesh geometry quality:
AngleMin=0.000926766
AverageMinAngle=39.256
Qmin=1.40081e-05
Qav=0.731144
Angles bellow 30 (%)=6.62604
------------------------------
Computing Curvature ........
The curvature indicator calculation took :9.11181 seconds.
Indicators Range : 0.000339764 39.5465
Input mesh: 4999996 vertices and 10000000 faces
Creating 9765 Regions for thread pooling...done
Multithreading layout computed in :2.19295 seconds
Processus arrêté bin/ACVDQP ~/data/meshes/xyzrgb_statuette.ply 200000 1.5
3. About the CreateFromPolyData : indeed the original mesh is indeed
modified, but this was for memory efficiency purpose. As the ACVD
executables run on their own, it is not a problem for them. But if you use
vtkSurface from an other code, maybe a simple solution is to clone the
polydata via DeepCOPY?
Could you split the modifications in different PRs? The threading code
does not seem mature enough to be pulled right now anyway.
—
Reply to this email directly, view it on GitHub
<#55?email_source=notifications&email_token=ABQJKYTPYAK4JW56YWD3EKL5XRVM5A5CNFSNUABFM5UWIORPF5TWS5BNNB2WEL2JONZXKZKDN5WW2ZLOOQXTMNRVG43TEMRZHE3KM4TFMFZW63VGMF2XI2DPOKSWK5TFNZ2KYZTPN52GK4S7MNWGSY3L#issuecomment-6657722996>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/ABQJKYRWUAF7O45VHPSMOZ35XRVM5AVCNFSNUABCKJSXA33TNF2G64TZHM4DQNJYGAZDWSLTON2WKOZWGIYTKNJTGA4DKOFBOYBA>
.
Triage notifications, keep track of coding agent tasks and review pull
requests on the go with GitHub Mobile for iOS
<https://github.com/notifications/mobile/ios/ABQJKYVM5QILLOLTBXMALBD5XRVM5A5CNFSNUABFM5UWIORPF5TWS5BNNB2WEL2JONZXKZKDN5WW2ZLOOQXTMNRVG43TEMRZHE3KM4TFMFZW63VGMF2XI2DPOKSWK5TFNZ2KUZTPN52GK4S7NFXXG>
and Android
<https://github.com/notifications/mobile/android/ABQJKYT2Z562I444ZHFR74D5XRVM5A5CNFSNUABFM5UWIORPF5TWS5BNNB2WEL2JONZXKZKDN5WW2ZLOOQXTMNRVG43TEMRZHE3KM4TFMFZW63VGMF2XI2DPOKSWK5TFNZ2K4ZTPN52GK4S7MFXGI4TPNFSA>.
Download it today!
You are receiving this because you authored the thread.Message ID:
***@***.***>
|
|
Will do
I work with a very different port.
Writing I/O inside classes is a nasty mesh, modifying input is a violation
of the VTK pipeline.
I can probably ask the AI to split it into just fixing the actual bugs in
one PR. There were quite a few, non-determinism and leaks are not the worst
of them. I switched to using SMP, since I could use TBB, STDThread and
Sequential. Then one can easily check determinism. Single-threaded must be
the same at MT.
Would you like a single PR, where just bugs are fixed.
Jens
On Thu, Nov 5, 2026 at 2:02 PM Jens Munk Hansen ***@***.***>
wrote:
… One could also allocate differently. The issue was a new / delete mismatch.
On Thu, Nov 5, 2026 at 1:15 PM Sébastien Valette ***@***.***>
wrote:
> *valette* left a comment (valette/ACVD#55)
> <#55 (comment)>
>
> Thank you for this PR. I will probably pull the memory leak fixes, but I
> have some questions:
>
> 1. What is this fix for?
>
>
> - SecondMember[i]= new double;
>
>
> - SecondMember[i]= new double[1];
>
>
> 2. on my box (14 cores, 64GB RAM), processing a large mesh crashes
> (OOM):
> bin/ACVDQP ~/data/meshes/xyzrgb_statuette.ply 200000 1.5
> load : /home/valette/data/meshes/xyzrgb_statuette.ply
>
> ------------------------------
>
> Mesh with 10000000 polygons, 4999996 points, 15000000 edges
> Bounding Box: [-117.973, -190.474, -99.8223]
> [117.251, 205.567, 103.339]
> The mesh is made only of 10000000 triangles
> 0 non-manifold edges and 0 boundary edges
> The mesh has 1 connected components
> Vertex valence entropy: 1.93073
> 0 disconnected vertices, 5e+06 connected vertices
> 55.5547 percent of irregular vertices
> Mesh geometry quality:
> AngleMin=0.000926766
> AverageMinAngle=39.256
> Qmin=1.40081e-05
> Qav=0.731144
> Angles bellow 30 (%)=6.62604
> ------------------------------
>
> Computing Curvature ........
> The curvature indicator calculation took :9.11181 seconds.
> Indicators Range : 0.000339764 39.5465
> Input mesh: 4999996 vertices and 10000000 faces
> Creating 9765 Regions for thread pooling...done
> Multithreading layout computed in :2.19295 seconds
> Processus arrêté bin/ACVDQP ~/data/meshes/xyzrgb_statuette.ply 200000 1.5
>
> 3. About the CreateFromPolyData : indeed the original mesh is indeed
> modified, but this was for memory efficiency purpose. As the ACVD
> executables run on their own, it is not a problem for them. But if you use
> vtkSurface from an other code, maybe a simple solution is to clone the
> polydata via DeepCOPY?
>
> Could you split the modifications in different PRs? The threading code
> does not seem mature enough to be pulled right now anyway.
>
> —
> Reply to this email directly, view it on GitHub
> <#55?email_source=notifications&email_token=ABQJKYTPYAK4JW56YWD3EKL5XRVM5A5CNFSNUABFM5UWIORPF5TWS5BNNB2WEL2JONZXKZKDN5WW2ZLOOQXTMNRVG43TEMRZHE3KM4TFMFZW63VGMF2XI2DPOKSWK5TFNZ2KYZTPN52GK4S7MNWGSY3L#issuecomment-6657722996>,
> or unsubscribe
> <https://github.com/notifications/unsubscribe-auth/ABQJKYRWUAF7O45VHPSMOZ35XRVM5AVCNFSNUABCKJSXA33TNF2G64TZHM4DQNJYGAZDWSLTON2WKOZWGIYTKNJTGA4DKOFBOYBA>
> .
> Triage notifications, keep track of coding agent tasks and review pull
> requests on the go with GitHub Mobile for iOS
> <https://github.com/notifications/mobile/ios/ABQJKYVM5QILLOLTBXMALBD5XRVM5A5CNFSNUABFM5UWIORPF5TWS5BNNB2WEL2JONZXKZKDN5WW2ZLOOQXTMNRVG43TEMRZHE3KM4TFMFZW63VGMF2XI2DPOKSWK5TFNZ2KUZTPN52GK4S7NFXXG>
> and Android
> <https://github.com/notifications/mobile/android/ABQJKYT2Z562I444ZHFR74D5XRVM5A5CNFSNUABFM5UWIORPF5TWS5BNNB2WEL2JONZXKZKDN5WW2ZLOOQXTMNRVG43TEMRZHE3KM4TFMFZW63VGMF2XI2DPOKSWK5TFNZ2K4ZTPN52GK4S7MFXGI4TPNFSA>.
> Download it today!
> You are receiving this because you authored the thread.Message ID:
> ***@***.***>
>
|
|
The weird delete was since an upstream usage in your code deleted it using
delete [], which is wrong. I will make a small bugfix PR. Then if you like
I can extend using the newer SMPTools, which is faster than the old
multi-threader.
You get the bugfix PR soon
/Jens
On Thu, Nov 5, 2026 at 2:07 PM Jens Munk Hansen ***@***.***>
wrote:
… Will do
I work with a very different port.
Writing I/O inside classes is a nasty mesh, modifying input is a violation
of the VTK pipeline.
I can probably ask the AI to split it into just fixing the actual bugs in
one PR. There were quite a few, non-determinism and leaks are not the worst
of them. I switched to using SMP, since I could use TBB, STDThread and
Sequential. Then one can easily check determinism. Single-threaded must be
the same at MT.
Would you like a single PR, where just bugs are fixed.
Jens
On Thu, Nov 5, 2026 at 2:02 PM Jens Munk Hansen <
***@***.***> wrote:
> One could also allocate differently. The issue was a new / delete
> mismatch.
>
> On Thu, Nov 5, 2026 at 1:15 PM Sébastien Valette <
> ***@***.***> wrote:
>
>> *valette* left a comment (valette/ACVD#55)
>> <#55 (comment)>
>>
>> Thank you for this PR. I will probably pull the memory leak fixes, but I
>> have some questions:
>>
>> 1. What is this fix for?
>>
>>
>> - SecondMember[i]= new double;
>>
>>
>> - SecondMember[i]= new double[1];
>>
>>
>> 2. on my box (14 cores, 64GB RAM), processing a large mesh crashes
>> (OOM):
>> bin/ACVDQP ~/data/meshes/xyzrgb_statuette.ply 200000 1.5
>> load : /home/valette/data/meshes/xyzrgb_statuette.ply
>>
>> ------------------------------
>>
>> Mesh with 10000000 polygons, 4999996 points, 15000000 edges
>> Bounding Box: [-117.973, -190.474, -99.8223]
>> [117.251, 205.567, 103.339]
>> The mesh is made only of 10000000 triangles
>> 0 non-manifold edges and 0 boundary edges
>> The mesh has 1 connected components
>> Vertex valence entropy: 1.93073
>> 0 disconnected vertices, 5e+06 connected vertices
>> 55.5547 percent of irregular vertices
>> Mesh geometry quality:
>> AngleMin=0.000926766
>> AverageMinAngle=39.256
>> Qmin=1.40081e-05
>> Qav=0.731144
>> Angles bellow 30 (%)=6.62604
>> ------------------------------
>>
>> Computing Curvature ........
>> The curvature indicator calculation took :9.11181 seconds.
>> Indicators Range : 0.000339764 39.5465
>> Input mesh: 4999996 vertices and 10000000 faces
>> Creating 9765 Regions for thread pooling...done
>> Multithreading layout computed in :2.19295 seconds
>> Processus arrêté bin/ACVDQP ~/data/meshes/xyzrgb_statuette.ply 200000 1.5
>>
>> 3. About the CreateFromPolyData : indeed the original mesh is indeed
>> modified, but this was for memory efficiency purpose. As the ACVD
>> executables run on their own, it is not a problem for them. But if you use
>> vtkSurface from an other code, maybe a simple solution is to clone the
>> polydata via DeepCOPY?
>>
>> Could you split the modifications in different PRs? The threading code
>> does not seem mature enough to be pulled right now anyway.
>>
>> —
>> Reply to this email directly, view it on GitHub
>> <#55?email_source=notifications&email_token=ABQJKYTPYAK4JW56YWD3EKL5XRVM5A5CNFSNUABFM5UWIORPF5TWS5BNNB2WEL2JONZXKZKDN5WW2ZLOOQXTMNRVG43TEMRZHE3KM4TFMFZW63VGMF2XI2DPOKSWK5TFNZ2KYZTPN52GK4S7MNWGSY3L#issuecomment-6657722996>,
>> or unsubscribe
>> <https://github.com/notifications/unsubscribe-auth/ABQJKYRWUAF7O45VHPSMOZ35XRVM5AVCNFSNUABCKJSXA33TNF2G64TZHM4DQNJYGAZDWSLTON2WKOZWGIYTKNJTGA4DKOFBOYBA>
>> .
>> Triage notifications, keep track of coding agent tasks and review pull
>> requests on the go with GitHub Mobile for iOS
>> <https://github.com/notifications/mobile/ios/ABQJKYVM5QILLOLTBXMALBD5XRVM5A5CNFSNUABFM5UWIORPF5TWS5BNNB2WEL2JONZXKZKDN5WW2ZLOOQXTMNRVG43TEMRZHE3KM4TFMFZW63VGMF2XI2DPOKSWK5TFNZ2KUZTPN52GK4S7NFXXG>
>> and Android
>> <https://github.com/notifications/mobile/android/ABQJKYT2Z562I444ZHFR74D5XRVM5A5CNFSNUABFM5UWIORPF5TWS5BNNB2WEL2JONZXKZKDN5WW2ZLOOQXTMNRVG43TEMRZHE3KM4TFMFZW63VGMF2XI2DPOKSWK5TFNZ2K4ZTPN52GK4S7MFXGI4TPNFSA>.
>> Download it today!
>> You are receiving this because you authored the thread.Message ID:
>> ***@***.***>
>>
>
|
|
I made a PR, which is just the immediate bugfixes.
On Thu, Nov 5, 2026 at 2:14 PM Jens Munk Hansen ***@***.***>
wrote:
… The weird delete was since an upstream usage in your code deleted it using
delete [], which is wrong. I will make a small bugfix PR. Then if you like
I can extend using the newer SMPTools, which is faster than the old
multi-threader.
You get the bugfix PR soon
/Jens
On Thu, Nov 5, 2026 at 2:07 PM Jens Munk Hansen <
***@***.***> wrote:
> Will do
>
> I work with a very different port.
>
> Writing I/O inside classes is a nasty mesh, modifying input is a
> violation of the VTK pipeline.
>
> I can probably ask the AI to split it into just fixing the actual bugs in
> one PR. There were quite a few, non-determinism and leaks are not the worst
> of them. I switched to using SMP, since I could use TBB, STDThread and
> Sequential. Then one can easily check determinism. Single-threaded must be
> the same at MT.
>
> Would you like a single PR, where just bugs are fixed.
> Jens
>
>
> On Thu, Nov 5, 2026 at 2:02 PM Jens Munk Hansen <
> ***@***.***> wrote:
>
>> One could also allocate differently. The issue was a new / delete
>> mismatch.
>>
>> On Thu, Nov 5, 2026 at 1:15 PM Sébastien Valette <
>> ***@***.***> wrote:
>>
>>> *valette* left a comment (valette/ACVD#55)
>>> <#55 (comment)>
>>>
>>> Thank you for this PR. I will probably pull the memory leak fixes, but
>>> I have some questions:
>>>
>>> 1. What is this fix for?
>>>
>>>
>>> - SecondMember[i]= new double;
>>>
>>>
>>> - SecondMember[i]= new double[1];
>>>
>>>
>>> 2. on my box (14 cores, 64GB RAM), processing a large mesh crashes
>>> (OOM):
>>> bin/ACVDQP ~/data/meshes/xyzrgb_statuette.ply 200000 1.5
>>> load : /home/valette/data/meshes/xyzrgb_statuette.ply
>>>
>>> ------------------------------
>>>
>>> Mesh with 10000000 polygons, 4999996 points, 15000000 edges
>>> Bounding Box: [-117.973, -190.474, -99.8223]
>>> [117.251, 205.567, 103.339]
>>> The mesh is made only of 10000000 triangles
>>> 0 non-manifold edges and 0 boundary edges
>>> The mesh has 1 connected components
>>> Vertex valence entropy: 1.93073
>>> 0 disconnected vertices, 5e+06 connected vertices
>>> 55.5547 percent of irregular vertices
>>> Mesh geometry quality:
>>> AngleMin=0.000926766
>>> AverageMinAngle=39.256
>>> Qmin=1.40081e-05
>>> Qav=0.731144
>>> Angles bellow 30 (%)=6.62604
>>> ------------------------------
>>>
>>> Computing Curvature ........
>>> The curvature indicator calculation took :9.11181 seconds.
>>> Indicators Range : 0.000339764 39.5465
>>> Input mesh: 4999996 vertices and 10000000 faces
>>> Creating 9765 Regions for thread pooling...done
>>> Multithreading layout computed in :2.19295 seconds
>>> Processus arrêté bin/ACVDQP ~/data/meshes/xyzrgb_statuette.ply 200000
>>> 1.5
>>>
>>> 3. About the CreateFromPolyData : indeed the original mesh is
>>> indeed modified, but this was for memory efficiency purpose. As the ACVD
>>> executables run on their own, it is not a problem for them. But if you use
>>> vtkSurface from an other code, maybe a simple solution is to clone the
>>> polydata via DeepCOPY?
>>>
>>> Could you split the modifications in different PRs? The threading code
>>> does not seem mature enough to be pulled right now anyway.
>>>
>>> —
>>> Reply to this email directly, view it on GitHub
>>> <#55?email_source=notifications&email_token=ABQJKYTPYAK4JW56YWD3EKL5XRVM5A5CNFSNUABFM5UWIORPF5TWS5BNNB2WEL2JONZXKZKDN5WW2ZLOOQXTMNRVG43TEMRZHE3KM4TFMFZW63VGMF2XI2DPOKSWK5TFNZ2KYZTPN52GK4S7MNWGSY3L#issuecomment-6657722996>,
>>> or unsubscribe
>>> <https://github.com/notifications/unsubscribe-auth/ABQJKYRWUAF7O45VHPSMOZ35XRVM5AVCNFSNUABCKJSXA33TNF2G64TZHM4DQNJYGAZDWSLTON2WKOZWGIYTKNJTGA4DKOFBOYBA>
>>> .
>>> Triage notifications, keep track of coding agent tasks and review pull
>>> requests on the go with GitHub Mobile for iOS
>>> <https://github.com/notifications/mobile/ios/ABQJKYVM5QILLOLTBXMALBD5XRVM5A5CNFSNUABFM5UWIORPF5TWS5BNNB2WEL2JONZXKZKDN5WW2ZLOOQXTMNRVG43TEMRZHE3KM4TFMFZW63VGMF2XI2DPOKSWK5TFNZ2KUZTPN52GK4S7NFXXG>
>>> and Android
>>> <https://github.com/notifications/mobile/android/ABQJKYT2Z562I444ZHFR74D5XRVM5A5CNFSNUABFM5UWIORPF5TWS5BNNB2WEL2JONZXKZKDN5WW2ZLOOQXTMNRVG43TEMRZHE3KM4TFMFZW63VGMF2XI2DPOKSWK5TFNZ2K4ZTPN52GK4S7MFXGI4TPNFSA>.
>>> Download it today!
>>> You are receiving this because you authored the thread.Message ID:
>>> ***@***.***>
>>>
>>
|
|
OK thanks, will have a look! |
|
I am using another adaptive remeshing now, but I think the smallest PR is something you should consider merging. It removes invalid memory handling and fixes the memory leaks. The non-determinism was fixed in my first larger PR. I will not look into that again. But I think the smaller PR fixing leaks is a good small improvement. Leaks in public repos is not nice. |
Threaded clustering (vtkThreadedClustering, used by ACVDP / ACVDQP / AnisotropicRemeshingQP) now runs on vtkSMPTools instead of a vtkMultiThreader pool. Each loop runs the regions in greedy rounds (region index order) whose regions share no cluster and no edge, then the edges between regions alone. The schedule no longer depends on measured run times or on the number of threads, and the per-cluster mutexes are gone, so the result is the same for every backend and thread count. The region count is items / max(ItemsPerRegion, 8 x cluster size); ItemsPerRegion (default 512) replaces PoolingRatio (ACVDQP: -ipr replaces -p).
The per-edge calls of the clustering loop are static instead of virtual: the most-derived class is passed down as a template parameter (Derived) through vtkSurfaceClustering / vtkDiscreteRemeshing to vtkThreadedClustering. vtkIsotropicDiscreteRemeshing, vtkQIsotropicDiscreteRemeshing and vtkAnisotropicDiscreteRemeshing pass themselves; the AnisotropicRemeshing tools use a small VerticesRemeshing class for the same purpose.
vtkUniformClustering::ReComputeStatistics and the polynomial fitting in vtkCurvatureMeasure use vtkSMPTools instead of OpenMP / vtkMultiThreader (vtkCurvatureMeasure::SetNumberOfThreads is removed). No OpenMP is left; the examples no longer look for it. The tools select the STDThread backend (VTK builds default to Sequential, and TBB is often not available); -np sets the vtkSMPTools thread count.
vtkSurfaceBase::CreateFromPolyData always copies the polygons. They were shared with the caller's polydata through the shallow copy whenever they were already in 64-bit storage, and CheckNormals() reoriented the caller's cells in place.
Checked (tooth 32k vertices and a lower jaw scan, 3000 vertices, gradation 1.5):
Note, not addressed here: AnisotropicRemeshing and AnisotropicRemeshingQ segfault on the tooth mesh (1000 vertices, gradation 1.5 or 0) in vtkUniformClustering::ReComputeStatistics, called from MinimizeEnergy. The unmodified upstream tools crash the same way (the jaw scan runs fine with both), so this predates this change.