Take pictures from python without using GUI

Need help, or want to share a macro? Post here!
Forum rules
Be nice to others! Respect the FreeCAD code of conduct!
wmayer
Founder
Posts: 20309
Joined: Thu Feb 19, 2009 10:32 am
Contact:

Re: Take pictures from python without using GIU

Post by wmayer »

Note: if you are using an old Mesa GL version, set the environment variable COIN_GL_NO_CURRENT_CONTEXT_CHECK to get around what may be a Mesa bug.
Can you try again after setting the environment variable COIN_GL_NO_CURRENT_CONTEXT_CHECK?
Therefore in a terminal enter

Code: Select all

export COIN_GL_NO_CURRENT_CONTEXT_CHECK=1
and then start FreeCAD from this terminal window.

If you still have problems then try the suggestions here.
User avatar
Kunda1
Veteran
Posts: 13434
Joined: Thu Jan 05, 2017 9:03 pm

Re: Take pictures from python without using GIU

Post by Kunda1 »

Also OP, in addition to what @wmayer just said ...could you please fix the typo in your thread topic from GIU to GUI. Thanks!
Alone you go faster. Together we go farther
Please mark thread [Solved]
Want to contribute back to FC? Checkout:
'good first issues' | Open TODOs and FIXMEs | How to Help FreeCAD | How to report Bugs
rkneills
Posts: 6
Joined: Wed Mar 06, 2019 1:55 pm

Re: Take pictures from python without using GUI

Post by rkneills »

Hello I'm trying to get png images of parts in a headless Docker container. I'm using this code snippet given by wmayer from the first page of this thread

Code: Select all

import FreeCAD, Part
from pivy import coin

box=Part.makeCone(10,8,10)
iv=box.writeInventor()

# SoInput.setBuffer seems broken with pivy, so save to file and load from there
output=open("part.iv","w")
output.write(iv)
output.close()

inp=coin.SoInput()
inp.openFile(output.name)
data = coin.SoDB.readAll(inp)

base = coin.SoBaseColor()
base.rgb.setValue(0.6,0.7,1.0)
data.insertChild(base,0)

root = coin.SoSeparator()
light = coin.SoDirectionalLight()
cam = coin.SoOrthographicCamera()
root.addChild(cam)
root.addChild(light)
root.addChild(data)

axo = coin.SbRotation(-0.353553, -0.146447, -0.353553, -0.853553)
viewport=coin.SbViewportRegion(400,400)
cam.orientation.setValue(axo)
cam.viewAll(root,viewport)
off=coin.SoOffscreenRenderer(viewport)
root.ref()
ret=off.render(root)
root.unref()

if ret > 0:
    off.writeToPostScript("crystal.ps")
    if off.isWriteSupported("PNG"):
        off.writeToFile("crystal.png","PNG")
When I run this function the program crashes with the error message below. It seems to be erroring out at the line ret=off.render(root)

Code: Select all

Coin error in glxglue_init(): Couldn't open NULL display.
Program received signal SIGSEGV, Segmentation fault.
#0  /lib/x86_64-linux-gnu/libc.so.6(+0x3ef20) [0x7fdaf58d9f20]
#1  /usr/lib/x86_64-linux-gnu/libX11.so.6(XDefaultScreenOfDisplay+0) [0x7fdadb7a97c0]
#2  /usr/lib/x86_64-linux-gnu/libCoin.so.80c(+0x3c6b9d) [0x7fdad5e37b9d]
#3  /usr/lib/x86_64-linux-gnu/libCoin.so.80c(+0x3c6d61) [0x7fdad5e37d61]
#4  /usr/lib/x86_64-linux-gnu/libCoin.so.80c(glxglue_context_create_offscreen+0x14) [0x7fdad5e38b84]
#5  /usr/lib/x86_64-linux-gnu/libCoin.so.80c(cc_glglue_context_max_dimensions+0x80) [0x7fdad5e306c0]
#6  0x7fdad5fa588c in CoinOffscreenGLCanvas::getMaxTileSize() from /usr/lib/x86_64-linux-gnu/libCoin.so.80c+0x7c                                                                                                  
#7  0x7fdad5fa5a1d in CoinOffscreenGLCanvas::clampSize(SbVec2s&) from /usr/lib/x86_64-linux-gnu/libCoin.so.80c+0x1d                                                                                               
#8  0x7fdad5fa5b67 in CoinOffscreenGLCanvas::setWantedSize(SbVec2s) from /usr/lib/x86_64-linux-gnu/libCoin.so.80c+0x17                                                                                            
#9  0x7fdad5fa01fa in SoOffscreenRendererP::renderFromBase(SoBase*) from /usr/lib/x86_64-linux-gnu/libCoin.so.80c+0xca                                                                                            
#10  /usr/lib/python2.7/dist-packages/pivy/_coin.x86_64-linux-gnu.so(+0x3db534) [0x7fdad6859534]
#11  python(PyEval_EvalFrameEx+0x695b) [0x557bda68a8db]
#12  python(PyEval_EvalCodeEx+0x6da) [0x557bda681d0a]
#13  python(PyEval_EvalFrameEx+0x5cb8) [0x557bda689c38]
#14  python(PyEval_EvalFrameEx+0x52b2) [0x557bda689232]
#15  python(PyEval_EvalCodeEx+0x6da) [0x557bda681d0a]
#16  python(PyEval_EvalCode+0x19) [0x557bda681629]
#17  python(+0x12461f) [0x557bda6b261f]
#18  python(PyRun_FileExFlags+0x82) [0x557bda6ad322]
#19  python(PyRun_SimpleFileExFlags+0x18d) [0x557bda6ac67d]
#20  python(Py_Main+0x68b) [0x557bda65b1ab]
#21  /lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xe7) [0x7fdaf58bcb97]
#22  python(_start+0x2a) [0x557bda65aa2a]
My base image is Ubuntu:18.04 and I'm using a freecad-daily ppa build "FreeCAD 0.18, Libs: 0.18R16093 (Git)"
Is this possible in a Docker container? Thanks.
rkneills
Posts: 6
Joined: Wed Mar 06, 2019 1:55 pm

Re: Take pictures from python without using GUI

Post by rkneills »

Found a solution to the above problem using FreeCADGui and the tool xvfb which lets you perform graphical operations in memory without requiring a display.
The setup process for xvfb on ubuntu looks something like this:

Code: Select all

apt-get install xvfb
Xvfb :5 -screen 0 800x600x24 &
export DISPLAY=:5
And heres my function to get pictures of parts:

Code: Select all

def generateThumbnail(model, fileName):
    import FreeCADGui

    FreeCADGui.showMainWindow()
    mw=FreeCADGui.getMainWindow()
    mw.hide()

    doc=FreeCAD.newDocument()

    try:
        Part.show(model)
    except:
        Mesh.show(model)

    view = FreeCADGui.getDocument(doc.Name).activeView()
    view.setAnimationEnabled(False)
    view.viewAxometric()
    view.fitAll()
    
    view.saveImage('%s.png' % fileName,800,600,'Transparent')
    FreeCAD.closeDocument(doc.Name)
This allows me to take pictures of parts while running in a ubuntu server/docker container
triplus
Veteran
Posts: 9471
Joined: Mon Dec 12, 2011 4:45 pm

Re: Take pictures from python without using GUI

Post by triplus »

Thanks for sharing the working solution.
Post Reply