Key Aspects of C++


ACIS is written in C++ and consists of a set of C++ functions and classes (including data and member functions, or methods). A developer uses these functions and classes to create an end user 3D modeling application. This section describes how ACIS uses features of C++.

ACIS is a solid modeler, but wireframe and surface models may also be represented in ACIS. ACIS integrates wireframe, surface, and solid modeling by allowing these alternative model representations to coexist naturally in a unified data structure, which is implemented as a hierarchy of C++ classes.

ACIS utilizes key features of C++, such as encapsulation, overloading, etc. to create a modular and maintainable interface. The API function interface remains stable from release to release, while the class interface may change.

The key aspects of C++ that ACIS takes advantage of are:


Data Encapsulation

A class provides not only data storage, but also methods (or member functions) that can access and manipulate that data. The concept of having private data and public methods for accessing data is common to ACIS classes. This is how ACIS uses C++ classes to provide data encapsulation and modularization. This permits reorganization of the internals of any component while maintaining the interface.

Although it is possible to make the class data members accessible to anyone (public), it is much more common to hide the data members by making them private. Access to private class data members is restricted to the public class methods. Not all class methods need to be exposed, so some methods are also private.

For example, consider the SPAposition class, which is used to define a position in space. The declaration for this class is shown in the following example. The internal data structure for this is an array of three real numbers and it has class methods for the x, y, and z components of the position: x, y, and z. At some later date, if the data structure for SPAposition were to use three separate real numbers instead of an array, this could be implemented and still be transparent to the users of this class, because the users can only access the public x, y, and z methods and not the private data elements directly.

Note:  ACIS globally defines the keyword real to be equivalent to a C++ double or float data type using a #define statement.

C++ Example
class DECL_KERN SPAposition {
    real coord[ 3 ];  // x, y and z coordinates of the position
public:
    // Force creation of all positions to be by constructor.
   SPAposition() {}
    // Construct a position from three doubles.
    SPAposition( double xi, double yi, double zi ) {
       coord[ 0 ] = (real) xi;
       coord[ 1 ] = (real) yi;
       coord[ 2 ] = (real) zi;
    }
    // Construct a position from an array of three doubles.
    SPAposition( double p[ 3 ] ) {
       coord[ 0 ] = (real) p[ 0 ];
       coord[ 1 ] = (real) p[ 1 ];
       coord[ 2 ] = (real) p[ 2 ];
    }
    // Copy a position
    SPAposition( SPAposition const &p ) {
       coord[ 0 ] = p.coord[ 0 ];
       coord[ 1 ] = p.coord[ 1 ];
       coord[ 2 ] = p.coord[ 2 ];
    }
    // Extract a coordinate value.
    double x() const  { return coord[ 0 ]; }
    double y() const  { return coord[ 1 ]; }
    double z() const  { return coord[ 2 ]; }
    double coordinate( int i ) const { return coord[ i ]; }
    // Extract a coordinate value for update.
    double &x() { return coord[ 0 ]; }
    double &y() { return coord[ 1 ]; }
    double &z() { return coord[ 2 ]; }
    double &coordinate( int i ) { return coord[ i ]; }
    // Set coordinate values.
    void set_x( double new_x ) { coord[ 0 ] = new_x; }
    void set_y( double new_y ) { coord[ 1 ] = new_y; }
    void set_z( double new_z ) { coord[ 2 ] = new_z; }
    void set_coordinate( int i, double new_c )
    void set_coordinate( int i, double new_c )
    { coord[ i ] = new_c; }
    // Position operators
    // Get displacement, that is, a vector, as difference of
    // two positions.
    friend DECL_KERN SPAvector operator-( SPAposition const &,
       SPAposition const & );
    // Translate a position by a vector.
    friend DECL_KERN SPAposition operator+( SPAposition const &,
       SPAvector const & );
    friend DECL_KERN SPAposition operator+( SPAvector const &,
       SPAposition const & );
    SPAposition const &operator+=( SPAvector const &);
    friend DECL_KERN SPAposition operator-( SPAposition const &,
       SPAvector const & );
    SPAposition const &operator-=( SPAvector const & );
    // Transform a position.
    friend DECL_KERN SPAposition operator*( SPAmatrix const &,
       SPAposition const & );
    friend DECL_KERN SPAposition operator*( SPAposition const &,
       SPAmatrix const & );
    SPAposition const &operator*=( SPAmatrix const & );
    friend DECL_KERN SPAposition operator*( SPAposition const &,
       SPAtransf const & );
    friend DECL_KERN SPAposition operator*( SPAposition const &p,
       SPAtransf const *t );
    SPAposition const &operator*=( SPAtransf const & );
    // Output details of a position
    void debug( FILE * = debug_file_ptr ) const;
};

Example. Declaration of SPAposition Class

The following example shows a code fragment of two attempts to use the SPAposition class. As the declaration of the SPAposition class in Example. Declaration of SPAposition Class shows, this has private data which is an array of three real numbers, called coord. Attempting to access the private data member coord directly fails at compile time. However, accessing the public methods, such as x, is valid and will compile.

C++ Example
// Declare an instance of the class.
SPAposition my_p1(10, 15, 20);
// The compile returns an error in next statement because
// "coord" is the private data member of this class.
double my_x = my_p1.coord[0];
// The correct way to access the x coordinate of the position.
double my_x = my_p1.x();

Overloading Class Constructors

Overloading class constructors means that there is more than one way to create a class instance. In ACIS, additional constructors are made available as a convenience based on the type of data that an application programmer may have on hand at the time a class instance is to be created.

The decision of which constructor to use happens at compile time, based on the argument types passed into the constructor.

Consider again the SPAposition class declared in Example. Declaration of SPAposition Class. A SPAposition instance can be created from three real numbers, from an array of three real numbers, or from another SPAposition instance. This is illustrated in the following example.

C++ Example
// Create an instance of SPAposition using 3 real numbers.
SPAposition p1 (3, 4, 5);
// Create an instance of SPAposition using an array.
double my_array[3] = { 3, 4, 5};
SPAposition p2 (my_array);
// Create an instance of SPAposition using a previously defined
// instance of SPAposition.
SPAposition p3 (p1);

Example. Overloaded Constructors

Copying Objects

ACIS provides class copy constructors, class methods, and functions for copying objects. A copy of an object may be a deep copy or a shallow copy.

A deep copy is a copy made by replicating the object plus any assets owned by the object, including objects pointed at by data members of the object being copied. The copied item does not share any data with the original. A deep copy allocates new storage for all member data and any pointers, so that all the information about that item is self-contained in its own memory block.

A shallow copy copies an object, but instead of copying all the other objects it references (a deep copy) it references the same objects that the original uses. A shallow copy stores only the first instance of the item in memory, and increments a reference count for each copy.

For a copy of an entity that does not share underlying information with the original, a deep copy should be used. One reason for using a deep copy of an entity is to move the deep copy into a different history stream, breaking all ties with the previous history stream. A call to api_deep_copy_entity is used to create the deep copy. There are some entities that are can not be deep copied (by design). If such entities are present during a deep copy, a sys_error will be thrown. A flag can be passed into the API if attributes that can not be deep copied need to be skipped over when doing a deep copy. Any non-attribute entities that cannot be deep copied will throw a sys_error regardless of the logical flag setting.

This section discusses ACIS copy behavior and terminology specific to this functionality. Discussions include:

Topics include:

Shallow, Deep, and Down Copy

This section details the various ACIS copy behaviors.

Shallow Copy

APIs: api_copy_entity, api_copy_entity_list

The goal of the ACIS shallow copy mechanism is to create an "up-and-down" copy of the input entity(s). "Up-and-down" is in reference to topology. For example, looking "up" from a SHELL are the topological entities LUMP and BODY. Accordingly, looking "down" from a COEDGE are the topological entities EDGE and VERTEX. Thus, if you pass a FACE as input to api_copy_entity, every reachable part of the topology above and below the FACE is copied, ultimately resulting in a full BODY copy.

The shallow copy process does not create copies of geometric entities (SURFACE, CURVE, PCURVE, and APOINT). Geometric entities are designed to have multiple owners, and during a shallow copy, new owners are simply added for the geometric entities on the source BODY. This sharing of geometric entities between the source BODY and copied BODY might be problematic if you intend to create a copy of an entity on a different history stream, because ACIS supports having various entities that make up a BODY be across different or multiple history streams. (Refer to "Deep Copy" for details on how it helps solve the problem of creating a copy of an entity that can be moved to a new history stream.)

Attributes (those entities derived from the ATTRIB class) can also participate in the shallow copy process. If the design intent of the attribute is to be copied when its owner is copied, then the attribute should implement its copyable() method to return TRUE.

Note: Attributes that do not implement copyable() are copyable by default.

Finally, the attribute implements its SCAN_DEF, COPY_DEF/COPY_WITH_DEEP_COPY_DEF, and FIX_POINTER_DEF entity derivation macros. Refer to "Copy-Related Entity Derivation Macros" for a detailed discussion about these macros.

Deep Copy

APIs: api_deep_copy_entity, api_deep_copy_entity_list

The ACIS deep copy mechanism is also an "up-and-down" copy similar to shallow copy, but it also makes copies of all geometric entities participating in the copy. Use this mechanism when you want to create a copy of an entity on a different history stream.

Only the ACIS geometric entities (PCURVE, CURVE, SURFACE, and APOINT) have special-purpose logic distinguishing between a shallow and a deep copy. Their design intent is to add new owners in a in a shallow copy, and only to be copied during a deep copy. Although there are other multiple-owned (use-counted) entities in ACIS, none share this design characteristic.

Down Copy

APIs: api_down_copy_entity

In contrast to the shallow and deep copy algorithms, the goal of the ACIS down copy mechanism is not to create an "up-and-down" copy, but rather, just a "down" copy of the input entity. Like a shallow copy, a down copy does not create copies of geometric entities.

For example, if a FACE is down copied, all of its LOOPs, COEDGEs, EDGEs, and VERTEXs are copied. The copied FACE is returned.

In contrast to the shallow and deep copy process, attributes have a different type of involvement with the down copy process. In a down copy, ACIS notifies the attributes that their owner has been copied after the down copy is complete. The notification is sent via the attribute’s copy_owner method.

Note: copy_owner is called regardless whether the attribute is copyable.

The fundamental reason for this delayed-notification approach is due to complex attributes (those that store pointers to entities other than their owner) are not fixed in the topological hierarchy and do not have the concept of what entities are "above" or "below".

For example, consider a complex attribute on a FACE that contains a BODY pointer as member data, and that the attribute’s BODY pointer points to the FACE’s owning BODY. If that FACE is down-copied, what should happen to the attribute? There are many choices as to what might be considered "correct" behavior. The attribute might choose to not be copied, or even to lose itself. A simple attribute, on the other hand, might create a new instance of itself on the new FACE copy. Whatever the decision, the attribute makes it in its copy_owner method.

The Copy Process

The following steps are common to all types of ACIS copy processes (shallow, deep, and down):

Step 1: Scan
Step 2: Copy
Step 3: Fix-pointers

The down copy process includes this additional step:

Step 4: Notify

These steps are discussed immediately below.

Step 1: Scan

All copy algorithms start with either a single entity or a list of entities to be copied. Given the input entity(s), the first step of the copy process includes scanning the input entity(s), thereby building a list of entities to be copied.

The scanning process queries an entity in order to determine the list of entities on which it depends. For example, when a LUMP is scanned for the purposes of a shallow copy, the LUMP adds its owning BODY, the next LUMP, and its SHELL.

The scan process generates a list of all entities that are involved in the copy (depending on the style of copy at hand). Therefore, every input entity is scanned, and every entity on which the input entities depend, and so on. This iterative process of scan/add/scan/add/etc. continues until all entities to be involved in the copy are scanned.

The following short sample generates a list of entities that are involved in a shallow copy of a given input_ent:

ENTITY * ent = NULL;
ENTITY_LIST shallow_copy_list;
shallow_copy_list.add( input_ent );
shallow_copy_list.init();
while ( ent = shallow_copy_list.next() )
	ent.copy_scan( shallow_copy_list, SCAN_COPY );

Note: The above sample employs the copy_scan method which drives the SCAN_DEF entity derivation macro. Refer to the section "Copy-Related Entity Derivation Macros" for more details about this macro.

Step 2: Copy

Previously, in "Step 1: Scan", you built a list of entities to be copied by scanning them. Once the scan-list has been generated, the actual copying begins.

In Step 2: Copy, you allocate storage for an array of copied entities. This array is referred to as the copy-list array, or simply "copy-list". Copy each entity from the scan-list and place it in the copy-list. In summary, for each entity in the scan-list:

  1. Construct a new entity of the same type.
  2. Copy the source entity’s data into the new entity.
  3. Store the new entity in the copy-list array.

Part of the challenge in (2), however, is copying entity pointers. Using the same entity pointers as the source breaks the topology linkage. Ideally, the new entity pointer member data needs to point to the respective copied entities in the copy-list. Unfortunately, because you copy each entity in order, the entities on which the entity being copied depends upon may not yet be copied.

However, the index contains where dependent entity pointers will eventually reside in the copy-list. Therefore, instead of copying entity pointers into each entity’s member data, you can, instead, store the index into the copy-list where the dependent entity will eventually reside.

Resolving the entity pointer indices into actual entity pointers takes place in "Step 3: Fix-pointers".

The entity methods that accomplish Step 2: Copy are:

These methods are related to the ENTITY_DEF (or ATTRIB_DEF for attributes) and COPY_DEF/COPY_WITH_DEEP_COPY_DEF entity derivation macros, respectively. Refer to the section "Copy-Related Entity Derivation Macros" for more information about these macros.

Step 3: Fix-pointers

At this point, you have accomplished the following:

However, each entity’s entity pointer member data in the copy-list actually stores an index into the copy-list. Because the copy-list has now become fully populated with valid copies of entities, Step 3: Fix-pointers can now complete the copy process by having each entity map the entity index that was copied into a real pointer by simply indexing into the copy-list.

The entity method that accomplishes this step is fix_common. This method is related to the FIX_POINTER_DEF entity derivation macro. Refer to the section "Copy-Related Entity Derivation Macros" for more information about these macros.

Step 4: Notify

Note: This step applies to the down copy process only.

As mentioned earlier, the attributes' involvement differs with the down copy process; that is, the previous steps exclude the attributes involvement. Instead, after completion of the previous steps, you notify each attribute on the source entity that its owner was copied via its copy_owner method. Refer to the topic Attributes for more guidance on implementing copy_owner.

Copy-Related Entity Derivation Macros

When you derive from ENTITY or ATTRIB to create your own entity or attribute, Spatial recommends that you use the entity derivation macros. The entity derivation macros encapsulate and simplify the implementation of new entities and attributes. Depending on the level of sophistication of your derived entity/attribute, you may implement up to ten of these macros. Four of the entity derivation macros you implement are related to the copy process:

The following section demonstrates how to implement these entity derivation macros for a fictional attribute. The design intent of this fictional attribute is that it be both copyable and deepcopyable. This attributes stores as member data a SPAbox m_box, and a pointer to a custom entity PROPS * m_props.

Note: Implementing a complex attribute such as this is non-trivial for many reasons (such as saving/restoring, rolling with history) outside of the copy process. The following example focuses on the copy aspects of our fictional complex attribute.

The discussion includes the copy-related entity derivation macros in the order the copy process uses them (which parallels the section "The Copy Process").

Step 1: SCAN_DEF

Entities implement the SCAN_DEF macro to specify how they should be scanned. Behind the SCAN_DEF macro, you implement your entity’s copy_scan method:

virtual void copy_scan(   ENTITY_LIST & list,
                          SCAN_TYPE reason = SCAN_COPY,
                          logical dpcpy_skip = FALSE) const;
ENTITY_LIST & list
The list of entities to be built during this step. Add entities to this list that you want included in the scan/copy/fix-up process.

SCAN_TYPE reason
The reason your entity is being scanned. Types of reasons relevant to the different styles of copy include:
  • SCAN_COPY: shallow copy
  • SCAN_DEEP_COPY: deep copy
  • SCAN_DOWN: down copy
Note: There are other scan reasons that are not copy-related.

logical dpcpy_skip
Used only by the base ENTITY and base ATTRIB class. No other derived entity or attribute utilizes this value. This logical indicates how non-deepcopyable attributes are handled during a deep copy. If TRUE, the copy continues even if it encounters attributes marked as not deep-copyable. By default (FALSE), if any attributes found to be not deep-copyable, a sys_error is thrown.
Note: This flag affects only how attributes are handled; any non-deepcopyable, non-attribute entities encountered cause a sys_error to be thrown regardless of this flag's setting.

For our fictional custom attribute, its SCAN_DEF implementation would look as follows:

SCAN_DEF
       switch (reason)
       {
              case SCAN_COPY:
              case SCAN_DEEP_COPY:
                      list.add( m_props );
                      break;

              // add other non-copy scan cases here...
       }

Our goal in implementing the above scan-def is to add your m_props entity to the scan-list. This ensures that m_props participates in the copy process.

Important notes about SCAN_DEF include:

Step 2: ENTITY_DEF/ATTRIB_DEF and COPY_DEF/COPY_WITH_DEEP_COPY_DEF

To perform the copy, these entity derivation macros are needed: ENTITY_DEF/ATTRIB_DEF and COPY_DEF/COPY_WITH_DEEP_COPY_DEF. Use ENTITY_DEF when deriving new non-attribute entities; use ATTRIB_DEF when defining new attributes.

Both COPY_DEF and COPY_WITH_DEEP_COPY_DEF describe how to copy your entity/attribute. When deriving, you must choose to implement one of these macros, but not both. Choose COPY_DEF to indicate that your entity/attribute is meant only to be shallow copied, and is not deep-copyable. Choose COPY_WITH_DEEP_COPY_DEF to indicate that your entity/attribute may be either shallow or deep copied.

Behind the ENTITY_DEF/ATTRIB_DEF is the copy_data entity method for allocating and copying a new entity.

virtual ENTITY* copy_data(  ENTITY_LIST & list,
                            pointer_map *pm = NULL,
                            logical dpcpy_skip = FALSE,
                            SCAN_TYPE reason = SCAN_COPY ) const;

copy_data is implemented behind the ENTITY_DEF/ATTRIB_DEF macro. It allocates storage for the desired entity (using ACIS_NEW), then invokes a call to the entity method copy_common.

void copy_common(  ENTITY_LIST & list,
                   const ENTITY * from,
                   pointer_map *pm = NULL,
                   logical dpcpy_skip = FALSE,
                   SCAN_TYPE reason = SCAN_COPY );

copy_common is the method behind the COPY_DEF/COPY_WITH_DEEP_COPY_DEF macro. The copy_data and copy_common methods have very similar signatures. They are described as follows:

ENTITY_LIST & list
The list of entities determined during the scan process, referred to as the scan-list. These are the entities involved in the copy. This list is meant for query purposes only.

const ENTITY * from
The newly constructed entity created in copy_data being passed into copy_common.

pointer_map *pm
Relevant if your entity has multiple owners, like ACIS curves and surfaces. ACIS CURVEs and SURFACEs are shared geometric entities, and are not copied during a shallow copy, only during a deep copy. The pointer map allows the implementer to add-to and/or query a list of already copied multiply-owned entities.

logical dpcpy_skip
Used only by the base ENTITY and base ATTRIB class. No other derived entity or attribute should need this value. This logical indicates how non-deepcopyable attributes are handled during a deep copy. If TRUE, the copy continues even if it encounters attributes marked as not deep-copyable. By default (FALSE), if any attributes found to be not deep-copyable, a sys_error is thrown. (This flag only affects how attributes are handled; any non-deepcopyable, non-attribute entities encountered cause a sys_error to be thrown regardless of this flag's setting.)

SCAN_TYPE reason
The scan reason used to create the ENTITY_LIST & list. In some circumstances, knowing the scan reason during the copy process may be useful.

Your objective in implementing COPY_DEF/COPY_WITH_DEEP_COPY_DEF is to describe how to copy the "from" entity’s data onto "this" entity.

For the fictional custom attribute, its COPY_WITH_DEEP_COPY_DEF implementation would look as follows:

							COPY_WITH_DEEP_COPY_DEF m_box = from->m_box; m_props = ( PROPS *) INTEXTEND 
							list.lookup( from->m_props );
						

When copying m_props, you are not actually copying a pointer value; you are storing an index into the m_props pointer. This is the index for the "from" entity as it is represented in list (the list generated by scanning). In other words, if the from entity is the 17th entry in the scan-list array, then after the assignment, m_props will be equal to 17. To resolve this index back into a real pointer, we rely on the final step of the copy process, fix-up pointers.

Step 3: FIX_POINTER_DEF

The last step of the copy process, fix-up pointers, relies on the FIX_POINTER_DEF macro. FIX_POINTER_DEF serves a dual purpose: it is used both by the copy process and the restore process. Whatever the process, the purpose of the fix-up process is the same: to convert entity pointer member data from indices to pointers.

Behind the FIX_POINTER_DEF macro is the fix_common entity method for fixing-up pointers:

void fix_common(  ENTITY * array[],
                  SCAN_TYPE reason = SCAN_COPY );
ENTITY * array[]
The array of copied entities. Has the same number of entities and is in the same order as the scan-list. To resolve indices into pointers, this array is indexed.

SCAN_TYPE reason
The scan reason used to create the scan-list. In some circumstances, knowing the scan reason during the fix-up process may be useful.

Returning to the fictional attribute’s implementation:

FIX_POINTER_DEF
       m_props = ( PROPS * ) read_array( array, m_props );

Using the global read_array function resolves the m_props pointer value. Note that after the COPY_DEF, m_props stores in index. Pass that to read_array as the second argument. read_array then indexes the array at this index and returns the desired entity pointer.

Summary

Types of methods to copy an entity include:

When copying entity(s), choose the copy API that fits what you want to accomplish:

When implementing your own entity/attribute, consider how you want your entity to behave.

Knowing the answers to these questions and how the copy process works will help you implement the entity derivation macros related to the copy process: SCAN_DEF, COPY_DEF/COPY_WITH_DEEP_COPY_DEF, and FIX_POINTER_DEF.

Deprecated Copy Functionality: api_copy_entity_contents

Spatial does not recommend the usage of api_copy_entity_contents; as of R16, this function has been deprecated. The API has been replaced by api_down_copy_entity.

The API api_copy_entity_contents has been deprecated because it did not follow the "standard" ACIS copy process. Many easily created scenarios using complex attributes cause api_copy_entity_contents to create an invalid model.

The API api_down_copy_entity follows the "standard" ACIS copy process and the rules therein.

Overloading Class Methods and Operators

ACIS overloads operators, such as the minus operator (-). This permits the proper handling of elements, depending on the particular class. For example, when one position is subtracted from another, the result is the vector that goes between the two positions, as is shown by the instance of the SPAvector class in the following example.

C++ Example
SPAposition p1 (3, 4, 5);
SPAposition p2 (6, 7, 8);
SPAvector v1 = p2 - p1;

Example. Overloaded Operators

ACIS makes use of the fact that C++ is a strongly typed to enforce rules of combination. For example, the concept of adding two positions does not make sense. However, it does make sense to create a new position that is the sum of a position and a vector, as is shown in the following example, which creates a new instance of the SPAposition class by adding a previous SPAposition instance to a SPAvector instance.

C++ Example
SPAposition p1 (3, 4, 5);
SPAposition p2 (6, 7, 8);
SPAposition p3 = p1 + p2; // Error: this does not compile
SPAvector v1 (10, 20 , 30);
SPAposition p4 = p1 + v1; // creates a new position offset from
                           // position p1 by vector v1.

Example. Using C++ Strong Types

Overloading Class new and delete

ACIS overloads the C++ new operator to allocate space on the portion of the heap controlled by ACIS. This is used in conjunction with the other constructors. Each class derived from ENTITY defines its own new and delete operators that the ACIS free list manager. (These operators are supplied by the ENTITY_FUNCTIONS and UTILITY_DEF macros.)

When working with Microsoft Developer Studio and/or MFC, the beginning of the file may have been enhanced by Microsoft during a _DEBUG compile. Sometimes you will see:

#ifdef _DEBUG
#define new DEBUG_NEW
// ... other code...
#endif

This interferes with the ACIS overloading of new for the entities. So you have two options. Either remove the offending define or move the code that creates your ENTITY objects to another file.

In fact it is an issue when trying to instantiate any object derived from an ACIS entity in MFC. ACIS overrides new and delete for all entity objects and thus one cannot use the standard new operator. Using the new operator for ENTITY derivations needs to have API_BEGIN/API_END around the ENTITY creation code, so it is best to do the allocation in an API function.

outcome api_make_attrib(ENTITY*& ent, ATTRIB_GEN_INTEGER*& attrib, char*& name, int& value)
{
    API_BEGIN
    #undef new
    attrib = new ATTRIB_GEN_INTEGER(ent, name, value);
    #define new DEBUG_NEW
    API_END
}

Overloading API Functions

Although the discussion so far in this section has been about C++ classes and their associated data elements and methods, much of this holds true for the API function interface.

The API functions form the primary interface to ACIS and add an additional level of interface stability. Class methods may change from release to release. However, the API interface remain consistent from release to release. The API functions are often wrappers for C++ class methods or groupings of methods.

Like C++ class methods, API functions can be overloaded. This means that a single name can refer to multiple forms of an API function, with the differences being in the number of arguments and/or in the argument types. The distinction between the overloaded forms of API functions happens at compile time.

[Top]