Programming Course

Chapter 7

Inventor I - From AutoCAD to Inventor and C++

7.1 Why Inventor

With Inventor it is possible to write programs that take advantage of fast graphics computing. Inventor is based on OpenGL (Open Graphics Language), which is available on many platforms. OpenGL is replacing the older GL, which was easier to program, but was only available on Silicon Graphics Machines. Inventor too will be available on other platforms and therefor the programs you write will be portable. Inventor writes iv-files, a format similar to VRML (Virtual Reality Markup Language). To know Inventor means to be ready for fast graphics programming and be able to create world-wide accessible virtual reality environments.

Lets start from what we know and approach Inventor and C++ programming step-by-step:

7.2 Export

7.2.1 File Formats and Translators

Different CAD-Programs store the description of objects in different formats. Usually the drawing files of one CAD program cannot be opened in another CAD program. Some standardized file formats had to be established, file formats that can be written by one program and read by another, to enable the user to transport a model into a different environment.

Several formats exist, the three most important ones are:

A translator is a program or procedure, that can write the data from a program in a specific file format. Its functioning is similar to translating from one language to another. Sometimes a translator can not translate every information into another format, because the other format does not support the underlying concept. For example solids from AutoCAD often get translated into wire frame objects, if the other format has no notion of a solid. A translated representation often becomes more complex than necessary, because the translator does not realize that special shapes and features could be formulated in a simpler way.

7.2.2 iv Format

iv is the Inventor file format for exchanging 3D data. Compared to dxf it is easy to read and modify. Scenes for Inventor could be written directly as iv-files, which might be the reason for basing VRML on this format.

AutoCAD-cube:
( (-1 . <Entity name: 600003cc>) 
  (0 . "POLYLINE") 
  (8 . "0") 
  (66 . 1) 
  (10 0.0 0.0 0.0)
  (5 . "2D") 
  (70 . 16) 
  (40 . 0.0) 
  (41 . 0.0) 
  (210 0.0 0.0 1.0) 
  (71 . 6)
  (72 . 3) 
  (73 . 0) 
  (74 . 0) 
  (75 . 0)
)



iv-cube:
Separator {
    Cube {
        width   1
        height  1
        depth   1
    }
}

Translation from AutoCAD to iv:
Separator {
    Label {
        label "group0"
        }
    Separator {
        Coordinate3 {
            point [ 1 0 1,
                    0 0 1,
                    0 0 0,
                    1 0 0,
                    0 1 1,
                    0 1 0,
                    1 1 1,
                    1 1 0 ]
        }
        ShapeHints {
            vertexOrdering COUNTERCLOCKWISE
            shapeType      SOLID
            faceType       UNKNOWN_FACE_TYPE
        }
        Normal {
            vector [ 0 -1  0,
                    -1  0  0,
                     0  1  0,
                     0  0  -1,
                     1  0  0,
                     0  0  1 ]
        }
        NormalBinding {
            value   PER_VERTEX_INDEXED
        }
        IndexedFaceSet {
            coordIndex 
 [ 0, 1, 2, 3, -1, 1, 4, 5,
   2, -1, 4, 6, 7, 5, -1, 5,
   7, 3, 2, -1, 7, 6, 0, 3,
  -1, 6, 4, 1, 0, -1 ]
            normalIndex 
 [ 0, 0, 0, 0, -1, 1, 1, 1,
   1, -1, 2, 2, 2, 2, -1, 3,
   3, 3, 3, -1, 4, 4, 4, 4,
  -1, 5, 5, 5, 5, -1 ]
        }
    }
}

A cube as AutoCAD entity, in iv format, and translated to iv-format, the translator was not able to recognize the cube and translated it into a group with an IndexedFaceSet.

7.3 Inventor

7.3.1 What is Inventor

(see also: "The Inventor Mentor", Addison Wesley, 1994)

Open Inventor is an object-oriented toolkit for developing interactive, 3D graphics applications. In other words: You can include and link the program you are writing with files from the Inventor library. Inventor is a toolkit for programmers.

An advantage of using a toolkit like Inventor is that you do not have to write low-level procedures for the graphics display. These have been written and optimized by specialized programmers. Inventor also makes sure that you do not have to know much about the capabilities of the computer you are using. For example you can call for texture mapping in your program, if your computer cannot do texture mapping the program will still run, without drawing the textures though.

7.3.2 Scenegraph: Nodes and Paths

For Inventor to know what to draw, when and how, a tree called Scenegraph is built. The nodes in this tree describe shapes, properties, and more. The connections between the nodes define the path along which the program moves while displaying the graphics.

The Scenegraph starts with a top node, by convention called root. Inventor loops through the tree starting at root and after the last node has been passed, restarting at root. The graph is traversed top to bottom, left to right.

Top to bottom, left to right traversal of a Scenegraph.

There are three important types of nodes: shape nodes, property nodes and group nodes. Examples of each are introduced next:

1) Shape Nodes: Sphere and Cube

For simple, often used shapes, like cubes and spheres, there are predefined shapes available. For a cube it then suffices to define the size of each of the three extensions. For a sphere only the radius needs to be specified.

More complicated shapes get defined by the coordinates of the vertices and how they are connected.

Scenegraph with a sphere shape node and a cube shape node.

2) Property Nodes: Material and Transformation

Before a shape is drawn, certain properties can be defined. To define the color means actually that the material's color has been defined. To specify the position a translation has to be applied. The properties have to be included as nodes before the shape node so that they get read first in the traversal of the Scenegraph.

Scenegraph for a red sphere

3) Group Node: Separator

The separator groups everything underneath it together. It is called separator, because it makes sure that any material and transformation defined underneath it is not applied to the following nodes. If you are building a blue composition with a red part somewhere, you can use a separator so that the red material is not applied to the following shapes. Separators also help to make a Scenegraph more readable, they are setting a mark for a subgraph.

The top node is preferably a Separator, like this each time Inventor redraws the Scenegraph, everything is reset to the defaults.

Scenegraph with separators, a red sphere, and a translated, blue cube.

7.4 C++

7.4.1 Programming Languages

Programming languages can be grouped into procedural, symbolic, and object oriented. In the following the characteristics of each group will be explained.

procedural

In procedural languages statements are executed in a well defined order, and the types of variables are specified. Languages like Pascal, C, FORTRAN, are procedural languages. They are suited for tasks that build on well understood series of operations, numerical instructions, and the necessity of maintaining precise data types.

symbolic

Symbolic languages, like LISP and AutoLISP, treat variables like symbols, which can change their type during execution of the program. These languages are fine for tasks that involve the manipulation of abstract concepts, associations between them, and data sizes and types, which may change or are not known in advance. For these reasons much AI (Artificial Intelligence) programming is done with symbolic languages.

object oriented

Object oriented languages, like C++ and Smalltalk, are strongly typed, but not procedural. The functions that are executed are called by the objects and will influence other objects. These languages are good for describing parts and the way they interact in a bottom up approach. Many graphics libraries are written with an object oriented approach, because first the elements and their behavior can be described and then they can be utilized to compose the whole picture.

7.4.2 Characteristics of C++

C++ is an object oriented language. An object is defined by a name, some variables and functions. For the use of C++ in combination with Inventor we can start without defining our own objects and just make use of the ones made available by Inventor. Lets start by looking at how to work with defined objects:

initializing an object

The creation of an object is called initialization and basically reserves the memory space to hold the objects description. Because initializing is an action to be taken by the program, the C++ operator new has to be used. When initializing an object you should assign it to a variable. The type of the variable is the object. For Inventor-objects the exact name can be looked up in the reference manual. The variable name is preceded by an asterisk (*). The variable is actually a pointer to the address in memory, where the object is stored.

Because pointers are a complex feature you should take this form of defining an object as a convention and learn how to use the asterisk (*) and also the arrow (->) to define and access the objects by copying from examples.

To create a cube node this program code looks like this:

SoCube *mycube = new SoCube;

assign a value to a variable

To define the dimensions of the cube, the variables for width, height and depth have to be set. All these variables have default values, which means that something will always be drawn even if you did not specify the values explicitly. You can look up the defaults in the reference manual. For example: SoCube has default of 2.0 for each dimension.

This is how the dimensions of the cube can be specified:

mycube->width = 1.5;
mycube->height = 2.7;
mycube->depth = 2.1;

use a function

Some nodes do not allow the values to be set directly, they provide a function to specify the values. An example is the SoTransform node. This node can do many transformations and has to coordinate them, therefore setting values implies the execution of some functions.

This is how a translation is defined:

SoTransform *mytrans = new SoTransform;
mytrans->translation.setValue(1.5, 2.1, 3.3);

main()

Even though C++ is an object oriented language there is a procedural part to it. A C++ program always starts by executing the function called main. main initializes the environment and can create the first objects, like the root node for the Scenegraph.

formalisms

A C++ program looks very different from a AutoLISP program:

7.5 Compiling

7.5.1 Interpreted versus Compiled Programs

Interpreting a program means to take each statement of the code and execute it one at a time. Examples for interpreted languages are LISP, AutoLISP, and Basic. Compiling a program means to translate the program into a lower level, machine dependent language. The translation also optimizes the program. Examples for languages that have to be compiled are FORTRAN, Pascal, C, and C++.

An advantage of a compiled program is that it will execute faster then an uncompiled one, because it is optimized for the machine it runs on. The process of compiling also includes the detection of certain errors, so called compile time errors. These can then be corrected before running the program and the number of remaining errors, runtime errors, is reduced. A disadvantage is that the compiled code cannot be read anymore and one needs the help of a debugging program to follow the execution of the program.

7.5.2 What happens when a C++ Program gets Compiled

As C++ application always has to be compiled. The following things happen during the process of compiling:

make is the command that starts a process defined in the file called Makefile, what happens can be described roughly as: check - compile - link.

1) Check if all the files and libraries specified in the Makefile are available.

1.1) Figure out which of these files need to be compiled or recompiled?

2) Compile each of them.

2.1) Check if all the files called by this file are available.

2.2) Check if there are no syntax errors.

2.3) Check if all names of variables and functions are used correctly.

3) Link the compiled files and the external libraries.

3.1) Check if all functions are defined.

7.6 Exercise 7 - Understand Inventor

There are 3 parts to this exercise The first part will help you to get to familiar with Inventor's structure of nodes and their effects on the graphics. Then you will modify some iv-code and in the last part you will look at a C++ program and compile it.

Download the files of exercise 7 to your directory. There are 4 files, example.iv, example.c++, ...

1) Editing in Gview

The Goal of this part is to get acquainted with the way Inventor handles and renders objects. Inventor objects are stored in a hierarchical structure that is called a Scenegraph, the single components of this structure are called nodes. Nodes are connected with paths. Some nodes have an influence on others some do not. A node can only have an influence on the ones following it. There are three kinds of nodes which you are going to use, nodes that group other nodes, nodes that influence other nodes and nodes that protect other nodes from being influenced.

  1. open up AutoCAD
  2. run your program from exercise 4
  3. export the house that it has created with the following command from the menu:
    SGI_tools->Inventor->SaveAs... (name of drawing will be name of iv-file)
  4. close AutoCAD

What you will see now is the representation of your house on the left-hand side and its Scenegraph on the right-hand side. Chose the arrow from the buttons on the right and double click on the different nodes to either get information about them, or expand them. Then try to play with the cut and paste commands. For example: Copy some of the nodes hidden under the bottom nodes up under the top node. Also try to change some of the values that appear when you double-click on a node.

  1. change color or position of some objects.
  2. create additional parts by inserting new nodes from the "node"-menu.
  3. Save it in gview.iv (command in the gview menu) and close the viewer. Move the gview.iv file into the exercise 7 directory. Be careful (!!!) to always rename the gview file. There is no "save as" command, iv files will always be written out as gview.iv and overwrite any existing file with the same name.

2) Editing of an iv-File

Open a Unix Shell and open the gview.iv in jot. The text will look something like this:

#Inventor V2.0 ascii

Separator { 

           ....

}

Insert the following just beneath the line containing the first Separator command:

TransformSeparator {

          Rotor {
              rotation 0 0 -1  4.25412
              speed 0.2
          }

          Translation {
              translation 30 30 70
          }

          PointLight { }
}
Save the file, close the editor, open a shell, cd to exercise 7 and write "gview gview.iv" to reopen gview and look at the components of the first node in the graph and try to figure out how it is working.

3) Looking at a C++ File and Compiling

How do you program a Scenegraph with C++? It is fairly straight forward, first you have to create a top node, in our exercises this will be a SoSeparator node, then you add other nodes under this SoSeparator node. And finally you tell the viewer, you are using, the name of the top node of the Scenegraph it should display.

Look at the files example.iv and example.c++ with the text editor, they both create the same Scenegraph.

You can look at the scene with the command: gview example.iv

To run the .c++ file you first have to compile it.

Either:

- double click on the Makefile-icon

- then double click the newly generated file example

or in a shell type:

- cd exercise7 the location where the c++ code and the Makefile can be found

- make example compile "example" according to the instruction s in Makefile

- example run the newly compiled program

This process will also create a Makefile.log or a Makedepend file. If you get error messages it is important for us to know about them, because we will have to either fix the environment or your account. When reporting errors, please include as much information as possible, like every line of warning and error messages and the name of the machine you were working on.

To Do: