HardCopy FAQs

  1. When should I use HardCopy vectorize actions for printing instead of the Open Inventor SoOffscreenRenderer class?
  2. How come textures in my scene graph are not printed with HardCopy?
  3. How come VolumeViz representations in my scene graph are not printed with HardCopy?
  4. How can I print an image and specify its size on the paper?
  5. How can I create hardcopy output that has specific physical dimensions?
  6. Why do I see my scene correctly in my viewer but my paper sheet is blank when I print it?
  7. Why do objects appear in front of other objects when they should be behind?
  8. Why are some shapes (e.g., PoRectangle,…) displayed correctly in my viewer in wireframe, but additional lines appear on my printout? What can I do?
  9. Why are some fonts in my scene graph (especially on Win32) rendered correctly in my viewer, but generate a parsing error when I try to read them with a PostScript viewer from an output file generated with SoVectorizePSAction?
  10. [Win32] How do I print within an MFC application?
  11. Why, even if I specify Gouraud shading, are printed shapes always shown with flat shading? Why isn’t the PER_VERTEX material binding supported?
  12. How can I print different scene graphs on the same sheet of paper?
  13. Why do clip planes (SoClipPlane) work correctly in my viewer, but not in HardCopy output?
  14. What are the limitations I should know about with respect to using HardCopy?

When should I use HardCopy vectorize actions for printing instead of the Open Inventor SoOffscreenRenderer class?

First, the short answer: You can/should use these actions to render resolution-independent output for large format plotters when your scene is 2D or 3D with wireframe or flat shaded rendering.You cannot use these actions for rendering realistic 3D scenes with smooth shading and textures.

Here’s a longer answer. SoOffScreenRenderer creates a bitmap image of your scene whereas SoVectorizeAction creates a vector representation of your scene.

With raster (bitmap) output, a shape is defined by a set of pixels. Supported bitmap formats include JPEG, BMP, TIFF, and others.

With vector output, shapes are defined by their coordinates. For example, a line segment is defined by the two coordinates of its end points. Supported vector formats include PostScript (SoVectorizePSAction), HPGL (SoVectorizeHPGLAction), CGM (SoVectorizeCGMAction) and GDI (SoVectorizeGDIAction).

For some purposes, bitmaps are superior. For others, vector output is superior.

Bitmap Pros and Cons:

+  A bitmap has full, realistic rendering -- Z-buffering, lighting, shading, transparency, textures, volume rendering, etc.
+/-  For a given bitmap dimension, it doesn’t matter how complex or simple the scene is, the bitmap’s size is constant.
-  Bitmaps have finite resolution and so don’t scale up to large sizes well.

Vector Pros and Cons:

+  Vector based. Can scale to any size without loss of detail.
-/+  If the scene is very complex, the output file will be large. (Conversely if the scene is very simple, the output file will be small.)
-  Certain rendering features are not available.

How come textures in my scene graph are not printed with HardCopy?

HardCopy does not support textures. The Open Inventor offscreen renderer (SoOffscreenRenderer) is the only way to produce an image containing textures.

NOTE: In some cases, an SoPattern node may be a suitable substitute for a texture node. SoPattern nodes are correctly rendered using HardCopy.

How come VolumeViz representations in my scene graph are not printed with HardCopy?

HardCopy does not support VolumeViz. The Open Inventor offscreen renderer (SoOffscreenRenderer) is the only way to produce an image of volume rendering.

How can I print an image and specify its size on the paper?

Insert an SoImage node in the scene graph that you want to print and use the setPixelImageSize() method of the SoVectorizeAction class to specify the size of a pixel in physical units.

How can I create hardcopy output that has specific physical dimensions?

The following are some hints for producing output with physically correct dimensions using CGM (or PostScript, HPGL, or GDI):

  • Work in printing coordinates
    For instance, a 10mm x 10mm cube will be defined as follows:
SoCube *cube = new SoCube;
cube ->width = 10;
cube->height = 10;
  • Configure the camera to the size of the paper. For 2D drawings, useSoOrthographicCamera with the viewport mapping set to LEAVE_ALONE (in order to prevent distortion).
    The following figure shows how to configure the camera and the Open Inventor shapes according to the dimensions of the paper:

Why do I see my scene correctly in my viewer but my paper sheet is blank when I print it?

All viewers automatically search for the first camera in the scene graph, starting at the root and searching downward from there. If the viewer finds a camera, it uses it. If it does not find one, it creates a camera. If the viewer is an editor (SoXtViewer::Type), it inserts the created camera under the scene graph root. If the viewer is a browser (the default), it inserts the created camera above the scene graph.
In the usual case, where the viewer is a browser and no camera is explicitly defined in the scene graph, if you directly apply a vectorize action to the scene graph root, HardCopy has no camera and uses a default view which is in the normalized space [-1,-1,-1] x [1,1,1]. This very often generates an empty document.

In order to get the camera added by the viewer, you must use the getSceneManager() method of SoXtViewer, then the getSceneGraph() method of SoSceneManager:

SoVectorizePSAction psVecAction;
psVecAction.apply(myViewer->getSceneManager()->getSceneGraph());
... 

Why do objects appear in front of other objects when they should be behind?

For performance reasons, by default HardCopy does not take into account the depth (z coordinates) of the Open Inventor shapes that it processes. So for a 3D scene, you may obtain unexpected results.

The method setHLHSRMode (HLHSRMode mode) of SoVectorizeAction allows you to specify how depth of shapes is handled.

However, except for the mode HLHSR_PAINTER_SURFACE_REMOVAL where hidden surfaces are removed, all surfaces are printed (even the ones that are hidden), but are sorted according to their depth.

Why are some shapes (e.g., PoRectangle,…) displayed correctly in my viewer in wireframe, but additional lines appear on my printout? What can I do?

HardCopy treats each Inventor face as a set of triangles and renders the triangles individually. For example, a rectangle is considered to be two separate triangles. HardCopy displays them in wireframe individually, so an extra diagonal line appears.

In this case, the only way to solve this problem is to use a line set shape (for example SoLineSet or SoIndexedLineSet) to draw the rectangle.

Why are some fonts in my scene graph (especially on Win32) rendered correctly in my viewer, but generate a parsing error when I try to read them with a PostScript viewer from an output file generated with SoVectorizePSAction?

This problem can only occur with non-vector text strings (such as SoText2) and occurs primarily on Windows platforms. It is due to the fact that Open Inventor for Windows uses TrueType fonts whereas PostScript uses PostScript fonts and their names do not match. For instance the Courier font is called “Courier New” on Windows but is called “Courier” in PostScript. (Arial is an exception. The name is the same for Windows and PostScript.) A PostScript file containing an unknown font name (such as “Courier New”) will not be correctly parsed by a PostScript viewer. In order to obtain useful PostScript output, you must temporarily change the font name (to one that PostScript recognizes) before applying the vectorize PostScript action, then restore the name just after.

For convenience, you can implement a table that maps between Window TrueType fonts and PostScript fonts.

The following PostScript fonts are almost always available:

  • Times-Roman
  • Times-Italic
  • Times-Bold
  • Times-BoldItalic
  • Helvetica
  • Helvetica-Oblique
  • Helvetica-Bold
  • Helvetica-BoldOblique
  • Courier
  • Courier-Oblique
  • Courier-Bold
  • Courier-BoldOblique
  • Symbol

[Win32] How do I print within an MFC application?

In order to print within a MFC application using theSoVectorizeGDIAction action you must do the following:

CxxxView: class name deriving from CView.

In the method CxxxView::OnPrint():

  1. Retrieve the printable size.
  2. Convert the printable size to 1/100 mm.

In the method CxxxView::OnDraw():

  1. Initialize a PRINTDLGstructure to initialize the Print dialog box.
  2. Invoke the print dialog box.
  3. Retrieve the handle of the device context of the printer.
  4. Retrieve the paper size from the handle of the device context and convert it to 1/100 mm.
  5. Compute margins from the paper size and the printable size.
  6. Configure the SoVectorizeGDIAction action according to the margins and the printable size (with the methodssetStartPosition() and setDrawingDimensions()).
  7. Pass the handle of the device context to the SoVectorizeGDIAction (with the method getOutput()->openFile(Hdc hdc)).
  8. Realize the output using the apply() method of SoVectorizeGDIAction.

An implementation corresponding to the previous explanation is available in the directory %OIVHOME%\src\MeshViz\Demos\Ivf\GDIPrintPreview.

Why, even if I specify Gouraud shading, are printed shapes always shown with flat shading? Why isn’t the PER_VERTEX material binding supported?

Most 2D vector formats do not support having a color specified at each vertex of a polygon, hence it is not possible to support Gouraud shading nor PER_VERTEX material binding. Nevertheless, HardCopy can take lighting effects into account for faces (not active by default) with the enableLighting() method of SoVectorizeAction.

NOTE: Starting with Version 5 of HardCopy, Gouraud (smooth) shading is supported if you are generating PostScript Level 3 output. To request smooth shading, use the the setShadeModel() method of SoVectorizeAction. To request PostScript Level 3 output, use SoPSVectorOutput::setLevel(3).

 How can I print different scene graphs on the same sheet of paper?

When you have several scene graphs, each one has its own coordinate system and its own viewing. The beginPage() and endPage() methods of SoVectorizeAction can be used to merge these different scene graphs in the same document.

The following source code shows you how:

SoVectorizePSAction vectPS ;
vectPS.beginPage(startPos, pageSize);

// Draw the scene graph root1 from the start point(x1, y1) to the
// end point (x1+width1, y1+height1)
vectPS.setStartPosition(x1, y1);
vectPS.setDrawingDimensions(width1, height1);
vectPS.setBorder(2.0);
vectPS.apply(root1);

// Draw the scene graph root2 from the start point(x2, y2) to the
// end point (x2+width2, y2+height2)
vectPS.setStartPosition(x2, y2);
vectPS.setDrawingDimensions(width2, height2);
vectPS.apply(root2);

... 

// Draw the scene graph rooti from the start point(xi, yi) to the
// end point (xi+widthi, yi+heighti)
vectPS.setStartPosition(xi, yi);
vectPS.setDrawingDimensions(widthi, heighti);
vectPS.apply(rooti);

vectPS.endPage();

Another approach consists of using one PoSceneView per scene graph.

Why do clip planes (SoClipPlane) work correctly in my viewer, but not in HardCopy output?

Modeling clipping is completely ignored by HardCopy.

What are the limitations I should know about with respect to using HardCopy?

Most (but not all) of the limitations have already been covered in the previous questions. For convenience, here is a quick summary of all of them:

  • Modeling clipping (SoClipPlane) is ignored.
  • Textures are ignored (polygons are drawn as if no texture is applied).
  • Transparency is ignored.
  • SoAnnotationnodes are handled like SoSeparator nodes.
  • Smooth shading is only supported with PostScript Level 3.
  • VolumeViz representations are not supported.
  • FXViz representations are not supported.

This info is also available in the SoVectorizeAction write-up of the Reference Manual.