-------------------------------------------------------------------------
The following is sample API code for a command named "~ApiExample" that
traverses the faces of the active part or assembly.  The code will be
used to create a dynamically linked library named "ApiExample.dll" 
that is loaded by ZW3D at runtime.
-------------------------------------------------------------------------

To build ApiExample.dll, you will need to put the code that follows
these comments into a file named "ApiExample.c".

You will also need to create a file in the same folder as ApiExample.c
named ApiExample.def and containing the following information:

      LIBRARY ApiExample.dll
      EXPORTS
      ApiExampleInit
      ApiExampleExit
      ApiExample

Compile ApiExample.c as follows:

   cl.exe /nologo /c /D WIN32 /MT /LD /Z7 ApiExample.c

Link ApiExample.dll as follows:

   link /DEF:ApiExample.def /DLL /OUT:ApiExample.dll *.obj zw3dmain.lib

Place ApiExample.dll in the "apilibs" sub-folder of your ZW3D user folder.

   C:\Documents and Settings\All Users\ZWSOFT\ZW3D 2010\apilibs"

Run ApiExample() by entering "~ApiExample" in the ZW3D command 
input area (without the quotemarks), or assign the command string 
"~ApiExample" to a button/icon on a custom menu defined in a ZW3D
GUI template file named "ApiExample.t".

Put the following information in ApiExample.t:

   # target=2
   ######################################################################
   MENU=ApiExample
   class=user
   lock

   ITEM=button
   label=Traverse
   command=~ApiExample
   hint=Traverse active part/assembly

Place ApiExample.t in the "supp" sub-folder of your ZW3D user folder.
The menu defined in it will show up in the "User" pulldown menu of
the GUI when a part/assembly is active.  Note that the name of the
file and the name of the menu must be the same (excluding the .t
extension).

-------------------------------------------------------------------------
Sample code starts below:
-------------------------------------------------------------------------

#include "stdio.h"

/* API header file */
#include "VxApi.h"

/* declare your custom function */
void ApiExample(void);

/* declare local functions */
static int TraversePart();

/* 
** Initialization function automatically called when ApiExample.dll
** is dynamically loaded during ZW3D startup.  Put ApiExample.dll in
** the "apilibs" subfolder of your ZW3D user folder.
*/
int ApiExampleInit(int format, void *data)
   {
   /* 
   ** Register your function with ZW3D.  It can be invoked by 
   ** entering ~ApiExample in the ZW3D command input area, or
   ** it can be assigned to an icon on your custom toolbar.
   */
   cvxCmdFunc("ApiExample",(void*)ApiExample,VX_CODE_GENERAL);

   return(0);
   }

/*
** Termination function automatically called when ZW3D shuts down.
*/
int ApiExampleExit(void)
   {
   /* put your cleanup code here */

   return(0);
   }

/*
** The following example function traverses the faces of the
** active part and/or assembly, retrieving the NURBS definition
** and rendering attributes of each face.  It also retrieves
** the light sources of the active part/assembly.
*/
void ApiExample(void)
   {
   vxName ActiveObject={""};
   int ObjectId=0;
   evxRootType ObjectType=0;
   int Err=0;
   int i=0, numLights=0;
   svxLight *Lights=NULL;
   char Text[256]={""};

   /* make sure a part/assembly is active */
   cvxRootInqActive(ActiveObject);
   if (ActiveObject[0]==0) {Err=1; goto F_END;}
   cvxRootId(ActiveObject, &ObjectId, &ObjectType);
   if (ObjectType != VX_ROOT_PART) {Err=1; goto F_END;}

   /* open ZW3D message window */
   cvxMsgAreaOpen();

   /* retrieve light source information */
   if (cvxDispGetLights(&numLights, &Lights)) {Err=2; goto F_END;}

   /* display light source names in ZW3D message window */
   cvxMsgDisp("---------------------------");
   for (i=0; i { numLights; i++)
      {
      sprintf(Text,"Light Source %s",Lights[i].name);
      cvxMsgDisp(Text);
      }
   cvxMsgDisp("---------------------------");

   /* recursively traverse shapes and components of the active part/assembly */
   if (TraversePart()) {Err=3; goto F_END;}

   /* free light source information */
   cvxMemFree((void**)&Lights);


   F_END:;
   switch (Err)
      {
      case 1: cvxMsgDisp("A part/assembly is not active"); break;
      case 2: cvxMsgDisp("Unable to retrieve light sources"); break;
      case 3: cvxMsgDisp("Unable to traverse active part/assembly"); break;
      }

   return;
   }

/* 
** Recursively traverse shapes and components of the active part/assembly,
** displaying information about each shape, face and component.  The code 
** has comments that show where you would retrieve geometry and rendering 
** attributes for each face.
**
** The function returns 1 if an error is encountered; 0 if successful.
*/
static int TraversePart(void)
   {
   int Err=0;
   int i=0, numShapes=0, *Shapes=NULL;
   int j=0, numFaces=0, *Faces=NULL;
   int k=0, numComps=0, *Comps=NULL;
   char Text[256]={""};
   vxName File, Part;

   /* disable display updates triggered by assembly traversal */
   cvxDispSwitch(VX_DISP_ALL, 0);

   /* get id's of shapes in the active part */
   if (Err=cvxPartInqShapes(NULL,NULL,&numShapes,&Shapes)) goto F_END;

   /* traverse shapes */
   for (i=0; i { numShapes; i++)
      {
      /* display shape id */
      sprintf(Text,"Shape %d",Shapes[i]);
      cvxMsgDisp(Text);

      /* get shape face id's */
      if (Err=cvxPartInqShapeFaces(Shapes[i],&numFaces,&Faces)) goto F_END;

      /* traverse faces */
      for (j=0; j { numFaces; j++)
         {
         /* display face id */
         sprintf(Text,"Face %d",Faces[j]);
         cvxMsgDisp(Text);

         /*
         ** Use cvxPartInqFaceSrf() to get the face's NURBS representation.
         **
         ** Use cvxPartInqFaceLoops(), cvxPartInqLoopEdges() and 
         ** cvxPartInqEdgeCrv() to get the face's trim curves.
         **
         ** Alternatively, use cvxPartInqFaceFacets() to get a list of
         ** triangular facets approximating the surface.  This function
         ** is new in version 14.40.
         **
         ** Use cvxPartInqFaceAt(), cvxPartInqFaceSh() and cvxPartInqFaceTx()
         ** to get rendering attributes for the face.
         */
         }

      /* free list of face id's */
      cvxMemFree((void**)&Faces);
      }

   /* free list of shape id's */
   cvxMemFree((void**)&Shapes);

   /* get id's of components in the active part */
   if (Err=cvxPartInqComps(NULL,NULL,&numComps,&Comps)) goto F_END;

   /* traverse components */
   for (k=0; k { numComps; k++)
      {
      /* display component id and the name of the part it instances */
      if (Err=cvxCompInqPart(Comps[k], File, Part)) goto F_END;
      sprintf(Text,"Component %d instances %s in %s",Comps[k],Part,File);
      cvxMsgDisp(Text);

      /* activate the part instanced by the component */
      if (Err=cvxCompEditPart(Comps[k])) goto F_END;

      /* traverse the component part */
      if (Err=TraversePart()) goto F_END;

      /* exit the part instanced by the component */
      cvxPartExit();
      }

   F_END:;
   /* re-enable display update */
   cvxDispSwitch(VX_DISP_ALL, 1);

   /* free lists (lists that are already free'd are ignored) */
   cvxMemFree((void**)&Shapes);
   cvxMemFree((void**)&Faces);
   cvxMemFree((void**)&Comps);
   return(Err);
   }