The AutoCAD Professional's API Toolkit -- PT-DISK
(c) 1993 New Riders Publishing
Version 12.00 for Release 12 PC-DOS/MS-DOS
Developed by Kurt Hampe and Jim Boyce

Permission to use, copy, modify, and distribute this software for any purpose is hereby granted, provided that no fees are collected directly or indirectly and that the above copyright notice and this permission notice appear in all copies and in all supporting documentation.

ADS Standards and Xdata

This document contains information regarding standards for ADS applications, potential ADS stumbling blocks, and proposed standards for Xdata. The information, suggestions, and source code provided in this document are all courtesy of Ketiv Technologies, Inc.

Ketiv Technologies, located in Portland, Oregon, desings and distributes application software for use with AutoCAD. Its products include ARCHT™, a full-featured architectural enhancement; Advanced Rendering Extension™ ARE-24 for high-quality renderings inside AutoCAD; and the KETIV Editor for text manipulation. All of the KETIV products mentioned were written by using ADS tools from Autodesk, Inc.

Ketiv Technologies is a large-scale AutoCAD developer with many years of experience in ADS development. Ketiv has established a set of standards to produce well-behaved ADS applications, and has established a convention for using Xdata that provides for extremely flexible and easy use of Xdata. These standards, warnings and conventions are provided here along with the source code used to follow the Xdata standards.

General ADS Standards

An ADS application should not have the right to modify the drawing database in any manner when loaded. If you register your application name, turn on handles, or initialize any entity info structures, you have modified the database, thus preventing the use of DXFIN or PURGE. Modifying the database is useless anyway, because if the user does an UNDO, all changes are undone. Instead, the application should have an entry function. Flags are passed to this function, which ensure that the appropriate settings and conditions are met before proceeding with the application's modifications. If a function uses Xdata and entity handles, for instance, the entry function would look like the following:

kti_entry(E_XDATA+E_HANDLES);

This function, which is called at the beginning of the application, turns on handles and registers applications on a demand-only basis. The function cannot be tripped up by an UNDO.

Potential Traps and Errors

The information provided in this section lists some of the traps and errors Ketiv has found in application development.

ADS_ENTMAKE, ADS-DRAGGEN, ADS_XFORMSS, and Proteus

These three functions (along with the Proteus interface) enable developers to write powerful applications. The only problem is that they do not work unless you stay in the WCS or attempt to duplicate AutoCAD's internal processing. Ketiv has taken the latter approach. The next few sections describe a few of the problems Ketiv has encountered when using these functions.

ADS_ENTMAKE

ADS - ENTMAKE expects the RESBUF chain to contain the exact values that AutoCAD would have produced to make that entity. All points have to be expressed in the Entity Coordinate System (ECS). Rotation angles expressed in the current UCS turn out to be completely different when put into the database by ADS-ENTMAKE. When making complex entities, such as polylines, you must be extremely accurate with the information that you specify, or you can get numerous errors from the AUDIT command. The SEQEND entity of a polyline, for example, has to have the same color, elevation, and so on, as the original POLYLINE header entity. ADS_ENTMAKE makes the entity just fine, but AUDIT produces an error on the polyline.

ADS_DRAGGEN and ADS_XFORMS

ADS_DRAGGEN and ADS_XFORMSS both use transformation matrices. Autodesk provides some examples of how to use these functions in the WCS. If you switch to a UCS other than the WCS, however, the examples do not work. If you want to use a transformation matrix in a different UCS, you need a clear understanding of matrix math. Even for developers with a good computer science background, using transformation matrices in a non-WCS UCS is not the easiest of tasks. It involves figuring out how Autodesk uses the transformation matrix and re-creating the AutoCAD UCS algorithms.

To write a well-behaved ADS application without attempting to duplicate AutoCAD's internal processing, you should use the ADS_COMMAND functions and let AutoCAD do the work for you.

Proteus

One of the subtle problems with edit boxes in Proteus is that it is easy to accidentally truncate the precision of floating-point numbers. If LUPREC is set to 4, for instance, DDMODIFY only lists the values to four decimal places. If you press Enter in an edit box just to move to the next box, the edit box truncates the precision to what is actually shown because of the LUPREC setting.

To prevent this problem from affecting your application, you should keep the backing float value to full precision, and when you press Enter in the edit box, format the backing value according to LUPREC. Then you can do a string comparison and call ADS_ DISTOF to set it to a new value, if the string in the dialog did not match the string that you just formatted.

Using Xdata

This section looks at using and accessing Xdata. Ketiv proposes an Xdata scheme as an initial standard for other developers to use. Ideally, all developers would use the same agreed-upon method and basic library routines to handle Xdata so that sharing Xdata among applications is simple and reliable.

The Ketiv method of handling Xdata is a 'tag-based' system, which is basically an extension of DXF codes. Each chunk of Xdata must have an associated tag that identifies it, just as DXF code 10 identifies the center point of a circle. Unlike DXF codes, more than one piece of Xdata can be associated with a tag, but it must then be in a pair of enclosing {} braces. This syntax, of course, is similar to AutoLISP, in which everything is an atom or a list. Ketiv tags are a short integer (not 'long" because AutoLISP programs would not be able to deal with the tags) and can easily be set and retrieved by a small number of list-handling routines.

The following Xdata chain example is tag-based:

/* arbitrary tags dreamed up by the specific developer */
#define XDT_MATERIAL     12001
#define XDT_WALL_PIECES	 13200
#define XDT_WALL_STYLE   13201

xdata = ads_buildlist( -3,
  1001, Appname,
  1070, XDT_MATERIAL,
  1000, "BRICK",
  1070, XDT_WALL_STYLE,
  1000, "FOUNDATION",
  1070, XDT_WALL_PIECES,
  1002, "{",
  1005, handlel,
  1005, handle2,
  1005, handle3,
  1002, "}",
  0
);

Then, a call to retrieve one of the tags looks like:

strcpy(style, Default_style);
/* overwrite the default if this tag is found
if ((rb = get_xdata_tag_item(xdata, XDT_WALL_STYLE, NULL)) != NULL)
{
  if (rb->rbnext)
  {
    rb = rb->rbnext; /* move past reference to the tag */
    /* make sure value is there and is actually RTSTR */
    if (!xdata_extract_str(&rb, style))
    {
      ads_printf("\nERROR: Xdata not in correct format!");
    }
  }
}

This tag-based system has several benefits, because it works much like DXF codes. Some of the benefits are as follows:

Developers who use this tag-based system are not very restricted, because they can format the Xdata in any manner as long as it has an associated tag, and as long as it is in enclosing braces if it exceeds a single item. If you have to save the values from a dialog box that were used to create an object so that you can later use those values to edit the object in a dialog box, for example, you can save all the values as the tagged item in a list.

The following code segment shows how to do this:

/* see source code that follows for details of these functions */
tag_xdata = ads-buildlist(
	1002, "f",
	1000, stylename_str,
	1040, width,
	1040, height,
	1010, start_pt,
	1002, "}",
0);

set-xdata-tag_item(&xdata, XDT_DIALOG_VALS, tag_xdata, Appname);
These values can be retrieved later with the following call:
/* retrieve values for dialog that created this object
if ((rb = get_xdata_tag_item(xdata, XDT_DIALOG_VALS, NULL)) != NULL)
{
  /* skip past tag and opening brace */
  if (rb->rbnext && rb->rbnext->rbnext)
  {
    rb = rb->rbnext->rbnext;
    if (!xdata_extract_str(&rb, stylename_str)) ||
       (!xdata_extract_real(&rb, &width)) ||
       (!xdata_extract_real(&rb, &height)))
    {
      ads_printf("\nERROR: Xdata in wrong format!");
    }
  }
}

Much of the work of using Xdata is tedious error-checking to make sure that pointers always actually point to something and that the data they point to are actually the expected data type. A few simple but powerful functions enable you to create complex relationships between objects in the drawing. By providing the source code for these routines, Ketiv encourages other developers to modify the code slightly to adapt to its return values, error messages, and so on.

Application Names and Registration

Ketiv has adopted the convention of using application names for Xdata registration, composed of its company initials/ name and the particular product. Its name for its Architectural package, for example, is _KTI_ARCHT . If it were Softdesk, it might be _SFTDSK_AARCH. The leading underscore prevents the name from becoming unobtrusive to the end user.

Most serious ADS applications need a control layer, as do AME and AV Render. Any control layers should remain frozen, and the user should not have any contact with them. The leading underscore character pushes those layers to the bottom of an alphabetical listing so that they are not in the user's way when doing things like DDLMODES. The same is true of application-defined blocks or other symbol table names. If they are under application control, the user should not always have to parse them out of their regular listings.

The AutoCAD Development System Programmer's Reference suggests using a long application name. This length, however, causes problems with Xrefs, because they append the Xref name to layer names with the '|'. Thus, layer names soon become so long that they get truncated, and are no longer reliable names for your application.

The other reason for a relatively short Appid is that Ketiv prefaces never conflict with commands from other developers. Ketiv then uses these semicryptic names in the code for the menus, but provides an "alias" file that can be incorporated into the user's ACAD.PGP file if they are to be entered at the AutoCAD command: prompt. Unfortunately, a leading underscore is not available for command names because Release 12 reserves those for international commands.

Summary

Autodesk has provided some wonderful tools to write very nice third-party applications. Some standards are needed, however, for the way information is to be shared by AutoCAD and numerous applications working on the same drawing file. In addition, there should be some informal standards about what makes a wellbehaved ADS application.

The potential exists for "reckless" programming with ADS that can cause the end user some serious harm (by crashing the machine or exhibiting generally strange behavior in a different UCS). Such programming might cast doubt on the validity of ADS as a whole. Ketiv hopes that Autodesk or the developer community can establish some of these standards for well-behaved ADS applications.

Xdata Functions Source Code Listing

The purpose of including this source code is to show how almost any Xdata situation can be handled with a small number of functions when using the "tagged" Xdata scheme. Two sample functions at the end show its use.

Ketiv has implemented some pretty complex relationships between objects in the drawing with just these routines. This source was taken directly from their libraries; obviously, other developers would have to modify it slightly to call their error routines and return their result codes.

Ketiv would like to make this Xdata scheme a standard for ADS development. Ketiv is sharing this source code to entice people to use the Ketiv standard rather than developing their own. If everyone were using these routines, all that would be required is to make the Xdata tag numbers available to other developers, and then everyone can share information in the drawing.

This software is provided AS IS without warranty of any kind, either express or implied, including but not limited to the implied warranties of merchantability and fitness for a particular purpose. Neither the publisher nor its dealers or distributors assumes any liability for any alleged or actual damages arising from the use of this program. (Some states do not allow the exclusion of implied warranties, so the exclusion may not apply to you.)

View the Source Code XDATAC.C