Element Trees: Principles of Feature Creation
This section describes the basic principles of programmatic feature creation that are applicable to all types of feature that can be created in the current version of Creo TOOLKIT. This section also describes how to extract the internal description of features of those feature types in the Creo TOOLKIT database, and how to modify them.
Overview of Feature Creation
This section provides references to additional material on feature creation and an overview of creating features.
References to Feature Creation Data
The creation of specific feature types is dealt with in more detail in the following sections:
This chapter defines and describes the following Creo TOOLKIT objects:
•  ProElement
•  ProElempath
•  ProValue
For a definition of the ProFeature object, see the section Core: Features.
Feature Creation
There are many kinds of feature in Creo Parametric and each one can contain a large and varied amount of information. All this information must be complete and consistent before a feature can be used in regeneration and give rise to geometry. This raises several problems for programmatic creation of features through an API.
It is necessary to build all the information needed by a feature into a data structure before passing that whole structure to Creo Parametric. However, the object-oriented style of Creo TOOLKIT requires that such a data structure is not directly visible to the application. Therefore, Creo TOOLKIT defines this structure as a workspace object that can be allocated and filled using special functions for that purpose, but that is not part of the Creo Parametric database.
There are three steps in creating a feature in Creo Parametric:
1. Allocate the workspace structure.
2. Fill the workspace structure.
3. Pass the workspace structure to Creo Parametric to create the feature.
Note
Creating sketched features requires a few more steps. For detailed information, see Element Trees: Sketched Features.
The procedure described above allows a feature of arbitrary complexity to be built up in a sequence of manageable steps, with the maximum of error checking along the way.
Although it is not yet possible to create all feature types using Creo TOOLKIT, the workspace structure must be capable of defining any feature type so the range of features can be extended without affecting the techniques already in use. For this reason, the workspace structure for feature creation takes the form of a tree of data elements. This has the advantage of being simple for simple features, yet is flexible enough to provide for all possible feature types without introducing new principles.
The root and branch points in the tree are called “elements,” and the complete tree is called the “feature element tree.” Each element is modeled by the object ProElement, which is a pointer to an opaque structure.
The feature element tree contains all the information required to define the feature. This includes the following:
•  All options and attributes, such as the material side and depth type for an extrusion or slot, placement method for a hole, and so on.
•  All references to existing geometry items, such as placement references, “up to” surfaces, sketching planes, and so on.
•  References to Sketcher models used for sections in the feature.
•  All dimension values.
Note
Because Creo TOOLKIT is the same toolkit used to build Creo Parametric, improvements to Creo Parametric may require the definition of the element tree to be altered for some features. PTC will make every effort to maintain upward compatibility. However, there may be cases where the old application will not run with the new version of Creo Parametric, unless you rewrite the application's code to conform to the new definition of the feature tree.
Note that although the values of dimensions used by the feature are in the element tree, there are no descriptions of, or references to, the dimension objects themselves. The only exception is as follows: for an element tree for a feature already in the Creo Parametric database, you can ask the identifier of the dimension used for a particular element using the function ProFeatureElemDimensionIdGet(). This is explained in detail in the section Feature Inquiry. For more general functions that access dimensions, see the section Core: Relations.
Each element in the tree is assigned an element ID, which is really a description of the role it is playing in this feature—the kind of information it is supplying. It is called an element ID because no two elements at the same level in the tree will have the same identifier, unless they belong to an array element, so the element ID also acts as a unique identifier.
The possible element roles are values in an enumerated type called ProElemId, declared in ProElemId.h. Example values are as follows:
•  PRO_E_FEATURE_TYPE
•  PRO_E_FEATURE_FORM
•  PRO_E_EXT_DEPTH
•  PRO_E_THICKNESS
•  PRO_E_4AXIS_PLANE
There are four different element types:
•  Single-valued
•  Multivalued
•  Compound
•  Array
A single-valued element can contain various types of value. The simplest is an integer used to define, for example, the type of the feature, or one of the option choices, such as the material side for a thin protrusion. The value can be a wide string (for example, the name of the feature), or a double (for example, the depth of a blind extrusion). If the element defines a reference to an existing geometry item in the solid, its value contains an entire ProSelection object so it can refer to anything in an entire assembly.
A multivalued element contains several values of one of these types. Multivalued elements occur at the lowest level of the element tree—the “leaves.” An example is the element with the identifier PRO_E_FIXT_COMPONENTS in a Fixture Setup feature in Creo NC. That element specifies the components in the assembly that belong to the fixture; in general, there can be any number of such components, so the element contains several component identifiers.
A compound element is one that acts as a branch point in the tree. It does not have a value of its own, but acts as a container for elements further down in the hierarchy.
An array element is also a branch point, but one that contains many child elements of the same element ID. An example of this is the PRO_E_DTMPLN_CONSTRAINTS element in a datum plane feature, which contains an array of elements of type PRO_E_DTMPLN_CONSTRAINT (note the singular), each of which is a compound element whose contents describe one of the constraints that determine the position of the datum plane.
The feature element tree enables you to build a complex feature in stages, with only a small set of functions. However, the form of the tree required for a particular feature needs to be clearly defined so you know exactly what elements and values to add, and so Creo TOOLKIT can check for errors each time you add a new element to the tree.
Creo TOOLKIT documents the necessary contents of the element tree for each type of feature that can be created programmatically. It does this through two types of description:
•  Feature element tree
•  Feature element table
The feature element tree defines the structure of the tree, specifying the element ID (or role) for the elements at all levels in the tree, and which elements are optional.
The feature element table defines the following for each of the element IDs in the tree:
•  A description of its role in the feature
•  The value type it has (that is, whether it is single value or compound; or an array of integer, double, or string)
•  The range of values valid for it in this context
Each type of feature that can be created using Creo TOOLKIT has its own header file that contains the feature element tree and table, in the form of code comments. The header files for the feature types that can be created in the current version are as follows:
Header File
Feature Type
ProAnalysis.h
External Analysis
ProAsmcomp.h
Assembly component, mechanism connection
ProChamfer.h
Chamfer or corner chamfer
ProDataShareFeat.h
General merge (merge, cutout, inheritance), copy geom., publish geom., shrinkwrap
ProDraft.h
Draft
ProDtmAxis.h
Datum axis
ProDtmCrv.h
Datum curve
ProDtmCsys.h
Datum coordinate system
ProDtmPln.h
Datum plane
ProDtmPnt.h
Datum point
ProExtrude.h
Extruded protrusion, cut, surface, surface trim, thin, sheetmetal wall, or sheetmetal cut
ProFixture.h
Fixture (for Creo NC)
ProFlatSrf.h
Fill surface or sheetmetal flat wall
ProForeignCurve.h
Foreign datum curve
ProHole.h
Hole
ProMerge.h
Merge
ProMirror.h
Mirror (geometry only)
ProMove.h
Move and copy (geometry only)
ProMfgoper.h
Manufacturing operation
ProNcseq.h
Manufacturing Creo NC sequence
ProProcstep.h
Process step
ProReplace.h
Surface replacement feature
ProRevolve.h
Revolved protrusion, cut, surface, surface trim or thin
ProRib.h
Rib
ProRound.h
Round
ProShell.h
Shell
ProSmtFlangeWall.h
Sheetmetal flange wall
ProSmtFlatWall.h
Sheetmetal flat wall
ProSolidify.h
Solidify
ProStdSection.h
Standard section
ProSweep.h
Simple swept protrusion, cut
ProThicken.h
Thicken
ProTrim.h
Trim
ProWcell.h
Manufacturing workcell
The feature element tree for the Fixture Setup feature defined in the header file ProFixture.h is deprecated. Use the element tree defined in the header file ProMfgFeatFixture.h instead. For more information, please refer to the section Manufacturing Holemaking Step.
The first two elements are common to all features. The root of a feature tree is always a compound element with the identifier PRO_E_FEATURE_TREE. The first element within the root always specifies the feature type; it is a single-valued element with the element ID PRO_E_FEAT_TYPE, whose value is one of the integers in the list of feature types in ProFeatType.h. In this case, the element table shows that the value must be PRO_FEAT_FIXSETUP.
The next element in a fixture setup gives the name of the feature; its element ID is PRO_E_FEAT_NAME, and it contains a single wide string. The element tree shows that this is optional.
The PRO_E_FIXT_COMPONENTS is a multivalued element, with the value type integer, which contains the identifiers of the assembly components that belong to the fixture.
The last element in a fixture setup is PRO_E_SETUP_TIME, which contains a double.
As you build the elements into the workspace element tree, Creo TOOLKIT checks the correctness of their types against the structure described by the element tree and table in the corresponding header file. This makes it easy to diagnose errors when you are creating features. The geometrical correctness is checked only when you try to create the feature in the Creo Parametric database.
The following sections of this chapter describe the functions used to build an element tree and create a feature. The sections are as follows:
•  Feature Element Values—Introduces the object ProValue, used to represent the value of a feature element.
•  Feature Element Paths—Introduces the object ProElempath, used to describe the location of an element in an element tree.
•  Feature Elements—Introduces the ProElement functions used to build and analyze an element tree.
•  Feature Element Diagnostics—Introduces the ProElementDiagnostics functions used to obtain the diagnostics for a feature element.
•  Calling ProFeatureCreate()—Describes the ProFeatureCreate() function in detail.
•  Example of Complete Feature Creation—Shows how to use functions from the other sections to perform all the steps needed to create a feature.
Feature Element Values
Functions introduced:
The object ProValue is an opaque workspace handle used to contain the value of a feature element. It is the output of the functions ProElementValueGet() and ProElementValuesGet(), which read the values of a feature element, and is the input to ProElementValueSet() and ProElementValuesSet().
You can access the contents of a ProValue object by translating it into an object of type ProValueData, which is declared as a visible data structure. The declaration is as follows:
typedef struct pro_value_data
{
  ProValueDataType   type;
  union
  {
    int            i;    /* integer */
    double         d;    /* double */
    void          *p;    /* pointer or reference */
    char          *s;    /* string */
    wchar_t       *w;    /* wchar_t */
    ProSelection   r;    /* selection */
  } v;
} ProValueData;
  typedef enum pro_value_data_type
  {
    PRO_VALUE_TYPE_INT           = 1,
    PRO_VALUE_TYPE_DOUBLE,
    PRO_VALUE_TYPE_POINTER,
    PRO_VALUE_TYPE_STRING,
    PRO_VALUE_TYPE_WSTRING,
    PRO_VALUE_TYPE_SELECTION
  } ProValueDataType;
ProValueData is simply a holder for data values of many different types.
Note
From Pro/ENGINEER Wildfire 2.0 onwards, elements with multiple values, for example, PRO_E_FIXT_COMPONENTS, are deprecated. In subsequent releases, these elements will be superseded by reference elements or single-value, type-specific elements. Use the function ProElementValuetypeGet() to determine the type of the element.
Note
To access reference elements use the functions ProElementReferencesGet() or ProElementReferencesSet(). To access single-value, type-specific elements, use the functions ProElement<type>Get() or ProElement<type>Set(), such as, ProElementDoubleGet(), ProElementIntegerGet() and so on.
The functions in this section access the contents of a ProValue through the ProValueData object.
The function ProElementDirectionGet() calculates the direction vector and origin point based on the direction reference and flip orientation stored inside the direction element. The input argument element is the PRO_E_DIRECTION_COMPOUND compound element, which contains two sub elements inside PRO_E_DIRECTION_REFERENCE and PRO_E_DIRECTION_FLIP. The output argument are:
•  vector—calculated ProVector direction vector.
•  origin—calculated Pro3dPnt direction origin point.
The function ProValueDataGet() provides the ProValueData object for the specified ProValue object.
The function ProValueAlloc() allocates a new ProValue in memory, as the first step towards setting the value of a feature element.
The function ProValueDataSet() sets the value of a ProValue object using the contents of a ProValueData structure.
The function ProValueFree() frees a ProValue object in memory.
The function ProWstringArrayToValueArray() provides a convenient way to allocate and fill an array of ProValue structures that all contain wide string values.
The function ProValueArrayToWstringArray() performs the reverse translation, allocating and filling an array of wide strings. In both cases, the output array is an expandable array, so you should release the memory using ProArrayFree().
The transform member of the union ProValueData is declared as double**. It must be passed a double[][] (a ProMatrix structure). The utility functions ProValuedataTransformGet() and ProValuedataTransformSet() specify how to assign the ProValueData in order to access the matrix correctly.
Feature Element Paths
Functions introduced:
An element path is used to describe the location of an element in an element tree. It is used by some of the ProElement functions as a convenient way to refer to elements already in a tree.
The object ProElempath is declared as an opaque pointer. It contains a description of the path from the root of the tree down to the element referred to. At most levels in the tree hierarchy, the relevant path member is the element ID of the element (which is unique at that level). When the path steps from an array element to one of its member arrays, the element path instead contains the array index of that element.
To be able to set the value of a ProElempath, Creo TOOLKIT provides a structure called ProElempathItem that can describe an element ID, or the index into an array element. An array of ProElempathItem structures is therefore a visible equivalent to the opaque contents of ProElempath.
The declaration of ProElempathItem is as follows:
typedef struct path
{
  ProElempathItemtype type;
  union
  {
    int elem_id;
    int elem_index;
  } path_item;
} ProElempathItem;
  typedef enum
  {
    PRO_ELEM_PATH_ITEM_TYPE_ID,
    PRO_ELEM_PATH_ITEM_TYPE_INDEX
  } ProElempathItemtype;
The object ProElempath, the structure ProElempathItem, and all the functions in this section are declared in the header file ProElempath.h.
The function ProElempathAlloc() allocates a new empty ProElempath object, whereas ProElempathFree() frees a ProElempath.
The function ProElempathDataSet() enables you to set the contents of a ProElempath by copying from an array of ProElempathItem structures.
The function ProElempathDataGet() reads the contents of a ProElempath into an array of ProElempathItem structures. The array is an expandable array that must be allocated by a call to ProArrayAlloc() before you call the function.
The function ProElempathCopy() copies the contents of one ProElempath object into another. The output object is allocated by the function.
The function ProElempathCompare() tells you whether two ProElempath objects refer to the same element.
The function ProElempathSizeGet() tells you the length of the element path contained in a ProElempath object.
Feature Elements
Functions introduced:
The function ProElementAlloc() allocates a new ProElement object with a specified element ID. The function ProElementFree() frees a ProElement.
The function ProElementIdGet() outputs the element ID of a specified ProElement. The function ProElementIdSet() enables you to set the element ID of a specified ProElement.
The function ProElemIdStringGet() returns the string representation of the specified element ID.
The function ProElemtreeElementGet() enables you to read a specified element in a tree. The inputs are the root of the tree, specified as a ProElement object, and the path to the element, specified by a ProElempath. The output is a ProElement object.
The function ProElemtreeElementAdd() adds a new element to the specified element tree. The inputs are the ProElement for the tree root, the ProElempath to the new element, and the ProElement for the new element.
The function ProElemtreeElementRemove() removes an element from a specified tree and path. It outputs a ProElement for the element removed.
The functions ProElementIsMultival(), ProElementIsCompound(), and ProElementIsArray() tell you the type of a specified element in a tree. See the section Overview of Feature Creation for an explanation of the types.
The function ProElementChildrenGet()provides an expandable array of ProElement objects for the children of the specified compound element in a tree. The array must be allocated using ProArrayAlloc() before you call this function. The function ProElementChildrenSet()adds a set of elements, specified by an expandable array of ProElement objects, as the children of the specified element in a tree.
The function ProElementArraySet() adds an expandable array of ProElement objects as the members of a specified array element in an element tree.
The function ProElementArrayGet() fills an expandable ProElement array with the members of an array element in an element tree. The function ProElementArrayCount() tells you how many members are in an array element in the specified element tree.
The function ProElemtreeElementVisit() visits the elements that are members of the specified array element in an element tree.
Access to ProElement Data
In earlier releases, Pro/TOOLKIT recommended using functions that access the element value(s) as ProValue objects. These functions are maintained for compatibility. PTC recommends using the functions in this section to provide greater flexibility for all new development related to any Pro/ENGINEER feature type. Use of these new functions is required for features first supported in Pro/ENGINEER Wildfire 2.0 and later.
Functions introduced:
These functions are the preferred method of accessing element values information over ProElementValueGet() or ProElementValueSet() and ProValueDataGet() or ProValueDataSet().
The function ProElementValuetypeGet() returns the nominal value type for the element.
The functions ProElementReferenceGet() and ProElementReferenceSet() returns and sets a single reference value for the element.
The function ProElementReferencesGet() returns an array of reference values for the element. The function outputs a reference array, which is a ProArray. Free this output using ProReferencearrayFree().
The function ProElementReferencesSet() sets the multiple reference values for the element.
The function ProElementIntegerGet() returns an integer value representation for the element. The function ProElementIntegerSet() sets the integer value for the element.
The function ProElementDoubleGet() returns a double value representation for the element. The function ProElementDoubleSet() sets the double value for the element.
The function ProElementDecimalsGet() obtains the number of decimal places to be used for the double value of an element in the feature.
The function ProElementDecimalsSet() assigns the number of decimals to be used for the double value of an element in the feature. The double value is used in the feature dimension related to this element.
Note
Use the function ProElementDecimalsSet() before using the function ProElementDoubleSet() to ensure that the double value is assigned with the correct number of decimal places.
The following functions show how options are constructed and set for ProElement*Get() functions.
The function ProElementwstroptsAlloc() allocates the options used to retrieve wide string values.
The function ProElementwstroptsExpressionsSet() sets the options to retrieve values as expressions or relations, if they exist, instead of a string representations of the actual value. This function is applicable to nominal double and integer value elements only.
The function ProElementwstroptsSignoptionsSet() sets the options to retrieve values with special sign formatting (+/-), etc. This function is applicable to nominal double and integer value elements only.
The function ProElementwstroptsFree() frees the options used to retrieve string values.
The function ProElementWstringGet() returns a string value representation for the element. The function allows, optionally, a ProElementWstrOpts() structure that dictates the format of the output. Use the function ProWstringFree() to free this string.
The function ProElementWstringSet() sets the string value for the element.
The function ProElementStringGet() returns an ASCII string value representation for the element. The inputs for this function are the element and options for how the string should be obtained. The output is the ASCII string value. Free this string using ProStringFree().
The function ProElementStringSet() sets the ASCII string value for the element.
The function ProElementSpecialvalueGet() returns the pointer representation for the element and the function ProElementSpecialvalueSet() sets the pointer representation for the element.
The function ProElementBooleanGet() returns the boolean representation for the element and the function ProElementBooleanSet() sets the boolean value for the element.
The function ProElementTransformGet() returns the transform representation for the element and the function ProElementTransformSet() sets the transform value for the element.
Feature Element Diagnostics
Functions Introduced:
The function ProElementDiagnosticsCollect() obtains a ProArray of diagnostics for the element. These diagnostics include warnings and errors regarding the value of the element within the context of the feature and remainder of the element tree. Use the function ProElemdiagnosticProarrayFree() to free the ProArray of diagnostic items.
The function ProElemdiagnosticSeverityGet() returns the severity of the diagnostic item for the element.
The function ProElemdiagnosticMessageGet() obtains the message describing the diagnostic item for the element. This message is in the user’s localized language.
The function ProElemdiagnosticFree() frees the diagnostic item for the element.
The function ProReferenceDiagnosticsCollect() obtains a ProArray of diagnostics for the reference element. These diagnostics include warnings and errors regarding the state of the reference element within the context of the feature.
Calling ProFeatureCreate()
Function introduced:
The syntax of ProFeatureCreate() is as follows:
ProError ProFeatureCreate (
  ProSelection             model,       /* (In)  The part on which the
                                                 feature is being 
                                                 created. If the feature
                                                 is created in an 
                                                 assembly, you must
                                                 specify the component 
                                                 path. */
  ProElement               elemtree,    /* (In)  The element tree. */
  ProFeatureCreateOptions  options[],   /* (In)  An array of user
                                                 options. */
  int                      num_opts,    /* (In)  The number of options
                                                 in the options array. */
  ProFeature              *p_feature,   /* (Out) The feature handle. */
  ProErrorlist            *p_errors     /* (Out) The list of errors. */
)
The first input argument to ProFeatureCreate() identifies the solid that is to contain the new feature. This is expressed in the form of a ProSelection object.
Note
The ProSelection object input to ProFeatureCreate(), and all the ProSelection objects assigned to elements in the feature element tree, must all refer to the same root assembly.
The second input argument is the ProElement object that forms the root of the feature element tree.
The next two inputs are an array of creation options and the size of the array. The creation options specify what ProFeatureCreate()should do if the element tree is incomplete, or if the geometry cannot be constructed. Each option is one of the following values of the enumerated type ProFeatureCreateOptions:
•  PRO_FEAT_CR_NO_OPTS—No options were chosen.
•  PRO_FEAT_CR_DEFINE_MISS_ELEMS—Prompt the user to complete the feature if any elements are missing.
•  PRO_FEAT_CR_INCOMPLETE_FEAT—Create the feature, even if some elements are missing. The feature will appear in the Creo Parametric feature list and model tree, but will not be used in regeneration.
•  PRO_FEAT_CR_FIX_MODEL_ON_FAIL—If the feature geometry cannot be constructed, prompt the user to fix the problem.
If no options are needed, you can set the array to NULL, and the size to zero. If you do not specify any options, ProFeatureCreate() fails and reports errors if the element tree is incomplete, or if the geometry cannot be constructed.
To check whether a feature is incomplete, use the function ProFeatureIsIncomplete().
The next argument is an output that provides a ProFeature object that identifies the newly created feature.
The final argument is an output that reports errors found in the feature element tree. This is designed as an aid to application developers because it is reporting errors that occur only as a result of incorrect application code; it is not designed as a way of reporting errors to the Creo Parametric user. The errors are written to a structure called ProErrorlist whose declaration, in ProItemerr.h, is as follows:
typedef struct
{
   ProItemerror         *error_list;
   int                  error_number;
} ProErrorlist;
  typedef struct
  {
    int                  err_item_id;
    ProErritemType       err_item_type;
    ProError             error;
  } ProItemerror;
    typedef enum ProErritemTypes
    {
      PRO_ERRITEM_NONE = -1,
      PRO_ERRITEM_FEATELEM = 1
    } ProErritemType;
The field error_list is an array of all the errors in the feature element tree found by ProFeatureCreate(). Each error has a value expressed in terms of the standard Creo TOOLKIT error type ProError, and can refer to an element of a specified identifier, or be a more general error.
Note
•  There are many useful utilities located in the Creo TOOLKIT sample code under the Creo TOOLKIT loadpoint. Utilities such as ProUtilElementtreePrint() are particularly useful when building and debugging element trees.
•  From Pro/ENGINEER Wildfire 5.0 onward, the function ProFeatureCreate() has been deprecated. Instead, use the function ProFeatureWithoptionsCreate() with its input argument flags set to PRO_REGEN_NO_FLAGS for the equivalent behavior. ProFeatureWithoptionsCreate() has been described in detail in the Manipulating Features based on Regeneration Flags section in the Core: Features section.
Example of Complete Feature Creation
This section illustrates all the techniques explained so far in this chapter by showing the code required to create a datum plane in a part or an assembly. The datum plane created here is offset from a plane surface, and therefore has the following element tree:
Example Element Tree: Offset Datum Plane
Image
(The full element tree for datum plane features is described in the section Element Trees: Datum Features.)
In the code examples that follow, no checks of function return statuses are shown, for clarity. No variable declarations are shown, but the style of the code samples should make these self-explanatory.
The example assumes that the datum plane is being created by a utility function that has two inputs describing the offset surface as a ProSelection relative to the current part or assembly, and the offset distance, as follows:
int ProDatumPlaneCreate (ProSelection offset_surface,
                         double       offset_dist);
The first step is to create the element that forms the root of the element tree. This element has the element ID PRO_E_FEATURE_TREE but has no value, so it can be created simply by a call to ProElementAlloc():
/*---------------------------------------------------------------*\
    Create the root of the element tree.
\*---------------------------------------------------------------*/
    ProElementAlloc (PRO_E_FEATURE_TREE, &elem_tree);
The first element inside the root is, as for all features, the feature type. Its ID is PRO_E_FEATURE_TYPE, and it has the single value PRO_FEAT_DATUM. To set the value, you must first create a ProValue object of type integer.
/*---------------------------------------------------------------*\
    Allocate the feature type element.
\*---------------------------------------------------------------*/
    ProElementAlloc (PRO_E_FEATURE_TYPE, &elem_ftype);
/*---------------------------------------------------------------*\
    Set the value of the feature type element.
\*---------------------------------------------------------------*/
    value_data.type = PRO_VALUE_TYPE_INT;
    value_data.v.i = PRO_FEAT_DATUM;
    ProValueAlloc (&value);
    ProValueDataSet (value, &value_data);
    ProElementValueSet (elem_ftype, value);
/*---------------------------------------------------------------*\
    Add the feature type element as a child of the tree root.
\*---------------------------------------------------------------*/
    ProElemtreeElementAdd (elem_tree, NULL, elem_ftype);
The next element is simply the holder for the datum plane constraints, and this in turn contains a single constraint element (to be used for the offset constraint).
/*---------------------------------------------------------------*\
    Add a PRO_E_DTMPLN_CONSTRAINTS element to the root of the
    tree.
\*---------------------------------------------------------------*/
    ProElementAlloc (PRO_E_DTMPLN_CONSTRAINTS, &elem_consts);
    ProElemtreeElementAdd (elem_tree, NULL, elem_consts);
/*---------------------------------------------------------------*\
    Add a PRO_E_DTMPLN_CONSTRAINT element to the constraints
    element.
\*---------------------------------------------------------------*/
    ProElementAlloc (PRO_E_DTMPLN_CONSTRAINT, &elem_offset);
    ProElemtreeElementAdd (elem_consts, NULL, elem_offset);
Inside the single constraint element, add an element of type PRO_E_DTMPLN_CONSTR_TYPE that specifies the constraint type to be PRO_DTMPLN_OFFS.
/*---------------------------------------------------------------*\
    Allocate the constraint type element.
\*---------------------------------------------------------------*/
    ProElementAlloc (PRO_E_DTMPLN_CONSTR_TYPE,
                     &elem_const_type);
/*---------------------------------------------------------------*\
    Set its value to be PRO_DTMPLN_OFFS.
\*---------------------------------------------------------------*/
    value_data.type = PRO_VALUE_TYPE_INT;
    value_data.v.i = PRO_DTMPLN_OFFS;
    ProValueAlloc (&value);
    ProValueDataSet (value, &value_data);
    ProElementValueSet (elem_const_type, value);
/*---------------------------------------------------------------*\
    Add it as a member of the constraint element.
\*---------------------------------------------------------------*/
    ProElemtreeElementAdd (elem_offset, NULL, elem_const_type);
Also in the constraint element, you need an element to identify the reference plane surface, PRO_E_DTMPLN_CONSTR_REF, with value type ProSelection.
/*---------------------------------------------------------------*\
    Allocate the offset reference element.
\*---------------------------------------------------------------*/
    ProElementAlloc (PRO_E_DTMPLN_CONSTR_REF, &elem_offset_ref);
/*---------------------------------------------------------------*\
    Set its value to be the ProSelection for the offset
    reference surface.
\*---------------------------------------------------------------*/
    value_data.type = PRO_VALUE_TYPE_SELECTION;
    value_data.v.r = offset_surface;
    ProValueAlloc (&value);
    ProValueDataSet (value, &value_data);
    ProElementValueSet (elem_offset_ref, value);
/*---------------------------------------------------------------*\
    Add it to the constraint element.
\*---------------------------------------------------------------*/
    ProElemtreeElementAdd (elem_offset, NULL, elem_offset_ref);
Finally, you need an element of type PRO_E_DTMPLN_CONSTR_REF_OFFSET to contain the double value of the offset distance.
/*---------------------------------------------------------------*\
    Allocate the offset distance element.
\*---------------------------------------------------------------*/
    ProElementAlloc (PRO_E_DTMPLN_CONSTR_REF_OFFSET,
                     &elem_offset_dist);
/*---------------------------------------------------------------*\
    Set its value to be the offset distance.
\*---------------------------------------------------------------*/
    value_data.type = PRO_VALUE_TYPE_DOUBLE;
    value_data.v.d = offset_dist;
    ProValueAlloc (&value);
    ProValueDataSet (value, &value_data);
    ProElementValueSet (elem_offset_dist, value);
/*---------------------------------------------------------------*\
    Add it to the constraint element.
\*---------------------------------------------------------------*/
    ProElemtreeElementAdd (elem_offset, NULL, elem_offset_dist);
The element tree is complete.
The next step is to set up a ProSelection object that refers to the solid in which you will create the datum plane.
You have the information about the context, in the form of the ProSelection object, for the offset surface that was an input to the function you are writing. The component path you need is the same one used to specify that surface. The solid to contain the new feature is the one that owns the offset surface. Therefore, you can build the ProSelection object for it as follows:
/*---------------------------------------------------------------*\
    Get the component path for the offset surface.
\*---------------------------------------------------------------*/
    ProSelectionAsmcomppathGet (offset_surface, &comppath);
/*---------------------------------------------------------------*\
    Get the model item for the offset surface.
\*---------------------------------------------------------------*/
    ProSelectionModelitemGet (offset_surface, &surf_modelitem);
/*---------------------------------------------------------------*\
    Make a ProModelitem that refers to the owner of the offset
    surface.
\*---------------------------------------------------------------*/
    ProMdlToModelitem (surf_modelitem.owner, &model_modelitem);
/*---------------------------------------------------------------*\
    Make a ProSelection for the solid that will contain the
    new feature.
\*---------------------------------------------------------------*/
    ProSelectionAlloc (&comppath, &model_modelitem, &featsel);
If the offset surface belongs to a part in a current assembly, and your function is required to add the datum plane not to the part but to the assembly, the code above would be replaced by this:
/*---------------------------------------------------------------*\
    Get the component path for the offset surface.
\*---------------------------------------------------------------*/
    ProSelectionAsmcomppathGet (offset_surface, &comppath);
/*---------------------------------------------------------------*\
    Make a ProModelitem that refers to the root of the assembly.
\*---------------------------------------------------------------*/
    ProMdlToModelitem (comppath.owner, &model_modelitem);
/*---------------------------------------------------------------*\
    Make a ProSelection for the root of the assembly.
\*---------------------------------------------------------------*/
    ProSelectionAlloc (NULL, &model_modelitem, &featsel);
Finally, call ProFeatureCreate().
/*---------------------------------------------------------------*\
    Create the datum plane feature.
\*---------------------------------------------------------------*/
    ProFeatureCreate (featsel, elem_tree, NULL, 0, &feature,
                      &errors);
Feature Inquiry
Functions introduced:
This section describes how to extract the element tree from a feature and analyze it. To find out how to inquire about the feature as a whole and its role in the owning solid, see the section Feature Inquiry.in the chaptersection Core: Features.
The function ProFeatureElemtreeCreate() creates a copy of the feature element tree that describes the contents of a specified feature in the Creo Parametric database. It is applicable only to those feature types that can be created using ProFeatureCreate() (as described in Overview of Feature Creation). The tree can then be analyzed using the read-access functions, such as ProElement*Get(),ProElement*Visit(), and ProElementArrayCount() described in the sections Feature Elements and Feature Element Paths.
Note
The function ProFeatureElemtreeCreate() has been deprecated as it does not provide options to resolve the paths of external references of the feature in case of assemblies. Use ProFeatureElemtreeExtract() instead.
The function ProFeatureElemtreeExtract() creates a copy of the feature element tree of a specified feature. It also provides options to resolve the paths of external references of the feature in case of assemblies.
Use the function ProFeatureElemtreeFree()to free a copy of the feature element tree extracted using ProFeatureElemtreeCreate()ProFeatureElemtreeExtract(). The function ProElementFree() does not free all of the feature-specific runtime data associated with the element tree, and thus can result in a memory leak for certain features.
Instead of copying the entire element tree to analyze it, you can extract information about particular elements directly from the feature. The remaining functions in this section serve that purpose.
The function ProFeatureElemValueGet() provides the value of a single-valued element specified by the ProFeature object and a ProElempath. The function ProFeatureElemValuesGet() provides the values of a multivalued element in a feature.
The function ProFeatureElemDimensionIdGet() gives you the integer identifier of the dimension in the Creo Parametric database used to define the value of the specified single-valued element.
The function ProFeatureElemIsVisible() distinguishes elements added to the tree by Creo Parametric for internal reasons only, and are neither defined as needed for creation of that type of feature, nor otherwise documented.
The function ProFeatureIsIncomplete() identifies features in the Creo Parametric database whose element trees are still incomplete. Such a feature can arise by using the option PRO_FEAT_CR_INCOMPLETE_FEAT when calling ProFeatureCreate(), and does not give rise to geometry until completed. If a feature is incomplete, you can find out which element in its tree is at fault using the function ProFeatureElemIsIncomplete(). Its input is a ProFeature and a ProElempath.
Feature Redefine
Function introduced:
The function ProFeatureRedefine() enables you to redefine a feature. It is applicable only to those feature types that can be created using ProFeatureCreate().
The function ProFeatureRedefine() has arguments for the create options and for the resulting element errors, like those for ProFeatureCreate()
To Redefine a Feature
1. Call ProFeatureElemtreeExtract() to get a copy of the element tree.
2. Analyze and modify the tree using functions ProFeatureElem*(), ProElement*(), and ProElempath*()
3. Call ProFeatureRedefine() to replace the old element tree with the new one.
XML Representation of Feature Element Trees
Creo TOOLKIT offers the capability of representing most feature element trees in the XML format. The XML representation of element trees simplifies the procedure of using Creo TOOLKIT access to Creo Parametric features. The Creo TOOLKIT API’s that access the XML for element trees are capable of converting the XML content to and from an element tree structure (ProElement.)
In Pro/ENGINEER Wildfire 2.0, PTC recommends the use of XML representation for the core Pro/ENGINEER features and for the new sheetmetal wall features. Manufacturing features support is not available in this release.
Introduction to Feature Element Trees in XML
In Creo TOOLKIT, the access to Creo Parametric features is available using a generic data-structure called element tree. You can use the element tree APIs to query, modify, and redefine the Creo Parametric features. To simplify the access to Creo Parametric feature using Creo TOOLKIT, the concept of XML representation of the element trees has been introduced. The XML representation shows the details of the element tree in text format. The XML files are easy to edit and you can recycle them back to create or to redefine features. All the Creo TOOLKIT supported features have support for their respective XML representations.
The function ProElemtreeWrite() writes the XML version of the element tree in a text file and the function ProElemtreeFromXMLCreate() is used to convert the XML version from a text file to the Creo TOOLKIT native element trees.
Functions Introduced:
The function ProElemtreeWrite() writes the feature element tree in XML format to the specified file. This function uses the Creo TOOLKIT native element tree as an input. The type of output required should be specified. Currently only XML format for the output is supported. The only output argument is the name of the output file included with the location and the extension.
The function ProElemtreeFromXMLCreate() reads in the XML file and converts into a corresponding Creo TOOLKIT native element tree. This function takes the name with location of the output XML file as an input and returns the generated element tree as the output.
The created element tree can be used as an input to ProFeatureCreate or ProFeatureRedefine.
In case of error in execution of this function, an error objects is populated and returned. This error object is a ProArray of errors. It contains the information like type of the error, path of the XML file, line number, column number, and the error message. The memory for the error object is allocated by the function is required to be freed in the Creo TOOLKIT application using ProXmlerrorlistProarrayFree(). The function has three levels of error on the basis of the severity warning, general error and fatal error. Upon encountering warning and general errors, the function continues parsing the input XML till the end and collects all the errors in the error object. For a fatal error, the function stops the parsing and returns immediately.
Validation Using XML Schema
XML schemas are used for validation of element tree which is used for feature creation. Element tree in the form of XML representations are validated and passed to ProFeatureCreate() and ProFeatureRedefine().
To use the Schema validation, the following config option must be set
The XML Schema defines the structure and data type for XML. The element name is compared with the element specified in schema for validation. In the case of compound elements, validation is done for name, order and number of the sub-elements. The Schema validates the accuracy of data to be passed as it supports the data type of the element. The Schema also checks whether the element is optional or compulsory.
The location of the Schema is <install_dir>/proe/xmlelem/schema/
ProTKFeature.xsd contains the representation of different feature element.
ProTKObjects.xsd contains the representation of basic and Creo TOOLKIT objects.
The schema validation of element tree takes place if the config option enable_protk_xml_schema is set to "yes" before passing XML file to ProElemtreeFromXMLCreate().
If the validation fails, the corresponding error is populated into the error object which can be printed out and can be used to correct the input XML file. The error object contains the line number, column number and the error message as debug information.
The following is an example of Schema for Solidify Feature:
<xsd:sequence> 
      <xsd:element name="PRO_E_FEATURE_TYPE"
type="StringData"
      minOccurs="1" maxOccurs="1"/> 
      <xsd:element name="PRO_E_FEATURE_FORM" type="StringData" 
        minOccurs="1" maxOccurs="1"/> 
      <xsd:element name="PRO_E_PATCH_QUILT" type="Selection" 
        minOccurs="1" maxOccurs="1"/> 
      <xsd:element name="PRO_E_PATCH_TYPE" type="IntegerData" 
        minOccurs="0" maxOccurs="1"/> 
      <xsd:element name="PRO_E_PATCH_MATERIAL_SIDE" type="IntegerData" 
        minOccurs="0" maxOccurs="1"/> 
      <xsd:element name="PRO_E_STD_FEATURE_NAME" type="StringData" 
        minOccurs="0" maxOccurs="1"/> 
     </xsd:sequence> 
    <!-- End Solidify --> 
Following code demonstrate how to use the error object to print the information
status = ProElemtreeFromXMLCreate ( input_file, &elemtree, &errors ); 
if ( ( status == PRO_TK_GENERAL_ERROR ) || ( status ==   PRO_TK_BAD_CONTEXT )) 
{ 
  printf ("ProElemtreeFromXMLCreate FAILURE ::  %d \n", status ); 
  status = ProArraySizeGet ( errors, &size_errors ); 
  printf("Size of the Error Object is %d \n", size_errors); 
  printf("Content of the Error Object are \n"); 
  for ( error_count = 0; error_count < size_errors; error_count++ ) 
    { 
      printf("Error No  = %d\n", error_count); 
      printf("\t+ Error Type  = %d\n", errors[error_count].error_type   ); 
      if ( status == PRO_TK_GENERAL_ERROR ) 
        { 
          printf("\t+ Error Path  = %s\n", 
       ProWstringToString ( temp_string, errors[error_count].error_source )); 
       printf("\t+ Line  No  = %d\n", errors[error_count].line_number); 
       printf("\t+ Column  No  = %d\n", errors[error_count].column_number); 
        } 
      else if ( status == PRO_TK_BAD_CONTEXT ) 
        { 
       printf("\t+ Element Sr No  = %d\n", 
errors[error_count].line_number); 
       printf("\t+ Element ID     = %d\n", 
errors[error_count].column_number); 
        } 
   ProWstringLengthGet ( errors[error_count].message, 
&string_length ); 
   temp_message_string = (char *) calloc ( 1, (string_length+1) * sizeof (char) ); 
   printf("\t+ Error Message  = %s\n", 
     ProWstringToString ( temp_message_string, 
errors[error_count].message )); 
    free ( temp_message_string ); 
    } 
} 
The list of features supported for XML schema validation are as follows:
Feature Type
Feature Name
PRO_FEAT_DATUM_AXIS
Datum Axis Feature
PRO_FEAT_DATUM
Datum Plane Feature
PRO_FEAT_CSYS
Datum Coordinate System Feature
PRO_FEAT_CURVE
Datum Curve Feature
PRO_FEAT_DATUM_POINT
Datum Point Feature
PRO_FEAT_CHAMFER
Chamfer Feature
PRO_FEAT_ROUND
Round Feature
PRO_FEAT_DRAFT
Draft Feature
PRO_FEAT_HOLE
Hole Feature
PRO_FEAT_WALL
Sheetmetal Flat or Flange Wall Feature
PRO_FEAT_COMPONENT
Assembly Component Feature
PRO_FEAT_DATUM_QUILT
Surface Merge Feature
PRO_FEAT_PATCH
Solidify Feature of the type Patch
PRO_FEAT_GEN_MERGE
General Merge Feature
PRO_FEAT_SRF_MDL
Mirror or Move Feature
PRO_FEAT_PROTRUSION
Solidify Feature of the type Protrusion
PRO_FEAT_SHELL
Shell Feature
PRO_FEAT_FIRST_FEAT
First Feature
PRO_FEAT_CUT
Solidify Feature of the type Cut
PRO_FEAT_SLOT
Slot Feature
PRO_FEAT_GEOM_COPY
Copy Geometry Feature
PRO_FEAT_RIB
Rib Feature
PRO_FEAT_REPLACE_SURF
Replace Surface Feature
XML Representations for Common Elements
The following section gives details about the XML representation of the common elements. The elements can represent a primitive type e.g. an integer or some complex Creo TOOLKIT object e.g. ProReference or ProCollection. The purpose of this representation is to enable externalize these objects in a model specific text format. The examples of the XML representations are also provided for easier understanding.
Single Valued Element
A single valued element contains an element of type Integer, Double, String, or Boolean. Its value will be shown as the XML tags. For example:
<PRO_E_REV_ANGLE_FROM_VAL type="double">0.00</PRO_E_REV_ANGLE_FROM_VAL> 
Empty or Optional Element
An empty element in XML does not have any data value, but just the opening and closing XML tags. Empty elements are ignored by ProElemtreeFromXMLCreate(). Unusedoptional elements in the feature’s element tree appear as empty in the XML output from ProElemtreeWrite().
<PRO_E_REV_ANGLE_FROM_REF type="selection" />
OR
<PRO_E_REV_ANGLE_FROM_REF type="selection"></PRO_E_REV_ANGLE_FROM_REF type>
XML Representation for ProSelection or ProReference
This represents the contents of the ProSelection or ProReference object. If the reference is currently not active or fully available, the reference is included. Consult the function ProReferenceStatusGet() for more information.The reference XML includes details like UV parameters and 3D point for specific elements that require them. The assembly component path will be available for references that include the assembly context.
<PRO_E_DPOINT_PLA_CONSTR_REF type="selection">
<PRO_XML_REFERENCE type="reference">
<PRO_XML_REFERENCE_STATUS type= int>PRO_REF_NOT_FOUND</PRO_XML_REFERENCE_STATUS>
<PRO_XML_REFERENCE_OWNER type="owner">COMP2.prt</PRO_XML_REFERENCE_OWNER> 
<PRO_XML_REFERENCE_ID type="id">46</PRO_XML_REFERENCE_ID> 
<PRO_XML_REFERENCE_TYPE type="protype">PRO_EDGE</PRO_XML_REFERENCE_TYPE> 
<PRO_XML_ASMCOMP_PATH comppath="compound">
<PRO_XML_ASMCOMP_PATH_OWNER type="model">ASM_PNT.asm</PRO_XML_ASMCOMP_PATH_OWNER> 
<PRO_XML_ASMCOMP_PATH_ARRAY type="array">
<PRO_XML_ASMCOMP_PATH_ITEM index="1">40</PRO_XML_ASMCOMP_PATH_ITEM> 
     </PRO_XML_ASMCOMP_PATH_ARRAY>
     </PRO_XML_ASMCOMP_PATH>
<PRO_XML_UV_PARAM uv_parameter="array">
<PRO_XML_DOUBLE_VALUE type="u">0.000000</PRO_XML_DOUBLE_VALUE> 
<PRO_XML_DOUBLE_VALUE type="v">0.000000</PRO_XML_DOUBLE_VALUE> 
</PRO_XML_UV_PARAM>
</PRO_XML_REFERENCE>
</PRO_E_DPOINT_PLA_CONSTR_REF>
XML Representation for ProCollection
This represents the contents of the ProCollection object. Collection type, collection instructions, instruction types, references, reference types are some of the contents. These are classified into surface and curve collections. Surface collection represents a set of surfaces in the model governed by rules like seed and boundary. Curve collection represents a set of edges or curves in the model governed by rules like one-by-one, surface-loop etc. The instruction type for the particular collection identifies the rule.
Curve Collection
<PRO_E_STD_CURVE_COLLECTION_APPL type="collection">
  <PRO_XML_COLLECTION type="curve">
    <PRO_XML_COLLECTION_INSTRUCTIONS type="array">
   <PRO_XML_COLLECTION_INSTRUCTION type="compound">
   <PRO_XML_COLLECTION_INSTRUCTION_TYPE type="int">105</PRO_XML_COLLECTION_
INSTRUCTION_TYPE> <PRO_XML_CRVCOLL_REFS type="array"> <PRO_XML_CRVCOLL_REF type="selection"> <PRO_XML_REFERENCE type="reference"> <PRO_XML_REFERENCE_OWNER type="owner">CRV_COLLECTION_PART.prt
</PRO_XML_REFERENCE_OWNER> <PRO_XML_REFERENCE_ID type="id">703</PRO_XML_REFERENCE_ID> <PRO_XML_REFERENCE_TYPE type="protype">PRO_QUILT</PRO_XML_REFERENCE_TYPE> </PRO_XML_REFERENCE> </PRO_XML_CRVCOLL_REF> <PRO_XML_CRVCOLL_REF type="selection"> <PRO_XML_REFERENCE type="reference"> <PRO_XML_REFERENCE_OWNER type="owner">CRV_COLLECTION_PART.prt
</PRO_XML_REFERENCE_OWNER> <PRO_XML_REFERENCE_ID type="id">679</PRO_XML_REFERENCE_ID> <PRO_XML_REFERENCE_TYPE type="protype">PRO_EDGE</PRO_XML_REFERENCE_TYPE> </PRO_XML_REFERENCE> </PRO_XML_CRVCOLL_REF> </PRO_XML_CRVCOLL_REFS> </PRO_XML_COLLECTION_INSTRUCTION> </PRO_XML_COLLECTION_INSTRUCTIONS> </PRO_XML_COLLECTION> </PRO_E_STD_CURVE_COLLECTION_APPL>
Surface Collection
<PRO_E_STD_SURF_COLLECTION_APPL type="collection">
  <PRO_XML_COLLECTION type="surface">
   <PRO_XML_COLLECTION_INSTRUCTIONS type="array">
   <PRO_XML_COLLECTION_INSTRUCTION type="compound">
      <PRO_XML_COLLECTION_INSTRUCTION_TYPE type="int">2
</PRO_XML_COLLECTION_INSTRUCTION_TYPE> <PRO_XML_SRFCOLL_INCLUDE type="boolean">1</PRO_XML_SRFCOLL_INCLUDE> <PRO_XML_SRFCOLL_REFS type="array"> <PRO_XML_SRFCOLL_REF type="compound"> <PRO_XML_SRFCOLL_REFITEM_TYPE type="int">3</PRO_XML_SRFCOLL_REFITEM_TYPE> <PRO_XML_SRFCOLL_REFITEM type="selection"> <PRO_XML_REFERENCE type="reference"> <PRO_XML_REFERENCE_OWNER type="owner"> SRF_COLLECTION_PART.prt</PRO_XML_REFERENCE_OWNER> <PRO_XML_REFERENCE_ID type="id">17</PRO_XML_REFERENCE_ID> <PRO_XML_REFERENCE_TYPE type="protype">PRO_SURFACE</PRO_XML_REFERENCE_TYPE> </PRO_XML_REFERENCE> </PRO_XML_SRFCOLL_REFITEM> </PRO_XML_SRFCOLL_REF> <PRO_XML_SRFCOLL_REF type="compound"> <PRO_XML_SRFCOLL_REFITEM_TYPE type="int">4</PRO_XML_SRFCOLL_REFITEM_TYPE> <PRO_XML_SRFCOLL_REFITEM type="selection"> <PRO_XML_REFERENCE type="reference"> <PRO_XML_REFERENCE_OWNER type="owner"> SRF_COLLECTION_PART.prt</PRO_XML_REFERENCE_OWNER> <PRO_XML_REFERENCE_ID type="id">26</PRO_XML_REFERENCE_ID> <PRO_XML_REFERENCE_TYPE type="protype">PRO_SURFACE</PRO_XML_REFERENCE_TYPE> </PRO_XML_REFERENCE> </PRO_XML_SRFCOLL_REFITEM> </PRO_XML_SRFCOLL_REF> </PRO_XML_SRFCOLL_REFS> </PRO_XML_COLLECTION_INSTRUCTION> </PRO_XML_COLLECTION_INSTRUCTIONS> </PRO_XML_COLLECTION> </PRO_E_STD_SURF_COLLECTION_APPL>
Pointer Element
Most pointer elements are written with their value appearing as “**”. Elements with this value type are not supported by ProElemtreeFromXMLCreate() (this element is not added to the created element tree.) The most common pointer element of this type is the Creo Parametric sketch element PRO_E_SKETCHER.
<PRO_E_SKETCHER type="pointer">**</PRO_E_SKETCHER>
Compound Element
A compound element represents a collection of different types of sub-elements. Following is an example in XML format.
<PRO_E_REV_ANGLE type="compound">
     <PRO_E_REV_ANGLE_FROM type="compound">
        <PRO_E_REV_ANGLE_FROM_TYPE type="int">262144</PRO_E_REV_ANGLE_FROM_TYPE> 
        <PRO_E_REV_ANGLE_FROM_VAL type="double">0.00</PRO_E_REV_ANGLE_FROM_VAL> 
        <PRO_E_REV_ANGLE_FROM_REF type="selection" /> 
        <PRO_E_REV_ANGLE_FROM_LIMIT type="int">0</PRO_E_REV_ANGLE_FROM_LIMIT> 
        </PRO_E_REV_ANGLE_FROM>
        <PRO_E_REV_ANGLE_TO type="compound">
        <PRO_E_REV_ANGLE_TO_TYPE type="int">4194304</PRO_E_REV_ANGLE_TO_TYPE> 
        <PRO_E_REV_ANGLE_TO_VAL type="double">120.00</PRO_E_REV_ANGLE_TO_VAL> 
        <PRO_E_REV_ANGLE_TO_REF type="selection" /> 
        <PRO_E_REV_ANGLE_TO_LIMIT type="int">0</PRO_E_REV_ANGLE_TO_LIMIT> 
   </PRO_E_REV_ANGLE_TO>
</PRO_E_REV_ANGLE>
Array Element
An array element represents a collection of elements of the same type. Following is an example of an array of PRO_E_RNDCH_RADIUS elements in XML format.
<PRO_E_RNDCH_RADII type="array">
     <PRO_E_RNDCH_RADIUS type="compound">
            <PRO_E_STD_POINT_COLLECTION_APPL type="selection">
                   <PRO_XML_REFERENCE type="reference">
<PRO_XML_REFERENCE_OWNER type="owner">K01_X_COLLECTION_PART.prt
</PRO_XML_REFERENCE_OWNER> <PRO_XML_REFERENCE_ID type="id">1268</PRO_XML_REFERENCE_ID> <PRO_XML_REFERENCE_TYPE type="protype">PRO_CRV_END</PRO_XML_REFERENCE_TYPE> </PRO_XML_REFERENCE> </PRO_E_STD_POINT_COLLECTION_APPL> <PRO_E_RNDCH_LEG1 type="compound"> <PRO_E_RNDCH_LEG_TYPE type="int">1</PRO_E_RNDCH_LEG_TYPE> <PRO_E_RNDCH_LEG_VALUE type="double">36.00</PRO_E_RNDCH_LEG_VALUE> <PRO_E_RNDCH_REFERENCE_EDGE type="selection" /> <PRO_E_RNDCH_REFERENCE_POINT type="selection" /> </PRO_E_RNDCH_LEG1> <PRO_E_RNDCH_LEG2 type="compound"> <PRO_E_RNDCH_LEG_TYPE type="int">0</PRO_E_RNDCH_LEG_TYPE> <PRO_E_RNDCH_LEG_VALUE type="double">0.00</PRO_E_RNDCH_LEG_VALUE> <PRO_E_RNDCH_REFERENCE_EDGE type="selection" /> <PRO_E_RNDCH_REFERENCE_POINT type="selection" /> </PRO_E_RNDCH_LEG2> </PRO_E_RNDCH_RADIUS> <PRO_E_RNDCH_RADIUS type="compound"> <PRO_E_STD_POINT_COLLECTION_APPL type="selection"> <PRO_XML_REFERENCE type="reference"> <PRO_XML_REFERENCE_OWNER type="owner">K01_X_COLLECTION_PART.prt
</PRO_XML_REFERENCE_OWNER> <PRO_XML_REFERENCE_ID type="id">1268</PRO_XML_REFERENCE_ID> <PRO_XML_REFERENCE_TYPE type="protype">PRO_CRV_START</PRO_XML_REFERENCE_TYPE> </PRO_XML_REFERENCE> </PRO_E_STD_POINT_COLLECTION_APPL> <PRO_E_RNDCH_LEG1 type="compound"> <PRO_E_RNDCH_LEG_TYPE type="int">1</PRO_E_RNDCH_LEG_TYPE> <PRO_E_RNDCH_LEG_VALUE type="double">55.39</PRO_E_RNDCH_LEG_VALUE> <PRO_E_RNDCH_REFERENCE_EDGE type="selection" /> <PRO_E_RNDCH_REFERENCE_POINT type="selection" /> </PRO_E_RNDCH_LEG1> <PRO_E_RNDCH_LEG2 type="compound"> <PRO_E_RNDCH_LEG_TYPE type="int">0</PRO_E_RNDCH_LEG_TYPE> <PRO_E_RNDCH_LEG_VALUE type="double">0.00</PRO_E_RNDCH_LEG_VALUE> <PRO_E_RNDCH_REFERENCE_EDGE type="selection" /> <PRO_E_RNDCH_REFERENCE_POINT type="selection" /> </PRO_E_RNDCH_LEG2> </PRO_E_RNDCH_RADIUS> </PRO_E_RNDCH_RADII>
Multivalued Element
The multi-valued element represents an array of same types of elements. The difference between the array and multi-valued elements lies in the Creo TOOLKIT handling of these elements. In the XML format both the representations are similar.
<PRO_E_SHELL_SRF type="multivalue">
     <PRO_E_SHELL_SRF_MULTI type="selection">
            <PRO_XML_REFERENCE type="reference">
<PRO_XML_REFERENCE_OWNER type="owner">X_SHELL_REDEF.prt</PRO_XML_REFERENCE_OWNER> 
<PRO_XML_REFERENCE_ID type="id">76</PRO_XML_REFERENCE_ID> 
<PRO_XML_REFERENCE_TYPE type="protype">PRO_SURFACE</PRO_XML_REFERENCE_TYPE> 
</PRO_XML_REFERENCE>
</PRO_E_SHELL_SRF_MULTI>
<PRO_E_SHELL_SRF_MULTI type="selection">
<PRO_XML_REFERENCE type="reference">
<PRO_XML_REFERENCE_OWNER type="owner">X_SHELL_REDEF.prt</PRO_XML_REFERENCE_OWNER> 
<PRO_XML_REFERENCE_ID type="id">72</PRO_XML_REFERENCE_ID> 
<PRO_XML_REFERENCE_TYPE type="protype">PRO_SURFACE</PRO_XML_REFERENCE_TYPE> 
</PRO_XML_REFERENCE>
</PRO_E_SHELL_SRF_MULTI>
<PRO_E_SHELL_SRF_MULTI type="selection">
<PRO_XML_REFERENCE type="reference">
<PRO_XML_REFERENCE_OWNER type="owner">X_SHELL_REDEF.prt</PRO_XML_REFERENCE_OWNER> 
<PRO_XML_REFERENCE_ID type="id">68</PRO_XML_REFERENCE_ID> 
<PRO_XML_REFERENCE_TYPE type="protype">PRO_SURFACE</PRO_XML_REFERENCE_TYPE> 
</PRO_XML_REFERENCE>
</PRO_E_SHELL_SRF_MULTI>
</PRO_E_SHELL_SRF>
Tips for Recycling XML Output of Element Trees
The easiest way to create an XML file for any feature element tree is to call ProFeatureElemtreeExtract() followed by ProElemtreeWrite(). The pt_userguide application includes this capability. While running this application, select a feature. Click the right mouse button and choose Export XML. The output XML produced can be used and reused with modifications by passing it to ProElemtreeFromXMLCreate() to create an element tree. The resulting element tree can be used for new feature creation or redefinition of an existing feature. The following tips would help easier reuse and understanding failures.
•  Creo Parametric models can have only a single feature with a specific name - before using the XML for creating a new feature, modify the value of the element PRO_E_STD_FEATURE_NAME appropriately. Since, feature name is an optional element, the XML tag for this element can be deleted from the XML file to promote reuse.
•  The function ProElemtreeWrite() writes all of the elements in the input Creo TOOLKIT native element tree. Optional elements with empty data within XML tags from the XML file can be removed before reusing the XML file. It is also permitted to keep the optional elements as they are in the XML, but these elements are ignored by ProElemtreeFromXMLCreate().
•  ProElemtreeFromXMLCreate() converts the XML file to an element tree without validating that the data is appropriate for that feature type (for example, ensuring that the correct type is selected for references.) The error is detected when the element tree is used by ProFeatureCreate() or ProFeatureRedefine().
•  ProElemtreeFromXMLCreate() supports some enumerated symbols or the actual integer values. Use the output XML file as a guide to see which enumerated type names are accepted.
•  The tag names used in the XML representation are derived from the list of ProElemId from ProElemId.h.These names must be used exactly as found in the ProElemId.h file.
•  XML files created by one version of Creo Parametric are not guaranteed to be usable by other Creo Parametric versions, because the structure of the element tree also change between versions.
A Sample Element Tree in XML for a Shell Feature
<?xml version="1.0" encoding="UTF-8"?>
<!--Sample XML File for shell feature -->
<PRO_E_FEATURE_TREE AppName="Creo Parametric" AppVersion="2003440" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xsi:noNamespaceSchemaLocation="ProTKFeature.xsd" type="compound">
  <PRO_E_FEATURE_TYPE type="int">PRO_FEAT_SHELL</PRO_E_FEATURE_TYPE> 
  <PRO_E_STD_FEATURE_NAME type="wstring">SHELL</PRO_E_STD_FEATURE_NAME> 
  <PRO_E_SHELL_SRF type="multivalue">
       <PRO_E_SHELL_SRF_MULTI type="selection">
              <PRO_XML_REFERENCE type="reference">
<PRO_XML_REFERENCE_OWNER type="owner">X_SHELL.prt</PRO_XML_REFERENCE_OWNER> 
<PRO_XML_REFERENCE_ID type="id">76</PRO_XML_REFERENCE_ID> 
<PRO_XML_REFERENCE_TYPE type="protype">PRO_SURFACE</PRO_XML_REFERENCE_TYPE> 
</PRO_XML_REFERENCE>
</PRO_E_SHELL_SRF_MULTI>
</PRO_E_SHELL_SRF>
<PRO_E_SHELL_THICK type="double">4.02</PRO_E_SHELL_THICK> 
<PRO_E_SHELL_FLIP type="int">1</PRO_E_SHELL_FLIP> 
       <PRO_E_ST_SHELL_LOCL_LIST type="array">
              <PRO_E_ST_SHELL_LOCL_CMPD type="compound">
<PRO_E_ST_SHELL_SPEC_SRF type="selection">
<PRO_XML_REFERENCE type="reference">
<PRO_XML_REFERENCE_OWNER type="owner">X_SHELL.prt</PRO_XML_REFERENCE_OWNER> 
<PRO_XML_REFERENCE_ID type="id">53</PRO_XML_REFERENCE_ID> 
<PRO_XML_REFERENCE_TYPE type="protype">PRO_SURFACE</PRO_XML_REFERENCE_TYPE> 
</PRO_XML_REFERENCE>
</PRO_E_ST_SHELL_SPEC_SRF>
<PRO_E_ST_SHELL_SPEC_THCK type="double">10.00</PRO_E_ST_SHELL_SPEC_THCK> 
</PRO_E_ST_SHELL_LOCL_CMPD>
<PRO_E_ST_SHELL_LOCL_CMPD type="compound">
<PRO_E_ST_SHELL_SPEC_SRF type="selection">
<PRO_XML_REFERENCE type="reference">
<PRO_XML_REFERENCE_OWNER type="owner">X_SHELL.prt</PRO_XML_REFERENCE_OWNER> 
<PRO_XML_REFERENCE_ID type="id">66</PRO_XML_REFERENCE_ID> 
<PRO_XML_REFERENCE_TYPE type="protype">PRO_SURFACE</PRO_XML_REFERENCE_TYPE> 
</PRO_XML_REFERENCE>
</PRO_E_ST_SHELL_SPEC_SRF>
<PRO_E_ST_SHELL_SPEC_THCK type="double">9.00</PRO_E_ST_SHELL_SPEC_THCK> 
</PRO_E_ST_SHELL_LOCL_CMPD>
<PRO_E_ST_SHELL_LOCL_CMPD type="compound">
<PRO_E_ST_SHELL_SPEC_SRF type="selection">
<PRO_XML_REFERENCE type="reference">
<PRO_XML_REFERENCE_OWNER type="owner">X_SHELL.prt</PRO_XML_REFERENCE_OWNER> 
<PRO_XML_REFERENCE_ID type="id">74</PRO_XML_REFERENCE_ID> 
<PRO_XML_REFERENCE_TYPE type="protype">PRO_SURFACE</PRO_XML_REFERENCE_TYPE> 
</PRO_XML_REFERENCE>
</PRO_E_ST_SHELL_SPEC_SRF>
<PRO_E_ST_SHELL_SPEC_THCK type="double">15.00</PRO_E_ST_SHELL_SPEC_THCK> 
</PRO_E_ST_SHELL_LOCL_CMPD>
</PRO_E_ST_SHELL_LOCL_LIST>
</PRO_E_FEATURE_TREE>
The following example shows how to use ProElemtreeWrite() to export a feature element tree to XML.
#include <ProToolkit.h>
#include <ProMenuBar.h>
#include <ProMdl.h>
#include <ProSelection.h>
#include <ProFeature.h>
#include <ProWstring.h>
static 
wchar_t MSGFIL[] = {'u','t','i','l','i','t','i','e','s','.','t','x','t','\0'};
/*=====================================================================*\
FUNCTION: UserFeatXMLWrite
PURPOSE:  Write a feature's element tree to an XML file.
\*=====================================================================*/
int UserFeatXMLWrite (ProFeature* feat)
{
  ProElement elemtree;
  wchar_t wFilename [PRO_FILE_NAME_SIZE];
/*--------------------------------------------------------------------*\
Prompt for the filename
\*--------------------------------------------------------------------*/
  ProMessageDisplay ( MSGFIL, "USER Enter the XML file name:");
  if (ProMessageStringRead (PRO_FILE_NAME_SIZE, wFilename) 
      != PRO_TK_NO_ERROR)
    return (0);
/*--------------------------------------------------------------------*\
Extract the element tree and convert it to XML
\*--------------------------------------------------------------------*/
  status = ProFeatureElemtreeExtract (feat,NULL,PRO_FEAT_EXTRACT_NO_OPTS,
                                      &elemtree);
  if ( status == PRO_TK_NO_ERROR )
  {
    status = ProElemtreeWrite (elemtree, PRO_ELEMTREE_XML, wFilename);
    ProElementFree (&elemtree);
  }
  return status;
}