Files
energy_storage/libs/pvb/include/pvserver/dxf.h

416 lines
13 KiB
C
Raw Normal View History

/*====================================================================
This software was written by Ian L. Kaplan, Chief Fat Bear, Bear Products
International. Use of this software, for any purpose, is granted on two
conditions:
1. This copyright notice must be included with the software
or any software derived from it.
2. The risk of using this software is accepted by the user. No
warranty as to its usefulness or functionality is provided
or implied. The author and Bear Products International provides
no support.
====================================================================*/
#ifndef DXF2GL_H
#define DXF2GL_H
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
// These rather convoluted ifndef's are required because both FALSE, TRUE
// and BOOLEAN are defined by various windows and windows/nt headers. When
// these headers are included, a redefine error results without these ifndefs.
//
typedef enum {
#ifndef FALSE
FALSE = 0,
#endif
#ifndef TRUE
TRUE = 1,
#endif
BOGUS
} BoolVals;
#ifndef _WIN32
typedef int BOOLEAN;
#endif
/* FileAccess - a class for opening and reading ASCII files.
Public functions:
FileAccess constructor - The argument to this constructor is
the file name. The constructor will
open the file and set the variable
FileOpenOK (which can be accessed via
FileOK).
FileAccess destructor - Close the file
get_line - get a line for the file and return it as a null
terminated string.
*/
class FileAccess {
// Variables
private:
FILE *FilePtr;
BOOLEAN FileOpenOK;
protected:
public:
// Class Functions
private:
//OpenFile(char *FileName);
void file_error(const char *msg);
protected:
public:
FileAccess(const char *FileName = "" );
~FileAccess(void);
BOOLEAN FileOK(void) { return FileOpenOK; }
BOOLEAN get_line(char *LineBuf, const int BufSize);
}; // FileAccess
/*
The page_pool object is designed to support rapid memory allocation
and deallocation of all allocated memory, once the object is no
longer needed. By using a block allocation scheme, the overhead of
memory allocation is greatly reduced, compared to "malloc" (or new).
Deallocation of large blocks of memory is also much faster than
calling free for every allocated block of memory.
The page_pool allocator allocates blocks of memory in "page_size"
increments. The page_size variable is set at start-up and contains
the system virtual memory page size.
The page_pool object contains the virtual function "add_to_list"
which can be implemented by the inherited function
ordered_list. Ordered list is a class that supports ordered list
insertion and deletion. In this case, this is used to support an
ordered list of free memory blocks. The ordered list is only
needed if the page_pool is used as the base for a memory allocater
that can allocate from a free list.
*/
class page_pool {
private: // typedefs and variables
typedef struct page_chain_struct
{ void *block;
unsigned int bytes_used;
unsigned int block_size;
page_chain_struct *next_page;
} page_chain;
// The min_block_size is the smallest block that will be returned by the
// page_pool allocater. The max_block_size is the largest memory block
// that can be requested. Ideally, this should be a multiple of the page
// size.
typedef enum { min_block_size = 96, max_block_size = 1024 * 8 } bogus;
page_chain *page_list_head;
page_chain *current_page;
static unsigned int page_size; // system page size, shared by all instances
private: // class functions
static unsigned int GetSysPageSize(void);
page_chain *new_block( unsigned int block_size );
void *add_block( unsigned int block_size );
public: // class functions
page_pool(void);
~page_pool(void);
void *page_alloc( unsigned int block_size );
void print_page_pool_info(void);
virtual void add_to_list(void *addr, unsigned int size);
}; // class page_pool
/*
A 3D graphic object can be described as a list of polygons. Each
of these polygons consists of three or more points in 3D space
(e.g., x, y, z coordinates).
The FaceList object will construct a list of polygon faces read from
a DXF file. Two DXF file polygon formats are supported:
- 3DFACE
- POLYLINE
The "face" structure member "f" is a pointer to an array of points.
This point array is dynamically allocated. The minimum number of
points that can be allocated for a polygon is four (a 3DFACE polygon
may only consist of three points, in which case the last point is
unused).
Although during creating there is a distinction made between DXF
3DFACE objects and POLYLINE objects, the class represents both as
polygon faces and no such distinction exists when the polygon
list is read.
The object supplies the following public functions for creating a
polygon list:
add_3DFACE_point - Add a 3D point to a 3DFACE polygon
add_poly_point - Add a 3D point to a POLYLINE polygon
get_new_3DFACE - Create a new 3DFACE polygon
get_new_poly_face - Create a new POLYLINE polygon
Once the polygon list is created, it can be read using the following
functions:
GetListStart - Return a handle for the start of the polygon face
list
GetFace - Get a polygon face, given a list handle
GetNextFace - Get the next polygon face in the list
*/
class FaceList {
public:
typedef enum {MinSize = 4} bogus; // minimum number of points
typedef enum {Xcoord, Ycoord, Zcoord} bogus2;
typedef struct { float v[3]; } vect; // a point in the 3D plane
typedef struct { vect *f; // an array of 3D points
int point_cnt; // number of points currently alloc'ed
int point_max; // max points
} face;
typedef void *ListHandle;
private:
typedef struct FaceListStruct { face cur_face;
struct FaceListStruct *next_face;
} FaceElem;
page_pool mem;
FaceElem *ListHead;
FaceElem *ListTail;
private:
void add_point(face *cur_face, float x, float y, float z);
// void GrowFace( face *cur_face );
public:
FaceList(void) { ListHead = NULL;
ListTail = NULL;
}
void add_3DFACE_point(float x, float y, float z );
void add_poly_point(float x, float y, float z);
void get_new_3DFACE(void);
void get_new_poly_face(int polypont);
ListHandle GetListStart(void) { return (ListHandle)ListHead; }
face *GetFace( ListHandle handle)
{ return &((FaceElem *)handle)->cur_face; }
ListHandle GetNextFace( ListHandle handle )
{ return (ListHandle)((FaceElem *)handle)->next_face; }
void print(void);
};
//
// The gl_token enumeration defines the tokens that are returned by the
// scanner and are used by the parser in attempting to recognize the
// components of a DXF file.
//
typedef enum { bad_gl_token,
section,
header,
endsec,
seqend,
blocks,
block,
endblk,
vertex,
tables,
table,
layer,
contin,
endtab,
entities,
three_d_face,
end_of_file,
polyline,
integer,
real,
name,
last_gl_token } gl_token;
/*
This file contains the stack object definition. The scanner
requires two token look ahead to resolve things like the EOF token
sequence. If this sequence is checked for, but not found, it is
necessary to "back up" the input stream. This is done via the token
stack.
Note that a DXF file may contain both integer and float values.
Two versions of "push_token" are implemented, one with an integer
value and one with a float value. The integer version may be used
with just a token value, in which case the default value will be
used for the integer.
*/
class token_stack {
public:
typedef union { int intval;
float realval;
} token_union;
typedef struct { gl_token token;
token_union val;
} token_stack_type;
private:
typedef enum {MaxTokens = 10} bogus1;
token_stack_type token_stack_buf[ MaxTokens ];
int token_sp;
public:
token_stack(void) { token_sp = MaxTokens; }
BOOLEAN StackHasItems(void) { return token_sp < MaxTokens; }
void push_token( gl_token token, int intval = 0 );
void push_token( gl_token token, float realval );
token_stack_type pop_token(void);
};
/*
This file contains the scanner object that tokenizes the input
stream. The scanner either returns a reserved word (e.g., section
or three_d_face), "name" (an identifier, such as a layer name or
face name), integer or real. The various DXF markers (e.g., the 70
marker or 0 for start) are returned as integers. This scanner is
designed as a front end for a program that reads a DXF file and
displays it as a 3D wire frame, using openGL (hense then "GL"
naming).
Scanning and parsing a DXF file is difficult, because the DXF file
format seems to have grown over time in an ad hoc manner. Further,
the documentation is obscure and/or incomplete. While parsing the
file, it is sometimes necessary to "back up". To support this, a
stack is maintained. Input tokens and values can be "pushed" onto
this stack and re-read. The token_stack class supports this feature.
*/
class GL_scanner {
// variables
private:
token_stack stack;
float gl_float;
int gl_int;
FileAccess *MyFileObj;
typedef enum {WordBufSize = 40} bogus2;
char WordBuf[ WordBufSize ];
protected:
public:
// class functions
private:
gl_token scan_number(char *cptr);
gl_token scan_word(char *cptr);
gl_token gl_name_lookup(void);
protected:
public:
GL_scanner( FileAccess *FileObj ) { MyFileObj = FileObj; }
float get_gl_float() { return gl_float; }
int get_gl_int() { return gl_int; }
char *get_gl_name() { return WordBuf; }
gl_token get_next_token(void);
BOOLEAN token_in_stack(void) { return stack.StackHasItems(); }
gl_token get_token_from_stack();
void put_token_in_stack(const gl_token token);
void put_token_in_stack(const gl_token token, int DX_val)
{ stack.push_token(token, DX_val); }
void print_token(const gl_token token);
};
/* This file contains the parser object that processes the DXF file.
The class function GL_GetFaceList returns the Face list for the
3D DXF object.
*/
class MinMax {
private:
float min;
float max;
public:
typedef enum {MAXVAL = 1024*1000} bogus;
// The initial values of max and min should be way beyond any reasonable
// range.
MinMax(void) { min = (float)MAXVAL; max = (float)(-(MAXVAL)); }
void SetMinMax( float val ) { if (val < min)
min = val;
if (val > max)
max = val;
}
float GetMin(void) { return min; }
float GetMax(void) { return max; }
};
class GL_object {
// variables
private:
GL_scanner *GL_scan;
protected:
public:
MinMax PointRange;
// class functions
private:
void set_min_max();
void undo(gl_token token);
BOOLEAN IsEndSec(void);
BOOLEAN IsStart(void);
BOOLEAN IsName(void);
BOOLEAN IsTable(void);
BOOLEAN IsLayerName(void);
BOOLEAN Is3DFace(void);
BOOLEAN IsEndSet(void);
float GetCoord(void);
void get_3DFACE_point(FaceList *FaceObjPtr);
void get_poly_point(FaceList *FaceObjPtr);
void SkipSection(void);
void Get3DFACE(FaceList *&CurObj);
void GetPolyLine(FaceList *&CurObj);
protected:
public:
GL_object(FileAccess *FileObj ) { GL_scan = new GL_scanner( FileObj ); };
~GL_object(void) { delete GL_scan; }
FaceList *GL_GetFaceList(void);
}; // GL_object
typedef enum { DXF_start = 0,
DXF_textval = 1,
DXF_name = 2,
DXF_othername1 = 3,
DXF_othername2 = 4,
DXF_entity_handle = 5,
DXF_line_type = 6,
DXF_text_style = 7,
DXF_layer_name = 8,
DXF_var_name = 9,
DXF_primary_X = 10,
DXF_other_X_1 = 11,
DXF_primary_Y = 20,
DXF_other_Y_1 = 21,
DXF_other_Z = 31,
DXF_elevation = 38,
DXF_thickness = 39,
DXF_floatvals = 40,
DXF_repeat = 49,
DXF_angle1 = 50, DXF_angle2 = 51,
DXF_angle3 = 52, DXF_angle4 = 53,
DXF_angle5 = 54, DXF_angle6 = 55,
DXF_angle7 = 56, DXF_angle8 = 57,
DXF_angle9 = 58,
DXF_colornum = 62,
DXF_entities_flg = 66,
DXF_ent_ident = 67,
DXF_SeventyFlag = 70,
DXF_SeventyOneFlag= 71,
DXF_SeventyTwoFlag= 72,
DXF_view_state = 69,
DXF_comment = 999 } DXF_values;
#endif