Je suis nouveau sur python et VTK alors s'il vous plaît soyez patient :)

En bref, j'ai un acteur et j'aimerais le faire pivoter autour d'une ligne que j'ai dessinée à l'aide de vtkLineSource(). J'ai choisi mes points de départ et d'arrivée et j'ai tracé la ligne. Maintenant, ce que je pensais (corrigez-moi si je me trompe) que je devrais créer un axe sur la ligne, puis appliquer le vtkTransformWXYZ() pour faire pivoter l'axe. Ça ne marche pas, ça donne une rotation bizarre autour du point choisi, mais pas celui que je désire. J'ai également essayé de définir l'axe au milieu de la ligne que j'ai tracée et d'y appliquer la rotation, mais lorsque j'essaie, il tourne autour des coordonnées globales et non locales. J'ai aussi essayé de donner en entrée le point ou la ligne, mais encore une fois, la rotation est très bizarre.

Existe-t-il un moyen de définir la ligne comme un axe et de faire pivoter l'acteur autour d'elle ? Jusqu'à présent, j'ai essayé comme dans les exemples suivants : https://lorensen.github .io/VTKExamples/site/Python/PolyData/RotationAroundLine/ et https://lorensen.github.io/VTKExamples/site/Python/Rendering/Rotations/ mais mon acteur tourne toujours d'une manière étrange.

Quelqu'un pourrait-il m'aider/m'orienter s'il vous plaît ?

Voici la partie de mon code où j'essaye de faire tourner l'acteur…

###################### create line to rotate about and display it

    lineStart = [16.8879, -106.476, -782.449]       
    lineFinish = [-17.827, -92.2757, lineStart[2]]
    lineMiddle = [(lineStart[0]+lineFinish[0])/2, (lineStart[1]+lineFinish[1])/2, lineStart[2]]
    
    lineSource = vtk.vtkLineSource()
    lineSource.SetPoint1(lineStart)
    lineSource.SetPoint2(lineFinish)
    lineSource.Update()
    
    mapperLine = vtk.vtkPolyDataMapper()
    mapperLine.SetInputConnection(lineSource.GetOutputPort())
    
    actorLine = vtk.vtkActor()
    actorLine.SetMapper(mapperLine)
    actorLine.GetProperty().SetLineWidth(4)
    actorLine.GetProperty().SetColor(1,0,0)
    ren.AddActor(actorLine)

############# rotate about the line

    modelMapper = vtk.vtkPolyDataMapper()
    modelMapper.SetInputData(cleanFilter.GetOutput())

    modelActor = vtk.vtkActor()
    modelActor.SetMapper(modelMapper)
    
    modelAxesSource = vtk.vtkAxes()
    modelAxesSource.SetScaleFactor(100)
    modelAxesSource.SetOrigin(lineMiddle)

    
    modelAxesMapper = vtk.vtkPolyDataMapper()
    modelAxesMapper.SetInputConnection(modelAxesSource.GetOutputPort())

    modelAxes = vtk.vtkActor()
    modelAxes.SetMapper(modelAxesMapper)


    ren.AddActor(modelAxes)
    modelAxes.VisibilityOn()
    ##this did not work
    ##modelActor.SetOrientation(lineMiddle)
    ##modelActor.RotateZ(45)
    ##ren.AddActor(modelActor)

transform = vtk.vtkTransform()
    transform.RotateWXYZ(45, lineMiddle)
    transformFilter = vtk.vtkTransformPolyDataFilter()
    transformFilter.SetTransform(transform)
    transformFilter.SetInputConnection(cleanFilter.GetOutputPort())
    transformFilter.Update()
    
    NewMapper = vtk.vtkPolyDataMapper()
    NewMapper.SetInputConnection(transformFilter.GetOutputPort())
    
    actorRotated = vtk.vtkActor()
    actorRotated.SetMapper(NewMapper)

    
    ren.AddActor(actorRotated)

J'ai également essayé ce qui suit:

    rotate = vtk.vtkRotationFilter()
    rotate.SetInputConnection(cleanFilter.GetOutputPort())
    rotate.SetAxisToY()
    rotate.SetCenter(lineMiddle)
    rotate.SetAngle(45)
    mapper = vtk.vtkDataSetMapper()
    mapper.SetInputConnection(rotate.GetOutputPort())
    actor = vtk.vtkActor()
    actor.SetMapper(mapper)
    ren.AddActor(actor)

Mais il n'affiche rien.

Toute aide est appréciée!

Merci d'avance Diane

0
Diana 6 nov. 2020 à 16:24

1 réponse

Meilleure réponse

Vous devrez peut-être écrire une fonction comme ceci :

    def rotate(obj, angle, axis=(1, 0, 0), axis_point=(0, 0, 0), rad=False):
        """Rotate around an arbitrary `axis` passing through `axis_point`."""
        if rad:
            anglerad = angle
        else:
            anglerad = np.deg2rad(angle)
        axis = utils.versor(axis)
        a = np.cos(anglerad / 2)
        b, c, d = -axis * np.sin(anglerad / 2)
        aa, bb, cc, dd = a * a, b * b, c * c, d * d
        bc, ad, ac, ab, bd, cd = b * c, a * d, a * c, a * b, b * d, c * d
        R = np.array(
            [
                [aa + bb - cc - dd, 2 * (bc + ad), 2 * (bd - ac)],
                [2 * (bc - ad), aa + cc - bb - dd, 2 * (cd + ab)],
                [2 * (bd + ac), 2 * (cd - ab), aa + dd - bb - cc],
            ]
        )
        rv = np.dot(R, obj.GetPosition() - np.array(axis_point)) + axis_point

        if rad:
            angle *= 180.0 / np.pi
        # this vtk method only rotates in the origin of the object:
        obj.RotateWXYZ(angle, axis[0], axis[1], axis[2])
        pbj.SetPosition(rv)

Le tester en utilisant vedo :

from vedo import *

c1 = Cube() # vtkActor
c2 = c1.clone().c('violet').alpha(0.5) # make a clone copy

v = vector(0.2,1,0)
p = vector(1,0,0)
c2.rotate(90, axis=v, axis_point=p)

l = Line(-v+p, v+p).lw(3).c('red') # vtkActor
show(c1, c2, l, axes=1)

enter image description here

0
mmusy 7 nov. 2020 à 13:21