Interface proposal for VRML1.1

Date: 15 Sept 1995
This document is part of a collection of VRML2.0 history at
Mitra <>
Tom Meyer <>

Interfaces to Separators

Interfaces are designed to allow data-hiding and abstraction, give us hierarchical naming, and support some notions of classes and objects, and provide a way to control access through the API. The model is that a separator is extended so that any access to nodes underneath the separator goes through the Interface.

A typical interface looks like:

    DEF MyToaster Toaster {
        isA Separator
        fields [ SFColor READ sideColor SFBool READWRITE handleDown ]
        sideColor 1 0 0
        handleDown FALSE
        ...                            # Some geometry
        DEF Side Separator {
            Material { emissiveColor USE MyToaster.sideColor }
        Switch {
            whichChild USE Toaster.handleDown
            { .. handle up geometry .. }
            { .. handle Down geometry }
In this example we declare that two of the fields of nodes of the class Toaster are accessable, the color of the side is read-only, the "handleDown" can be written to in order to change the state of the Toaster.

Interfaces to Nodes

If we want to change the geometry of the object, as opposed to some property of it, then we would need a slightly more complex example:
    DEF MyChangableToaster ChangableToaster {
        isA Toaster
        fields [ SFNode READWRITE toast ]
        toast { ... }           # geometry for default toast
        Separator { 
            Transform { ... }
            USE MyChangableToaster.toast    # Draw it here
In this case, some external behavior could change the "toast" field, to replace it with a Bagel.

Note that we still only have backwards references, from the USE to the place its defined. Also note that as for any use of "isA" the ChangableToaster inherits the READWRITE field "handleDown" and the READ field "sideColor".

Interfaces to WWWInlines

It would be very usefull to be able to access the contents of a WWWInline, currently DEF..USE are scoped to the file they are read from, and cannot be used for this purpose. To put the example above into a WWWInline would be easy:
   DEF InlinedToaster WWWInline { "" }
   Switch { 
        whichChild InlinedToaster.handleDown 
        { ... } # handle Up action 
        { ... } # handle down action


In order to be able to reuse complex items defined with these interfaces, and be able to change their fields independantly then DEF and USE are extended to DEF, USE and COPY. COPY is identical to USE except a complete copy of a node is made (and any of its children). For example:
    DEF Toaster1 WWWInline { "" }
    DEF Toaster2 COPY Toaster1
Now, the handleDown field of these two toasters can be changed independantly.


The new node Prototype is defined as a separator which doesn't render any of its children.
   Prototype {
        DEF InlineToaster WWWInline { "" } 
   DEF Toaster1 USE InlineToaster
   DEF Toaster2 USE InlineToaster
It has the advantage that now all the instances of InlineToaster can be identical, and if the Toaster is not used it won't be rendered, and deleting instantiations of the toaster can no longer have the nasty side-effect of deleting the Toaster class.

It behaves exactly as the nasty hack

    Switch { whichChild=0 ..... }


Variables - for example for synchronising behavior between two external applets, are just fields of an Interface.


The connect node proposed for connecting sensors to actions becomes just a "USE" of a field in an interface, and so is no longer needed. (Note - Trigger is still needed).

Open questions

Mitra <>
Tom Meyer <>