home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The World of Computer Software
/
World_Of_Computer_Software-02-385-Vol-1of3.iso
/
i
/
iritsm3s.zip
/
poly3d
/
postscrp.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-01-02
|
6KB
|
194 lines
/*****************************************************************************
* Module to handle PostScript output. *
* *
* Written by: Gershon Elber Ver 1.0, Apr. 1990 *
*****************************************************************************/
#ifdef __MSDOS__
#include <sys\types.h>
#else
#include <sys/types.h>
#endif
#include <stdio.h>
#include <string.h>
#include <time.h>
#include "program.h"
#include "genmat.h"
#include "interact.h"
#include "graphgen.h"
static FILE *PSFile = NULL; /* Used to save PostScript text file. */
static void (* SavedMoveToPtr)(RealType Coord[3]);
static void (* SavedDrawToPtr)(RealType Coord[3]);
static void PSMoveTo(RealType Coord[3]);
static void PSDrawTo(RealType Coord[3]);
/*****************************************************************************
* Routine to save the current view as PostScript text file. *
* Although this routine dumps EPSF-1.2 compatible code, it still dumps *
* the 'showpage' command. The 'showpage' is allowed by the EPSF document and *
* it is the responsibility of the including program to disable showpage. *
*****************************************************************************/
void SavePostScript(IPObjectStruct *Objects)
{
int i;
time_t time1970 = time(NULL);
char *p, FileName[PATH_NAME_LEN];
static char FileCount = '0';
static char *PSHeader[] = {
"%!PS-Adobe-2.0 EPSF-1.2",
"%%BoundingBox: 36 108 540 612", /* 7x7 inches, LL at [0.5, 1.5]. */
"%%Title:",
"%%Creator: Poly3d",
"%%CreationDate:",
"%%EndComments",
"",
"gsave",
"",
"72 72 scale", /* First scale to inches, se we can speak in inches. */
"4.0 5.0 translate", /* To Center of image area. */
"3.5 3.5 scale", /* Make the universe -1..1 on both X and Y. */
"",
"/line {",
" newpath",
" moveto",
" lineto",
" stroke",
"} def",
"",
"/setdashline {",
" [0.012 0.024] 0 setdash",
"} def",
"",
"/setfullline {",
" [] 0 setdash",
"} def",
"",
"0.006 setlinewidth", /* Set some default line attributes. */
"1 setlinecap",
"1 setlinejoin",
"setfullline",
"",
NULL
};
static char *PSTrailer[] = {
"",
"showpage",
"grestore",
NULL
};
strcpy(FileName, GENERIC_PS_FILE);
if ((p = strchr(FileName, '#')) != NULL) {
*p = FileCount;
if (FileCount++ == '9') FileCount = '0';
}
if ((PSFile = fopen(FileName, "wt")) == NULL) {
GGTone(700, 200);
return;
}
for (i = 0; PSHeader[i] != NULL; i++) {
if (strcmp(PSHeader[i], "%%Title:") == 0)
fprintf(PSFile, "%s %s\n", PSHeader[i], GlblFirstDataFileName);
else if (strcmp(PSHeader[i], "%%CreationDate:") == 0)
fprintf(PSFile, "%s %s", PSHeader[i], ctime(&time1970));
else
fprintf(PSFile, "%s\n", PSHeader[i]);
}
SavedMoveToPtr = MoveToPtr;
SavedDrawToPtr = DrawToPtr;
MoveToPtr = PSMoveTo;
DrawToPtr = PSDrawTo;
DrawAllObjects(Objects);
MoveToPtr = SavedMoveToPtr;
DrawToPtr = SavedDrawToPtr;
for (i = 0; PSTrailer[i] != NULL; i++)
fprintf(PSFile, "%s\n", PSTrailer[i]);
fclose(PSFile);
}
static RealType LastCoord[3]; /* Used to store last point we moved/draw to. */
/*****************************************************************************
* Routine to mave to 3D point given as Coord[3], using Mat transform. *
*****************************************************************************/
static void PSMoveTo(RealType Coord[3])
{
MultVecby4by4(LastCoord, Coord, CrntViewMat); /* Set last point coord. */
}
/*****************************************************************************
* Routine to draw to 3D point given as Coord[3], using Mat transform, from *
* the last point we moved to. *
*****************************************************************************/
static void PSDrawTo(RealType Coord[3])
{
static DashState = FALSE;
RealType NewCoord[3], MiddleCoord[3], t;
MultVecby4by4(NewCoord, Coord, CrntViewMat); /* Set last point coord. */
if (GlblClosedObject && NewCoord[2] < LastCoord[2]) {
GEN_COPY(LastCoord, NewCoord, 3 * sizeof(RealType));
return;
}
/* Implementation of simple depth cue - if line is >Z or <Z ... */
if (LastCoord[2] <= 0.0 && NewCoord[2] <= 0.0) {
if (GlblDepthCue && !DashState) {
fprintf(PSFile, "setdashline\n");
DashState = TRUE;
}
fprintf(PSFile, "%10.7lf %10.7lf ", LastCoord[0], LastCoord[1]);
fprintf(PSFile, "%10.7lf %10.7lf line\n", NewCoord[0], NewCoord[1]);
}
else if (LastCoord[2] >= 0.0 && NewCoord[2] >= 0.0 ||
ABS(LastCoord[2] - NewCoord[2]) < EPSILON) {
if (GlblDepthCue && DashState) {
fprintf(PSFile, "setfullline\n");
DashState = FALSE;
}
fprintf(PSFile, "%10.7lf %10.7lf ", LastCoord[0], LastCoord[1]);
fprintf(PSFile, "%10.7lf %10.7lf line\n", NewCoord[0], NewCoord[1]);
}
else { /* Line intersect Z = 0 plane. */
t = LastCoord[2] / (LastCoord[2] - NewCoord[2]);
MiddleCoord[0] = LastCoord[0] * (1.0 - t) + NewCoord[0] * t;
MiddleCoord[1] = LastCoord[1] * (1.0 - t) + NewCoord[1] * t;
if (GlblDepthCue && DashState) {
fprintf(PSFile, "setfullline\n");
DashState = FALSE;
}
if (LastCoord[2] > 0.0) {
fprintf(PSFile, "%10.7lf %10.7lf ", LastCoord[0], LastCoord[1]);
fprintf(PSFile, "%10.7lf %10.7lf line\n", MiddleCoord[0], MiddleCoord[1]);
}
else {
fprintf(PSFile, "%10.7lf %10.7lf ", MiddleCoord[0], MiddleCoord[1]);
fprintf(PSFile, "%10.7lf %10.7lf line\n", NewCoord[0], NewCoord[1]);
}
if (GlblDepthCue && !DashState) {
fprintf(PSFile, "setdashline\n");
DashState = TRUE;
}
if (LastCoord[2] < 0.0) {
fprintf(PSFile, "%10.7lf %10.7lf ", LastCoord[0], LastCoord[1]);
fprintf(PSFile, "%10.7lf %10.7lf line\n", MiddleCoord[0], MiddleCoord[1]);
}
else {
fprintf(PSFile, "%10.7lf %10.7lf ", MiddleCoord[0], MiddleCoord[1]);
fprintf(PSFile, "%10.7lf %10.7lf line\n", NewCoord[0], NewCoord[1]);
}
}
GEN_COPY(LastCoord, NewCoord, 3 * sizeof(RealType)); /* Current point. */
}