# How to run cgx in batch mode and create screenshots

**URL:** <https://calculix.discourse.group/t/how-to-run-cgx-in-batch-mode-and-create-screenshots/1807>\
**Category:** CalculiX GraphiX\
**Created:** [September 11, 2023, 10:18am UTC](https://calculix.discourse.group/t/how-to-run-cgx-in-batch-mode-and-create-screenshots/1807 "2023-09-11T10:18:30Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![Megidd](https://yyz2.discourse-cdn.com/free1/user_avatar/calculix.discourse.group/megidd/32/1875_2.png) [@Megidd](https://calculix.discourse.group/u/Megidd)\
**Post date:** [September 11, 2023, 10:18am UTC](https://calculix.discourse.group/t/how-to-run-cgx-in-batch-mode-and-create-screenshots/1807/1 "2023-09-11T10:18:30Z")

</div>

# Background

I have studied the [documentation](http://www.dhondt.de/cgx_2.21.pdf) section B.14 about how to run cgx in batch mode. But I cannot figure out a problem.

I have this FBD file:

```auto
# Change file name to the job name you used.
read C:\Users\m3\AppData\Local\Temp\result-layer0-to-layer3.frd

capt "Layer 0 to 3"

# Data set number depends on how may things you saved!
ds 2 e 7

gonly off

rot y
frame
hcpy png right

gonly on

rot r 90
frame
hcpy png front

rot r 90
frame
hcpy png left

rot r 90
frame
hcpy png back

rot y
rot u 90
frame
hcpy png top

rot d 180
frame
hcpy png bottom

quit

```

# Good case

When I run this FBD file like this, everything is fine:

```bash
cgx_STATIC.exe -b C:\Users\m3\AppData\Local\Temp\shot-710971079.fbd

```

The PNG files are stored next to CGX executable as expected:

 ![2023-09-11 13_39_13-net48](https://global.discourse-cdn.com/free1/uploads/calculix/original/2X/2/26698f41ff5843fd264ad26c365dd604006ea27a.png)

And the CGX logs are:

```auto
on a Windows 10 machine, nodename ADMINISTRATOR, release 10, version 10.0 19041, machine 8664
 The win HOME was detected:C:\Users\m3
parameters:3 arguments:2
GL_MAX_EVAL_ORDER:32, mesh threads:1
 C:\Users\m3\AppData\Local\Temp\shot-710971079.fbd opened

 reading file
 # Change file name to the job name you used.
 file:C:\Users\m3\AppData\Local\Temp\result-layer0-to-layer3.frd opened
 reading frd format
 MODEL NAME: record: 1UModel: 3D model Date: 2023-Sep-11 UTC
record: 1UUSER
record: 1UDATE 11.september.2023
record: 1UTIME 13:12:17
record: 1UHOST
record: 1UPGM CalculiX
record: 1UVERSION Version 2.20
record: 1UCOMPILETIME Sat Apr 1 21:09:13 2023
record: 1UDIR
record: 1UDBN
record: 1UMAT 1RESIN
record: 2C 2362 1
reading Nodes

 2362 nodes reallocated
record: 3C 5651 1
reading Elements

 5651 elements reallocated
record: 1PSTEP 1 1 1
record: 100CL 101 1.000000000 2362 0 1 1
reading Dataset No:1
 gen lc[0] ncomps:4
ncomps:3 nvals:3
record: 1PSTEP 2 1 1
record: 100CL 101 1.000000000 2362 0 1 1
reading Dataset No:2
 gen lc[1] ncomps:6
ncomps:6 nvals:6
record: 1PSTEP 3 1 1
record: 100CL 101 1.000000000 2362 0 1 1
reading Dataset No:3
 gen lc[2] ncomps:1
ncomps:1 nvals:1
record: 9999
gtol calculated:8.495190e-05
 ready
 # Data set number depends on how may things you saved!

2 L 101 1.000000 STRESS Mises
 Extremal values from displayed mesh-entities:
 max:1.165530e-03 at node:1790
 min:0.000000e+00 at node:1

2 L 101 1.000000 STRESS Mises
 Extremal values from displayed mesh-entities:
 max:1.165530e-03 at node:1790
 min:0.000000e+00 at node:1

2 L 101 1.000000 STRESS Mises
 Extremal values from displayed mesh-entities:
 max:1.165530e-03 at node:1790
 min:0.000000e+00 at node:1

2 L 101 1.000000 STRESS Mises
 Extremal values from displayed mesh-entities:
 max:1.165530e-03 at node:1790
 min:0.000000e+00 at node:1
create right.png
 ready

2 L 101 1.000000 STRESS Mises
 Extremal values from displayed mesh-entities:
 max:1.165530e-03 at node:1790
 min:0.000000e+00 at node:1

2 L 101 1.000000 STRESS Mises
 Extremal values from displayed mesh-entities:
 max:1.165530e-03 at node:1790
 min:0.000000e+00 at node:1

2 L 101 1.000000 STRESS Mises
 Extremal values from displayed mesh-entities:
 max:1.165530e-03 at node:1790
 min:0.000000e+00 at node:1
create front.png
 ready

2 L 101 1.000000 STRESS Mises
 Extremal values from displayed mesh-entities:
 max:1.165530e-03 at node:1790
 min:0.000000e+00 at node:1

2 L 101 1.000000 STRESS Mises
 Extremal values from displayed mesh-entities:
 max:1.165530e-03 at node:1790
 min:0.000000e+00 at node:1
create left.png
 ready

2 L 101 1.000000 STRESS Mises
 Extremal values from displayed mesh-entities:
 max:1.165530e-03 at node:1790
 min:0.000000e+00 at node:1

2 L 101 1.000000 STRESS Mises
 Extremal values from displayed mesh-entities:
 max:1.165530e-03 at node:1790
 min:0.000000e+00 at node:1
create back.png
 ready

2 L 101 1.000000 STRESS Mises
 Extremal values from displayed mesh-entities:
 max:1.165530e-03 at node:1790
 min:0.000000e+00 at node:1

2 L 101 1.000000 STRESS Mises
 Extremal values from displayed mesh-entities:
 max:1.165530e-03 at node:1790
 min:0.000000e+00 at node:1

2 L 101 1.000000 STRESS Mises
 Extremal values from displayed mesh-entities:
 max:1.165530e-03 at node:1790
 min:0.000000e+00 at node:1
create top.png
 ready

2 L 101 1.000000 STRESS Mises
 Extremal values from displayed mesh-entities:
 max:1.165530e-03 at node:1790
 min:0.000000e+00 at node:1

2 L 101 1.000000 STRESS Mises
 Extremal values from displayed mesh-entities:
 max:1.165530e-03 at node:1790
 min:0.000000e+00 at node:1
create bottom.png
 ready

```

# Bad case

But when running the CGX with the `-bg` parameter to run it in batch mode:

```auto
cgx_STATIC.exe -bg C:\Users\m3\AppData\Local\Temp\shot-710971079.fbd

```

No PNG image is created. The CGX logs are:

```auto
on a Windows 10 machine, nodename ADMINISTRATOR, release 10, version 10.0 19041, machine 8664
 The win HOME was detected:C:\Users\m3
parameters:3 arguments:2
 C:\Users\m3\AppData\Local\Temp\shot-710971079.fbd opened

 reading file
 # Change file name to the job name you used.
 file:C:\Users\m3\AppData\Local\Temp\result-layer0-to-layer3.frd opened
 reading frd format
 MODEL NAME: record: 1UModel: 3D model Date: 2023-Sep-11 UTC
record: 1UUSER
record: 1UDATE 11.september.2023
record: 1UTIME 13:12:17
record: 1UHOST
record: 1UPGM CalculiX
record: 1UVERSION Version 2.20
record: 1UCOMPILETIME Sat Apr 1 21:09:13 2023
record: 1UDIR
record: 1UDBN
record: 1UMAT 1RESIN
record: 2C 2362 1
reading Nodes

 2362 nodes reallocated
record: 3C 5651 1
reading Elements

 5651 elements reallocated
record: 1PSTEP 1 1 1
record: 100CL 101 1.000000000 2362 0 1 1
reading Dataset No:1
 gen lc[0] ncomps:4
ncomps:3 nvals:3
record: 1PSTEP 2 1 1
record: 100CL 101 1.000000000 2362 0 1 1
reading Dataset No:2
 gen lc[1] ncomps:6
ncomps:6 nvals:6
record: 1PSTEP 3 1 1
record: 100CL 101 1.000000000 2362 0 1 1
reading Dataset No:3
 gen lc[2] ncomps:1
ncomps:1 nvals:1
record: 9999
gtol calculated:8.495190e-05
 ready
 # Data set number depends on how may things you saved!

2 L 101 1.000000 STRESS Mises
 Extremal values from displayed mesh-entities:
 max:1.165530e-03 at node:1790
 min:0.000000e+00 at node:1

```

# Question

I studied the documentation but I could not figure out why with `-bg` parameter, CGX won’t create the PNG files.

I have to run CGX in batch mode since I’m going to run it by another program to create the PNG files. I don’t want the user of the other program to observe the pop-up of the CGX graphic window.

---

<div class="post-metadata">

**Author:** ![Megidd](https://yyz2.discourse-cdn.com/free1/user_avatar/calculix.discourse.group/megidd/32/1875_2.png) [@Megidd](https://calculix.discourse.group/u/Megidd)\
**Post date:** [September 11, 2023, 11:15am UTC](https://calculix.discourse.group/t/how-to-run-cgx-in-batch-mode-and-create-screenshots/1807/2 "2023-09-11T11:15:28Z")

</div>

Adding the command `stack on` to the FBD file didn’t help.

---

<div class="post-metadata">

**Author:** ![rsmith](https://yyz2.discourse-cdn.com/free1/user_avatar/calculix.discourse.group/rsmith/32/1684_2.png) [@rsmith](https://calculix.discourse.group/u/rsmith)\
**Post date:** [September 11, 2023, 7:10pm UTC](https://calculix.discourse.group/t/how-to-run-cgx-in-batch-mode-and-create-screenshots/1807/3 "2023-09-11T19:10:23Z")

</div>

> [@Megidd](#):
>
> I studied the documentation but I could not figure out why with `-bg` parameter, CGX won’t create the PNG files.

I’m not sure if it is in the documentation, but it is tied to the way `cgx` works.

Basically (and I’m skimping over a lot here) the 3D API that CalculiX GraphicX uses (OpenGL) renders the 3D scene to a “frame buffer”, a piece of memory to store a 2D pixel image.  
The `hcpy` function basically copies the image from the frame buffer and saves it to a file.

If you use `-bg` there is no screen to render to, so no image.

Now, OpenGL does support off-screen rendering but it’s not automatic, the programmer has to explicitly program that to make it work. And if you’re rendering off-screen, how big should the image be?

---

<div class="post-metadata">

**Author:** ![Megidd](https://yyz2.discourse-cdn.com/free1/user_avatar/calculix.discourse.group/megidd/32/1875_2.png) [@Megidd](https://calculix.discourse.group/u/Megidd)\
**Post date:** [September 12, 2023, 9:57am UTC](https://calculix.discourse.group/t/how-to-run-cgx-in-batch-mode-and-create-screenshots/1807/4 "2023-09-12T09:57:20Z")

</div>

Right ✅

I’m reading the CGX version 2.21 source code. I see that `HCPY` calls `createHardcopy()` function that calls `getTGAScreenShot()` function that calls `glutSetWindow()` function and `SaveTGAScreenShot()` function that is calling `glReadPixels()` function like this:

```c
/* This will save a screen shot to a file. */
void SaveTGAScreenShot(char *filename, int w, int h)
{
   char *imageData;
   imageData = (char *)malloc(sizeof(char) * w * h * 4);
   glReadPixels(0, 0, w, h,GL_RGBA,GL_UNSIGNED_BYTE, (GLvoid *)imageData);
   WriteTGA(filename,w,h,imageData);
   // release the memory
   free(imageData);
}

```

I’m going to research further 📚

---

<div class="post-metadata">

**Author:** ![Megidd](https://yyz2.discourse-cdn.com/free1/user_avatar/calculix.discourse.group/megidd/32/1875_2.png) [@Megidd](https://calculix.discourse.group/u/Megidd)\
**Post date:** [September 12, 2023, 10:11am UTC](https://calculix.discourse.group/t/how-to-run-cgx-in-batch-mode-and-create-screenshots/1807/5 "2023-09-12T10:11:51Z")

</div>

By the way, CGX source code sometimes considers the Windows OS by:

```c
#ifdef WIN32
    sprintf (buffer, "move /y \"%s\" \"%s.fbb\"", datin, setname );
#else
    sprintf (buffer, "mv %s %s.fbb", datin, setname );
#endif

```

But there are many places that Windows OS is not considered at all, like this case:

```c
void getTGAScreenShot(int nr)
{
    //...
    sprintf( buffer, "rm -f *__.tga %s",DEV_NULL);
    // ...
}

```

Now I understand why I had to copy `rm.exe` and `mv.exe` from `C:\cygwin64\bin` next to my CGX executable 🙂

---

<div class="post-metadata">

**Author:** ![Megidd](https://yyz2.discourse-cdn.com/free1/user_avatar/calculix.discourse.group/megidd/32/1875_2.png) [@Megidd](https://calculix.discourse.group/u/Megidd)\
**Post date:** [September 12, 2023, 11:01am UTC](https://calculix.discourse.group/t/how-to-run-cgx-in-batch-mode-and-create-screenshots/1807/6 "2023-09-12T11:01:02Z")

</div>

The CGX version 2.21 source code indicates that `inpformat` variable is set to `0` in the case of `-bg` mode:

```c

      else if( compare( argv[j], "-bg", 3 ) == 3 )
      { 
        // ...
        inpformat=0;
        // ...
      }

```

And then, screenshot creation is skipped altogether if `inpformat` is set to `0` like this:

```c
void createHardcopy( int selection, char *filePtr )
{

  if(!inpformat) return;

  // ...
}

```

Also here:

```c
void getTGAScreenShot(int nr)
{

    if(!inpformat) return;

    // ...
}

```

---

<div class="post-metadata">

**Author:** ![rsmith](https://yyz2.discourse-cdn.com/free1/user_avatar/calculix.discourse.group/rsmith/32/1684_2.png) [@rsmith](https://calculix.discourse.group/u/rsmith)\
**Post date:** [September 12, 2023, 5:43pm UTC](https://calculix.discourse.group/t/how-to-run-cgx-in-batch-mode-and-create-screenshots/1807/7 "2023-09-12T17:43:08Z")

</div>

> [@Megidd](#):
>
> But there are many places that Windows OS is not considered at all

Maybe send a patch to Klaus Wittig?

> [@Megidd](#):
>
> screenshot creation is skipped altogether if `inpformat` is set to `0`

With OpenGL it is possible to set up an off-screen render context. So it _could_ probably be done. Although I don’t know if that functionality is available on all platforms that `cgx` runs on. The question then is also how big to make that image? That should probably be made configurable as well.

---

<div class="post-metadata">

**Author:** ![Megidd](https://yyz2.discourse-cdn.com/free1/user_avatar/calculix.discourse.group/megidd/32/1875_2.png) [@Megidd](https://calculix.discourse.group/u/Megidd)\
**Post date:** [September 12, 2023, 8:52pm UTC](https://calculix.discourse.group/t/how-to-run-cgx-in-batch-mode-and-create-screenshots/1807/8 "2023-09-12T20:52:21Z")

</div>

> [@rsmith](#):
>
> Maybe send a patch to Klaus Wittig?

Good idea 👍

> [@rsmith](#):
>
> With OpenGL it is possible to set up an off-screen render context. So it _could_ probably be done.

Thanks. I’m going to research that 📚

> [@rsmith](#):
>
> Although I don’t know if that functionality is available on all platforms that `cgx` runs on.

Maybe just Windows OS is enough for me at this point.

> [@rsmith](#):
>
> The question then is also how big to make that image? That should probably be made configurable as well.

Right ✅ The window size should be configured.

---

<div class="post-metadata">

**Author:** ![rgre](https://avatars.discourse-cdn.com/v4/letter/r/dec6dc/32.png) [@rgre](https://calculix.discourse.group/u/rgre)\
**Post date:** [September 22, 2023, 11:02am UTC](https://calculix.discourse.group/t/how-to-run-cgx-in-batch-mode-and-create-screenshots/1807/9 "2023-09-22T11:02:44Z")

</div>

If it is an option, maybe you can run cgx on a Linux machine and use the virtual frame buffer Xvfb. This allows to run graphical applications without a screen attached. It has come in handy for me in the past, although I have not tested with cgx.

It should be than as easy as running ‘xvfb-run cgx -b [frd]’

If you run into issues with OpenGL, you may find some pointers on Stackoverflow: [opengl es - GLX offscreen rendering in headless system - Stack Overflow](https://stackoverflow.com/questions/75680223/glx-offscreen-rendering-in-headless-system)

I’m not aware of similar options for Windows though…

Edit: just tried, using Xvfb works for me on Linux.
