Почему нормали на сетке в vtk отличаются в зависимости от цвета сетки?

#python #vtk #normals

#python #vtk #нормали

Вопрос:

Я пытаюсь вычислить нормали сетки в vtk для каждой вершины. Когда я их отображаю, кажется, что нормали вершины для зеленой вершины имеют меньшую длину, чем вершины с белым цветом. Я не понимаю, почему я получаю этот результат.

Чтобы раскрасить сетку, я использовал эту функцию :

 def update_colors(self,couleurs=None,Vertex_correspondance=None):
    Colors = vtk.vtkUnsignedCharArray()
    Colors.SetNumberOfComponents(3)
    Colors.SetName("Colors")
    for i in range(self.points.shape[0]):
        if not i in Vertex_correspondance :
            Colors.InsertNextTuple3(255,255,255)
        else:
            Colors.InsertNextTuple3(couleurs[0] ,  couleurs[1] , couleurs[2])
    self.GetOutput.GetPointData().SetScalars(Colors)
    self.GetOutput.Modified()
 

Поэтому я присваиваю зеленый цвет некоторым вершинам сетки (30 вершин).

Для вычисления нормалей я использую :

         poly_data = self.actor.GetMapper().GetInput()

        normalsCalc = vtk.vtkPolyDataNormals()

        normalsCalc.SetInputData(poly_data)
        normalsCalc.ComputePointNormalsOn()
        normalsCalc.ComputeCellNormalsOff()
        normalsCalc.SplittingOff()
        normalsCalc.FlipNormalsOff()
        normalsCalc.ConsistencyOn()
        normalsCalc.AutoOrientNormalsOn()
        normalsCalc.Update()

        arrowSource = vtk.vtkArrowSource()

        glyph3D = vtk.vtkGlyph3D()
        glyph3D.SetSourceConnection(arrowSource.GetOutputPort())
        glyph3D.SetVectorModeToUseNormal()
        glyph3D.SetInputData(normalsCalc.GetOutput())
        glyph3D.SetScaleFactor(0.02)
        glyph3D.OrientOn()
        glyph3D.Update()

        mapper = vtk.vtkPolyDataMapper()
        mapper.SetInputConnection(glyph3D.GetOutputPort())

        self.glyphActor = vtk.vtkActor()
        self.glyphActor.SetMapper(mapper)
        self.glyphActor.GetProperty().SetColor([0, 0, 1])
 

вот дисплей, который я получаю
введите описание изображения здесь

Также, если я вычисляю длину нормалей после с

     normals = []
    array = normalsCalc.GetOutput().GetPointData().GetNormals()
    for i in range(array.GetNumberOfTuples()):
        normals.append(array.GetTuple(i))
    self.Normals = np.array(normals)
    np.linalg.norm(self.Normals,axis=1)
 

У меня число действительно близко к 1.
Таким образом, нормали, похоже, были вычислены хорошо…

Ответ №1:

Может быть, вам нужно использовать SetScaleModeToDataScalingOff() , это, кажется, работает:

 from vedo import Ellipsoid, show
import vtk

s = Ellipsoid().computeNormals()
arr = s.points()[:,2]
s.cmap('jet_r', arr)

arrowSource = vtk.vtkArrowSource()
glyph3D = vtk.vtkGlyph3D()
glyph3D.SetSourceConnection(arrowSource.GetOutputPort())
glyph3D.SetVectorModeToUseNormal()
glyph3D.SetInputData(s.polydata())
glyph3D.SetScaleFactor(0.2)
glyph3D.OrientOn()
glyph3D.SetScaleModeToDataScalingOff() ###### <--
glyph3D.Update()

show(s, glyph3D, axes=1)
 

введите описание изображения здесь