June 96 - Adding Custom Data to QuickDraw 3D Objects
Adding Custom Data to QuickDraw 3D Objects
PABLO FERNICOLA, NICK THOMPSON and KENT DAVIDSON
Custom attributes and elements provide a way to attach data such
as scaling information, sound, and strings to QuickDraw 3D
objects. In this article we explain how to create and attach custom
attributes and elements. We illustrate the process by showing you
how to attach a string containing a World Wide Web URL to a
QuickDraw 3D object to enable 3D navigation through the Web. We
also describe six new custom elements with implementations
included on this issue's CD.
In QuickDraw 3D, attribute objects (known more simply as attributes) generally
store information about the surface properties of objects in a model, such as color and
transparency. QuickDraw 3D defines 12 basic attribute types, and it also allows you to
define custom attribute and element types so that you can attach data different from the
predefined types to QuickDraw 3D objects. Your custom data need not apply to the
appearance of objects or to how objects are drawn, although it can.
For example, with custom attributes and elements you can add scaling information,
directional information, or sound to objects in your 3D scene. You can add a string
containing a name for a QuickDraw 3D object, so that you can refer to that object by
name and control it from a scripting language in your application. Your application can
enable users to navigate through the World Wide Web in 3D, by attaching a URL to a
QuickDraw 3D object, as illustrated by the code discussed in this article and included
on this issue's CD. These are just a few of the ways you can extend the functionality of
QuickDraw 3D and add value to your 3D application by adding custom data to objects.
Before we explain and illustrate how to create custom attributes and elements, and how
to attach them to QuickDraw 3D objects, we'll look at how attributes and elements
relate to each other and to other QuickDraw 3D objects. To get the most from this
article, you should already be familiar with the basics of QuickDraw 3D, as presented
in the previous develop articles "QuickDraw 3D: A New Dimension for Macintosh
Graphics" (Issue 22) and "The Basics of QuickDraw 3D Geometries" (Issue 23). The
book 3D Graphics Programming With QuickDraw 3D, included on this issue's CD,
provides complete documentation for the QuickDraw 3D programming interfaces.
ABOUT ATTRIBUTES AND ELEMENTS
Attributes and elements are types of QuickDraw 3D objects used to store information
about objects they're attached to. Each consists of a type and some associated data. You
apply attributes and elements to objects by creating an instance of a specific type of
attribute or element, defining its data, adding it to a set, and then attaching the set to
an object (if the set isn't already attached).
Note that attributes and elements are attached to objects, as opposed to simply being
added to a group. The reason for binding data to objects is that both QuickDraw 3D and
the 3DMF format maintain a strong data encapsulation model. For example, this allows
QuickDraw 3D objects to be moved from file to file without losing data.
ATTRIBUTES AND ELEMENTS IN THE QUICKDRAW 3D HIERARCHY
To better understand how attributes and elements relate to each other and to other
QuickDraw 3D objects, take a look at the partial class hierarchy shown in Figure 1. As
you can see, an attribute is actually a type of element (that is, it's a subclass of the
Element class, TQ3ElementObject). An element is any QuickDraw 3D object that can be
part of a set. In contrast with shared objects (objects of the class TQ3SharedObject),
elements aren't shared (that is, they can't be referenced by multiple objects or the
application at the same time) and are always removed from memory whenever they're
disposed of. An attribute has all of these properties but also can be inherited by
subclasses of the object it's attached to.
Figure 1. Partial QuickDraw 3D class hierarchy, showing set and attribute set
attachment
Custom data to be attached to an object can be stored in an element or an attribute. So
how do you decide which to use? Use an attribute when you want your custom data to be
inherited. For example, suppose we create a custom attribute named Temperature and
we want to be able to assign a different temperature to an entire geometry, a face, or a
vertex. During a view traversal loop, our attribute will be inherited along with the
other attributes. This becomes extremely important with the introduction of plug-in
renderers, which will be available in a future QuickDraw 3D release. A particular
renderer might take advantage of this inherited attribute by coloring each vertex
according to the temperature inherited.
SETS AND ATTRIBUTE SETS
We mentioned earlier that attributes and elements are usually collected in sets. A set
is an instance of the Set class (TQ3SetObject), which in turn is a subclass of the
Shared class (TQ3SharedObject), as shown in Figure 1. A set collects zero or more
different elements or attributes and their associated data; it can contain only one
element or attribute of a given type. Anattribute set is a type of set; in fact,
TQ3AttributeSet is the only subclass of the class TQ3SetObject. An attribute set has all
the properties of a set but also allows inheritance.
Both elements and attributes can be collected in sets and attribute sets. Since the
AttributeSet class is derived from the Set class, you can call Q3Set_XX on an attribute
set, but you can't call Q3AttributeSet_XX on a set. In the text that follows, be sure to
pay attention to whether we're talking about sets or attribute sets; we don't use the
terms interchangeably.
Sets and attribute sets can't be attached to just any QuickDraw 3D object, but only to
those objects for which it makes sense to store additional data in this way. Attribute
sets can be attached to view objects, group objects, and geometric objects, plus most of
the parts of a geometric object: faces, vertexes, mesh edges, and mesh corners. (See
"How to Attach Attribute Sets" for details.) In contrast, sets can be attached only to
objects in the Shape class or subclasses of the Shape class. (Attaching a set to a shape
is fairly straightforward; we give an example of how to do this later, in Listing 3.)
The Shape class actually has a class field of type set, meaning that any class derived
from Shape has a set object. The Geometry class has a class field of type set (inherited
from the Shape class) plus a class field of typeattributeSet, meaning that any class
derived from Geometry has both a set object and an attribute set object.
______________________________
HOW TO ATTACH ATTRIBUTE SETS
It may be news to you that attribute sets can be attached to views or groups,
because how to do this is less than obvious. We'll tell you how.
To attach an attribute set to a view object, use the
Q3View_GetDefaultAttributeSet routine to get the default attribute set (all
view objects have one), and then use Q3AttributeSet_Add to add attributes to
that set. For example, the following code shows how to apply a default specular
color to all objects submitted to a view.
Q3View_GetDefaultAttributeSet(theDocument
->theView, &viewSet);
Q3AttributeSet_Add(viewSet,
kQ3AttributeTypeSpecularColor, &clearColor);
Q3Object_Dispose(viewSet);
You can still override the default behavior of the view by attaching attributes
to objects before submitting them. If you write the view hints out in 3DMF
format using the QuickDraw 3D API, the attribute set for the view will also be
written out. You can preserve these settings by looking in and using the view
hints when you read the 3DMF data back in.
To attach an attribute set to a group object, just add the attribute set to the