ome > Getting Started Guide > Architecture > Extending the Modeler
Deriving Classes
The class interface consists of all public ACIS classes and their methods (member functions). Class derivation allows developers to add new data to derived classes, and to define new methods for accessing the data.
This section describes how to extend ACIS by deriving new classes from existing ACIS classes. It includes an example of the classes that might be derived for assembly modeling.
Note: The examples in this section are non-working examples; they have been modified for illustration purposes.
Levels of Derivation
Many developers from different organizations derive new classes from existing ACIS classes. To reduce the potential for name collisions and to identify owning organizations of derived classes, the first derivation from an ACIS class is always an organization class. The organization class merely identifies the organization using a two or three character sentinel, which is a unique identifier that prevents name collisions and identifies the owner of the class. The organization sentinel may identify a company or component.
Organization classes define no methods or data of their own. Organization classes are never instantiated. Application specific classes are derived from the organization class. They define data and methods and can be instantiated.
The assembly modeling example illustrates the organization class, ENTITY_XYZ, and two application specific classes, ASSEMBLY and INSTANCE.
Class Names
Derived organization classes are generally named <BASE-CLASS>_<sentinel>, where <BASE-CLASS> is the name of the base class from which this class is derived, and sentinel is the organization sentinel. Application specific and subsequent derived classes do not have any such naming restrictions.
In the assembly modeling example, the organization is named XYZ, and the organization class derived from ENTITY is named ENTITY_XYZ. The examples in this section derive two application specific classes, ASSEMBLY and INSTANCE.
Files
Each class has a .hxx header file that declares the class, includes necessary header files, and prototypes related functions. The header file contains a comment block that describes the class in a standard format. (ACIS header files are shipped in readable format with both object code and source code shipments.)
In the assembly modeling example, the application specific class, ASSEMBLY, is defined in the assembly.hxx file. Each class has a .cxx source file that implements all of the methods of the class that were not defined as inline methods within the body of the class. The methods file defines class specific macros, and includes the .hxx class header file.
In the assembly modeling example the method for the ASSEMBLY class are implemented in the assembly.cxx file.
ENTITY Class Derivation
ENTITY is the common class for all data structure entity definitions. It defines the base class for all permanent model types.
Macros are provided in the ENTITY class header file (entity.hxx) for simplifying the definition of user entities as classes derived from ENTITY. There are many class methods required for any entity. Many of them are the same for all entities, and many of the others have elements in common. The macros help with this commonality. Refer to Entity Derivation Macros, for descriptions of these macros and how to use them.Assembly Modeling Class Derivation Example
This example is a simple implementation of the derived classes for an assembly modeler. This example is not an exhaustive treatment of assembly modeling. It just provides an example of classes derived from ENTITY that have some use.
The organization class is ENTITY_XYZ, and there are two application specific classes, ASSEMBLY and INSTANCE.Assembly Modeling
Assemblies are a way of making complex parts that consist of repeated building blocks. For example, in steel frame manufacture, bolt groups frequently have to be modeled. It is highly advantageous to be able to model a single bolt and then instance the bolt many times as though it were in the different locations that form the bolt group. Two benefits of assembly modeling are that model space is reduced and that many instances are modified by editing or replacing the body to which an instance refers.
In the simple assembly example, an assembly contains a pointer to an instance and a transform. The transform allows the assembly to be moved cheaply with bodies. Each instance is made up of a pointer to a body and a transform. Instances are connected in a NULL terminated doubly linked list. Refer to the diagram in the following figure.
Figure. Assembly Pointers
To model a car as an assembly, one might create two bodies, CHASSIS and WHEEL, and then five instances, one pointing to CHASSIS and the other four pointing to WHEEL. The transform pointed to by each instance arranges the assembly so that there is an instance of WHEEL at each corner of the instance of CHASSIS.
Organization Class
The organization class is called ENT_XYZ. Its purpose is to identify all classes derived from it as coming from the organization, in this example, XYZ. The abstract class is defined in the ent_xyz.hxx header file and the ent_xyz.cxx source file.
C++ Example
// ent_xyz.hxx
#if !defined( ENTITY_XYZ_CLASS )
#include logical.h
#include en_macro.hxx
// Identifier used to find out (via identity() defined below) to
// what an entity pointer refers. extern int ENTITY_XYZ_TYPE;
// Identifier that gives number of levels of derivation of this
// class from ENTITY.
#define ENTITY_XYZ_LEVEL (ENTITY_LEVEL + 1)
// The XYZ master data structure entity, of which all its private
// specific types are subclasses.
MASTER_ENTITY_DECL( ENTITY_XYZ,NONE )
#define ENTITY_XYZ_CLASS
#endifExample. ent_xyz.hxx
C++ Example
//ent_xyz.cxx
#include <stdio.h>
#include acis.hxx
#include dcl_kern.h
#include datamsc.hxx
#include ent_xyz.hxx
// Identifier used externally to identify a particular entity
// type. This is only used within the save/restore system for
// translating to/from external file format.
// Macros used to tell the master macro who we are and where we
// stand in the hierarchy
#define THIS() ENTITY_XYZ
#define THIS_LIB NONE
#define PARENT() ENTITY #define PARENT_LIB KERN
#define ENTITY_XYZ_NAME xyz
// Now a grand macro to do the rest of the implementation.
MASTER_ENTITY_DEFN( xyz master entity );Example. ent_xyz.cxx
Application-Specific Classes
An application specific class derivation defines each of the data elements with the class, and each of the methods that create, destroy, modify, or inquire these data elements. Application specific classes are instantiated.
The two classes in this example (ASSEMBLY and INSTANCE) encapsulate the functionality of an assembly.
ASSEMBLY Class
The assembly.hxx file contains the class declaration, data definitions, inline methods, and prototypes for non-inline methods. The assembly.cxx source file contains implementations for all of the classs non-inline methods.
C++ Example
// assembly.hxx
#if !defined( ASSEMBLY_CLASS )
#define ASSEMBLY_CLASS
#include ent_xyz.hxx
#include transfrm.hxx
class INSTANCE;
// Identifier that gives number of levels of derivation of this
// class from ENTITY
extern int ASSEMBLY_TYPE;
#define ASSEMBLY_LEVEL (ENTITY_XYZ_LEVEL + 1)
// ASSEMBLY declaration proper.
class ASSEMBLY: public ENTITY_XYZ
{
// Pointer to the start of a list of instances
INSTANCE *instance_ptr;
// This transformation relates the local coordinate system
// to the global one in which the assembly resides.
TRANSFORM *transform_ptr;
// Include the standard member functions for all entities.
ENTITY_FUNCTIONS( ASSEMBLY, NONE )
// Search a private list for this object, used for debugging.
LOOKUP_FUNCTION
// Now the functions specific to ASSEMBLY.
// The assembly constructor initializes the record, and makes
// a new bulletin entry in the current bulletin board to
// record the creation of the assembly.
ASSEMBLY( INSTANCE * = NULL );
// Data reading routines.
INSTANCE *instance() const { return instance_ptr; }
TRANSFORM *transform() const { return transform_ptr; }
// Data changing routines. Each of these routines checks
// that the record has been posted on the bulletin-board
// before performing the change. If not, the routine provokes
// an error, so that the omission (forgetting to call backup()
// first) can be rectified in the program. In production
// versions of the program, these checks may be disabled, to
// improve efficiency.
void add_instance( INSTANCE * );
void set_instance( INSTANCE * );
void set_transform( TRANSFORM * );
};
#endifExample. assembly.hxx
C++ Example
// assembly.cxx
#include <stdio.h>
#include <string.h>v #include <memory.h>
#include acis.hxx
#include logical.h
#include transfrm.hxx
#include datamsc.hxx
#include assembly.hxx
#include instance.hxx
// Include the standard member functions via the usual macros.
// First declare our class name and that of our parent.
#define THIS() ASSEMBLY
#define THIS_LIB NONE
#define PARENT() ENTITY_XYZ
#define PARENT_LIB NONE
// External name for this entity type, for save/restore and
// general communications with the user.
#define ASSEMBLY_NAME assembly
ENTITY_DEF( ASSEMBLY_NAME )
// Print out a readable description of this body.
debug_new_pointer( Instance list, instance(), fp );
debug_new_pointer( Transform, transform(), fp );
LOOKUP_DEF
SAVE_DEF
write_ptr( instance(), list );
write_ptr( transform(), list );
RESTORE_DEF
instance_ptr = (INSTANCE *)read_ptr();
transform_ptr = (TRANSFORM *)read_ptr();
COPY_DEF
instance_ptr = (INSTANCE *)list.lookup( from->instance() );
transform_ptr = (TRANSFORM *)list.lookup( from->transform() );
SCAN_DEF
list.add( instance() );
list.add( transform() );
FIX_POINTER_DEF
set_instance( (INSTANCE *)read_array( array, (int)instance() ) );
set_transform( (TRANSFORM*)read_array( array, (int)transform() ) );
TERMINATE_DEF
// ************************************************************
//
// Now implement the members specific to ASSEMBLY, and those which
// are not part of the macros.
//
// ************************************************************
ASSEMBLY::ASSEMBLY(INSTANCE *inst)
{
//printf(Assembly Constructor In\n);
set_instance(inst);
set_transform(NULL);
//printf(Set back pointers in instances\n);
// Set back pointers in instances
INSTANCE *this_inst = instance();
while (this_inst != NULL)
{
this_inst->set_assembly( this );
this_inst = this_inst->next();
}
//printf(Assembly Constructor Out\n);
}
// Fix up a copy of this object for a change bulletin, after the
// object is constructed and copied memberwise.
void ASSEMBLY::fixup_copy (ASSEMBLY *rollback) const
{
PARENT()::fixup_copy( rollback );
}
// User destructor for a ASSEMBLY. Performs type-specific work,
// then leaves the rest to the generic ENTITY destructor.
void ASSEMBLY::lose()
{
transform_ptr->lose();
// This record is itself rolled back, so we
// dont set the pointer to NULL
ENTITY::lose();
}
// Final record discard.
ASSEMBLY::~ASSEMBLY()
{
check_destroy();
}
// Member-setting functions. Each ensures that the object has been
// backed up for rollback before making any change.
void ASSEMBLY::add_instance( INSTANCE * inst)
{
//printf(Assembly - Adding instance pointer\n);
backup();
if
( inst == NULL )
{
printf(Error - Cannot add a NULL instance\n);
return;
}
else
{
inst->set_previous(NULL);
inst->set_next(instance());
if ( instance() != NULL )
instance()->set_previous(inst);
set_instance(inst);
inst->set_assembly(this);
}
}
void ASSEMBLY::set_instance( INSTANCE * inst)
{
//printf(Assembly - setting instance pointer\n);
backup();
instance_ptr = inst;
}
void ASSEMBLY::set_transform( TRANSFORM * trfm )
{
//printf(Assembly - Setting transform pointer\n);
backup();
transform_ptr = trfm;
}
Example. assembly.cxx
INSTANCE Class
Once the assembly classes and methods are defined, instances are created and initialized with proper data. The INSTANCE class is derived from ENTITY.
If this example were used to construct a room (assembly) full of chairs (instances), each instances body pointer would point to the template of a chair, the assembly pointer would point to the room, and the transform would locate each individual chair somewhere in the room.
When a constructor creates an instance, the instances template body, the assembly to which the instance belongs, and the spatial transformation are all initially NULL. Member routines provide a way to set and to inquire these parameters.
The instance.hxx header file prototypes the functions and includes other necessary header files. The instance.cxx source file implements the functions for instantiation.
C++ Example
// instance.hxx
#if !defined( INSTANCE_CLASS )
#define INSTANCE_CLASS
#include "ent_xyz.hxx"
class BODY;
class TRANSFRM;
class ASSEMBLY;
// Identifier that gives number of levels of derivation of this
// class from ENTITY
extern int INSTANCE_TYPE;
#define INSTANCE_LEVEL (ENTITY_XYZ_LEVEL + 1)
// INSTANCE declaration proper.
class INSTANCE: public ENTITY_XYZ
{
// Pointer to the start of a list of instances
ASSEMBLY *assembly_ptr;
INSTANCE *next_ptr;
INSTANCE *previous_ptr;
// This transformation relates the local coordinate system to
// the global one in which the assembly resides.
TRANSFORM *transform_ptr;
BODY *body_ptr;
// Include the standard member functions for all entities.
ENTITY_FUNCTIONS( INSTANCE, NONE )
// Search a private list for this object, used for debugging.
LOOKUP_FUNCTION
// Now the functions specific to INSTANCE.
// The instance constructor initializes the record, and makes
// a new bulletin entry in the current bulletin board to
// record the creation of the instance.
INSTANCE( ASSEMBLY *ass = NULL, BODY *b = NULL,
TRANSFORM *t = NULL);
// Data reading routines.
ASSEMBLY *assembly() const { return assembly_ptr; }
INSTANCE *previous() const { return previous_ptr; }
INSTANCE *next() const { return next_ptr; }
TRANSFORM *transform() const { return transform_ptr; }
BODY *body() const { return body_ptr; }
// Data changing routines. Each of these routines checks
// that the record has been posted on the bulletin-board
// before performing the change. If not, the routine provokes
// an error, so that the omission (forgetting to call backup()
// first) can be rectified in the program. In production
// versions of the program, these checks may be disabled, to
// improve efficiency.
void set_assembly( ASSEMBLY * );
void set_previous( INSTANCE * );
void set_next( INSTANCE * );
void set_transform( TRANSFORM * );
void set_body( BODY * );
};
#endifExample. instance.hxx
C++ Example
// instance.cxx
#include <stdio.h>
#include <string.h>
#include <memory.h>
#include "acis.hxx"
#include "logical.h"
#include "transfrm.hxx"
#include "body.hxx"
#include "datamsc.hxx"
#include "assembly.hxx"
#include "instance.hxx"
// Include the standard member functions via the usual macros.
// First declare our class name and that of our parent.
#define THIS() INSTANCE
#define THIS_LIB NONE
#define PARENT() ENTITY_XYZ
#define PARENT_LIB NONE
// External name for this entity type, for save/restore and
// general communications with the user.
#define INSTANCE_NAME "instance"
ENTITY_DEF( INSTANCE_NAME )
// Print out a readable description of this entity.
debug_new_pointer( "Owning assembly", assembly(), fp );
debug_new_pointer( "Next instance", next(), fp );
debug_new_pointer( "Previous instance", previous(), fp );
debug_new_pointer( "Transform", transform(), fp );
debug_new_pointer( "Body", body(), fp );
LOOKUP_DEF
SAVE_DEF
write_ptr( assembly(), list );
write_ptr( transform(), list );
write_ptr( body(), list );
write_ptr( previous(), list );
write_ptr( next(), list );
RESTORE_DEF
assembly_ptr = (ASSEMBLY *)read_ptr();
transform_ptr = (TRANSFORM *)read_ptr();
body_ptr = (BODY*)read_ptr();
previous_ptr = (INSTANCE*)read_ptr();
next_ptr = (INSTANCE*)read_ptr();
COPY_DEF
assembly_ptr = (ASSEMBLY *)list.lookup( from->assembly() );
transform_ptr = (TRANSFORM *)list.lookup( from->transform() );
body_ptr = (BODY*)list.lookup( from->body() );
previous_ptr = (INSTANCE*)list.lookup( from->previous() );
next_ptr = (INSTANCE*)list.lookup( from->next() );
SCAN_DEF
list.add( assembly() );
list.add( transform() );
list.add( body() );
list.add( previous() );
list.add( next() );
FIX_POINTER_DEF
set_assembly( (ASSEMBLY *)read_array( array,(int)assembly() ) );
set_transform( (TRANSFORM*)read_array( array,(int)transform() ) );
set_body( (BODY*)read_array( array, (int)body() ) );
set_previous( (INSTANCE*)read_array( array,(int)previous() ) );
set_next( (INSTANCE*)read_array( array, (int)next() ) );
TERMINATE_DEF
// ************************************************************
//
// Now implement the members specific to INSTANCE, and those which
// are not part of the macros.
//
// ************************************************************
INSTANCE::INSTANCE(ASSEMBLY *ass, BODY *b, TRANSFORM *t)
{
//printf("Instance Created\n");
set_assembly(ass);
if ( ass != NULL )
{
ass->add_instance(this);
}
set_body(b);
set_transform(t);
set_previous(NULL);
}
// Fix up a copy of this object for a change bulletin, after the
// object is constructed and copied memberwise.
void INSTANCE::fixup_copy(
INSTANCE *rollback
) const
{
PARENT()::fixup_copy( rollback );
}
// User "destructor" for an INSTANCE. Performs type-specific work,
// then leaves the rest to the generic ENTITY destructor.
void INSTANCE::lose()
{
transform_ptr->lose();
// This record is itself rolled back,
// so we do not set the pointer to NULL
ENTITY::lose();
}
// Final record discard.
INSTANCE::~INSTANCE()
{
check_destroy();
}
// Member-setting functions. Each ensures that the object has been
// backed up for rollback before making any change.
void INSTANCE::set_previous( INSTANCE * inst)
{
//printf("Instance - Setting previous instance pointer\n");
backup();
previous_ptr = inst;
}
void INSTANCE::set_next( INSTANCE * inst)
{
//printf("Instance - Setting next instance pointer\n");
backup();
next_ptr = inst;
}
void INSTANCE::set_assembly( ASSEMBLY * ass )
{
//printf("Instance - Setting assembly pointer\n");
backup();
assembly_ptr = ass;
}
void INSTANCE::set_body( BODY * b )
{
//printf("Instance - Setting body pointer\n");
backup();
body_ptr = b;
}
void INSTANCE::set_transform( TRANSFORM * trfm )
{
//printf("Instance - Setting transform pointer\n");
backup();
transform_ptr = trfm;
}Example. instance.cxx
[Top]
© 1989-2007 Spatial Corp., a Dassault Systèmes company. All rights reserved.