Computer Graphics Workshop '96 Lecture Notes | 1/16/96 |
Recall that a face set node fundamentally only tells Inventor how to "bind together" the coordinates povided by another node. A face set can represent multiple planar polygons, either convex or concave. (If you give Inventor non-planar vertices and tell it to construct a polygon for them using a face set, the result will be an arbitrary triangular tesselation of those vertices.)
A triangle strip set is another shape which has more constraints than a face set. As the name implies, it creates a strip of triangles between points alternating between the top and bottom of the strip. Here's an example of how one of these is created:
0-----2-----4 | /| /| | / | / | | / | / | | / | / | |/ |/ | 1-----3-----5Vertices 0 through 5 would be specified inside a Coordinate3 node. The triangle strip set would then have "6" as the sole value in its numVertices field.
Triangle strip sets have the advantage of rendering faster than face sets; however, they can not represent geometry as general as face sets can.
The final type of polygonal shape in Inventor is the quad mesh; this node constructs quadrilaterals out of the provided coordinates by considering the vertices to be points along the rows of the mesh. While a triangle strip set can represent all the shapes a quad mesh can, a quad mesh can be convenient when you can easily represent your shape as some distortion of a flat sheet of points.
Here's a simple example of a triangle strip set:
(define viewer (new-SoXtExaminerViewer)) (-> viewer 'show) (define root (new-SoSeparator)) (-> root 'ref) (define coords (new-SoCoordinate3)) (-> root 'addChild coords) (define tri-strip-set (new-SoTriangleStripSet)) (-> root 'addChild tri-strip-set) (set-mfield-values! (-> coords 'point) 0 '(#(0 1 0) #(0 0 0) #(1 1 0) #(1 0 0) #(2 1 0) #(2 0 0) #(3 1 0) #(3 0 0) #(4 1 0) #(4 0 0) #(5 1 0) #(5 0 0) #(6 1 0) #(6 0 0) #(7 1 0) #(7 0 0) #(8 1 0) #(8 0 0) #(9 1 0) #(9 0 0) #(10 1 0) #(10 0 0) #(11 1 0) #(11 0 0) #(12 1 0) #(12 0 0) #(13 1 0) #(13 0 0))) (set-mfield-values! (-> tri-strip-set 'numVertices) 0 '(4 4 4)) (-> viewer 'setSceneGraph root)Inventor can represent 3D points and lines as well as filled polygons. An SoLineSet constructs polylines out of the given coordinates. For example:
(define root (new-SoSeparator)) (-> root 'ref) (define coords (new-SoCoordinate3)) (-> root 'addChild coords) (set-mfield-values! (-> coords 'point) 0 '(#(0 0 0) #(0 1 0) #(1 0 0) #(1 1 0) #(2 0 0) #(2 1 0))) (define line-set (new-SoLineSet)) (-> root 'addChild line-set) (set-mfield-values! (-> line-set 'numVertices) 0 '(4 2))Note that the first four points are connected in a polyline, while the second two points are disconnected from them.
The SoPointSet works in a similar way to all the above shapes, but has a single-valued numPoints field instead of a numVertices field since points do not have to be grouped together.
The SoMaterial node affects the coloring for line sets and point sets as well as for other vertex-based and primitive shapes. However, there are additional parameters for lines and points: for example, how thick should the lines be? The line thickness for a point set can be specified by adding an SoDrawStyle node to the scene graph. This node has floating-point fields for setting the point size (pointSize) and the line width (lineWidth); these values are measured in "printer's points" (1 inch = 72.27 printer's points). If this node were inserted in front of the line-set node in the above example, we could make the lines thicker by writing
(-> (-> draw-style 'lineWidth) 'setValue 2.0)This node also contains a field, style, which changes the drawing style for all shapes, not just vertex-based shapes. By setting this field's value to SoDrawStyle::LINES, for example, you could create a wireframe view of a cone.
All of the previously described vertex-based shapes have been "non-indexed"; that is, all of the coordinates of the desired shape must appear in order in the Coordinate3 node. In some cases, this can lead to repetition in the specification of vertices. Face sets, line sets, and triangle strip sets have indexed analogues (SoIndexedFaceSet, SoIndexedLineSet, SoIndexedTriangleStripSet) in which the values specified in these nodes are indices into the array of coordinates, material properties, etc. rather than numbers of vertices per part. However, since the same results can be obtained by using the non-indexed versions of these nodes, we leave the description of the usage of these nodes to the Inventor Mentor.
(define coords (new-SoCoordinate3)) (-> (-> coords 'point) 'set1Value 0 2 3 4)The set1Value method takes an index (starting at 0) and the new value for that slot in the array; some of the field types (like SoMFVec3f, the type of the point field in the SoCoordinate3 node) have additional convenience functions to allow the new value to be expressed in several different ways. For example, we could have written the last line above as
(-> (-> coords 'point) 'set1Value 0 '#(2 3 4)) (-> (-> coords 'point) 'set1Value 0 (new-SbVec3f 2 3 4))Because single-valued fields can only store one value, they all use the getValue method to return the value they contain. Multiple-valued fields do not have a "get1Value" method defined; instead, the C++ syntax for getting one value out of an mfield uses the brackets operator:
const SbVec3f &myVec = coords->point[3];The conversion of this syntax to Scheme is the following: (define my-vec (-> (-> coords 'point) 'operator-brackets 3)) In other words, the brackets operator is converted into a method of all multiple-valued fields.
We have defined a convenience function, set-mfield-values! (defined in InventorInit.scm), which sets multiple values in an mfield for you. It takes as arguments, in order, the following:
(define coords (new-SoCoordinate3)) (-> (-> coords 'point) 'set1Value 10 '#(3 4 5))The point field now has 11 slots in it (remember, in Inventor, as in C, all indices start at 0). The slots numbered 0-9 have undefined values stored in them; the one with index 10 has the vector (3,4,5) stored in it:
(define my-vec (-> (-> coords 'point) 'operator-brackets 10)) (-> my-vec 'getValue)There are situations in which you would want the number of accessed values in a field to decrease rather than increase; perhaps your application culls a large portion of geometry before manipulating the on-screen geometry. In this case your application might use the set1Value method to copy the new geometry into a Coordinate3 node; however, the node would still consider the largest-accessed index to be the largest valid index. To change this value, use the setNum method:
(-> (-> coords 'point) 'setNum 3)This tells the point field that there are three valid values in it, with indices 0, 1, and 2.
Unfortunately, when many changes are made to a single field which is contained within a node that is part of the active scene graph, the notification process can become slow. We therefore will demonstrate how to disable and reenable this process. Note that you should only use these functions in the following situations:
(-> (-> coords 'point) 'enableNotify 0)The enableNotify method takes an SbBool as argument; recall that SbBools are represented in Scheme as integer values of 0 and 1 for FALSE and TRUE, respectively. Once notification is disabled, we can change the values in the field. When we have finished changing the values, we must re-enable notification:
(-> (-> coords 'point) 'enableNotify 1)If this were the only node we were modifying, we might now want to schedule a render of the scene graph; since notification was disabled during the modification we just made, Inventor would still be using the old values of the field. We therefore tell Inventor that new values are in the field:
(-> (-> coords 'point) 'touch)Note again that especially in Scheme there is so much other overhead that the notification process will not be the limiting factor in the performance of your applications. However, when you are writing interactive Inventor applications in C++ which deal with a lot of data, disabling and reenabling the notification process can provide more control over the behavior of your Inventor application.
$Id: index.html,v 1.5 1996/01/16 21:23:16 kbrussel Exp $