How to Write an IRIS Inventor File Translator
Release 1.0
Section 5 File Format Syntax
This section outlines details of the syntax for the Inventor ASCII file format.
Inventor's file format ignores extra white space created by spaces, tabs, and
new lines (except within quoted strings). Comments begin with a number sign (#)
anywhere on a line and continue to the end of the line:
# this is a comment in the Inventor file format
See the IRIS Inventor Nodes Quick Reference for individual descriptions
of the file format for each Inventor class.
- 5.1 File Header
- Every Inventor data file must have a standard header to identify it. This header has the
following form:
#Inventor V1.0 ascii
or
#Inventor V1.0 binary
To determine whether a file is an Inventor file or not, use the
SoDB::isValidHeader() method and pass in the first line of the file
in question. Although the header may change from version to version, it is
guaranteed that it will begin with a # sign, will be no more than
80 characters, and will end at a newline. Therefore, the C
fgets() routine can be used. The isValidHeader()
method returns TRUE if the file contains an Inventor header.
An example of using fgets() to check the header is
FILE *fp = fopen ( filename, "r" );
char headerString [80];
fgets( headerString, 80, fp );
if( SoDB::isValidHeader( headerString ))
printf( "File has valid Inventor header\n");
else
printf( "Invalid Inventor header\n");
- 5.2 Writing a Node
- A node is written as:
nodename {
field1name value
field2name value
.
.
.
[child nodes]
[ . . . ]
}
For example:
DrawStyle {
style LINES
lineWidth 3
linePattern 0x00ff
}
- 5.3 Writing Values within a Field
- Fields within a node are written as the name of the field, followed by the
value or values contained in the field. If the field value has not been changed
from its default value, that field is not written out. Fields within a node can
be written in any order. An example of writing field values is
Transform {
translation 0 -4 0.2
}
LightModel {
model BASE_COLOR
}
Use brackets to surround multiple-value elds, with commas separating the
values, as shown below for the diffuseColor field. It's all right
to have a comma after the last value as well:
[ value1, value2, value3, ]
For example:
Material {
ambientColor .3 .1 .1
diffuseColor [.8 .7 .2,
1 .2 .2,
.2 1 .2,
.2 .2 1]
specularColor .4 .3 .1
emissiveColor .1 0 .1
}
Single-value fields (SF) do not contain any brackets or commas. Multiple-value
fields (MF) usually have brackets, but they are not necessary if only one value
is present:
specularColor .4 .3 .1
or
specularColor [.4 .3 .1 ]
The value that is written depends on the type of the field, as follows:
Type of Field Acceptable Formats
longs, shorts, integers
unsigned shorts
floats integer or floating point number. For example:
13
13.0
13.123
1.3e-2
names, strings double quotation marks (" ") around the name if it is more than
one word, or just the name (with no white space) if it is a single
word. For example:
label " front left leg "
label car
You can have any character in the string, including newlines and
backslashes, except for double quotation marks. To include a double
quotation mark in the string, precede it with a backslash (\").
enums either the mnemonic form of the enum or the integer equivalent.
(The mnemonic form is recommended, both for portability and
readability of les.) For example:
MaterialBinding {
value PER_FACE
}
bit mask one or more mnemonic ags, separated by a vertical bar (|) if there
are multiple ags. When more than one ag is used, parentheses are
required.
Cylinder {
parts SIDES
}
Cylinder {
parts (SIDES | TOP)
}
vectors n floats separated by white space:
(SbVecnf, where n is
the number of PerspectiveCamera {
components of the position 0 0 9.5
vector) }
colors 3 floats (RGB) separated by white space:
BaseColor {
rgb 0.3 0.2 0.6
}
rotation a 3-vector of oats for the axis, followed by a oat for the angle (in
radians), separated by white space:
Transform {
rotation 0 1 0 1.5708
# y axis ... PI/2 radians
}
matrix 16 floats, separated by white space (row major order)
path An SoSFPath has one value, a pointer to a path. To write this
value, write the path (see Section 12.3.5 of the Inventor
Programming Guide, Volume I). An SoMFPath has multiple
values, which are all pointers to paths. To write this value, enclose
the path list in brackets, and use commas to separate each path:
[ first_path, second_path, ... nth_path ]
node An SoSFNode has one value, a pointer to a node. To write this
value, write the node using the standard format for all nodes. An
SoMFNode has multiple values, which are all pointers to nodes. To
write this value, enclose the node list in brackets, and use commas to
separate each node:
[ node1, node2, ... noden ]
- 5.4 Ignore Flag
- The ignore flag for a node (see Chapter 3 of the Inventor Programming
Guide, Volume I) is written as a tilde ( ~ ), either after or in place of
the field value or values. For example:
transparency [ .9, .1 ] ~
or
transparency ~
The first case preserves the values even though the field is ignored. The
second case uses the default value but ignores the field.
- 5.5 Sample Scene Graph and Inventor File
- Here is the file for a sample scene graph, which creates chartreuse, rust,
and violet wireframe spheres. Figure 13 shows the scene graph for this file.
Separator {
PerspectiveCamera {
position 0 0 9.53374
aspectRatio 1.09446
nearDistance 0.0953375
farDistance 19.0675
focalDistance 9.53374
}
DirectionalLight { } # note: default fields for this light
Transform {
rotation -0.189479 0.981839 -0.00950093 0.102051
center 0 0 0
}
DrawStyle {
style LINES
}
Separator {
LightModel {
model BASE_COLOR
}
Separator {
Transform {
translation -2.2 0 0
}
BaseColor {
rgb .2 .6 .3 # chartreuse
}
Sphere { }
}
Separator {
BaseColor {
rgb .6 .3 .2 # rust
}
Sphere { }
}
Separator {
Transform {
translation 2.2 0 0
}
BaseColor {
rgb .3 .2 .6 # violet
}
Sphere { }
}
}
}
Figure 13 Scene graph for a scene with three spheres
- 5.6 Instancing
- When a scene graph contains shared instances of a node, Inventor defines a
temporary name for the node and uses that name when writing subsequent
occurrences of that node in the scene graph. It inserts the letters
DEF (for define), followed by the name for the first use of the
node. Thereafter, Inventor simply writes USE plus the name defined
for that node.
For example, the scene graph shown in Figure 14 would be written as follows
(without the comments):
Group { # group A
Group { # group B
DEF d Cube { } # define D and use it
}
Group { # group C
USE d # use D again
}
}
Figure 14 Defining a node for multiple uses
Inventor uses this DEF/USE technique for paths as well as for nodes. For les to
be read into Inventor, the name for a node or path can be any valid identifier.
This name is thrown away after the file is read. (Identifiers start with an
underscore or a letter and must consist entirely of letters, numbers, and
underscores.) Names used within a file must be unique. A name can,
however, be used in multiple les, since each file maintains its own list of
names.
- 5.7 Including Other Files
- To include a file within another le, use an
SoFile node. This node is
written as
File {
name "myFile.iv"
}
where the name field is the name of the file to be included. The contents of the file
myFile.iv are added as children of SoFile .
The SoFile node has an associated WriteBack flag. If
this flag is TRUE (the default), then the children of
SoFile are written back to their original file if anything below
the SoFile node changed. If this flag is FALSE , then
the original file remains untouched, even if changes occurred to the sub-graph
below the node. Use the setWriteBack() and
getWriteBack() methods to change the value of this ag and to
obtain its current value. If the file cannot be written, Inventor prints a
warning.
- 5.8 ASCII and Binary Versions
- The
SoOutput object in an SoWriteAction has a
setBinary() method, which sets whether the output should be in
ASCII (default) or binary format. The getOutput() method returns a
pointer to the SoOutput . When a file is written, Inventor inserts
a header line that indicates whether the file is in ASCII or binary format, as
well as the Inventor version number.
For example, to write in ASCII to a file:
SoWriteAction w;
w.getOutput()->setBinary( FALSE );
if ( w.getOutput()->openFile( "myFile.iv" )) {
w.apply( root );
w.getOutput()->closeFile();
}
|