Hcpy problem in CGX

Hello, I am testing a cloud application containing CGX at https://az.nuvolos.cloud/

There I came across the following strange behaviour with CGX hcpy command.

Left is the preview of the png file in vscode, to the right you see the actual cgx window.
The triad including the “s” tag is mirrored about the horizontal axis and the graphics area also seems to be mirrored, at least the title is gone and the upper margin (where the title could have gone) is cut off.

This looks the same for gif files.

The native export format of CGX seems to be tga, other formats are generated using the convert command.

Yet hcpy tga generates a file, which also isn’t correct. In Inkscape it displays like this

This means the file is still wrong and not just mis-oriented.

here is another example of a “piecewise mirrored” image:

CCX and CGX have been built from source by the nuvolos admins, the user (me) just has no access to the header file, i.e. I can’t compile

The following added info might be of help:

  • if compiled and run on a quite old virtual box (Linux machine, nodename vb, release 3.16.0-38-generic, version #52~14.04.1-Ubuntu SMP Fri May 8 09:43:57 UTC 2015, machine x86_64), the hcpy command works correct.
  • if I copy that executable from the virtual box to the nuvolos application, the problem appears again.
  • so I assume that it is not a problem on CGX code side but in some library or external tool used in the process of hardcopying, or even in the graphics interface of the system.

Has anyone encountered and possibly fixed this kind of problem? Or any idea where to dig for a solution?

Martin Kraska

Seems there is some discussion about the issue here:

And the workaround to add -auto-orient to the convert command worked for me.

[feacluster@micro src]$ grep convert *.c | grep auto
cgx.c:      sprintf( buffer, "convert -auto-orient hcpy_%d.tga -page A4 %s", psNr, fileName);
cgx.c:      sprintf( buffer, "convert -auto-orient hcpy_0.tga _%d.gif",gifNr);
cgx.c:      sprintf( buffer, "convert -auto-orient hcpy_%d.tga %s", gifNr, fileName);
cgx.c:      sprintf( buffer, "convert -auto-orient hcpy_%d.tga %s", pngNr, fileName);

Thank you for pointing to the issue. Yet, the problem is that already the tga file is wrong, As you see in the inkscape screenshot, the title is missing and the triade is wrongly placed.

The screenshot actually seems to be composed of 3 individual tga files, which are then composed into the final one. Thus, either these screenshots are already mis-oriented and mis-cropped or the call to composite is broken. I’ll have to create a modified CGX executable which does not delete the intermediate tga files.

I adapted the workaround by feacluster to solve the problem by applying “convert -auto-orient 0__.tga 0__.tga” to all three raw tga files (frame with legend, graphics area, triade).

Then the result on both test systems is correct.

I think there should be a smarter fix but for now I am fine with how it is.

in cgx.c:

	// get the orientation of the tga files right
	sprintf( buffer, "convert -auto-orient 0__.tga 0__.tga");
	system (buffer);
	sprintf( buffer, "convert -auto-orient 1__.tga 1__.tga");
	system (buffer);
	sprintf( buffer, "convert -auto-orient 2__.tga 2__.tga");
	system (buffer);

Hi,

I’m a new Calculix user so I’m not able to distinguish between a program bug and a script bug.
I have Windows 11 and I use cgx 2.10.1 (installed with bConverged).

It seems that I have the problem related to this topic.
I attached the figures I got with the code below.
In both figures, I’m not able to set the figure name.
The first figure is rotated and not fitted properly.
The second figure is not fitted properly.

Is it a script problem or a program bug?

Thanks

# Geometry 
valu beam_length 100
valu beam_height 10
valu force_y 10

# Set line divisions
valu ld1 100
valu ld2 10
valu ld3 100
valu ld4 10

# Create nodes
pnt p1 0 0 0
pnt p2 beam_length 0 0
pnt p3 beam_length beam_height 0
pnt p4 0 beam_height 0

# Display points with names
# pa = p (points) + a (names)
plot pa all

# Create lines 
line l1 p1 p2
line l2 p2 p3
line l3 p3 p4
line l4 p4 p1

# Assign line divisions (density of elements)
div l1 ld1
div l2 ld2
div l3 ld3
div l4 ld4

# Plot lines
# plus (append to previous plot, i.e. points)
# ld = l (lines) + d (divisions)
plus ld all

# Create line sets
# All entities must be stored at least in one set to be reachable
seta s1_lines l l1 l2 l3 l4

# Create surface
surf s1_surf s1_lines

# all surfaces will be flipped in a way
# that they share a common direction (in or out of a volume)
flip s1_surf auto

# Contain all surfaces in a set
seta surf_all s all

# Plot surfaces
# plus (append to previous plot, i.e. points + lines)
# sa = s (surfaces) + a (names)
plus sa all

# Rotate view
rot -z

# Print geometry view
hcpy png geometry


## Meshing

# Assign element type to sets
# qu4 (quadrangle, 4 node shell element) + s (plane stress)
# *---*
# |   |
# *---*
elty surf_all qu4s

# Mesh the geometry
mesh all

# Store all nodes in a set
seta nodes_all n all

# # Assign to set "ux_fixed" the nodes in set "nodes_all" 
# # with coordinates (x=0, y=_ (infinite range), z=0) with a tolerance of 0.001
enq nodes_all ux_fixed rec 0 _ 0 0.001
# # Assign to set "uy_fixed" the nodes in set "nodes_all" 
# # with coordinates (x=0, y=_ (infinite range), z=0) with a tolerance of 0.001
enq nodes_all uy_fixed rec 0 _ 0 0.001

# Node sets containing boundary condition nodes are written to files
# abq = Abaqus format mesh (used by calculix solver)
# nam = sets of nodes and elements
send ux_fixed abq nam
send uy_fixed abq nam

# Export loading surface information to a file
seta force l l2
comp force do
send force abq sur

# All nodal information is exported to a file
send nodes_all abq

# Elemental information is exported to a file
seta ps e surf_all
send ps abq


# Save image of the mesh model
rot -z
ulin test xxxxx.
view elem
# plot faces
plot f all t
plus n ux_fixed r 10 
plus n uy_fixed g 10
plus n force b 10
frame
hcpy png model

It is a problem with ImageMagick (which cgx uses for picture manipulation and conversion), specifically when moving from ImageMagick 6 to 7. I noticed it in 2022 and communicated with Klaus Wittig about it.

According to the developers of ImageMagick, the --auto-orient flag should always be used when converting TGA file.
Unfortunately, composite does not accept this flag.

So the solution that was implemented is to use mogrify --auto-orient on the TGA files before combining them with composite. This was fixed in version 2.20.

Since you are reading and writing the same file, it might be better to use mogrify instead of convert, since the former is meant to convert files in-place, while convert isn’t. It’s also shorter, since you only need the filename once.

Hi,

thanks for your answer.
I’ve just installed cgx 2.21. Now, I can save the figures with their names and legends.
However, I got the following errors:

 'mogrify' is not recognized as an internal or external command,
operable program or batch file.
'mogrify' is not recognized as an internal or external command,
operable program or batch file.
'mogrify' is not recognized as an internal or external command,
operable program or batch file.

I installed “ImageMagick-7.1.1-20-Q16-x64-dll” on my PC but I still get the same errors.
However, If I run magick mogrify on cmd I get the messages below (it should be ok).

Do you know a possible solution for this?
Thanks

C:\Users\Cristian>magick mogrify
Version: ImageMagick 7.1.1-20 Q16 x64 98bb1d4:20231008 https://imagemagick.org
Copyright: (C) 1999 ImageMagick Studio LLC
License: https://imagemagick.org/script/license.php
Features: Channel-masks(64-bit) Cipher DPC Modules OpenCL OpenMP(2.0)
Delegates (built-in): bzlib cairo flif freetype gslib heic jng jp2 jpeg jxl lcms lqr lzma openexr pangocairo png ps raqm raw rsvg tiff webp xml zip zlib
Compiler: Visual Studio 2022 (193532217)
Usage: mogrify [options ...] file [ [options ...] file ...]

Image Settings:
  -adjoin              join images into a single multi-image file
  -affine matrix       affine transform matrix
  -alpha option        activate, deactivate, reset, or set the alpha channel
  -antialias           remove pixel-aliasing
  -authenticate password
                       decipher image with this password
  -attenuate value     lessen (or intensify) when adding noise to an image
  -background color    background color
  -bias value          add bias when convolving an image
  -black-point-compensation

On UNIX-like operating systems the commands like convert and mogrify are just symbolic links to magick.
ImageMagick checks how it is invoked and acts accordingly.
It seems the ms-windows package doesn’t have those.

I see at least two possible solutions;

  1. Create shortcuts to magick named convert, composite and mogrify in the folder where the magick binary resides.
  2. Create batch files, e.g. mogrify.bat that contains the correct invocation. In this case magick mogrify %*

Since I don’t use ms-windows, I can’t check if (1) works on that platform. It will depend on what is supplied as the first argument, the name of the file or the name of the link.

With option 2 I don’t get error messages anymore, thank you.
However, the legend is rotated.
I think I can keep the error messages…
What really matters is: does my .fbd code produce the desired figures or something is missing? i.e. what cgx is trying to do with the mogrify failed commands?

CalculiX GrpahicX uses the composite command from ImageMagick to combine the different parts of the window that are saved as TGA files into one image.

However, as of ImageMagick 7, the -auto-orient flag mandatory needed to orient the TGA files properly. However, the composite command doesn’t support that flag. So cgx first uses mogrify to fix the images, and then uses composite to combine them into one image.

You can see that here in the source code.

1 Like