Menu

#29 Writing non-finite normals

2.1.0
closed
bug (7)
2026-05-13
2026-05-06
No

I use gVirtualXRay for some X-ray simulations. During scene setup, I write out exact scene content. But the written files are sometimes not readable by the latest VTK (v9.6.1).

This is the simplified code fragment I use:

gvxr.loadMeshFile(label, "table_0159.stl", "mm", True, root_node)
gvxr.moveToCenter(label)
rotate = [45, -22.5, 0]
gvxr.rotateNode(label, *rotate)
gvxr.applyCurrentLocalTransformation(label)
gvxr.moveToCenter(label)
gvxr.scaleNode(label, localScaleFactor, localScaleFactor, localScaleFactor)
gvxr.applyCurrentLocalTransformation(label)
gvxr.moveToCenter(label)
gvxr.translateNode(label, *translationVector, "cm")
gvxr.applyCurrentLocalTransformation(label)
gvxr.setMixture(label, material["Znumber"], material["Weights"])
gvxr.setDensity(label, material["density"], "g/cm3")
gvxr.saveSTLfile(label, "08_table_0159.stl")

And when trying to load the file using latest 3D Slicer nightly, I run into:

Error: Loading .../08_table_0159.stl - ERROR: In vtkSTLReader.cxx, line 298
vtkSTLReader (00000288285BAD10): Normal vector non-finite.

vtkSTLReader has this code there:

  for (size_t i = 0; stream->Read(&facet, triSize) > 0; ++i)
  {
    vtkByteSwap::Swap4LE(facet.n);
    vtkByteSwap::Swap4LE(facet.n + 1);
    vtkByteSwap::Swap4LE(facet.n + 2);
    if (!std::isfinite(facet.n[0]) || !std::isfinite(facet.n[1]) || !std::isfinite(facet.n[2]))
    {
      vtkErrorMacro("Normal vector non-finite.");
      return false;
    }

Loading the input file using the same program works fine. Both input and output meshes are attached. This affects the latest released Python package (v2.0.10).

2 Attachments

Discussion

  • Dženan Zukić

    Dženan Zukić - 2026-05-07

    The error fires for i=16, all 3 normal components are -nan(ind).

     
  • Franck Vidal

    Franck Vidal - 2026-05-08

    Thanks for letting me know. Same problem with MeshLab. I'll have a look and fix the issue for the next release.

     
  • Dženan Zukić

    Dženan Zukić - 2026-05-08

    Thanks for responses. Looking forward to the new package.

     
  • Franck Vidal

    Franck Vidal - 2026-05-08

    Did you install the package from the source (if so which version) or using pip install gvxr?
    What OS did you use?

    I tried on Windows with both the latest version on pip and the future release and did not have any problem.

     
  • Dženan Zukić

    Dženan Zukić - 2026-05-08

    We use it on both Windows and Linux. We do pip install gvxr.

     
  • Franck Vidal

    Franck Vidal - 2026-05-08

    Strange. Here is a fully contained test. It worked after making sure it was with a fresh install.
    I even tried with a negative value of localScaleFactor.
    Can you try the code below? If still no luck, we'll have to arrange a video call.

    #!/usr/bin/env python3
    
    from gvxrPython3 import gvxr
    
    label = "table"
    rotate = [45, -22.5, 0]
    translationVector = [1, 2, 3]
    localScaleFactor = 2
    
    gvxr.createNewContext()
    
    gvxr.loadMeshFile(label, "table_0159.stl", "mm", True)
    gvxr.moveToCenter(label)
    gvxr.rotateNode(label, 45, -22.5, 0)
    gvxr.applyCurrentLocalTransformation(label)
    gvxr.moveToCenter(label)
    gvxr.scaleNode(label, localScaleFactor, localScaleFactor, localScaleFactor)
    gvxr.applyCurrentLocalTransformation(label)
    gvxr.moveToCenter(label)
    gvxr.translateNode(label, *translationVector, "cm")
    gvxr.applyCurrentLocalTransformation(label)
    # gvxr.setMixture(label, material["Znumber"], material["Weights"])
    # gvxr.setDensity(label, material["density"], "g/cm3")
    gvxr.saveSTLfile(label, "08_table_0159.stl")
    
     
  • Dženan Zukić

    Dženan Zukić - 2026-05-08

    The output of this repro code is not bit-identical to mine (of course), but it still causes problems:

    Error: Loading M:/.../08_table_0159_new.stl - ERROR: In vtkSTLReader.cxx, line 298
    vtkSTLReader (000002D5C47BB840): Normal vector non-finite.
    

    I tried in two virtual environments.

    • Old: Python 3.10.11
    • New: Python 3.11.0

    This new environment is entirely fresh. If it matters, here is requirements.txt:

    numpy==1.25.2
    tqdm==4.67.1
    opencv-python==4.11.0.86
    pandas==2.3.3
    vtk==9.5.2
    torch==2.4.1 --index-url https://download.pytorch.org/whl/cu124
    torchvision==0.19.1 --index-url https://download.pytorch.org/whl/cu124
    tensorboard==2.20.0
    viser==1.0.22
    nerfview==0.1.3
    splines==0.3.3
    
    wheel==0.46.3
    ninja==1.13
    jaxtyping==0.3.7
    rich==14.3.2
    matplotlib==3.10.8
    
    gvxr==2.0.10
    loguru==0.7.3
    notebook==7.5.2
    pymeshlab==2025.7
    
    itk==5.4.6
    pycocotools==2.0.11
    scikit-learn==1.7.2
    ultralytics==8.4.11
    onnx==1.20.1
    onnxslim==0.1.85
    onnxruntime-gpu==1.23.2
    pyYAML==6.0.3
    
     
  • Dženan Zukić

    Dženan Zukić - 2026-05-08

    I made a change to VTK to work around this problem. But of course NaN normals should not be produced.

     
  • Franck Vidal

    Franck Vidal - 2026-05-12

    I had a look at the original file you provided. There are a few triangles defined by colinear vectors, i.e. their three vertices are along a line. It led to a division by zero when normalising the normal vector (as the lengthof the normal was null).
    There is now a test to avoid the division by zero, i.e. the normal vector will remain null rather than infinite. It'll make it more robust.
    The alternative was to remove the triangle, but I decided against it to avoid altering the original data. However, it may lead to issues when the triangles are processed down the line. Best would be for the original exporter to avoid the use of such triangles.

    If you are happy with the solution Dženan, I'll close the ticket. Thanks for helping us make gVXR more robust!

     
    👍
    1
  • Dženan Zukić

    Dženan Zukić - 2026-05-12

    Zero normal is better then NaN normal. Thank you for taking care of it. You can close the issue.

     
  • Franck Vidal

    Franck Vidal - 2026-05-13
    • status: open --> closed
    • assigned_to: Franck Vidal
    • Milestone: 2.0.11 --> 2.1.0
     
  • Dženan Zukić

    Dženan Zukić - 2026-05-13

    Confirming as fixed via inofficial wheel. Presumably via commit b05b2a4ccbe760533bf7f5e53a4e88529dbca338.

     

Log in to post a comment.

Auth0 Logo