Search STEP Tools Web Support

Overview

The class generator processes a STEP mapping table as defined in the AP. The mapping table must be converted to an XML form, as defined in this document. We have tried to keep the conversion as simple as possible, while providing room for annotations that are used as assist in the code generation.

The tool can process multiple mapping tables at a time, and each mapping table is contained in a single XML document, to enable simple conversion from an AP document. The root element of this document is named <MAP>

Within the <MAP> element, there may be a <title> element, and one or more <arm-object> elements. The <title> contains text that describes the table. This is for documentation only and is ignored by the class generator.

The <arm-object> element describes a single application (ARM) object. There may be multiple <arm-object> elements in a mapping table. The arm-object contains the same information that a printed mapping table contains for a single application object.

The overall structure of a mapping table XML file is as follows:

<MAP>
  <title>Sample mapping table</title>

  <arm-object>
      ...
  </arm-object>

  <arm-object>
      ...
  </arm-object>
</MAP>

<arm-object> element

The arm-object element can have the following attributes:

name
The name of the ARM object. This is used to identify the object, and to control the name of the generated C++ class. There may also be a <name> element, but the element is not used.
abstract
Has the literal value "true" or "false" to indicate if the specified ARM object is abstract.
supers
A space seperated list of the supertype ARM objects. The properties of these ARM objects are merged into the given object when it is processed. The items referenced in this list are references to the name attribute of other ARM objects.
pnew
A callout on the root path to specify a creator function for one or more entity instances there. (See below for more information)
validate
The literal string "true" or "false" (default=false) if true, a callout is generated in the data mining code to validate that an instance of the ARM type actually exists.

The abstract and supers information is not available in the mapping table in the AP document, and so must be derived from an ARM EXPRESS model for the AP, or otherwise manually entered.

The arm-object element has the following elements. Any other elements are ignored by the processor.

<path> or <aim>
A attribute path, in the syntax defined by the mapping tables. This defines the root constraints imposed on the ARM object. If this is empty, the <aim> element is used instead to get the root constraints.
<property>
Defines a single property of the ARM object. See below for more details.

<property> element

The property element describes an application object property. This includes a name and collection of AIM objects that hold the value and link it back to the root AIM object for the ARM concept. The property element can have the following attributes:

name
The name of the attribute. This may include a series of #1:xxx choices. If the #1:name syntax is used, it is possible to define multiple properties that share a path. This will often be necesasary since the mapping taples specified in the APs tend to be more loosly typed than C++ requires.
    <property arm-type="workpiece shape_aspect" 
        name="#1:owner_workpiece #2:owner_shape_aspect" use="required">
      <aim>PATH</aim>
      <source/>
      <rules/>
      <path><![CDATA[
        property_definition
        property_definition.definition ->
        characterized_definition
    #1: ( characterized_definition = characterized_product_definition
          characterized_product_definition
          characterized_product_definition = product_definition
          product_definition)
    #2: ( characterized_definition = shape_definition
          shape_definition
          shape_definition = shape_aspect
          shape_aspect)
      ]]></path>
    </property>
arm-type
This indicated the ARM type of the attributes. This information is not curently used, but may be in a future version of this tool.
use
Indicates the usage pattern for the attribute. It can have the value "required", "optional", "collection" or "implied". If the property is a collection, the use attribute must have a value of collection. Otherwise, it is a scalar property, and the use flag must have the value of optional is it is an optional property, and reqired otherwise. If use="implied" then the ARM property is a boolean flag that is true if the object and path exists, and false if it is missing.
element-start
For collection properties, indicates where in the path the sharing should stop. All the elements of the property share the instances that come before the indicated one in the path. After this instance, each element has an unshared copy of the remaining instances in the path.
pnew
The pnew attribute indicates the AIM instances in the path that require a special (user written) creation function. The code generator will generate a call this function instead of using the ROSE pnew operator.

The syntax of the pnew string consists of a space seperated list of strings where each string is of the form: #n:fn. #n indicates a label in the path, and fn is the function. For example:

    pnew="#1:get_feature_component_pds #2:get_feature_component"
put
Indicates a callout to be included in the put method of the generated code. This is used when there are requirements for sharing objects that cannot be indicated in the constrol file. The put string consists of a label and a function to be called. This function must populate everything in the path below the indicated item. An example declaration is as follows:
    put="#1:get_workpiece_value"
describe
specifies a callback function which provides a string that describes the property in the header
instance-validate
Specifies a callback function that is used to validate a property when mining the data. This function is called after the property is recognized, and must return ROSE_TRUE if the value is set.
generate-inverse
If true this is set, an ARM-level inverse is added. This will result in a nested class (of the _IF) named Inverse_<propname>, and a static method inverse_<prop> (val *), that will return the inverse object.

<property> has the following child elements:

<path>
The path as specified in the mapping table
<subprop>
A subproperty is a value on the path of another property. A get and put method is generated, but it is not searched for in the data mining phase. name - the name of the subproperty type - indicates the type to which the subprop begins. The first instances of this type in the path is the subproperty value
<aim>
Ignored. The terminating AIM element as specified in the mapping table
<source>
Ignored. ISO standard containing the terminating AIM element
<rules>
Ignored. Reference to AP rules that apply to this property.

Callouts

The mapping table includes a number of options for specifiying callout functions. Callout functions are implemented in C++

Pnew Callout

A pnew callout specifies a function to be called for creating a specific instance. This can be use to populate attributes that are not specified in the mapping table, or to arrange for global staring of objects that otherwise would be created for every ARM object.

The pnew attribute on the consists of one or more items seperated by whitespace. An item consists of a label followed by a colon, followed by a function name.

An example usage of the pnew property is the following:

  <arm-object name="pocket_bottom_condition" abstract="true"
     pnew="#1:get_feature_component_pds #2:get_feature_component" >
    <name>POCKET_BOTTOM_CONDITION</name>
    <aim>pocket_bottom</aim>
    <source>10303-522</source>
    <rules/>
    <path><![CDATA[
        pocket_bottom <=
        shape_aspect
        { shape_aspect.of_shape ->
   #1:  product_definition_shape <=
        property_definition
        property_definition.definition ->
        characterized_definition
        characterized_definition = characterized_object
        characterized_object =>
   #2:  feature_component_definition }
    ]]></path>

In this case, the product_definition_shape and the feature_component_definition in the path are created by calling the user provided functions, respectively, get_feature_component_pds and get_feature_component.

The pnew functions always take a RoseDesign pointer as the parameter, and return an object of the type expected. A trivial implementation (which is provided in the PNEW.cxx.eg) would be to simply create a new instance is the specified design and return it.

You could implement the get_feature_component_pds function as follows:

stp_product_definition_shape * get_feature_component_pds(RoseDesign * des)
{
    return pnewIn(des) stp_product_definition_shape;
}

Put Callout

A put callout function is used to define the put method used for the last few values on a path. Can used primarially to control the sharing of AIM instances where the shared instances are value dependant. A put callout function is a bit more complex than a pnew, so you should use a pnew instead of a put when you are able to do so.

A put callout takes responsibility for creating all the instances in a path after a given point. The generated code still handles the items before that point in the path.

A declaration of the put method in the mapping table XML file requires a tag and a function name. For example, the following property declaration declares a put callout:

    <property name="its_priority" use="required" 
         put="#1:get_const_dri">
      <name>its_priority</name>
      <aim>descriptive_representation_item</aim>
      <source>10303-45</source>
      <rules/>
      <path><![CDATA[
         machining_toolpath <=
         action_method
         characterized_action_definition = action_method
         characterized_action_definition <-
         action_property.definition
         { action_property.name = 'priority' }
         action_property <-
         action_property_representation.property
         action_property_representation
         action_property_representation.representation ->
  #1:    representation
         representation.items[i] ->
         representation_item =>
         descriptive_representation_item
         descriptive_representation_item.description
         { (descriptive_representation_item.description = 'required' )
           (descriptive_representation_item.description = 'suggested' ) }
      ]]></path>
    </property>

This then generates the following prototype:

void get_const_dri(
	RoseDesign * des, 
	const char * req_val,
	stp_representation ** req_rep,
	stp_descriptive_representation_item ** req_dri
	);

The first argument is the RoseDesign containing the values. The second the the value that the property is getting set to. The remaining arguments are the path objects. These must be populated by the callout. A simple implementation of the put function is the following:

void get_const_dri(RoseDesign * des, 
    const char * value,
    stp_representation ** arg_1,
    stp_descriptive_representation_item ** arg_2)
{
    *arg_1 = pnewIn(des) stp_represenation;
    *arg_2 = pnewIn(des) stp_descriptive_represenation_item;

    Set(stp_representation_item) ris 
       = pnewIn(des) Set(stp_representation_item);

    (*arg_1)->items(ris);
    ris->add(*arg_2);
    arg_2->description(value);
}

Validate Callout

The validate callout is used by the data mining code to provide a user-defined callout which has the final say on whether an ARM object is really an instance of the specified type. This can be used to overcome limitiation in the mapping table.

The validate callout is controlled by the validate attribute on the <arm-object> element in the mapping table file. If the attribute has a value of "true", then a validate function is generated. The function is named validate_arm, and take an parameter of the type of the ARM object it is validating. When the validate function is called, the ARM recognition for the given ARM object is complete, and all the properties have been populated. Thus, you can call get methods on the arm object to make the decision.

If the validate returns ROSE_FALSE, the ARM object is deleted, and the same root instance is tried against other ARM types -- including those that are mutually exclusive to the type specified.

For example, the following declaration causes a validate function to be generated.

  <arm-object name="closed_pocket" abstract="false" supers="pocket" 
       validate="true">

The validate function can be implemented as follows:

RoseBoolean validate_arm(Closed_pocket * arm)
{
    return arm->isset_feature_boundary();
}

Instance Validate Callout

The instance validate callout is used to attach additional constraints onto an instance in the path in the event that the constraints cannot be specified in the mapping table language. This can occur when you want to eliminate subtypes from consideration.

The instance-validate property takes a list of #tag:function callouts.

The validation function takes a paramter of the entity type specified in the mapping table, and returns a boolean value indicating whether the value conforms to the constraint. For example:

    <property name="its_related_geometry" use="collection" 
        instance-validate="#1:validate_related_geometry">
      <name>its_geometry</name>
      <aim>advanced_brep_shape_representation</aim>
      <source>STEP Tools - Boeing data</source>
      <rules/>
      <path><![CDATA[
          product_definition
          characterized_product_definition = product_definition
          characterized_product_definition
          characterized_definition = characterized_product_definition
          characterized_definition <-
          property_definition.definition
          { property_definition =>
          product_definition_shape }
          property_definition
          represented_definition = property_definition
          represented_definition <-
          property_definition_representation.definition
          {property_definition_representation =>
          shape_definition_representation }
          property_definition_representation
          property_definition_representation.used_representation ->
          representation =>
          shape_representation <-
	  representation_relationship.rep_1
     #1:  { representation_relationship =>
  	    shape_representation_relationship }
	  representation_relationship
	  representation_relationship.rep_2 ->
          representation =>
          shape_representation
      ]]></path>
    </property>

This is then implemented by the following validation method:

RoseBoolean validate_related_geometry(stp_shape_representation_relationship * val)
{
    return (!val->isa(ROSE_DOMAIN(stp_representation_relationship_with_transformation)));
}

Describe Callout

A describe callout function provides a human readable description for the property. This is used for a string which is included in the ARM comments of the Part 21 file.

The describe function takes a STModule (generic ARM object), and a list of RoseObject representing the path. (This very generic interface was chosen to allow the describe functions to be reused). For example, the following declaration in the ARM:

    <property name="plane_angle_unit" use="optional" arm-type="" 
          describe="getUnitName">

Generates a call to the getUnitName function, which can be implemented as follows:

RoseStringObject getUnitName(STModule * mod, List(RoseObject) * path)
{
    RoseObject * last = path->last();

    if (last->isa(ROSE_DOMAIN(stp_named_unit)))
	return stix_get_unit_fullname(ROSE_CAST(stp_named_unit, last));

    if (last->isa(ROSE_DOMAIN(stp_derived_unit)))
	return stix_get_unit_fullname(ROSE_CAST(stp_derived_unit, last));
        
    return "????";
}

Path Annotations

Collection index - #

Use a constraint with the value '#' to indicate the property that serves as the index of a property.

{ make_from_usage_option.ranking = #}

Optional constraints - ?

A constraint (anything in {}) can be turned into a "suggestion" by preceeding it with a ?. The generated code will still try to find the suggested value, but will fall back to ignoring the suggestion. For example, in a path:

        ? { property_definition =>
            product_definition_shape }