VTK scene

Need help, or want to share a macro? Post here!
Forum rules
Be nice to others! Respect the FreeCAD code of conduct!
Zoltan
Posts: 62
Joined: Wed Jul 07, 2021 10:08 am

VTK scene

Post by Zoltan »

Hi,

Is it possible to use a VTK scene in FreeCAD? I would like to visualize vtkImageData objects. I looked for it in the source code of the FEM module, but could not find an answer.

Thank you,
Zoltan
ickby
Veteran
Posts: 3116
Joined: Wed Oct 05, 2011 7:36 am

Re: VTK scene

Post by ickby »

Freecad can load some vtk data and visualize it, but I'm unsure if the image data is supported, as I never worked with it and don't know what it is about. You can just try to get a vtk file containing it and try to load it into freecad with the import function.

In general freecad is searching for triangulated data and puts it in its own scene graph. So if the image data provides that there are good chances it works, if it is another kind of data it won't.
Zoltan
Posts: 62
Joined: Wed Jul 07, 2021 10:08 am

Re: VTK scene

Post by Zoltan »

try to load it into freecad with the import function
Which function do you mean?
In general freecad is searching for triangulated data and puts it in its own scene graph
That is what I am afraid of: for FEM, one needs triangulated surfaces, not an image. What I would like to do is creating slices of a 3D grayscale image (volume) and display it. I could display a slice as a 2D bitmap image using the Image module, but I hope it is possible directly.
ickby
Veteran
Posts: 3116
Joined: Wed Oct 05, 2011 7:36 am

Re: VTK scene

Post by ickby »

Open a new document, and then use menu file->import. There you can choose FEM result vtk/vtu and then select your file.

If the vtk data is a volume you will most likely be able to use some vtk filters to convert it to a triangulated shape, or an image. But it is not implemented in freecad, and also not possible to do in Python. You would need to work in c++
Zoltan
Posts: 62
Joined: Wed Jul 07, 2021 10:08 am

Re: VTK scene

Post by Zoltan »

Thank you for the tips. I looked for it, and I would need isosurface extraction to represent the image as a mesh. During this process, I would lose information. So FreeCAD is currently not able to visualize image data, only polygonal data, like meshes. Is there any incentive to embed Paraview into FreeCAD (as in Salome)? That would do the job, although ParaView is a massive library, and FreeCAD is a CAD application, not a CAE environment...
ickby
Veteran
Posts: 3116
Joined: Wed Oct 05, 2011 7:36 am

Re: VTK scene

Post by ickby »

Zoltan wrote: Fri Oct 08, 2021 4:03 pm Is there any incentive to embed Paraview into FreeCAD (as in Salome)? That would do the job, although ParaView is a massive library, and FreeCAD is a CAD application, not a CAE environment...
Before implementing the current way of FreeCADs vtk integrtion I was thinking about that way, but decided actively against it. IMHO the Salome way is extremely cumbersome, and has almost no benefit over using Paraviw as standalone. For FreeCAD a consistant way of handling things is IMHO important, using the same tree view, same 3dview, being able to overlay FEM results with Geometry etc.. Also Paraview has a dramatically different user interaction in how it works, it would mean learning things all over again within FreeCAD. So I implemented basic functionality into FreeCAD, and an export possibility for VTK data, so that one can easily use Paraview if FreeCAD is not enough.
Zoltan
Posts: 62
Joined: Wed Jul 07, 2021 10:08 am

Re: VTK scene

Post by Zoltan »

It makes sense.
In the meantime, I found a wonderful Python library, called vedo, with its only dependency being VTK (which is already part of FreeCAD). vedo can be embedded to a PyQt5 window, as described here. According to the wiki, "FreeCAD uses the Quarter library to use Coin3D in a Qt environment.". Is it possible to somehow use this link (i.e. vedo: VTK -> Qt, Quarter: Qt -> Coin3D) to display VTK graphics by vedo in the FreeCAD scene? Sorry if my question is naive, I know little about graphics.
ickby
Veteran
Posts: 3116
Joined: Wed Oct 05, 2011 7:36 am

Re: VTK scene

Post by ickby »

It uses a completely different rendering pipeline, so no, you cannot add it to the same scene graph. However, seems it would be possible with some scripting to add a new tab in freecad document window with the Vedo rendering inside.
Zoltan
Posts: 62
Joined: Wed Jul 07, 2021 10:08 am

Re: VTK scene

Post by Zoltan »

Could you please give me some links so that I can get started?
it would be possible with some scripting
Do you mean that no C++ is required, just Python?
wmayer
Founder
Posts: 20309
Joined: Thu Feb 19, 2009 10:32 am
Contact:

Re: VTK scene

Post by wmayer »

This way you can add a view to the mdi area:

Code: Select all

mw = Gui.getMainWindow()
mdi = mw.findChild(Qt.QMdiArea)
view = MainWindow()
sub = mdi.addSubWindow(view)
sub.show()
In the example you you've linked you have to make two changes:
  • Replace

    Code: Select all

    from PyQt5 import Qt
    with

    Code: Select all

    from PySide2 import QtWidgets as Qt
    from PySide2.QtCore import Slot
    
    because we use PySide2 as Python binding
  • Replace the decorator

    Code: Select all

    @Qt.pyqtSlot()
    with

    Code: Select all

    @Slot()
    But you can also omit it.

Code: Select all

from vedo import Plotter, Cone
import vtk.qt
from vtk.qt.QVTKRenderWindowInteractor import QVTKRenderWindowInteractor

from vedo import Plotter, Cone

from PySide2 import QtWidgets as Qt
from PySide2.QtCore import Slot

class MainWindow(Qt.QMainWindow):
    def __init__(self, parent=None):
        Qt.QMainWindow.__init__(self, parent)
        self.frame = Qt.QFrame()
        self.vl = Qt.QVBoxLayout()
        self.vtkWidget = QVTKRenderWindowInteractor(self.frame)
        self.vl.addWidget(self.vtkWidget)
        
        # create renderer and add the actors
        self.vp = Plotter(qtWidget=self.vtkWidget)
        
        self.vp += Cone().rotateX(20)
        self.vp.show(interactorStyle=0)
        
        # set-up the rest of the Qt window
        button = Qt.QPushButton("My Button makes the cone red")
        button.setToolTip('This is an example button')
        button.clicked.connect(self.onClick)
        self.vl.addWidget(button)
        self.frame.setLayout(self.vl)
        self.setCentralWidget(self.frame)
        self.show() # <--- show the Qt Window
        
    def onClose(self):
        #Disable the interactor before closing to prevent it
        #from trying to act on already deleted items
        self.vtkWidget.close()
        
    @Slot()
    def onClick(self):
        self.vp.actors[0].color('red').rotateZ(40)
        self.vp.interactor.Render()

mw = Gui.getMainWindow()
mdi = mw.findChild(Qt.QMdiArea)
view = MainWindow()
sub = mdi.addSubWindow(view)
sub.show()
Post Reply