STL written by vtkSTLWriter is not properly visible in Unity3D!

Hello,

I am new to VTK and interested to make a CAD software. Recently I have been working with decimation. I have tried to write the reduced STL using vtkSTLWriter. But the exported STL is not correctly visible due to disturbed vertices.

Weird thing is if I import the same STL in blender, the export seems fine. And If I export an STL of the same vtkSTLWritten imported STL from blender, then the blender exported STL is visible fine in Unity3D.

Please help what I am missing here?

Welcome to VTK, @rai-sam. Could you add a screenshot that show what is going wrong?

@cory.quammen Let me know if anything else needed at my end. Please help. :slight_smile:

It looks like faces are not oriented correctly. You can use vtkPolyDataNormals to fix it (make sure “Consistency” is enabled).

@lassoan If I SetFlipNormals(true) using vtkPolyDataNormals then problem seemed solved. Is this fine practice? What could be the issue?

Some filters may not preserve consistency of cell orientations, so I would consider it to be normal that you need to reorient (unless you analysed all input data sets and processing filters and based on that you would not expect it to be necessary).

@lassoan So what I am going to assume in this case is vtkSTLReader is somehow reading STL with flipped faces? So that before exporting, I need to perform setFlipNormals(true) everytime. Right?

If triangle points may be ordered incorrectly in your input STL files then you can use vtkPolyDataNormals filter to fix them.

@lassoan I wrote a code to Flip normals in Unity3D after importing STL mesh.
I have verified by test case of original input STL and vtk written STL files that vtk is causing this issue to output STL files. I discarded the use of vtkPolyDataNormals at vtkSTLWriter time.

Test Files:
original.stl (input)
original_test.stl (export of original.stl by vtk)
original_test2.stl (export of original_test.stl by vtk)
original_test3.stl (export of original_test2.stl by vtk)

After importing all 4 STL files in Unity3D, I see original input STL all fine and all 3 vtk exported STL files faces incorrectly oriented. So I place the code to Flip normals in Unity3D for all, and this time original input STL faces were incorrectly oriented due to code and all 3 vtk exported STL files were fine as fixed by code.

My point is if I missing something at write time? Maybe stlWriter->Update()?

What is your full VTK processing pipeline? You can post code if you’d like or just list the reader/filters/writers are you have them connected.

I am using Tools:
VTK v8.2.0
Cmake 3.14.5
Visual Studio 2015

Code:

#include <vtkPolyData.h>
#include <vtkSTLWriter.h>
#include <vtkSTLReader.h>
#include <vtkSmartPointer.h>
#include <vtkPolyDataMapper.h>
#include <vtkActor.h>
#include <vtkRenderWindow.h>
#include <vtkRenderer.h>
#include <vtkRenderWindowInteractor.h>

using namespace std;

int main(int argc, char *argv[])
{
  if(argc != 3)
  {
    cout << "Required parameters: input Filename(.stl) OR output filename.stl" << endl;
    return EXIT_FAILURE;
  }

  string inputFileName = argv[1];
  string outputFileName = argv[2];

  // read input stl
  vtkSmartPointer<vtkSTLReader> inputReader = vtkSmartPointer<vtkSTLReader>::New();
  inputReader->SetFileName(inputFileName.c_str());
  inputReader->Update();

  // write output file
  vtkSmartPointer<vtkSTLWriter> stlWriter = vtkSmartPointer<vtkSTLWriter>::New();
  stlWriter->SetFileName(outputFileName.c_str());
  stlWriter->SetInputConnection(inputReader->GetOutputPort());
  stlWriter->Write();

  // Read and display for verification
  vtkSmartPointer<vtkSTLReader> outputReader = vtkSmartPointer<vtkSTLReader>::New();
  outputReader->SetFileName(outputFileName.c_str());
  outputReader->Update();

  vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
  mapper->SetInputConnection(outputReader->GetOutputPort());

  vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();
  actor->SetMapper(mapper);

  vtkSmartPointer<vtkRenderer> renderer = vtkSmartPointer<vtkRenderer>::New();
  vtkSmartPointer<vtkRenderWindow> renderWindow = vtkSmartPointer<vtkRenderWindow>::New();
  renderWindow->AddRenderer(renderer);
  vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor = vtkSmartPointer<vtkRenderWindowInteractor>::New();
  renderWindowInteractor->SetRenderWindow(renderWindow);

  renderer->AddActor(actor);
  renderer->SetBackground(.3, .6, .3); // Background color green

  renderWindow->Render();
  renderWindowInteractor->Start();

  return EXIT_SUCCESS;
}

The code looks fine and straightforward. Saving and loading and STL file with VTK, I didn’t see any reorientation of the geometry faces taking place.

Could you share a small STL file that shows the odd behavior with this program?

I have sent you the STL file exported by running this same code. Check this file in Unity3D any version if you can as well.

@cory.quammen NO luck? :frowning:

Sorry, I’ve been completely swamped. Are you blocked by this issue?

@cory.quammen Yes! These STL exports should work for Unity3D as well. At-least for now.

I have a work around importing it to blender and then exporting. But that is 1 more step.

I have looked at both your original STL files and the files converted by VTK. The only difference I see between the original files and VTK-produced files is that the original is a binary STL file and those saved out from the VTK STL writer are binary. Content-wise, they are exactly the same in terms of polygon winding, points, and normals, aside from some minor precision differences in the floating point numbers. Hence, there is no problem with VTK.

Perhaps the difference is in how Unity is importing binary vs. STL files. You can check whether this is the case by calling

vtkSTLWriter::SetFileTypeToBinary()

and saving out the VTK files that way. Hopefully Unity will treat normals in those files the same way as your original binary STL.

1 Like