home - about - advertise     
 
 
Sponsors
Navigation
Partners

 
Pro/ENGINEERTutorial

Pro/TOOLKIT: The First Steps Are the Hardest

By Vojin Jovanović, July 2, 2003

An Application Programmers Interface (API), Pro/TOOLKIT allows Pro/ENGINEER functionality to be augmented and/or customized to meet the specific needs of PTC's customer base using the "C" programming language. Specifically, Pro/TOOLKIT provides the ability to customize the standard Pro/ENGINEER user interface, automate processes involving repetitive steps, integrate proprietary or other external applications with Pro/ENGINEER and develop customized end-user application for model creation, design rule verification and drawing automation.

Unfortunately, Pro/TOOLKIT deservingly gained a reputation of being hard to work with. This state of the affairs is the result of PTC's current vision, which dictates where and how this product ought to augment the functionality of Pro/ENGINEER. This vision, as the series of the articles to follow will show, is by no means offers the ideal toolkit users would hope for; rather, it leaves quite a few features to be desired. In these articles we will explore what it takes to work with Pro/TOOLKIT and how to go beyond what PTC supports today.

Note: If you haven't yet, please read (or read again) my article, Pro/TOOLKIT: Setting Up Your Environment in VC++ .NET, which will prepare you for what follows.

Getting Started

If you know how to write C programs you are already on your way to success with Pro/TOOLKIT. Although you don’t need to possess any C++ knowledge, it might be useful. Pro/TOOLKIT was written in C a long time ago and its sheer size and internal complexity, in my opinion, is the main reason why PTC did not make it an objects-oriented tool. This situation seems likely to persist given PTC's silence on the issue.

You don’t need to be an expert in C either, although you should understand the "pointers" business. You’ll use them often as you transfer your data from one function to another.

The main tool you’ll use is the API browser, which contains over 2000 functions and is cross-referenced with example code and user guide. So make sure that you install it properly with the required Java plug-in. It may take some time to set everything up, but don’t get discouraged.

In addition, if you're going to work with geometry (which happens to be my area of expertise), you’ll need a decent understanding of vectors and be able to imagine how things are oriented.

Finally, once you get going it will probably take about one month of work (at 40 hours per week) to get comfortable with Pro/TOOLKIT. To speed things up you may want to consider attending one of the 5-day Pro/TOOLKIT classes given by PTC.

Overall Organization

Since all of Pro/TOOLKIT is written in C, each object is represented with a structure. Which object needs to be used, and how you derive them from various structures, is an art in itself. (This is due to the mixing of some objects before Pro/TOOLKIT’s time, which were used in Pro/DEVELOP - Pro/TOOLKIT’s predecessor).

In order to work with structures you need to have the means to access them. Pro/TOOLKIT provides a number of “typedefs”; you will eventually develop a sense how to use them. The typedefs are nothing but disguised pointers to internal Pro/E structures. For example:

typedef struct entity* ProPoint;
typedef struct sld_part* ProSolid;

These are also called OHandles (from Opaque handles) and they directly access the memory locations of objects in Pro/E. Since that can be dangerous in some cases, PTC provides another type of structure that contains only minimal information about items stored in Pro/E’s internal database. The structure (labeled DHandle from data handle) is of a generic type and contains the type of the object, its ID and its owner. A lot of designed words are associated with this structure as you can see below:

typedef struct pro_model_item
{
ProType type;
int id;
ProMdl owner;
} ProModelitem, ProGeomitem, ProExtobj, ProFeature, ProProcstep,
ProSimprep, ProExpldstate, ProLayer, ProDimension, ProDtlnote,
ProDtlsyminst, ProGtol, ProCompdisp, ProDwgtable;

If you are planning to work on geometry problems, you’ll mostly use ProModelitem, ProGeomitem and ProFeature. ProModelitem is the most generic type of object and it can represent objects other than geometry items.

ProType in DHandle structure is enumerated typedef with a large number of keywords. Once you receive an object from a function or search for it in some contour, for example, you’ll often have a need to check what type it is.

The first thing you will notice when looking at the browser is that Pro/TOOLKIT function names are chosen based on what objects they usually work with. For example, any function that starts with ProSolid has the input argument ProSolid.

A very important class of functions that you’ll have to learn how to work with is the visiting functions. These functions contain the word “Visit” in their name. The functions provide a way to search through complex Pro/E internal structures. They always take as an input argument a pointer to your own user-defined action function, which does some work at each structure found.

The above may seem overwhelming at first but as you go along I promise that things will fall into place. Don’t worry if you're a little unsure about what I've said so far. The best way to counteract the confusion is to try to make some concrete functions in Pro/TOOLKIT, which are provided below.

The first steps

One of the first functions that you need to know about is ProMdlCurrentGet(). The beginning of its description in API Browser is shown below.

Description
Initializes the p_handle with the current Pro/ENGINEER object.
Synopsis
#include <ProMdl.h>
ProError ProMdlCurrentGet (
ProMdl *p_handle
/* (Out)
The model handle
*/
)

The function takes one argument, a pointer to ProMdl typedef and you use it like this:

ProMdl mdlhandle;
ProMdlCurrentGet(&mdlhandle);

mdlhandle is OHandle and in this case it is OK to use it because this handle will persist as long as your part (or whatever it is) remains in the session. Now, what can you do with this object? A lot of things. For example, you can make a call with ProMdlDataGet() and get some initial information about this model.

ProMdldata mdldata;
ProMdlDataGet (mdlhandle, &mdldata);

mdldata is a simple structure that contains name, type, path and other info about the model. Let’s print the type of the model.

The most members of the structure are declared as wide characters so you cannot just go ahead and do printf(“%s\n”,mdldata.type);. You have to translate the type to a regular character array with ProWstringToString() as shown below:

char type_in_c[PRO_TYPE_SIZE]; /* uses predefined Pro/T constants like PRO_TYPE_SIZE */
ProWstringToString (type_in_c, mdldata.type);
printf(“%s\n”,type_in_c);

Note how the names of Pro/TOOLKIT functions are chosen by PTC. Also note in this case that input and output to the function may not be what you would expect. The first argument is the output, while the second is the input.

Now let’s print the name of the model. You could do the same as above and extract the name from mdldata structure; instead try a different, more convenient method:

ProName current_name;
char current_name_in_c[PRO_NAME_SIZE];
ProMdlNameGet(mdlhandle, current_name);
ProWstringToString(current_name_in_c,current_name);
printf(“%s\n”, current_name_in_c);

How about printing the features that are contained in the model? First, you need to initialize a model item handle and supply it to ProModelitemInit(). You will need to do this often. In fact, what all of the functions that contain Init in their name do is initialize handles. Please note that in some situations, since you know that most of the handles are structures, you may want to circumvent the process and fill up those handles yourself; for example: mdlhandle.name = “a name”. But avoid this, because doing somay lead to unpredictable behavior and you’ll wind up spending a lot of time chasing errors. Therefore, always use Init functions for this kind of job.

Here is how to do it properly:

ProName current_name;
char current_name_in_c[PRO_NAME_SIZE];
ProError err;
ProModelitem mdlitem;
long mdlhandle;
int id;
id = 38: /* change this number to be a number for a feature in your feature tree, ideally you should ask the user to enter a number, but we are not ready to do that here yet*/
ProModelitemInit(mdlhandle,id,PRO_FEATURE,&mdlitem);
err=ProModelitemNameGet(&mdlitem,current_name);
if(err == PRO_TK_E_NOT_FOUND) /* in some cases the feature may be odd so we’ll check for that*/
ProFeatureTypenameGet(&mdlitem,current_name);

ProWstringToString(current_name_in_c,current_name);
printf(“%s\n”, current_name_in_c);

Note that in Init function you specify PRO_FEATURE, which indicates what type of object you want to initialize.

Visiting Functions

Next, let's look at visiting functions, an important topic related to collecting items from a model.

As you can imagine, the model may consist of a large number of objects that can contain many sub-objects. Since you don’t know a priori the number of those, you need to be able to somehow collect the objects you are looking for. For that type of need PTC provides visiting functions.

In previous versions of Pro/TOOLKIT (called Pro/DEVELOP), PTC provided different functionality where you could, with one function call, obtain a list of needed objects. But with the coming of Pro/TOOLKIT a shift was made toward visiting objects, and previous Pro/DEVELOP functionality was dropped. Visitation process obviously has its advantages, as you’ll see, and while visiting it is possible to do all kinds of actions to visited objects. In my opinion, however, this was better accomplished the way Pro/DEVELOP managed it.

The visitation process consists of 2 components. One is the PTC’s visitation action call itself and the other is the supplied user’s function that should work on every object visited. Let's look at a simple example.

Suppose that you want to visit all of the features contained in a model and collect their ids. The function to do this (which you will use often) is ProSolidFeatVisit(). The function takes 4 arguments: ProSolid handle, a vesting function pointer, a filtering function pointer and a pointer to an arbitrary structure. The purpose of the filtering function is to be able to filter access to particular objects, but I find that cumbersome and do filtering on my own within the visiting function itself. The final input argument, the pointer to an arbitrary structure, provides a way to store the collected data and use it at the top level before the visitation call is made.

If the above confuses you don’t worry. It's not difficult as it may sound.

Let's look at an example where everything will fall into place. Note that I like to use STL for its convenience and I suggest that, if you still have not done it, you get familiar with STL’s objects. It will save you a lot of time.

// action function, note the layout it is always the same
static ProError user_action_get_feat_ids(
ProFeature *feature,
ProError status,
ProAppData appdata)
{
ProBoolean visible;
vector<int> *fids = (vector<int> *)appdata;

ProFeatureVisibilityGet(feature,&visible); /* we’ll only work with visible features */
if(visible == PRO_B_TRUE){ // and collect their ids
fids->push_back(feature->id);
}
return(PRO_TK_NO_ERROR); /* always return this constant unless you want to stop visiting for some reason */
}

vector<int> feat_ids; // STL vector object, a very useful one

// the main Pro/TOOLKIT call
ProSolidFeatVisit((ProSolid) mdlhandle,(ProFeatureVisitAction)user_action_get_feat_ids,NULL,(ProAppData) &feat_ids); /* you’ll need to cast the pointers if you don’t want the warnings */

Note the use of mdlhandle that I used before and note that ProMdl and ProSolid can be interchanged in function calls. You can use ProMdl object where ProSolid is needed. Also note that I put NULL for the filtering function since I don’t want to use it.

Now you obtained a list of ids in feat_ids and you can do with them anything you want. For example print them out.

for(unsigned int i=0; i<feat_ids.size(); i++){
cout<<feat_ids[i]<<endl;
}

I’ll stop here to let you absorb things so far. Pro/TOOLKIT may seem a bit overwhelming at first, but in time you'll get the knack of it.

Conclusion

Above I have presented the most fundamental and most-used concepts that you’ll need to learn. I suggest that you study those examples and experiment with their variations. Consult the large number of example functions that come with the installation, which are cross-referenced in the Pro/TOOLKIT API browser.

And stay tuned - soon we’ll try to make some more steps with Pro/TOOLKIT!

About the Author

Vojin Jovanović is an independent consultant with 5 years of experience developing Pro/TOOLKIT applications in the area of design optimization and automation as well as over 10 years of experience in developing scientific numerical applications. He has published in international journals and presented at various conferences. His area of expertise is in computational geometry related to MCAD and in development of financial applications. You can reach him at fractal97@hotmail.com and visit his website at: <http://www.purplerose.biz/Vin>.

Related Articles

 
CADdigest Weekly
Email (required) *

A week's worth of articles will be emailed to you. See latest issue .