Script to take screenshots without showing the main window

Need help, or want to share a macro? Post here!
Forum rules
Be nice to others! Respect the FreeCAD code of conduct!
Post Reply
marceljoseph
Posts: 4
Joined: Sat May 13, 2023 1:54 pm
Contact:

Script to take screenshots without showing the main window

Post by marceljoseph »

I want to use FreeCAD to convert 3D files to images heedlessly. I use the ranger file manager, which uses openscad to generate image previews for 3mf, stl, etc., but openscad doesn't support step.

I made this Python script, which is based on this tutorial:

Code: Select all

import sys
sys.path.append('/usr/lib/freecad/lib/')
from pathlib import Path

import FreeCAD
import FreeCADGui as Gui
import Part
# Loading test part
out_dir = Path('/tmp')

# Gui.showMainWindow()
Part.open('.../3d/SOT-25-5.step')

# Creating images with different Views, Cameras and sizes
for p in ['PerspectiveCamera','OrthographicCamera']:
    Gui.SendMsgToActiveView(p)
    for f in ['ViewAxo','ViewFront','ViewTop']:
        Gui.SendMsgToActiveView(f)
        for x,y in [[500,500],[1000,3000],[3000,1000],[3000,3000],[8000,8000]]:
            Gui.ActiveDocument.ActiveView.saveImage(str(out_dir / f'Blade_{p}_{f}_{x}_{y}.jpg'), x, y, 'White')
            Gui.ActiveDocument.ActiveView.saveImage(str(out_dir / f'Blade_{p}_{f}_{x}_{y}.png'), x, y, 'Transparent')

# Close active document
FreeCAD.closeDocument(FreeCAD.ActiveDocument.Name)
This script works, but it shows the FreeCAD window. Ideally, I want this to happen totally headlessly. Is there a way I can do showMainWindow() virtually without anything actually showing on the screen?

Thank you!
User avatar
onekk
Veteran
Posts: 6149
Joined: Sat Jan 17, 2015 7:48 am
Contact:

Re: Script to take screenshots without showing the main window

Post by onekk »

marceljoseph wrote: Sat May 13, 2023 2:00 pm ...
Is there a way I can do showMainWindow() virtually without anything actually showing on the screen?
...
You coukd hide the window, but as the thing is not related to "camera" you have to use the GUI part (headless is usually intented as "without GUI").

I remember that some time ago @wmayer has explained a way to use the GUI without showing it, but sadly I had not take note of the link.

Regards

Carlo D.
GitHub page: https://github.com/onekk/freecad-doc.
- In deep articles on FreeCAD.
- Learning how to model with scripting.
- Various other stuffs.

Blog: https://okkmkblog.wordpress.com/
User avatar
saso
Veteran
Posts: 1920
Joined: Fri May 16, 2014 1:14 pm
Contact:

Re: Script to take screenshots without showing the main window

Post by saso »

Some time ago I made a small script for something similar, I am not sure if it still works :roll: but check it out if it can be of any help to you...

viewtopic.php?p=384879#p384879
marceljoseph
Posts: 4
Joined: Sat May 13, 2023 1:54 pm
Contact:

Re: Script to take screenshots without showing the main window

Post by marceljoseph »

saso wrote: Sat May 13, 2023 3:46 pm Some time ago I made a small script for something similar, I am not sure if it still works :roll: but check it out if it can be of any help to you...

viewtopic.php?p=384879#p384879
Thanks, but it doesn't seem to work any more.

Code: Select all

AttributeError: module 'FreeCADGui' has no attribute 'Selection'
marceljoseph
Posts: 4
Joined: Sat May 13, 2023 1:54 pm
Contact:

Re: Script to take screenshots without showing the main window

Post by marceljoseph »

My current best solution is just to minimize the FreeCAD window after opening it. Not ideal, but best I could come up with for now. Please let me know if you have a better idea.

Here is my current code. It's called the same way as openscad_image in ranger's scopes.sh file:

Code: Select all

#!/usr/bin/python

import sys
sys.path.append('/usr/lib/freecad/lib/')
from pathlib import Path

import FreeCAD
import FreeCADGui as Gui
import Part, Mesh

_, dimensions, path_out, path_in = sys.argv
path_in = Path(path_in)

Gui.showMainWindow()
window = Gui.getMainWindow()
window.showMinimized()

if path_in.suffix.lower() == '.obj':
    Mesh.open(str(path_in))
else:
    Part.open(str(path_in))

x, y = (int(n) for n in dimensions.split(','))

Gui.SendMsgToActiveView('OrthographicCamera')
Gui.SendMsgToActiveView('ViewAxo')

Gui.ActiveDocument.ActiveView.saveImage(path_out, x, y, 'Transparent')

FreeCAD.closeDocument(FreeCAD.ActiveDocument.Name)

wmayer
Founder
Posts: 20243
Joined: Thu Feb 19, 2009 10:32 am
Contact:

Re: Script to take screenshots without showing the main window

Post by wmayer »

Try: https://github.com/FreeCAD/FreeCAD/blob ... napshot.py

You can use it like this:

Code: Select all

import FreeCAD
import FreeCADGui

import make_snapshot
make_snapshot.make_snapshot("file.step", "image.png", 400)
I have tried the module and it still works but required this fix: git commit 3c8ee2213f8
A workaround should be adding this beforehand:

Code: Select all

from PySide2 import QtWidgets
app = QtWidgets.QApplication()
marceljoseph
Posts: 4
Joined: Sat May 13, 2023 1:54 pm
Contact:

Re: Script to take screenshots without showing the main window

Post by marceljoseph »

wmayer wrote: Sun May 14, 2023 4:47 pm Try: https://github.com/FreeCAD/FreeCAD/blob ... napshot.py

You can use it like this:

Code: Select all

import FreeCAD
import FreeCADGui

import make_snapshot
make_snapshot.make_snapshot("file.step", "image.png", 400)
I have tried the module and it still works but required this fix: git commit 3c8ee2213f8
A workaround should be adding this beforehand:

Code: Select all

from PySide2 import QtWidgets
app = QtWidgets.QApplication()

Thanks @wmayer! This looks very promising. However, I'm still getting this error>

Code: Select all

Traceback (most recent call last):
  File "/home/marcel/.local/bin/freecad_image.py", line 31, in <module>
    make_snapshot.make_snapshot(path_in,path_out, x)
  File "/home/marcel/.dotfiles/bin/make_snapshot.py", line 74, in make_snapshot
    off = FreeCADGui.SoQtOffscreenRenderer(width, height)
AttributeError: module 'FreeCADGui' has no attribute 'SoQtOffscreenRenderer'
It seems like this is also a method that only works when the GUI is loaded.
wmayer
Founder
Posts: 20243
Joined: Thu Feb 19, 2009 10:32 am
Contact:

Re: Script to take screenshots without showing the main window

Post by wmayer »

marceljoseph wrote: Fri May 19, 2023 2:53 pm However, I'm still getting this error>
You need v0.21.
It seems like this is also a method that only works when the GUI is loaded.
It requires the FreeCADGui module in order to access the visual representations of objects or the off-screen renderer but it doesn't show any windows to the user.
Post Reply