/* $Header: /mit/crlcad/dxfcvt/RCS/defs.h,v 1.0 90/11/07 14:14:15 phils
 * Exp Locker: phils $ */
#ifndef _DXFCONVERT             /* only once */

#include <stdio.h>
#include <ctype.h>
#include <math.h>
#include <strings.h>
/* #include <malloc.h> */
#ifdef  MSDOS
#include <float.h>
#endif
#include "config.h"

/* define some data structures */
typedef double MATRIX[4][4];

typedef enum {
    ASCII, BINARY
} FileType;

typedef enum {
    INTEGER, FLOAT, STRING
} GroupType;

/* define value data structure for parsing */
typedef struct GROUP {
    int code;                   /* group code */
    GroupType type;             /* type of result */
    int intval;                 /* integer value */
    double fltval;              /* floating number */
    char *strval;               /* string (text) */
} GROUP;

/* define layer data structure */
typedef struct LAYER {
    char *name;                 /* layer name */
    double *point;              /* layer reference point, if any  */
    struct LAYER *next;         /* next layer name in the list */
} LAYER;

/* define data structure for optional properties */
typedef struct OPTIONS {
    int linetypeset;            /* 1 if linetype is set */
    int elevationset;           /* 1 if elevation value is set
                                 * shouldn't occur in a 3d dxf file */
    double elevation;           /* elevation value, if nonzero */
    int thicknessset;           /* 1 if thickness value is set */
    double thickness;           /* thickness vaule, if nonzero */
    int colornumberset;         /* 1 if color number is set */
    int extrusionset;           /* 1 if extrusion value is set */
    double *extrusion;          /* extrusion direction, if not parallel
                                 * to the World Z axis */
} OPTIONS;

/* define general entity data structure */
typedef struct ENTITY {
    int type;                   /* entity type */
    VOID *data;                 /* actual data of the entity */
    LAYER *layer;               /* pointer to its layer name */
    OPTIONS *options;           /* optional parameters */
    struct ENTITY *next;        /* next entity */
} ENTITY;

/* define entity types */
#define ENTITY_NULL     0       /* null, i.e. error */
#define ENTITY_LINE     1       /* line */
#define ENTITY_POINT    2       /* point */
#define ENTITY_CIRCLE   3       /* circle */
#define ENTITY_ARC      4       /* arc */
#define ENTITY_TRACE    5       /* trace */
#define ENTITY_SOLID    6       /* solid */
#define ENTITY_TEXT     7       /* text */
#define ENTITY_SHAPE    8       /* shape */
#define ENTITY_BLOCK    9       /* block, only in BLOCKS section */
#define ENTITY_ENDBLK   10      /* end of block, BLOCKS section only */
#define ENTITY_INSERT   11      /* insert a block */
#define ENTITY_ATTDEF   12      /* attribute definition */
#define ENTITY_ATTRIB   13      /* attributes */
#define ENTITY_POLYLINE 14      /* polyline, very general */
#define ENTITY_VERTEX   15      /* vertex of polyline, only connected
                                 * with polyline */
#define ENTITY_SEQEND   16      /* end of vertex sequence, only with
                                 * polyline */
#define ENTITY_3DLINE   17      /* 3D line, same as line */
#define ENTITY_3DFACE   18      /* 3D face */
#define ENTITY_DIMENSION        19      /* dimension */

/* define (text) attribute data structure (not used now) */
typedef struct ATTRIB {
    double start[3];            /* start point of text */
    double height;              /* text height */
    char *defaulttext;          /* default value of text */
    char *prompt;               /* prompt strval */
    char *tag;                  /* tag strval */
    int attribflag;             /* attribute flags */
    double length;              /* field length, default 0 */
    double rotation;            /* text rotation, default 0 */
    double scale;               /* relative X scale factor, default 1 */
    double angle;               /* obliquing angle, default 0 */
    char *style;                /* text style name, default STANDARD */
    int generationflag;         /* text generation flags, default 0 */
    int justificationtype;      /* text justification type, default 0 */
    double alignment[3];        /* aligment point, only if text
                                 * justification type is present and
                                 * nonzero */
    OPTIONS *options;           /* optional parameters */
} ATTRIB;

/* define block data structure */
typedef struct BLOCK {
    char *name;                 /* block name */
    int flag;                   /* block type flags */
    double basepoint[3];        /* block base points */
    ENTITY *entitylist;         /* list of entities in the block */
    ATTRIB *attrib;             /* attributes of the block, if any */
    LAYER *layerlist;           /* layers defined in the block */
    OPTIONS *options;           /* optional parameters */
    struct BLOCK *next;         /* next block in the list */
} BLOCK;

/* define attribute flags (bit-coded) */

#define ATTRIB_INVISIBLE        1       /* attribute is invisible (does
                                         * not display */
#define ATTRIB_CONSTANT         2       /* a constant attribute */
#define ATTRIB_VERIFICATION     4       /* verification is required on
                                         * input of this attribute */
#define ATTRIB_PRESET           8       /* attribute is preset no
                                         * prompt during insertion */

/* define vertex data structure */
typedef struct VERTEX {
    double point[3];            /* location of the vertex */
    int startwidthset;          /* if starting width is present */
    double startwidth;          /* starting width, default is defined
                                 * by POLYLINE */
    int endwidthset;            /* if ending width is present */
    double endwidth;            /* ending width, default is defined by
                                 * POLYLINE */
    double bulge;               /* bulge, what is its meaning ? */
    int vertexflag;             /* vertex flag (bit-coded) */
    double fittangentset;       /* if the fittangent is present */
    double fittangent;          /* curve fit tangent direction */
    OPTIONS *options;           /* optional parameters */
} VERTEX;

/* define data structure for tesselation of a polyline */
typedef struct SEGMENT {
    double point[3];            /* starting point of the segment ending
                                 * point in the next segment */
    double plusoffset[3];       /* point offset in "outer" direction */
    double minusoffset[3];      /* point offset in "inner" */
} SEGMENT;


/* define vertex flags (bit-coded) */
#define VERTEX_EXTRA            1       /* extra vertex created by
                                         * curve fitting */
#define VERTEX_TANGENT          2       /* curve fit tangent defined
                                         * for this vertex. a curve fit
                                         * tangent direction of 0 may
                                         * be omitted from the DXF
                                         * output, but is significant
                                         * if this bit is set */
#define VERTEX_UNUSED           4       /* unused (never set in DXF
                                         * files */

#define VERTEX_SPLINE           8       /* spline vertex created by
                                         * spline  fitting */
#define VERTEX_CONTROL          16      /* spline frame control point */

#define VERTEX_POLYGON          32      /* 3D POLYLINE vertex */

#define VERTEX_MESH             64      /* 3D POLYLINE mesh vertex */

/* define data structure for block insertion */
typedef struct INSERT {
    int attribflag;             /* attributes follow flag, default 0 */
    char *blockname;            /* block name used when the block has
                                 * not defined yet during parsing  will
                                 * be freed later during output, if the
                                 * block is really defined */
    BLOCK *block;               /* pointer to the block */
    double point[3];            /* insertion point */
    double xscale;              /* X scale factor, default 1 */
    double yscale;              /* Y scale factor, default 1 */
    double zscale;              /* Z scale factor, default 1 */
    double angle;               /* rotation angle, default 0 */
    int columncount;            /* repeat column counts, default 1 */
    double columnspace;         /* repeat column spacing, default 0 */
    int rowcount;               /* repeat row counts, default 1 */
    double rowspace;            /* repeat column spacing, default 0 */
} INSERT;

/* define stack data structure for block handling */
typedef struct STACK {
    INSERT *insert;             /* current insert block */
    MATRIX singlematrix[2];     /* a pair of current transformation
                                 * matrix defined by the insert block */
    MATRIX matrix[2];           /* a pair of transformation matrics
                                 * defined by multiply all matrics of
                                 * insert blocks */
} STACK;

/* define max stack level */
#define MaxStackLevel           64

/* define object name data structure, for output only */
typedef struct NAME {
    char *name;                 /* object name, maybe a layer name,
                                 * block name + layer name */
    struct NAME *next;          /* next name */
} NAME;

/* define process function for entities */
typedef struct ENTITYPROCS {
    int type;                   /* entity type */
    ENTITY *(*dxfparse) ();     /* DXF parsing function returning an
                                 * entity pointer */
    VOID (*crloutput)();        /* function for output of CRL file */
    VOID (*defoutput)();        /* function for output of DEF file */
    VOID (*nffoutput)();        /* function for output of NFF file */
    VOID (*dxfoutput)();        /* function for output of DXF file */
} ENTITYPROCS;

/* define constants for circle/arc tesselation */
#define DefaultMinCircleRadius  10.0
#define MinCircleTesselation    12
#define MaxCircleTesselation    360

/* define some basic constants and macros */
#define TRUE    1
#define FALSE   0
#define TOE     1.0e-10         /* tolerance error */
#ifndef M_PI
#define M_PI    3.1415926535
#endif

#ifdef  MSDOS
#ifndef DBL_MAX
#define DBL_MAX 1.0e+38
#endif
#ifndef HUGE
#define HUGE    DBL_MAX
#endif
#endif

#ifndef MAXdouble
#define MAXdouble        HUGE
#endif

#define Malloc(typename, n) ((typename*)Alloc(sizeof(typename) * (n)))
#define Bcopy(a,b,c)    bcopy((char*)(a), (char*)(b), (int)(c))
#define max(x,y)        ((x) > (y) ? (x) : (y))
#define min(x,y)        ((x) < (y) ? (x) : (y))
#define signof(a)       ((a) >= 0 ? 1 : (-1))

/* define macro for converting of angles between degrees and radius */
#define DEG_TO_RAD(x)   ((double) (x) * M_PI / 180.0)
#define RAD_TO_DEG(x)   ((double) (x) * 180.0 / M_PI)

#ifdef notdef
/* define macros for vector operation */
#define VecCopy(a,b)    ((b)[0] = (a)[0], (b)[1] = (a)[1],\
                         (b)[2] = (a)[2])

#define VecScale(s,a,b)  ((b)[0] = (s) * (a)[0], (b)[1] = (s) * (a)[1],\
                         (b)[2] = (s) * (a)[2])

#define VecAdd(a,b,c)    ((c)[0] = (a)[0] + (b)[0],\
                         (c)[1] = (a)[1] + (b)[1],\
                         (c)[2] = (a)[2] + (b)[2])

#define VecSub(a,b,c)    ((c)[0] = (a)[0] - (b)[0],\
                         (c)[1] = (a)[1] - (b)[1],\
                         (c)[2] = (a)[2] - (b)[2])

#define VecDot(a,b)      (double) ((a)[0] * (b)[0] +\
                         (a)[1] * (b)[1] +\
                         (a)[2] * (b)[2])

#define VecNegate(a, b)  ((b)[0] = - (a)[0], (b)[1] = - (a)[1],\
                         (b)[2] = - (a)[2])

#define VecAddS(s,a,b,c) ((c)[0] = (s) * (a)[0] +(b)[0],\
                         (c)[1] = (s) * (a)[1] +(b)[1],\
                         (c)[2] = (s) * (a)[2] +(b)[2])

#define VecCross(a,b,c)  ((c)[0] = (a)[1] * (b)[2] -(a)[2] * (b)[1],\
                         (c)[1] = (a)[2] * (b)[0] -(a)[0] * (b)[2],\
                         (c)[2] = (a)[0] * (b)[1] -(a)[1] * (b)[0])

#define VecLength(s)     sqrt(VecDot((s), (s)))
#endif

/* define output file types */
#define FILE_CRL		0		/* for CRL file */
#define FILE_DEF        1       /* for DEF file used by Radiosity */
#define FILE_NFF        2       /* for NFF file used by Raytracing */
#define FILE_DXF        3       /* for exploded (3DFACE) DXF file */

/* define global GetNextGroup function */
#define GetNextGroup()  (*GlobalGetNextGroup) ()

#include "extern.h"
#include "function.h"

#define         _DXFCONVERT
#endif
/*** end defs.h ***/
