home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 1997 February / PCWK0297.iso / autodesk / acltwin / dxfix.doc < prev    next >
Text File  |  1996-05-30  |  73KB  |  1,516 lines

  1.  
  2.                               D X F I X
  3.                               =========
  4.  
  5.   An open, programmable application permits translation of ASCII or
  6.   binary DXF files to input compatible with any release of AutoCAD.
  7.  
  8.                             by John Walker
  9.             Revision 2 by Duff Kurland -- February 18, 1991
  10.             R13->R12 conversion additions by Gary Scott -- March 9, 1995
  11.  
  12.  
  13.                Of one power  even God is deprived,  and
  14.                that is the power of making what is past
  15.                never to have been.
  16.                                  -- Aristotle, 340 B.C.
  17.  
  18.  
  19. Ever  since  the  first incremental update to AutoCAD(R), the issue of
  20. downward compatibility has been raised by users.  Unlike many software
  21. products, AutoCAD has always taken great pains to maintain 100% upward
  22. compatibility from  release  to  release--any  drawing  made  with  an
  23. earlier  release of AutoCAD can be edited with any subsequent release.
  24. The converse, however, is not the case.  Once a drawing is edited with
  25. a given release of AutoCAD it cannot be loaded by a prior release.  In
  26. fact, prior to Release 10, DXF(tm) files written by a later version of
  27. AutoCAD could not be loaded into an  earlier  version  without  manual
  28. modification.
  29.  
  30. In Release 10, we introduced code in DXFIN to ignore header variables,
  31. symbol tables, and entity fields not defined by the version of AutoCAD
  32. loading  the  DXF  file.   While  this  fixes  many  of  the  problems
  33. encountered  in  loading  DXF  written  by a later release of AutoCAD,
  34. experience has proven it inadequate; Release 10 still cannot read  DXF
  35. written by Release 11 without manual editing of the file.
  36.  
  37. This  shouldn't  be  surprising.   Solving  the  problem  of  downward
  38. compatibility in  a  general  way  is  extremely  difficult  since  it
  39. requires the developer, in essence, to anticipate the future direction
  40. of product  development.   Further,  the  need  to  maintain  downward
  41. compatibility  with  products  already  in the field may encourage bad
  42. design decisions in new product development, burdening those  products
  43. with  inefficiencies  and  unneeded  complexity.   While  it's easy to
  44. omit  entire  objects  that aren't recognized when loading a DXF file,
  45. coping with the subtler differences between releases of  AutoCAD  such
  46. as new bits denoting variants of Polylines, changes to text alignment,
  47. and the like cannot be reasonably done at the DXF input  level.   (The
  48. introduction  of  AUDIT  in  Release  11  will  go  a  long way toward
  49. detecting and discarding undefined  information  received  from  later
  50. releases  of  AutoCAD.   But  that,  of  course, doesn't help users of
  51. releases prior to 11.  Further, AUDIT will never be able to  translate
  52. entities  in subsequent releases into their equivalents in the release
  53. on which it's running.)
  54.  
  55. With the end approaching for support of various venerable AutoCAD host
  56. machines (e.g., the 8086 and 8088 in Release 11), the need  arises  to
  57. allow  users  of  those  machines  to  load,  albeit with some loss of
  58. information,  drawings  made  by  AutoCAD  Release  11  and,  ideally,
  59. releases   after   that.   The  fact  that  information  may  be  lost
  60. down-converting a drawing may not be as serious as it appears at first
  61. glance--the  user  of an obsolete machine is, in all likelihood, using
  62. it for pretty basic 2D drafting work.  Having the polyface meshes  and
  63. registered  application  name tables purged from a drawing is unlikely
  64. to bother such a user, particularly when the alternatives  are  either
  65. not  being  able  to  edit  the  drawing  at all or having to junk his
  66. computer.
  67.  
  68. The most straightforward way  to  provide  this  compatibility  is  by
  69. translating  a  DXF  file written by a new release of AutoCAD into one
  70. that can be  loaded  by  an  earlier  target  system.   Prior  to  the
  71. introduction  of  binary  DXF  in  Release 10, this was a very painful
  72. process since DXF files were huge, took forever to read and write, and
  73. forced a tradeoff between file size and accuracy of the numbers in the
  74. file.  With binary DXF, however, nothing  is  lost  in  exporting  and
  75. transferring  a  drawing via DXF, and the file sizes and I/O times are
  76. comparable to regular drawing (.dwg) files.
  77.  
  78. What we need, then, is a DXF converter  program--one  that  reads  DXF
  79. from  Release  11  and emits DXF compatible with Release 10.  Ideally,
  80. such a product should  be  configurable  so  changes  made  in  future
  81. releases  do  not require continual modification of the DXF converter.
  82. Indeed, the  converter  should  be  *programmable*,  so  that  it  can
  83. translate  DXF  from  ANY  release  of AutoCAD into that of any other.
  84. Best of all would be a converter that was open,  programmable  by  the
  85. user, one that  could  perform  any  transformation  on  a  DXF  file.
  86. DXFIX(tm)  (Drawing  eXchange  File  Inter Xlator) is precisely such a
  87. tool.   Incorporating  the  FORTH-based  Autodesk  Threaded   Language
  88. Application System Toolkit (ATLAST (tm)), DXFIX is an open system that
  89. can be used, without speed penalty, for the simple task of  converting
  90. DXF  from  Release  11  to  Release  10, or programmed by anybody with
  91. access to this documentation to perform arbitrary translation of  DXF.
  92.  
  93.  
  94. Running DXFIX
  95. -------------
  96.  
  97. To convert a Release 11 DXF file to Release 10, use the command:
  98.  
  99.     dxfix  [options]  infile  outfile
  100.  
  101. where  "infile"  is  the  input DXF file name (an extension of .dxf is
  102. assumed if no explicit extension  is  given),  and  "outfile"  is  the
  103. output  DXF file name (.dxf is also added to this name if no extension
  104. is present).  The input DXF file can be either binary or ASCII format;
  105. binary format is much faster to process and maintains full accuracy of
  106. drawing objects, but if you supply  an  ASCII  DXF  file,  DXFIX  will
  107. process  it  without difficulty.  DXFIX reads binary DXF files written
  108. in AutoCAD portable format regardless of the system  on  which  it  is
  109. running,  and  ASCII  DXF  with  any  of  the  end of line conventions
  110. recognized by AutoCAD.
  111.  
  112. The "outfile" is written, by default,  in  binary  DXF  format.   When
  113. transferring  data to AutoCAD Release 10, this format is preferable by
  114. far as it is much faster to write, generally  smaller,  and  preserves
  115. full  accuracy.  If you want ASCII DXF output instead (for example, if
  116. the DXF is intended for an AutoCAD  prior  to  Release  10  that  only
  117. supports  ASCII DXF, or is being sent to a non-Autodesk DXF processing
  118. program that requires ASCII), specify  the  "-Adigits"  option,  where
  119. "digits" is a number giving the precision, in decimal places, to which
  120. numbers should be edited in the ASCII DXF file.
  121.  
  122. For example, to convert a Release 11 DXF file named "house11.dxf" to a
  123. Release  10  DXF  file  named  "house10.dxf" (writing "house10.dxf" in
  124. binary format), use:
  125.  
  126.     dxfix  house11  house10
  127.  
  128. To perform the same translation, but generating an ASCII  output  file
  129. with six decimal places of precision, use:
  130.  
  131.     dxfix  -a6  house11  house10
  132.  
  133. The  actual  translation  relies  on  specifications given in the file
  134. "dxfix.dxt", which is assumed to  reside  in  the  current  directory.
  135. Alternatively,  you can use the "-Tname" option to specify a different
  136. location  or  name  for  the  translation  specifications  file.   For
  137. instance:
  138.  
  139.     dxfix  -a6  -t\dxfix\11_to_10  house11  house10
  140.  
  141. tells  DXFIX  to  find  its  translation  specifications  in  the file
  142. "\dxfix\11_to_10.dxt".  Note that the extension  .dxt  is  assumed  if
  143. none is supplied.
  144.  
  145.  
  146. Release 11 to 10 translations
  147. -----------------------------
  148.  
  149. The  following  Release 11 to Release 10 translations are specified by
  150. the standard "dxfix.dxt" file provided with  this  version  of  DXFIX.
  151.  
  152. Deleting new header variables
  153.   The  following drawing header variables, added since Release 10, are
  154.   deleted.  (The names in the DXF file are preceded by  dollar  signs;
  155.   we give the base names here, as they are more familiar.)
  156.  
  157.     DIMCLRD      Dimension line colour
  158.     DIMCLRE      Dimension extension line colour
  159.     DIMCLRT      Dimension text colour
  160.     DIMGAP       Dimension block gap
  161.     DIMSTYLE     Current dimension style
  162.     DIMTFAC      Dimension text vertical position
  163.     MAXACTVP     Maximum active viewports
  164.     PELEVATION   Paper elevation
  165.     PEXTMAX      Paper maximum extents
  166.     PEXTMIN      Paper minimum extents
  167.     PINSBASE     Paper insertion base
  168.     PLIMCHECK    Paper limit checking
  169.     PLIMMAX      Paper maximum limits
  170.     PLIMMIN      Paper minimum limits
  171.     PUCSNAME     Paper UCS name
  172.     PUCSORG      Paper UCS origin
  173.     PUCsXDIR     Paper UCS X direction
  174.     PUCSYDIR     Paper UCS Y direction
  175.     SHADEDGE     SHADE command edge rendering mode
  176.     SHADEDIF     Shading diffuse illumination factor
  177.     TILEMODE     Tiled viewports mode
  178.     UNITMODE     Drawing unit mode bits
  179.     VISRETAIN    Layer/viewport visibility retention
  180.  
  181. Flattening Z extents
  182.   The  drawing  extents,  output  as  the  $EXTMAX  and $EXTMIN header
  183.   variables, contain Z extents for  the  first  time  in  Release  11.
  184.   Earlier  releases  report an error when encountering an unexpected Z
  185.   coordinate, so the Z coordinates are removed from  these  variables.
  186.  
  187. Trapping zero $DIMSCALE
  188.   In Release 11, the DIMSCALE dimensioning variable can be set to zero
  189.   for paper space scaling.  If a zero is detected, it  is  changed  to
  190.   1.0.
  191.  
  192. Deleting new symbol tables
  193.   The  following new symbol tables were added in Release 11.  They are
  194.   deleted in their entirety from the TABLES section.
  195.  
  196.     APPID     - Registered application table
  197.     DIMSTYLE  - Dimension style table
  198.  
  199. Handling new LAYER table flag bits
  200.   The 70 (flags) group of the LAYER table entry has a  few  new  bits.
  201.   The  "frozen  by  default  in  new  viewports" bit has no meaning in
  202.   Release 10 and is zeroed.  If any of the "dependent symbol" bits are
  203.   set, the entire layer entry is discarded.
  204.  
  205. Deleting new entities
  206.   All VIEWPORT entities, used by the multiple view facility of Release
  207.   11, are deleted whenever  encountered  in  the  ENTITIES  or  BLOCKS
  208.   section.
  209.  
  210. Deleting new entity fields
  211.   The following fields, representing features added in Release 11, are
  212.   deleted from the entities in which they appear.
  213.  
  214.     BLOCK entity:
  215.       The 1 (Xref path name) and 3 (block name)  groups  are  deleted.
  216.       In  addition,  all Xref-related bits of the 70 (flags) group are
  217.       zeroed.  If the BLOCK was an Xref, it  becomes  a  dummy  BLOCK.
  218.  
  219.     DIMENSION entity:
  220.       The  3  (dimension  style),  52  (obliquing angle), and 53 (text
  221.       rotation angle) groups are deleted.
  222.  
  223. Deleting new common entity fields
  224.   The following fields, which can occur on any entity in the database,
  225.   are deleted wherever encountered.
  226.  
  227.     Extended entity data:
  228.       Extended  entity data (entity attributes) has group codes in the
  229.       1000 to 1100 range.  All  groups  in  that  range  are  deleted,
  230.       stripping all extended entity data from the drawing.
  231.  
  232.     Paper/model space indicator
  233.       A  new  common  property  of all entities, the paper/model space
  234.       indicator, is represented in DXF by a 67 group, where:
  235.  
  236.         0 = model space
  237.         1 = paper space
  238.  
  239.       All other values are reserved for future use.  Since versions of
  240.       AutoCAD  prior  to  Release  11 don't support paper space, DXFIX
  241.       deletes all entities whose 67 group is nonzero.  If the 67 group
  242.       is zero, just that group is deleted.
  243.  
  244. Adjusting text vertical alignment
  245.   In  Release  11,  general specification of the vertical alignment of
  246.   Text, Attribute Definition, and Attribute entities was  implemented.
  247.   Earlier  releases  provided  general  horizontal alignment, with one
  248.   special case providing both horizontal and vertical centering.   The
  249.   new-style   "MCenter"   specification   is   translated   into   the
  250.   near-equivalent "MID" form accepted by versions prior to Release 11.
  251.   All other instances of vertical alignment cause the text to be reset
  252.   to  left/baseline  justification.   In such cases, a warning message
  253.   informs the user of the  loss  of  alignment  information,  and  the
  254.   justification  point  (group  11)  is  deleted.   In  all cases, the
  255.   vertical alignment group (73 in a Text entity, 74 in an Attribute or
  256.   Attribute Definition) is deleted.
  257.  
  258. Exploding polyface meshes
  259.   In Release 11 a new variant of the  Polyline  entity,  the  polyface
  260.   mesh,  was introduced.  Consisting of a table of vertices and faces,
  261.   it is a far more compact representation of tiled surfaces  than  the
  262.   3Dface  entities  used  prior  to Release 11.  However, any polyface
  263.   mesh can be represented by a collection of 3Dface, Line,  and  Point
  264.   entities.   If  the  mesh is EXPLODEd prior to DXFOUT, the resulting
  265.   file can be loaded into Release 10 without difficulty.  To eliminate
  266.   this requirement (and to demonstrate by a flashy but convenient tour
  267.   de force the ATLAST-derived power of DXFIX), polyface meshes present
  268.   in  the  DXF  input  file  are  automatically  transformed  into the
  269.   equivalent collection of  individual  entities.   This  is  done  by
  270.   saving  the  vertices  in  a  temporary  file,  then  replacing each
  271.   polyface entity with the  corresponding  simple  entity.   Invisible
  272.   edge specifications are converted from the negative-vertex form used
  273.   in polyface meshes to the invisible edge bits used in 3Dfaces.   The
  274.   temporary  file,  "$pface.$ac",  is  deleted  at the end of DXF file
  275.   translation.
  276.  
  277.  
  278. Translation specifications
  279. --------------------------
  280.  
  281. Most customers who use DXFIX to convert Release 11 DXF to  Release  10
  282. need  know  nothing more about the program than the information above:
  283. how to run  it  and  what  information  is  lost  in  the  process  of
  284. converting  a  drawing.  DXFIX is, however, far more than a Release 11
  285. to Release 10 DXF translator.  In fact, it  knows  nothing  about  the
  286. contents of either Release 11 or Release 10 DXF.  DXFIX is actually an
  287. ATLAST-based, general purpose, open architecture DXF  translator.   As
  288. long  as  no  fundamentally  new  data types are added to DXF (and the
  289. extended entity group codes and binary chunks of Release 11  were  the
  290. first  additions  to the format in 5 years and 6 releases), DXFIX will
  291. be able, given suitable specifications,  to  translate  DXF  from  any
  292. AutoCAD  of  the future to any AutoCAD target system of Release 2.0 or
  293. later.  (Earlier versions of AutoCAD used a totally different form  of
  294. DXF,  and  while  DXFIX could even be made to generate that format, it
  295. would hardly be worth the bother.)
  296.  
  297. The transformation of a DXF file by DXFIX can be controlled at several
  298. different levels, provided  by  the  natural  layering  of  an  ATLAST
  299. application.  Each will be discussed in turn.
  300.  
  301.  
  302. Layer 0:  Translation file selection
  303. ------------------------------------
  304.  
  305. The transformations performed by DXFIX are defined in  a  "translation
  306. specification  file",  which  is actually an executable ATLAST program
  307. loaded by  DXFIX  to  perform  the  translation.   If  no  translation
  308. specification  file  is  named  on the DXFIX command line, the default
  309. file named "dxfix.dxt" is used.  The version of "dxfix.dxt"  furnished
  310. with  the  initial  version of DXFIX performs Release 11 to Release 10
  311. translation.  It is intended  that  when  DXFIX  is  shipped  with  an
  312. AutoCAD  release,  it  will normally be accompanied with a "dxfix.dxt"
  313. file that converts DXF from that release to the immediately prior one.
  314.  
  315. If  you  wish to use different translation specifications, specify the
  316. "-Tname" switch on  the  DXFIX  command  line,  where  "name"  is  the
  317. translation  specification  file  name.  If no extension is specified,
  318. ".dxt" is automatically appended.  For example,  if  you  had  a  file
  319. named  "r11_r9.dxt"  that  converts Release 11 DXF to input compatible
  320. with Release 9, you could translate a DXF  file  called  "chair11.dxf"
  321. with the command:
  322.  
  323.     dxfix  -tr11_r9  chair11  chair9
  324.  
  325. Since  Release  9  cannot read binary DXF, the "r11_r9.dxt" file would
  326. automatically  select  ASCII  output  format,  even  though  the  user
  327. specified  no "-Adigits" switch on the command line.  (We'll see later
  328. how the translation specifications can control  that  and  much,  much
  329. more.)
  330.  
  331.  
  332. Layer 1: Object processing specifications
  333. -----------------------------------------
  334.  
  335. Since much of the process of translating a DXF file consists of simply
  336. deleting material added in  later  releases,  much  of  a  translation
  337. specification  file  consists of statements that specify what is to be
  338. deleted, which bits should be turned off in mask fields, and the like.
  339. The  ability  to  define  new  data  types  and  methods  in ATLAST is
  340. exploited to  make  these  specifications  simple  and  readable.   To
  341. understand the bulk of the specifications in the "dxfix.dxt" file, you
  342. must first understand the hierarchy of a DXF file and the nomenclature
  343. DXFIX uses to designate different levels and objects in the structure.
  344.  
  345. The overall structure of a DXF file is as follows:
  346.  
  347.   Sections        Subsections      Objects      Groups
  348.   ---------       -----------      -------      ------
  349.   HEADER      
  350.                                    Variables
  351.                                                 Groups
  352.   TABLES
  353.                  LTYPE
  354.                                    Entries
  355.                                                 Groups
  356.                  LAYER
  357.                                    Entries
  358.                                                 Groups
  359.                  STYLE
  360.                                    Entries
  361.                                                 Groups
  362.                  ...
  363.   BLOCKS
  364.                                    Entities
  365.                                                 Groups
  366.   ENTITIES
  367.                                    Entities
  368.                                                 Groups
  369.   EOF
  370.  
  371. Processing  of  different  parts  of  this hierarchy is specified by a
  372. "structure name" that selects the portions(s) of the hierarchy  to  be
  373. processed.   Each  structure  name  begins  with the characters "DXF:"
  374. followed by the path through the hierarchy  with  wild-card  selection
  375. available by specifying the "*" character at various places.
  376.  
  377. To  illustrate  the  use of structure names, we'll use the most common
  378. declaration  in  a  translation  specification  file,   the   "remove"
  379. statement.   All objects that match the structure name are deleted, in
  380. their entirety, from the DXF file.  Here is  how  "dxfix.dxt"  deletes
  381. the paper space extents header variables from Release 11 DXF.
  382.  
  383.   remove dxf:header:$pextmax
  384.   remove dxf:header:$pextmin
  385.  
  386. The structure name "dxf:header:$pextmax" specifies the HEADER variable
  387. section, object $pextmax (recall that all header  variable  names  are
  388. prefixed  with a "$" in DXF files).  When this variable is encountered
  389. in the DXF file, its action, "remove", is executed,  thereby  deleting
  390. the  variable  from  the  output  file.   To  delete additional header
  391. variables, just add "remove" statements naming them.
  392.  
  393. To demonstrate the generality of this approach, let's examine how  the
  394. new  Release  11  DIMSTYLE  (Dimension  Style)  table is deleted.  The
  395. specification that accomplishes this is just:
  396.  
  397.   remove dxf:tables:dimstyle
  398.  
  399. Unlike the HEADER variables section, the TABLES  section  can  contain
  400. multiple  objects  in each table--in this case any number of dimension
  401. styles.  The structure name triggers, however, when it matches to  the
  402. end  of  the  name  specification,  so this "remove" statement will be
  403. executed for each entry in the DIMSTYLE table.  Since  each  execution
  404. has the effect of deleting the current item (and since the table start
  405. and table end items are also matched  as  part  of  the  table),  this
  406. single  statement deletes the entire dimension style symbol table from
  407. the output DXF.
  408.  
  409. As part of the multiple view plotting facility in Release  11,  a  new
  410. VIEWPORT entity was added to the database.  All of these entities must
  411. be removed when converting a DXF file for use with Release 10.   Since
  412. VIEWPORT  entities  can  appear  in either the ENTITIES section or, if
  413. part of a Block Definition, in the BLOCKS section, we can remove  them
  414. from both sections with the statements:
  415.  
  416.   remove dxf:blocks:viewport
  417.   remove dxf:entities:viewport
  418.  
  419. The  "remove"  declaration  isn't  the  only action we can take when a
  420. section name is matched.  The "ditchgroup" statement causes the  named
  421. group  (which must be specified to the group level) to be deleted from
  422. the current object.  For example, three new groups were added  to  the
  423. Dimension  entity  in  Release  11.   To  remove these, we can use the
  424. statements:
  425.  
  426.   ditchgroup dxf:*:dimension:3
  427.   ditchgroup dxf:*:dimension:52
  428.   ditchgroup dxf:*:dimension:53
  429.  
  430. The  first  statement  matches the 3 group of objects (entities) named
  431. DIMENSION appearing in any section of the DXF file  (effectively  just
  432. the  BLOCKS and ENTITIES sections, since DIMENSION objects appear only
  433. there).  The action of "ditchgroup" causes the 3 group to  be  deleted
  434. wherever  it  appears  within a Dimension entity.  The statements that
  435. follow similarly delete the 52 and 53 groups.
  436.  
  437. Extended  entity  data  (entity attributes) were introduced in Release
  438. 11.  These are written to DXF files with group codes between 1000  and
  439. 1100, and must be removed when translating DXF for earlier versions of
  440. AutoCAD.  We can remove all extended entity data, wherever present  in
  441. the DXF file, with the statement:
  442.  
  443.   ditchgroup dxf:*:*:1000-1100
  444.  
  445. In  this  case we're wild-carding both the section and the object type
  446. and taking advantage of the ability to specify a range of group  codes
  447. to  be selected.  If we wanted to select the polyface vertex fields in
  448. a Vertex entity, we could use "dxf:*:vertex:71-74".
  449.  
  450. If special processing  is  specified  at  more  than  one  level  (for
  451. example,   a   given  group  might  be  selected  by  a  global  group
  452. specification, as a group of an entity of that type, or as a member of
  453. an  object  of  that  type), processing is done with the most specific
  454. (group) first to the most general (item) last.
  455.  
  456.  
  457. Layer 2:  Translation programming
  458. ---------------------------------
  459.  
  460. What appears at first glance to be a  data  file  that  specifies  the
  461. changes to be made to a DXF  file  is,  in  actuality,  an  executable
  462. ATLAST  program.   The  program  has  access  to  all the usual ATLAST
  463. facilities and, in addition, a set of  primitives  provided  by  DXFIX
  464. that  allow  easy manipulation of objects in the DXF file.  The key to
  465. understanding how DXFIX and ATLAST work together is the structure name
  466. specifications  described  in  Layer  1  above.   Each  structure name
  467. specification   is   actually   an   executable   ATLAST    definition
  468. automatically  invoked  when  a  matching component of the DXF file is
  469. encountered.  The ability to potentially run  a  user-defined  program
  470. for  every  component  of  the file permits DXFIX to perform arbitrary
  471. transformations on the DXF files it  processes.   The  quickness  with
  472. which  DXFIX  can  determine  if special processing is requested for a
  473. component of the DXF file (by pre-scanning the ATLAST  dictionary  for
  474. the  "DXF:"  definitions and building a hierarchically-organized table
  475. of processing requests, it is just a  matter  of  a  few  pointer  and
  476. integer  comparisons), and the inherent speed of executing precompiled
  477. ATLAST code in an already-looked-up definition, result in DXFIX  being
  478. able to perform substantial user-specified processing while running at
  479. essentially the same speed  as  a  simple  DXF  copy  program  written
  480. entirely in C.
  481.  
  482. To  understand  how DXFIX and ATLAST are woven together into a unified
  483. general purpose translation tool, let's start with the DXF  processing
  484. primitives  added  to  ATLAST by DXFIX.  Many of these primitives will
  485. rarely be used in any but the most ambitious DXF translation  projects
  486. (far  more  complicated than converting Release 11 to Release 10), but
  487. they're available if you need them.  Key to  understanding  the  DXFIX
  488. primitives is the "current item".  DXFIX is always working on one item
  489. (structure delimiter, header variable, symbol table entry, or  entity)
  490. from  the  DXF  file  at  a  time.   This  current  item is implicitly
  491. referenced by all of the item and group manipulation primitives.
  492.  
  493.  
  494. Item primitives
  495. ---------------
  496.  
  497. The item primitives operate upon entire items (lists of groups forming
  498. the fundamental objects in the DXF file).
  499.  
  500.   CLEARITEM    All groups of the current item are deleted.  You'd only
  501.                use this if you intended  to  build  a  new  item  from
  502.                scratch using ADDGROUP.  The stack is not affected.
  503.  
  504.   ITEMPOS      The position at which the current item began in the DXF
  505.                file is placed on the stack.  This is the  line  number
  506.                of  the  first  group  of the item if the input file is
  507.                ASCII or its byte number if the input is binary.   Both
  508.                lines and bytes are numbered from zero.
  509.  
  510.   PRINTITEM    All  groups  of  the  current  item  are printed on the
  511.                output file specified by the top of the stack.  You can
  512.                use  the  predefined  and  automatically opened streams
  513.                STDOUT and STDERR to send  output  to  the  user.   For
  514.                example,   if   an  Arc  is  the  current  entity,  the
  515.                statement:
  516.  
  517.                  stdout printitem
  518.  
  519.                might generate the following output:
  520.  
  521.                   0:  "ARC"
  522.                   8:  "0"
  523.                  10:  (3, 2, 0)
  524.                  40:  1
  525.                  50:  0
  526.                  51:  90
  527.  
  528.   READITEM     The next item is read from the DXF file and becomes the
  529.                current  item.   If  the  item  is read normally, -1 is
  530.                placed on the stack; if end of file  or  a  read  error
  531.                occurs,  0  is  placed  on the stack.  When the item is
  532.                read, all  special  processing  declared  by  structure
  533.                names  that  match  the item and/or groups within it is
  534.                automatically  performed  BEFORE  the  item   is   made
  535.                available  to  the caller of READITEM.  If the previous
  536.                current item has not been written to  the  output  file
  537.                with  WRITEITEM  before  READITEM is called to read the
  538.                next, it will be lost--deleted from the output file.
  539.  
  540.   WRITEITEM    The  current item is written to the output file, unless
  541.                marked for deletion.  If the item is  written  normally
  542.                or  is  to  be  deleted, -1 is placed on the top of the
  543.                stack.  If an error occurs attempting to write the item
  544.                to the output file, 0 is returned on the stack top.  If
  545.                the DELITEM (delete item) shared variable  is  nonzero,
  546.                the  item  is  not  written to the output file, and the
  547.                DELITEM variable is cleared to zero.  If  the  DELCITEM
  548.                (delete  complex  item) shared variable is nonzero, the
  549.                item is not written to the output file and, if the item
  550.                is  a  Sequence  End  entity,  the DELCITEM variable is
  551.                cleared to zero.
  552.  
  553.   (Added for R13->R12 conversion)
  554.   SETUPSPLINE  This primitive was added to allow Spline entities to
  555.                be converted into more primitive entities. It is
  556.                used just prior to calling the EVALSPLINE
  557.                primitive below and again just after. The first
  558.                call before EVALSPLINE should pass the following
  559.                values on the stack:
  560.  
  561.                Top of stack -> true (integer)
  562.                                Order of spline (integer)
  563.                                Number of weights (integer)
  564.                                Weight_0 (floating point)
  565.                                ...
  566.                                Weight_M (floating point)
  567.                                Control point Z_0 (floating point)
  568.                                Control point Y_0 (floating point)
  569.                                Control point X_0 (floating point)
  570.                                ...
  571.                                Control point Z_M (floating point)
  572.                                Control point Y_M (floating point)
  573.                                Control point X_M (floating point)
  574.                                Number of knots (integer)
  575.                                Knot_0 (floating point)
  576.                                ...
  577.                                Knot_N (floating point)
  578.  
  579.  
  580.                Note that the number of weights is equal to the
  581.                number of control points.                 
  582.  
  583.                After EVALSPLINE is called, SETUPSPLINE should be
  584.                called again with only the value 'false' on
  585.                top of the stack. This frees up any memory
  586.                allocated during the initial call.
  587.  
  588.   (Added for R13->R12 conversion)
  589.   EVALSPLINE   This primitive was added to allow Spline entities to
  590.                be evaluated after setting up the parameters with
  591.                the SETUPSPLINE call above. It uses a Cox-de Boor
  592.                B-spline function to return a 3D point given a
  593.                certain parameter value. For example, the R13->R12
  594.                translator varies the parameter from the value of
  595.                the first knot to the last knot over an equaly
  596.                spaced interval.             
  597.                 
  598.                  -> 23.45 evalspline f. f. f.
  599.                  6.78 9.01 2.34
  600.  
  601.  
  602. Group primitives
  603. ----------------
  604.  
  605. The group primitives provide access to the individual data fields that
  606. make  up an item.  In the following descriptions of primitives, assume
  607. that the current item is a Line entity on layer  0,  from  coordinates
  608. (1,1,0)  to  (2,2,0).   This item would be displayed with the sequence
  609. "stdout printitem" as:
  610.  
  611.    0:  "LINE"
  612.    8:  "0"
  613.   10:  (1, 1, 0)
  614.   11:  (2, 2, 0)
  615.  
  616. Groups within an item can be identified either by  group  code  or  by
  617. their  position  within  the  item.   Regular  AutoCAD item fields are
  618. always unique and may be  identified  simply  by  their  group  codes.
  619. Extended entity data, however, uses the same group code for all fields
  620. of a given type,  so  group  codes  are  not  necessarily  unique.   A
  621. positive number used to designate a group chooses the first occurrence
  622. of that group code in the current item.  A negative number of the form
  623. -(10000 + n), where "n" specifies the position of the group within the
  624. item (with the first group numbered zero), selects the  nth  group  in
  625. the  chain  of  groups  composing the item and may be used to uniquely
  626. specify extended entity groups that appear more than once in an  item.
  627.  
  628.   PRINTGROUP   The group identified by the second item on the stack is
  629.                printed on the output stream specified by  the  top  of
  630.                stack.  For example:
  631.  
  632.                  -> 10 stdout printgroup
  633.                    10:  (1, 1, 0)
  634.                  -> -10001 stdout printgroup
  635.                     8:  "0"
  636.  
  637.   GROUPCOUNT   Places  the number of groups in the current item on the
  638.                top of the stack.
  639.  
  640.                  -> groupcount .
  641.                  4
  642.  
  643.   (Added for R13->R12 conversion)
  644.   GROUPCOUNT2  Places the number of a particular group in the current
  645.                item on the top of the stack. This is useful, for
  646.                example, in MText entities to find out how many 3
  647.                groups are in an item.
  648.  
  649.                  -> 10 groupcount2 .
  650.                  1
  651.  
  652.   (Added for R13->R12 conversion)
  653.   ITEMPOS2     The zero based index at which the specified group began
  654.                in the current item is placed on the stack. This
  655.                is useful, for example, in a Spline entity to
  656.                determine where to start requesting the control
  657.                point groups (10 groups) using the -(10000 + n)
  658.                technique mentioned above.
  659.  
  660.                  -> 10 itempos2 .
  661.                  2
  662.  
  663.   GROUP?       If the group with group code given by the  top  of  the
  664.                stack  is  present in the item, -1 is placed on the top
  665.                of the stack.  If the group  does  not  appear  in  the
  666.                item, 0 is returned.
  667.  
  668.                  -> 10 group? .
  669.                  -1
  670.                  -> 40 group? .
  671.                  0
  672.  
  673.   DELGROUP     The  group  on the top of the stack is deleted from the
  674.                item, if  present.   If  the  specified  group  is  not
  675.                present, DELGROUP is simply ignored.
  676.  
  677.                  -> stdout printitem
  678.                     0:  "LINE"
  679.                     8:  "0"
  680.                    10:  (1, 1, 0)
  681.                    11:  (2, 2, 0)
  682.                  -> 8 delgroup
  683.                  -> stdout printitem
  684.                     0:  "LINE"
  685.                    10:  (1, 1, 0)
  686.                    11:  (2, 2, 0)
  687.  
  688.   GROUP        The  value  of the specified group, in whatever form is
  689.                appropriate for it, is placed on the top of the  stack.
  690.                Integers are stored as single stack items; real numbers
  691.                and angles as pairs of stack items  representing  their
  692.                floating point values; coordinates as triples of pairs,
  693.                each giving a floating coordinate with Z at the top  of
  694.                the  stack,  Y next, and then X; strings as the address
  695.                of a temporary string buffer containing the  text;  and
  696.                binary  chunks as a length, in bytes, on the top of the
  697.                stack and the address of the chunk data,  stored  in  a
  698.                temporary string buffer, next on the stack.
  699.  
  700.                  -> 10 group f. f. f.
  701.                  0 1 1
  702.  
  703.   ADDGROUP     A  group with the type given by the top of the stack is
  704.                added to the end of the item.  The value field  of  the
  705.                group  is  cleared  to  zero,  and may be then set with
  706.                SETGROUP.
  707.  
  708.                  -> 62 addgroup
  709.                  -> stdout printitem
  710.                     0:  "LINE"
  711.                    10:  (1, 1, 0)
  712.                    11:  (2, 2, 0)
  713.                    62:  0
  714.  
  715.   SETGROUP     Sets the value of the group specified by the top of the
  716.                stack  to  the values below it (in the same form as the
  717.                results  returned  by  GROUP).    Removes   the   group
  718.                specification and the values from the stack.
  719.  
  720.                  -> 3 62 setgroup
  721.                  -> 3.0 4.0 5.0 10 setgroup
  722.                  -> stdout printitem
  723.                     0:  "LINE"
  724.                    10:  (3, 4, 5)
  725.                    11:  (2, 2, 0)
  726.                    62:  3
  727.  
  728.  
  729. Diagnostic primitives
  730. ---------------------
  731.  
  732.   DUMPSPECIAL  The hierarchy of the DXF file is printed, including all
  733.                items named by  structure  name  declarations  (whether
  734.                seen  in  the  DXF  file  or  not)  and  those actually
  735.                encountered in processing the input file so far.  Those
  736.                items  for  which  special  processing is requested are
  737.                identified with the legend "(Special)".  At the end  of
  738.                the listing, wild-card specifications are listed.  Here
  739.                is the output from  DUMPSPECIAL  after  the  first  few
  740.                header variables of a DXF file are processed when using
  741.                the standard  Release  11  to  Release  10  "dxfix.dxt"
  742.                specifications.
  743.  
  744.                  -> readitem readitem readitem readitem
  745.                  -> dumpspecial
  746.                  START (Special)
  747.                  HEADER
  748.                      $INSBASE
  749.                      $ACADVER
  750.                      $DIMCLRD (Special)
  751.                      $DIMCLRE (Special)
  752.                      $DIMCLRT (Special)
  753.                      $DIMGAP (Special)
  754.                      $DIMSTYLE (Special)
  755.                      $DIMTFAC (Special)
  756.                      $MAXACTVP (Special)
  757.                      $PELEVATION (Special)
  758.                      $PEXTMAX (Special)
  759.                      $PEXTMIN (Special)
  760.                      $PINSBASE (Special)
  761.                      $PLIMCHECK (Special)
  762.                      $PLIMMAX (Special)
  763.                      $PLIMMIN (Special)
  764.                      $PUCSNAME (Special)
  765.                      $PUCSORG (Special)
  766.                      $PUCSXDIR (Special)
  767.                      $PUCSYDIR (Special)
  768.                      $SHADEDGE (Special)
  769.                      $SHADEDIF (Special)
  770.                      $TILEMODE (Special)
  771.                      $UNITMODE (Special)
  772.                      $VISRETAIN (Special)
  773.                      $EXTMAX (Special)
  774.                      $EXTMIN (Special)
  775.                      $DIMSCALE (Special)
  776.                  TABLES
  777.                      APPID (Special)
  778.                      DIMSTYLE (Special)
  779.                      LAYER (Special)
  780.                  ENTITIES
  781.                      VIEWPORT (Special)
  782.                  BLOCKS
  783.                      VIEWPORT (Special)
  784.                      BLOCK (Special)
  785.                  END (Special)
  786.  
  787.                  Group range actions:
  788.                  DXF:*:DIMENSION:3
  789.                  DXF:*:DIMENSION:52
  790.                  DXF:*:DIMENSION:53
  791.                  DXF:*:*:1000-1100
  792.                  DXF:*:TEXT:73
  793.                  DXF:*:ATTDEF:74
  794.                  DXF:*:ATTRIB:74
  795.                  DXF:*:*:67
  796.                  DXF:*:POLYLINE:70
  797.                  DXF:*:SEQEND:*
  798.                  DXF:*:VERTEX:70
  799.  
  800.  
  801. Command line primitives
  802. -----------------------
  803.  
  804. The  following  primitives  provide access to the command line used to
  805. invoke DXFIX.  They can be used by advanced  translation  programs  to
  806. obtain  parameters  from  the  command  line.  The following primitive
  807. descriptions assume that DXFIX has been invoked with  a  command  line
  808. of:
  809.  
  810.     dxfix  -i  -v11  -y=NO  dxin  dxout
  811.  
  812.   OPTION       Tests whether a command line option letter, prefixed by
  813.                a minus sign,  is  present.   If  that  option  is  not
  814.                specified, 0 is placed on the top of the stack.  If the
  815.                option is present, a pointer to the text  that  follows
  816.                the  option  letter  is  placed on the top of the stack
  817.                (the pointer is guaranteed to be nonzero).   Note  that
  818.                if  no text follows the option letter, the pointer will
  819.                still be nonzero indicating the option  was  specified.
  820.                The  pointer will point to a null string, in that case.
  821.  
  822.                  -> "v" option type cr
  823.                  11
  824.                  -> "x" option . cr
  825.                  0
  826.                  -> "Y" option type cr
  827.                  =NO
  828.  
  829.   ARGCOUNT     Places the number of command line arguments,  including
  830.                the zeroth argument that gives the program name itself,
  831.                on the top of the stack.
  832.  
  833.                  -> argcount
  834.                  6
  835.  
  836.   ARGVALUE     Given a number from 0 to ARGCOUNT-1 on the top  of  the
  837.                stack,  returns  a pointer to a temporary string buffer
  838.                containing a copy of that command  line  argument.   If
  839.                the  number  is less than 0 or >= ARGCOUNT, 0 is placed
  840.                on the top of the stack.
  841.  
  842.                  -> 2 argvalue type cr
  843.                  -v11
  844.                  -> 6 argvalue . cr
  845.                  0
  846.                  -> : targs argcount 0 do i argvalue type
  847.                  :>  cr loop ;
  848.                  -> targs
  849.                  dxfix
  850.                  -i
  851.                  -v11
  852.                  -y=NO
  853.                  dxin
  854.                  dxout
  855.  
  856.  
  857. Shared variables
  858. ----------------
  859.  
  860. A number of shared variables serve  to  exchange  information  between
  861. DXFIX  and  the  ATLAST  translation  specification  program.    These
  862. variables are all integers (with the exception of OFILE and
  863. IFILE), and have the following meanings.
  864.  
  865.   DELITEM      DELITEM causes the current item to  be  deleted  rather
  866.                than   being  written  to  the  output  DXF  file  when
  867.                WRITEITEM is invoked.  You can  set  DELITEM  from  any
  868.                structure  name  definition  to  cause  the  item  that
  869.                invoked that definition to be deleted from  the  output
  870.                file.
  871.  
  872.   DELCITEM     DELCITEM  causes  the  current item, and all subsequent
  873.                items up to and including the next Sequence End  entity
  874.                to  be  deleted  from  the  output DXF file rather than
  875.                being written to it by  WRITEITEM.   A  structure  name
  876.                definition  may set DELCITEM when processing the header
  877.                of a complex entity (for example, a polygon mesh,  when
  878.                generating  DXF  for  a  version  of  AutoCAD  prior to
  879.                Release 10) which should be deleted  in  its  entirety.
  880.  
  881.   INBINARY     If the input file is binary, INBINARY has the value -1.
  882.                If the input file is ASCII, it's 0.
  883.  
  884.   OUTPREC      The OUTPREC variable specifies the mode of  the  output
  885.                file  and,  if  ASCII,  the precision of floating point
  886.                numbers written to it.  If the output file  is  binary,
  887.                OUTPREC  is  set  to  -1;  if  this  default  has  been
  888.                overridden with a "-Adigits" specification on the DXFIX
  889.                command  line, OUTPREC will be set to "digits".  If the
  890.                value of OUTPREC is set by a  DXF:START  definition  in
  891.                the  translation  program,  the  value  specified  will
  892.                override the default or  the  value  from  the  command
  893.                line.
  894.  
  895.   DUMPINPUT    If  DUMPINPUT is nonzero, each item read from the input
  896.                DXF file will be dumped to standard output.
  897.  
  898.   DUMPOUTPUT   If DUMPOUTPUT is nonzero,  each  item  written  to  the
  899.                output DXF file will be dumped to standard output.
  900.  
  901.   SPECIALDONE  When   an   item   matches   multiple   structure  name
  902.                definitions, each is normally executed in sequence.  If
  903.                a  structure name definition performs an action that by
  904.                its very nature completes the processing  of  the  item
  905.                (for  example,  setting  DELITEM  to delete it from the
  906.                output  file),  it  may  set  SPECIALDONE.   Once  this
  907.                variable is set nonzero by a structure name definition,
  908.                no other structure name  definition  triggered  by  the
  909.                item  will  be  processed.   This is particularly handy
  910.                when you wish processing  of  a  certain  group  of  an
  911.                entity to replace the default handling of entities with
  912.                that group missing.
  913.  
  914.   DXFTRACE     If the translation program sets DXFTRACE  nonzero,  all
  915.                invocations  of  structure name definitions are printed
  916.                on standard output.  Here is the  output  generated  by
  917.                translation  of a Release 11 DXF file with DXFTRACE set
  918.                to 1.
  919.  
  920.                  Invoking DXF:START
  921.                  Invoking DXF:HEADER:$EXTMIN
  922.                  Invoking DXF:HEADER:$EXTMAX
  923.                  Invoking DXF:HEADER:$DIMSCALE
  924.                  Invoking DXF:HEADER:$DIMSTYLE
  925.                  Invoking DXF:HEADER:$DIMCLRD
  926.                  Invoking DXF:HEADER:$DIMCLRE
  927.                  Invoking DXF:HEADER:$DIMCLRT
  928.                  Invoking DXF:HEADER:$DIMTFAC
  929.                  Invoking DXF:HEADER:$DIMGAP
  930.                  Invoking DXF:HEADER:$PELEVATION
  931.                  Invoking DXF:HEADER:$PUCSNAME
  932.                  Invoking DXF:HEADER:$PUCSORG
  933.                  Invoking DXF:HEADER:$PUCSXDIR
  934.                  Invoking DXF:HEADER:$PUCSYDIR
  935.                  Invoking DXF:HEADER:$SHADEDGE
  936.                  Invoking DXF:HEADER:$SHADEDIF
  937.                  Invoking DXF:HEADER:$TILEMODE
  938.                  Invoking DXF:HEADER:$MAXACTVP
  939.                  Invoking DXF:HEADER:$PINSBASE
  940.                  Invoking DXF:HEADER:$PLIMCHECK
  941.                  Invoking DXF:HEADER:$PEXTMIN
  942.                  Invoking DXF:HEADER:$PEXTMAX
  943.                  Invoking DXF:HEADER:$PLIMMIN
  944.                  Invoking DXF:HEADER:$PLIMMAX
  945.                  Invoking DXF:HEADER:$UNITMODE
  946.                  Invoking DXF:HEADER:$VISRETAIN
  947.                  Invoking DXF:TABLES:LAYER
  948.                  Invoking DXF:TABLES:LAYER
  949.                  Invoking DXF:TABLES:LAYER
  950.                  Invoking DXF:TABLES:APPID
  951.                  Invoking DXF:TABLES:APPID
  952.                  Invoking DXF:TABLES:APPID
  953.                  Invoking DXF:TABLES:DIMSTYLE
  954.                  Invoking DXF:TABLES:DIMSTYLE
  955.                  Invoking DXF:TABLES:DIMSTYLE
  956.                  Invoking DXF:BLOCKS:BLOCK
  957.                  Invoking DXF:BLOCKS:BLOCK
  958.                  Invoking DXF:*:SEQEND
  959.                  Invoking DXF:BLOCKS:BLOCK
  960.                  Invoking DXF:BLOCKS:BLOCK
  961.                  Invoking DXF:*:TEXT:73
  962.                  Invoking DXF:*:DIMENSION:3
  963.                  Invoking DXF:*:POLYLINE:70
  964.                  Invoking DXF:*:SEQEND
  965.                  Invoking DXF:*:SEQEND
  966.                  Invoking DXF:BLOCKS:BLOCK
  967.                  Invoking DXF:BLOCKS:BLOCK
  968.                  Invoking DXF:*:TEXT:73
  969.                  Invoking DXF:*:*:1000-1100
  970.                  Invoking DXF:*:*:1000-1100
  971.                  Invoking DXF:*:*:1000-1100
  972.                  Invoking DXF:*:*:1000-1100
  973.                  Invoking DXF:*:*:67
  974.                  Invoking DXF:ENTITIES:VIEWPORT
  975.                  Invoking DXF:END
  976.  
  977.   (Added for R13->R12 conversion)
  978.   REWIND       If the translation program sets REWIND  nonzero,
  979.                traslation will be rerun from the beginning after
  980.                the current translation is complete. This is used
  981.                to update the handle seed value when new entities
  982.                are added to the output dxf file (for example,
  983.                when an ellipse is decomposed into a polyline).
  984.  
  985.   (Added for R13->R12 conversion)
  986.   OFILE        This stream is made available to directly access
  987.                the output file. It is used in R13 conversion to
  988.                directly write new entities to the output file.
  989.  
  990.   (Added for R13->R12 conversion)
  991.   IFILE        This stream is made available to directly access
  992.                the input file. It is not currently used in R13
  993.                dxf conversion but is supplied here to complement
  994.                the OFILE stream.
  995.  
  996. Missing Z coordinates
  997. ---------------------
  998.  
  999. Some versions of DXF files contain two dimensional as  well  as  three
  1000. dimensional  points.   Unfortunately,  these objects are distinguished
  1001. only by the absence or presence, respectively, of a 3x  group  in  the
  1002. DXF  file.   They  cannot  be  told  apart  by  group  code alone once
  1003. assembled into composite structures with group codes from  10  to  19.
  1004. To  allow translation programs to determine whether a Z coordinate was
  1005. supplied in input and to control whether a  Z  coordinate  is  written
  1006. when  a point group is output, a special floating point variable named
  1007. MISSING_Z is defined.  The variable has a value of -1*(10^308),  which
  1008. should  never  occur in a valid AutoCAD database.  If the Z coordinate
  1009. of a point group tests equal to MISSING_Z, no Z coordinate was present
  1010. in  the  DXF input file.  If you set the Z coordinate of a point group
  1011. to MISSING_Z, only X and Y coordinates will be written for that  point
  1012. when it is output.  See the definition of DROP_Z in "dxfix.dxt" for an
  1013. example of MISSING_Z being used to discard an unwanted  Z  coordinate.
  1014.  
  1015.  
  1016. Structure name execution
  1017. ------------------------
  1018.  
  1019. As each item is read from the input DXF file, DXFIX matches it against
  1020. the  structure  words  (such  as  DXF:ENTITIES:LINE)  defined  in  the
  1021. translation   program.   When  a  match  occurs,  that  definition  is
  1022. executed, allowing it to perform whatever operations  it  wishes  upon
  1023. the current item.  Two kinds of structure names can be specified.  The
  1024. first contains no wild cards or group number and is  triggered  by  an
  1025. entire item in the input; it will be executed only once per item.  The
  1026. second form of structure name does contain wild cards and/or  a  group
  1027. number  or  range  of  group  numbers.  This form of structure name is
  1028. triggered at the individual group level; note that  a  structure  name
  1029. with  a  wild  card and no group range is triggered for EVERY group in
  1030. the item (if you don't want this to happen,  simply  specify  a  group
  1031. code  known  to  appear  only  once in the item, or set SPECIALDONE to
  1032. avert further processing of structure names for the  item).   The  two
  1033. forms  of structure names are executed in different ways as well.  The
  1034. following examples should make the distinctions clear.
  1035.  
  1036.  
  1037. Item level structure names
  1038. --------------------------
  1039.  
  1040. Examples  of  item  level  structure  names  are   DXF:HEADER:$EXTMIN,
  1041. DXF:TABLES:APPID,  and  DXF:ENTITIES:VERTEX.   Each of these denotes a
  1042. definition triggered when  an  object  with  that  sequence  of  names
  1043. appears  in  the  DXF hierarchy.  The test for the presence of an item
  1044. level structure name is extremely fast, as DXFIX knows  at  all  times
  1045. where  it  is  in  the hierarchy and does not need to search a list of
  1046. definitions.
  1047.  
  1048. When an item just read from the input file triggers a structure  name,
  1049. the  definition  for that name is run.  Nothing is placed on the stack
  1050. before executing the definition, and the definition  should  leave  no
  1051. result  on the stack.  Since the definition can examine and manipulate
  1052. the current item  with  the  primitives  provided  for  that  purpose,
  1053. there's no need to pass data on the stack.
  1054.  
  1055. Suppose  we  want to delete the UNITMODE header variable.  This can be
  1056. accomplished with the following definition:
  1057.  
  1058.   : dxf:header:$unitmode
  1059.       1 delitem !
  1060.   ;
  1061.  
  1062. Now when the $UNITMODE item is encountered in the HEADER section, this
  1063. definition will be run.  It stores 1 into the shared variable DELITEM,
  1064. which  causes  DXFIX  not  to  emit  the  item  to  the  output  file,
  1065. accomplishing the objective of the definition.
  1066.  
  1067. Another  example  of  an item level structure name is provided by this
  1068. definition that deletes the Xref information  from  Release  11  block
  1069. definitions:
  1070.  
  1071.   : dxf:blocks:block
  1072.       70 group? if
  1073.           70 group 3 and 70 setgroup
  1074.       then
  1075.       1 delgroup
  1076.       3 delgroup
  1077.   ;
  1078.  
  1079. When  triggered  by  each BLOCK entity in the BLOCKS section (the only
  1080. place they appear), this definition obtains its 70 group flags, clears
  1081. the Xref bits if set, and stores the revised flags using SETGROUP.  It
  1082. then uses DELGROUP twice to delete any 1 and 3 Xref groups present  in
  1083. the BLOCK entity.  Since DELGROUP does nothing if the group is absent,
  1084. the definition need not use  GROUP?   to  test  whether  those  groups
  1085. exist.
  1086.  
  1087.  
  1088. Group level structure names
  1089. ---------------------------
  1090.  
  1091. Group  level  structure  names contain wild card specifications, group
  1092. numbers or ranges, or both.  Group level structure names  are  matched
  1093. and  executed  at  the group level, and are passed the group code that
  1094. triggered them on the stack when invoked.   Examples  of  group  level
  1095. structure  names are DXF:*:*:1000-1100 which is triggered by any group
  1096. with a code between 1000 and 1100, wherever found in the  input  file;
  1097. DXF:TABLES:STYLE:70,  executed  for  the 70 group of each entry in the
  1098. STYLE table  of  the  TABLES  section;  and  DXF:*:TEXT:73,  activated
  1099. whenever a 73 group is encountered in a TEXT item anywhere in the file
  1100. (of course,  TEXT  items  appear  only  in  the  BLOCKS  and  ENTITIES
  1101. sections).
  1102.  
  1103. Checking  for  the  presence  of a group level structure definition is
  1104. somewhat less efficient than determining if an item  level  definition
  1105. exists.   You should use group level names only when you need the wild
  1106. card selection and group identification they provide.
  1107.  
  1108. In translating Release 11 DXF to Release 10, we want to delete all  52
  1109. groups  from  Dimension entities.  These entities can appear in either
  1110. the BLOCKS or the ENTITIES section.  We can accomplish this with:
  1111.  
  1112.   : dxf:*:dimension:52
  1113.       delgroup
  1114.   ;
  1115.  
  1116. Since this is a group level structure name definition, the group  code
  1117. that  invoked  it  (in this case 52) is placed on the top of the stack
  1118. before our definition is executed.  Knowing it's there, we  need  only
  1119. execute DELGROUP to remove the group from all DIMENSION items.
  1120.  
  1121. Actually,  we  want  to  get rid of both 52 and 53 groups in Dimension
  1122. entities.  This requires only our specifying the range of groups:
  1123.  
  1124.   : dxf:*:dimension:52-53
  1125.       delgroup
  1126.   ;
  1127.  
  1128. Again, since the group code  that  triggered  the  structure  name  is
  1129. placed on the stack, the definition does not need to "know" what group
  1130. caused it to be run.
  1131.  
  1132. An extreme example of a group range is provided by a  definition  that
  1133. removes all extended entity data from a DXF file.
  1134.  
  1135.   : dxf:*:*:1000-1100
  1136.       delgroup
  1137.   ;
  1138.  
  1139. Here  we delete all groups between 1000 and 1100 in any section of the
  1140. file.  (We should only find such groups in  the  BLOCKS  and  ENTITIES
  1141. section, but no harm is done by this more general specification.)
  1142.  
  1143. We can do anything we like with groups, not just delete them.  Suppose
  1144. we wished to guarantee that the 4 bit was never set in the 70 group of
  1145. a  Vertex  entity  (it's never supposed to be set anyway, but what the
  1146. heck).  The following definition will  clear  any  erroneously  set  4
  1147. bits.
  1148.  
  1149.   : dxf:*:VERTEX:70
  1150.       group 4 not and
  1151.       70 setgroup
  1152.   ;
  1153.  
  1154. When  this definition is activated, we use the group code on the stack
  1155. to obtain the current value of the field.  We then push the constant 4
  1156. for  the bit we wish to clear and use NOT to complement its bits.  AND
  1157. gives us the value with the 4 bit guaranteed to be off.  We then  push
  1158. the  group  code  of 70 (we could have copied the version on the stack
  1159. originally, but since this definition is only executed for 70  groups,
  1160. using  the  constant  is simpler and faster) and use SETGROUP to store
  1161. the masked value back into the group.
  1162.  
  1163. The only limits on the amount of processing you can do when  triggered
  1164. by a group are your ambition in writing code and your patience waiting
  1165. for it to execute.  Take a gander at the definition of DXF:*:VERTEX:70
  1166. actually  used in "dxfix.dxt" to translate polyface meshes into simple
  1167. entities for an idea of where the deep end begins.
  1168.  
  1169.  
  1170. Layer 3: Structure defining words
  1171. ---------------------------------
  1172.  
  1173. "But hey!", you say, "Those definitions you just showed me don't  look
  1174. anything  like  the  'remove'  and 'ditchgroup' statements you told me
  1175. about that are used in 'dxfix.dxt.'"
  1176.  
  1177. Right you are.  In "dxfix.dxt" we took advantage of one  of  the  most
  1178. powerful  aspects  of  ATLAST  to  make the translation specifications
  1179. compact,  readable,  and  efficient.   ATLAST  allows  you  to  create
  1180. "defining  words"  which  can subsequently be used to declare new data
  1181. types complete with method code to be executed when the data  type  is
  1182. referenced.   If the motive of ATLAST is "every product programmable",
  1183. its means are "every token executable".  When you say "2 3  +"  in  an
  1184. ATLAST  program, you're EXECUTING the literal 2 (in the implementation
  1185. as well as conceptually), which has the effect of  placing  2  on  the
  1186. stack.   You  next  EXECUTE  the literal 3, placing it on top of the 2
  1187. already there.  Finally, you EXECUTE the primitive "+", which adds the
  1188. two numbers and leaves their sum, 5, on the stack.
  1189.  
  1190. Not  only  can you add definitions which are executed just like system
  1191. primitives, you can also define new data types by creating definitions
  1192. called  "defining  words"  that  allocate  and  initialize storage and
  1193. specify a runtime method.  I took advantage of this facility to create
  1194. the REMOVE statement, defined as follows:
  1195.  
  1196.   : remove
  1197.       create
  1198.       does>
  1199.           drop
  1200.           1 delitem !
  1201.   ;
  1202.  
  1203. When you specify:
  1204.  
  1205.   remove dxf:entities:viewport
  1206.  
  1207. you  are actually EXECUTING the definition of REMOVE.  This definition
  1208. performs a CREATE, which causes the next token to be defined an a new,
  1209. executable  definition.   Following  the  CREATE  one can allocate and
  1210. initialize storage for  the  definition  (what  are  called  "instance
  1211. variables"  in  object-land).   This  definition  requires no data, so
  1212. CREATE is followed immediately by DOES>, which introduces  the  method
  1213. to be executed when the new definition is itself executed.  Whenever a
  1214. definition made with CREATE is executed, the address  of  its  storage
  1215. area  (instance  variables)  is passed to it on the stack--how can you
  1216. know what you need to do if you don't know who  you  are?   Since  our
  1217. definition  doesn't  need this address, we discard it with DROP.  That
  1218. taken care of, we need only set DELITEM to  1,  thereby  deleting  the
  1219. current  item,  and we're done.  Recall that REMOVE is declaring a new
  1220. EXECUTABLE word.  When we use it to  declare  a  DXF  structure  name,
  1221. we're  automatically  registering the processing defined by its method
  1222. to be done whenever that word is triggered.  Thus the user can  simply
  1223. write "remove statements", oblivious of the underlying mechanism.
  1224.  
  1225. We  can  exploit  instance  variables  to  create  more  sophisticated
  1226. defining words.  Here is a definition that allows us to AND  arbitrary
  1227. groups in a DXF file with any mask we wish:
  1228.  
  1229.   : maskfield
  1230.       create       (   Define Data Type:    )
  1231.       ,            ( Compile bitmask        )
  1232.       does>        (    Runtime Method:     )
  1233.           over     ( Duplicate group index  )
  1234.           group    ( Extract value of group )
  1235.           swap     ( Bitmask address to top )
  1236.           @        ( Get value of bitmask   )
  1237.           and      ( Mask value of field    )
  1238.           swap     ( Get group code on top  )
  1239.           setgroup ( Update group in item   )
  1240.   ;
  1241.  
  1242. We  can  use  this  definition to clear the 4 bits in Vertex entities,
  1243. rather than the less readable explicit definition we used before:
  1244.  
  1245.   4 not maskfield dxf:*:vertex:70
  1246.  
  1247. When this is executed we push 4 on the stack, invert its bits  to  get
  1248. our  AND  mask,  and  then execute MASKFIELD.  It performs a CREATE to
  1249. define the following token (in this case our structure name), and uses
  1250. the comma primitive to remove the value from the top of the stack (the
  1251. AND mask) and store it in the next instance variable field of the word
  1252. we're defining.
  1253.  
  1254. When DXFIX encounters a 70 group in a Vertex entity in the input file,
  1255. it will push the group code, 70, then  execute  DXF:*:VERTEX:70.   The
  1256. definition  pushes  its  instance variable address and runs the method
  1257. that follows the DOES> in the definition.  That method, in turn, grabs
  1258. the  group  index  from  the second item on the stack (OVER), gets its
  1259. current value (GROUP), moves the instance variable address, where  the
  1260. mask used by this word has been stored to the top of the stack (SWAP),
  1261. loads the mask from that location (@), logically ANDs  the  mask  with
  1262. the  value from the group, moves the group code to the top (SWAP), and
  1263. updates the group in the current item (SETGROUP).
  1264.  
  1265. Once a defining word like this has been created, the user can  use  it
  1266. to  simply  list  the  masks  and  field names to which they should be
  1267. applied without thinking about how it's all really working.
  1268.  
  1269. You can create defining words with  arbitrarily  complicated  methods.
  1270. An  example  is  the  definition  of  TEXTVADJ  in  "dxfix.dxt", which
  1271. declares the special processing of Release 11 text vertical  alignment
  1272. groups.   Since  these  groups  appear  in  three  different  kinds of
  1273. entities (Text,  Attributes,  and  Attribute  Definitions),  and  bear
  1274. different  group  codes in Text and the Attributes, this defining word
  1275. allows concise declaration of where the changes  are  to  be  applied.
  1276.  
  1277.  
  1278. Interposition processing (hooks)
  1279. --------------------------------
  1280.  
  1281. A  translation program can, by defining specified words, interpose its
  1282. own code before processing of the DXF  file  commences,  supplant  the
  1283. standard loop that processes items from the file, and perform closeout
  1284. actions after processing of the file is complete.
  1285.  
  1286.   DXF:START      If DXF:START is defined, it is  executed  before  the
  1287.                  first item is read from the input file.  The INBINARY
  1288.                  and OUTPREC shared variables are  set  based  on  the
  1289.                  properties  of  the  input  file and the command line
  1290.                  arguments.  The DXF:START definition can override the
  1291.                  OUTPREC  setting at this point to, for example, force
  1292.                  an ASCII output file for input  to  AutoCAD  versions
  1293.                  prior to Release 10.
  1294.  
  1295.   DXF:TRANSLATE  If DXF:TRANSLATE is defined, it is invoked instead of
  1296.                  the standard loop that reads  items  from  the  input
  1297.                  file   and   writes  them  to  the  output  file.   A
  1298.                  DXF:TRANSLATE definition that performs the same basic
  1299.                  functions as the standard loop is as follows:
  1300.  
  1301.                    : dxf:translate
  1302.                        begin
  1303.                            readitem while
  1304.                            writeitem drop
  1305.                        repeat
  1306.                    ;
  1307.  
  1308.   DXF:END        If  DXF:END  is defined, it is called after all items
  1309.                  in the DXF file have been processed, just before  the
  1310.                  input  and  output  DXF files are closed.  If the DXF
  1311.                  translation  program  has,   for   example,   created
  1312.                  temporary  files, this is an excellent opportunity to
  1313.                  close and delete them.
  1314.  
  1315.  
  1316. Interactive operation
  1317. ---------------------
  1318.  
  1319. To ease debugging of translation programs, you can  run  DXFIX  in  an
  1320. interactive  mode  where  you're  "talking"  directly  to  the  ATLAST
  1321. interpreter.  If you specify the "-I"  switch  on  the  DXFIX  command
  1322. line,  DXFIX  will pause and display the prompt "->" after opening the
  1323. input file, running the DXF:START definition (if any), and opening the
  1324. output  file.   At  this point you can enter any primitive provided by
  1325. ATLAST or DXFIX or invoke any definition in  the  translation  program
  1326. file.   When  you  enter  an end of file character (CTRL-Z followed by
  1327. RETURN on DOS, CTRL-D on Unix), DXFIX runs the DXF:END definition  (if
  1328. any), closes the input and output files, and exits.
  1329.  
  1330.  
  1331. Summary
  1332. -------
  1333.  
  1334. DXF  files have developed a well-deserved reputation for being easy to
  1335. read but difficult to process.   DXF  has  always  permitted  one,  in
  1336. theory,  to convert all mutually representable objects between any two
  1337. versions of AutoCAD, but the reality of the  process  was  often  much
  1338. more  difficult  and  time consuming than the easily-uttered, "You can
  1339. always edit the DXF..." would lead one to suspect.
  1340.  
  1341. DXFIX meets the immediate  need  for  converting  Release  11  DXF  so
  1342. Release 10 can load it.  With little or no additional development time
  1343. over that required to write a dedicated program for that  task,  DXFIX
  1344. can,  given  proper  specifications,  perform  any  DXF translation or
  1345. modification job that can reasonably be done in a serial scan  of  the
  1346. file.   Inheriting  most  of  its generality and flexibility merely by
  1347. including   ATLAST,  DXFIX  provides  a  textbook  case  of  how  open
  1348. architecture,  programmability,  and  data  driven  organization   can
  1349. expedite  the  development  and  reduce the life cycle costs of even a
  1350. small utility with a modest  charter.   The  implementation  of  DXFIX
  1351. provides  a  worked  example  of  how  ATLAST  can  be applied to more
  1352. ambitious products and projects.
  1353.  
  1354.  
  1355. DXFIX Primitives: Alphabetical Reference
  1356. ----------------------------------------
  1357.  
  1358. ADDGROUP    gcode --        Add group to item
  1359.                             Adds  a  new  group of type "gcode" to the
  1360.                             end of the current item.
  1361.  
  1362. ARGCOUNT          -- n      Command line argument count
  1363.                             Places  the   number   of   command   line
  1364.                             arguments,  including  the zeroth argument
  1365.                             giving the command name, on the stack.
  1366.  
  1367. ARGVALUE        n -- s      Command line argument string
  1368.                             Places the address of a  temporary  string
  1369.                             buffer  "s"  containing  a copy of command
  1370.                             line argument "n" on the stack.  If "n" is
  1371.                             less than zero or greater than ARGCOUNT-1,
  1372.                             0 is returned.
  1373.  
  1374. CLEARITEM         --        Clear current item
  1375.                             All  groups  of  the  current   item   are
  1376.                             deleted.
  1377.  
  1378. DELGROUP    group --        Delete group
  1379.                             The  group  selected by "group" is deleted
  1380.                             from the current item.
  1381.  
  1382. DUMPSPECIAL       --        Dump structure name table
  1383.                             The table of structure names selected  for
  1384.                             special   processing   and   DXF   objects
  1385.                             encountered so far in the file is  printed
  1386.                             on standard output.
  1387.  
  1388. GROUP       group -- value  Group value
  1389.                             The value of the group in the current item
  1390.                             selected by "group" is placed on  the  top
  1391.                             of  the  stack.  The value is stored as an
  1392.                             integer, a floating point value, a  triple
  1393.                             of  floating point values for coordinates,
  1394.                             the address of a temporary string  buffer,
  1395.                             or  the  address  of  a  temporary  string
  1396.                             buffer with a binary chunk length  on  the
  1397.                             top  of the stack depending on the group's
  1398.                             data type.
  1399.  
  1400. GROUP?      group -- flag   Test group present
  1401.                             If the designated "group"  is  present  in
  1402.                             the  current  item -1 is placed on the top
  1403.                             of the stack.  If no such group appears in
  1404.                             the current item, 0 is returned.
  1405.  
  1406. GROUPCOUNT        -- n      Number of groups in item
  1407.                             The  number  of groups in the current item
  1408.                             is placed on the top of the  stack.   This
  1409.                             number can be used in conjunction with the
  1410.                             -(10000 + n) group specification  to  scan
  1411.                             streams  of  extended  entity  data groups
  1412.                             with identical group codes.
  1413.  
  1414. (Added for R13->R12 conversion)
  1415. GROUPCOUNT2 group -- n      Number of particular groups in item
  1416.                             The  number  of particular groups  in  the
  1417.                             current item are placed on the top of  the
  1418.                             stack.
  1419.  
  1420. ITEMPOS           -- n      Current item position
  1421.                             The location in  the  input  DXF  file  at
  1422.                             which  the current item began is placed on
  1423.                             the top of the  stack.   This  is  a  byte
  1424.                             number  if  the  input file is binary or a
  1425.                             line number if it is  ASCII.   Both  bytes
  1426.                             and lines are numbered from zero.
  1427.  
  1428. (Added for R13->R12 conversion)
  1429. ITEMPOS2    group -- n      Current item index in group
  1430.                             The zero based index at which the specified group began
  1431.                             in the current item is placed on the stack. This
  1432.                             is useful, for example, in a Spline entity to
  1433.                             determine where to start requesting the control
  1434.                             point groups (10 groups) using the -(10000 + n)
  1435.                             technique.
  1436.  
  1437. OPTION         s1 -- s2     Command line option
  1438.                             If  a  command  line  specification of the
  1439.                             form "-xspec" is present, where "x" is the
  1440.                             same  as  the  first  character  of string
  1441.                             "s1", compared without  regard  to  letter
  1442.                             case,  "s2"  is returned as a pointer to a
  1443.                             temporary  string  buffer  containing  the
  1444.                             balance  of  the option specification.  If
  1445.                             nothing follows the  option  letter,  "s2"
  1446.                             will  be  a  pointer to a null string.  If
  1447.                             the  option  selected  by  "s1"   is   not
  1448.                             present, 0 is returned.
  1449.  
  1450. PRINTGROUP   group -- file  Print group
  1451.                             The  value of the specified "group" of the
  1452.                             current item is printed on "file".
  1453.  
  1454. PRINTITEM         -- file   Print current item
  1455.                             All groups of the current item are printed
  1456.                             on "file".
  1457.  
  1458. READITEM          -- flag   Read next item
  1459.                             The  next  item from the input DXF file is
  1460.                             read and becomes the current item and  all
  1461.                             processing  specified  by  structure  name
  1462.                             definitions is performed.  If the item was
  1463.                             read  normally, -1 is placed on the top of
  1464.                             the stack; if the end of file  is  reached
  1465.                             or  an  error  is  encountered reading the
  1466.                             item, 0 is returned.
  1467.  
  1468. SETGROUP   value group --   Set group value
  1469.                             The selected "group" is set to the "value"
  1470.                             that  precedes  it on the stack.  The form
  1471.                             of the "value" depends on the group's data
  1472.                             type; see the GROUP primitive for details.
  1473.  
  1474. WRITEITEM         -- flag   Write item
  1475.                             The current item is written to the  output
  1476.                             DXF file unless marked for deletion by the
  1477.                             setting of DELITEM  and/or  DELCITEM.   If
  1478.                             the   item  was  written  successfully  or
  1479.                             deleted, -1 is placed on the stack.  If an
  1480.                             error  occurred  writing  the  item,  0 is
  1481.                             returned.  DELITEM is cleared to zero, and
  1482.                             DELCITEM  is  cleared  if the current item
  1483.                             was a Sequence End.
  1484.  
  1485. (Added for R13->R12 conversion)
  1486. SETUPSPLINE                 Set up parameters for Spline
  1487.                             Called before EVALSPLINE with the
  1488.                             stack shown below. The top stack item
  1489.                             should be 'true'.
  1490.     Kn ... K0 #knots Xm Ym Zm ... X0 Y0 Z0 Wm ... W0 #Weights Order t/f --
  1491.                             Called again after the last call to
  1492.                             EVALSPLINE with one stack item,
  1493.                             'false' to free up memory allocated
  1494.                             during spline evaluation.
  1495.  
  1496. (Added for R13->R12 conversion)
  1497. EVALSPLINE      p -- x y z  Evaluate a Spline for given parameter
  1498.                             Called repeatedly with a floating
  1499.                             point parameter 'p' which usually
  1500.                             varies from the value of the first
  1501.                             knot to the last.
  1502.  
  1503. Known Problems
  1504. --------------
  1505. Under certain memory conditions, DXFIX may freeze while transforming a
  1506. drawing that contains a polyface mesh.  If you experience this problem,
  1507. EXPLODE the mesh before creating the DXF file.  Refer to the section
  1508. earlier in this document, "Exploding polyface meshes".
  1509.  
  1510. Running out of disk space will result in a zero-lenght output
  1511. file.
  1512.  
  1513.  
  1514. AutoCAD is a registered trademark of Autodesk, Inc.
  1515. DXF, DXFIX, and ATLAST are trademarks of Autodesk, Inc.
  1516.