home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Chip 1997 January
/
Chip_1997-01_cd.bin
/
ms95
/
disk21
/
dir03
/
f016570.re_
/
f016570.re
Wrap
Text File
|
1996-04-02
|
18KB
|
607 lines
/*----------------------------------------------------------------------+
| |
| Copyright (1995) Bentley Systems, Inc., All rights reserved. |
| |
| "MicroStation" is a registered trademark and "MDL" and "MicroCSL" |
| are trademarks of Bentley Systems, Inc. |
| |
| Limited permission is hereby granted to reproduce and modify this |
| copyrighted material provided that the resulting code is used only |
| in conjunction with Bentley Systems products under the terms of the |
| license agreement provided therein, and that this notice is retained |
| in its entirety in any such reproduction or modification. |
| |
+----------------------------------------------------------------------*/
/*----------------------------------------------------------------------+
| |
| $Workfile: autoplot.mc $
| $Revision: 1.6 $
| $Date: 09 Aug 1995 11:55:40 $
| |
+----------------------------------------------------------------------*/
/*----------------------------------------------------------------------+
| |
| Function - |
| |
| autoplot.mc - example to illustrate the technique for generating a |
| plot without using the MicroStation plot dialog |
| |
| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
| |
| Public Routine Summary - |
| |
| |
+----------------------------------------------------------------------*/
/*----------------------------------------------------------------------+
| |
| Include Files |
| |
+----------------------------------------------------------------------*/
#include <mdl.h>
#include <msdefs.h>
#include <tcb.h>
#include <rscdefs.h>
#include <pltstrct.h>
#include <string.h>
#include <stdlib.h>
#include "autoplot.h"
#include "aplotcmd.h"
#include <msrsrc.fdf>
#include <msfile.fdf>
#include <msdialog.fdf>
#include <msoutput.fdf>
#include <msview.fdf>
#include <msparse.fdf>
#include <msplot.fdf>
#include <mstmatrx.fdf>
#include <msrmatrx.fdf>
#include <mscnv.fdf>
/*----------------------------------------------------------------------+
| |
| Local defines |
| |
+----------------------------------------------------------------------*/
#define USE_DEFAULT_SIZE 0
#define USE_SCALE 1
#define USE_X_SIZE 2
#define USE_Y_SIZE 3
#define USE_MAXIMUM_SIZE 4
#define CCW_ROTATE 0
#define CW_ROTATE 1
#define NO_ROTATE 2
#define ERROR_BAD_PLTCFG 1
#define ERROR_BAD_PAPERSIZE 2
#define ERROR_INVALID_VIEW_PARAMS 3
#define ERROR_INVALID_PAPER_PARAMS 4
/*----------------------------------------------------------------------+
| |
| name cvtUpoint3dToDpoint3d |
| |
| author BSI 6/91 |
| |
+----------------------------------------------------------------------*/
Private void cvtUpoint3dToDpoint3d
(
Dpoint3d *dPnt, /* <= */
Upoint3d *uPnt /* => */
)
{
dPnt->x = (double) uPnt->x;
dPnt->y = (double) uPnt->y;
dPnt->z = (double) uPnt->z;
}
/*----------------------------------------------------------------------+
| |
| name swapDoubles |
| |
| author BSI 6/91 |
| |
+----------------------------------------------------------------------*/
Private void swapDoubles
(
double *a,
double *b
)
{
double temp;
temp = *a;
*a = *b;
*b = temp;
}
/*----------------------------------------------------------------------+
| |
| name findPaperSize |
| |
| author BSI 6/91 |
| |
+----------------------------------------------------------------------*/
Private int findPaperSize
(
char *pageName
)
{
int i;
Plot_spec *pSpec = &plotStat->plotSpec;
strupr (pageName);
for (i=0; i < plotStat->plotter.num_papsz; i++)
{
if (strcmp (pageName, plotStat->plotter.size[i].name) == 0)
{
pSpec->paper_num = i;
pSpec->paper_size = plotStat->plotter.size[i].num;
pSpec->manual_origin = plotStat->plotter.size[i].manual_origin;
return SUCCESS;
}
}
return ERROR;
}
/*----------------------------------------------------------------------+
| |
| name calculateFenceBounds |
| |
| author BSI 6/91 |
| |
+----------------------------------------------------------------------*/
Private int calculateFenceBounds
(
Point3d *origin,
Dpoint3d *delta
)
{
int i;
double activeZ;
Dpoint3d viewOrigin, viewDelta, fenpts[101], fencelow, fencehigh;
RotMatrix rMatrix;
if (tcb->fence == 0)
return ERROR;
plotStat->plotView = tcb->fenvw;
mdlView_getParameters (&viewOrigin, NULL, &viewDelta, &rMatrix, &activeZ,
tcb->fenvw);
mdlRMatrix_rotatePoint (&viewOrigin, &rMatrix);
for (i = 0; i < tcb->fence; i++)
{
if (tcb->ndices == 3)
{
fenpts[i].x = (double) tcb->fenpts[i].x + viewOrigin.x;
fenpts[i].y = (double) tcb->fenpts[i].y + viewOrigin.y;
fenpts[i].z = activeZ;
}
else
{
fenpts[i].x = (double) tcb->fenpts[i].x;
fenpts[i].y = (double) tcb->fenpts[i].y;
fenpts[i].z = fc_zero;
mdlRMatrix_rotatePoint (&fenpts[i], &rMatrix);
}
}
/* find the extents (highest and lowest coordinates) of the fence */
fencelow = fencehigh = fenpts[0];
for (i = 1; i < tcb->fence; i++)
{
if (fenpts[i].x < fencelow.x)
fencelow.x = fenpts[i].x;
if (fenpts[i].y < fencelow.y)
fencelow.y = fenpts[i].y;
if (fenpts[i].x > fencehigh.x)
fencehigh.x = fenpts[i].x;
if (fenpts[i].y > fencehigh.y)
fencehigh.y = fenpts[i].y;
}
/* set the extents */
delta->x = fencehigh.x - fencelow.x;
delta->y = fencehigh.y - fencelow.y;
delta->z = viewDelta.z;
/* set the origin */
fencelow.z = viewOrigin.z;
mdlRMatrix_unrotatePoint (&fencelow, &rMatrix);
mdlCnv_DPointToIPoint (origin, &fencelow);
return SUCCESS;
}
/*----------------------------------------------------------------------+
| |
| name setPlotViewParameters |
| |
| author BSI 6/91 |
| |
+----------------------------------------------------------------------*/
Private int setPlotViewParameters
(
Plot_spec *pSpec,
int viewNumber,
int useFence
)
{
if (useFence)
{
if (calculateFenceBounds (&pSpec->origin, &pSpec->delta) != SUCCESS)
return ERROR;
}
else
{
plotStat->plotView = viewNumber;
pSpec->origin = tcb->view[viewNumber].origin;
cvtUpoint3dToDpoint3d (&pSpec->delta, &tcb->view[viewNumber].delta);
}
return SUCCESS;
}
/*----------------------------------------------------------------------+
| |
| name setPlotPaperParameters |
| |
| author BSI 6/91 |
| |
+----------------------------------------------------------------------*/
Private int setPlotPaperParameters
(
Plot_spec *pSpec,
double param,
int useFlag
)
{
double maxScale, uorsPerMast, h_center, v_center;
double point_000001 = .000001, point_00005 = .00005;
Dpaper_pnt paperMax, paperSize, plotSize, plotMin;
Dpoint2d maxSize;
Pltr_papsz *currSize;
/* get # of UORS per master unit */
uorsPerMast = tcb->subpermast * tcb->uorpersub;
/* If manual origin or maximizing, eliminate user offsets */
if (useFlag == USE_DEFAULT_SIZE || pSpec->manual_origin)
{
pSpec->user_off.h = fc_zero;
pSpec->user_off.v = fc_zero;
}
currSize = &plotStat->plotter.size[pSpec->paper_num];
paperMax.h = (currSize->bound.h + currSize->offset.h) /
plotStat->plotter.resolution.h;
paperMax.v = (currSize->bound.v + currSize->offset.v) /
plotStat->plotter.resolution.v;
paperSize.h = currSize->bound.h / plotStat->plotter.resolution.h;
paperSize.v = currSize->bound.v / plotStat->plotter.resolution.v;
/* Calculate the absolute maximums for the paper size */
maxSize.x = currSize->bound.h;
maxSize.y = currSize->bound.v;
/* See if we should rotate the plot */
if (useFlag == USE_DEFAULT_SIZE && !pSpec->rotate &&
(plotStat->plotter.rotate_direction != NO_ROTATE))
{
if ((pSpec->delta.x < pSpec->delta.y) ^ (paperSize.h < paperSize.v))
pSpec->rotate = TRUE;
else
pSpec->rotate = FALSE;
}
/* If the image is to be rotated, rotate the extents */
if (pSpec->rotate)
swapDoubles (&pSpec->delta.x, &pSpec->delta.y);
if (pSpec->delta.x / maxSize.x > pSpec->delta.y / maxSize.y)
maxSize.y = pSpec->delta.y * (maxSize.x / pSpec->delta.x);
else
maxSize.x = pSpec->delta.x * (maxSize.y / pSpec->delta.y);
maxScale = ((pSpec->delta.x / uorsPerMast) / maxSize.x);
switch (useFlag)
{
case USE_DEFAULT_SIZE:
if (plotStat->plotter.def_scale &&
(plotStat->plotter.scalefctr > (maxScale - point_00005)))
{
pSpec->scale = plotStat->plotter.scalefctr;
break;
}
case USE_MAXIMUM_SIZE:
pSpec->scale = maxScale;
break;
case USE_SCALE:
pSpec->scale = param;
if (pSpec->scale < maxScale - point_00005)
return ERROR;
if (pSpec->scale < maxScale)
pSpec->scale = maxScale;
if (pSpec->scale * uorsPerMast < point_000001)
return ERROR;
break;
case USE_X_SIZE:
pSpec->size.x = param;
if (pSpec->size.x > maxSize.x + point_00005)
return ERROR;
if (pSpec->size.x > maxSize.x)
pSpec->size.x = maxSize.x;
pSpec->scale = (pSpec->delta.x / uorsPerMast) / pSpec->size.x;
break;
case USE_Y_SIZE:
pSpec->size.y = param;
if (pSpec->size.y > maxSize.y + point_00005)
return ERROR;
if (pSpec->size.y > maxSize.y)
pSpec->size.y = maxSize.y;
pSpec->scale = (pSpec->delta.y / uorsPerMast) / pSpec->size.y;
break;
}
/* Calculate the size of the plot */
pSpec->size.x = (pSpec->delta.x / uorsPerMast) / pSpec->scale;
pSpec->size.y = (pSpec->delta.y / uorsPerMast) / pSpec->scale;
/* Get the size of the plot in each direction */
plotSize.h = pSpec->size.x / plotStat->plotter.resolution.h;
plotSize.v = pSpec->size.y / plotStat->plotter.resolution.v;
/* Should we "auto-center" */
if ((useFlag == USE_DEFAULT_SIZE || useFlag == USE_MAXIMUM_SIZE)
&& plotStat->plotter.auto_center && !pSpec->manual_origin)
{
h_center = (paperSize.h - plotSize.h) / fc_2;
v_center = (paperSize.v - plotSize.v) / fc_2;
if (h_center < fc_zero)
h_center = fc_zero;
if (v_center < fc_zero)
v_center = fc_zero;
pSpec->user_off.h = (h_center * plotStat->plotter.resolution.h);
pSpec->user_off.v = (v_center * plotStat->plotter.resolution.v);
}
plotMin.h = (currSize->offset.h + pSpec->user_off.h) /
plotStat->plotter.resolution.h;
plotMin.v = (currSize->offset.v + pSpec->user_off.v) /
plotStat->plotter.resolution.v;
/*
* It's necessary to truncate here instead of rounding, since
* we sometimes exceed the p1 and p2 pts set for the plotter's range.
*/
pSpec->p1.h = (long) plotMin.h;
pSpec->p2.h = (long) (plotMin.h + plotSize.h);
pSpec->p1.v = (long) plotMin.v;
pSpec->p2.v = (long) (plotMin.v + plotSize.v);
if ((pSpec->p2.h > mdlCnv_roundDoubleToLong (paperMax.h + fc_p001)) ||
(pSpec->p2.v > mdlCnv_roundDoubleToLong (paperMax.v + fc_p001)))
return ERROR;
if (pSpec->size.x <= fc_zero || pSpec->size.y <= fc_zero)
return ERROR;
/* Calculate the paper coordinates for the lower left and
upper right corners of the area being plotted. */
pSpec->ll = pSpec->p1;
pSpec->ur = pSpec->p2;
mdlTMatrix_getIdentity (&pSpec->trans);
if (pSpec->rotate)
{
double angle;
Dpoint3d offset;
pSpec->ll.h = pSpec->p1.v;
pSpec->ll.v = pSpec->p1.h;
pSpec->ur.h = pSpec->p2.v;
pSpec->ur.v = pSpec->p2.h;
memset (&offset, 0, sizeof(offset));
if (plotStat->plotter.rotate_direction == CCW_ROTATE)
{
angle = fc_piover2;
offset.x = 2*pSpec->p1.h + plotSize.h;
}
else
{
angle = -fc_piover2;
offset.y = 2*pSpec->p1.v + plotSize.v;
}
mdlTMatrix_rotateByAngles (&pSpec->trans, NULL, fc_zero, fc_zero,
angle);
mdlTMatrix_setTranslation (&pSpec->trans, &offset);
}
return SUCCESS;
}
/*----------------------------------------------------------------------+
| |
| name setPlotParameters |
| |
| author BSI 6/91 |
| |
+----------------------------------------------------------------------*/
Private int setPlotParameters
(
char *pageName,
char *plotFileName,
int viewNumber,
int rotate,
int useFence,
int useFlag,
double param
)
{
Plot_spec *pSpec = &plotStat->plotSpec;
/* first find the paper size by name */
if (findPaperSize (pageName) != SUCCESS)
return ERROR_BAD_PAPERSIZE;
pSpec->pf_fence = useFence;
pSpec->rotate = rotate;
/* set viewing extents */
if (setPlotViewParameters (pSpec, viewNumber, useFence) != SUCCESS)
return ERROR_INVALID_VIEW_PARAMS;
/* set values that relate to size and location of the plot on the page */
if (setPlotPaperParameters (pSpec, param, useFlag) != SUCCESS)
return ERROR_INVALID_PAPER_PARAMS;
/* set plotfile name */
mdlFile_find (plotStat->plotSpec.file_name, plotFileName,
"MS_PLTFILES", plotStat->plotter.defExtension);
return SUCCESS;
}
/*----------------------------------------------------------------------+
| |
| name doAutoPlot |
| |
| author BSI 6/91 |
| |
+----------------------------------------------------------------------*/
Private void doAutoPlot
(
void
)
{
char configName[MAXFILELENGTH], plotFileName[MAXFILELENGTH];
char pageName[128];
int viewNumber, rotate, useFence, useFlag, status;
double param;
Plot_spec *pSpec;
/* read the current plotter configuration file */
configName[0] = '\0';
if (mdlPlot_getInfo (plotStat, configName) != SUCCESS)
{
mdlOutput_rscPrintf (MSG_ERROR, NULL, MESSAGELISTID_Messages,
ERRID_ConfigFile);
tcb->relerr = ERROR_BAD_PLTCFG;
return;
}
/* get the parameters from the user command */
viewNumber = tcb->uc_r[0];
rotate = tcb->uc_r[1];
useFence = tcb->uc_r[2];
useFlag = tcb->uc_r[3];
param = tcb->uc_a[0];
/* get the page name from C0 */
memset (pageName, 0, sizeof(pageName));
strncpy (pageName, tcb->uc_c[0].c, tcb->uc_c[0].len);
/* get the border comment from C1 */
pSpec = &plotStat->plotSpec;
memset (pSpec->bdr_comment, 0, sizeof(pSpec->bdr_comment));
strncpy (pSpec->bdr_comment, tcb->uc_c[1].c, tcb->uc_c[1].len);
/* get name of plot file from C2 */
memset (plotFileName, 0, sizeof(plotFileName));
strncpy (plotFileName, tcb->uc_c[2].c, tcb->uc_c[2].len);
/* fill in the plotStat structure */
if ((status = setPlotParameters (pageName, plotFileName, viewNumber,
rotate, useFence, useFlag, param)) != SUCCESS)
{
/* something bad happened, tell user command */
tcb->relerr = status;
return;
}
/* generate the actual plot */
mdlPlot_execute ();
/* indicate successful plot */
tcb->relerr = 0;
}
/*----------------------------------------------------------------------+
| |
| name autoPlot |
| |
| author BSI 6/91 |
| |
+----------------------------------------------------------------------*/
Private void autoPlot
(
void
) cmdNumber CMD_AUTOPLOT
{
char configName[MAXFILELENGTH];
PlotStatic *holdPlotStat;
/*------------------------------------------------------------------+
Due to V5.5 plotting changes, the memory for MicroStation's
plotStat global variable may be allocated prior to this command
running. Therefore, we must save the pointer to this memory
area, and restore the pointer when we are finished processing.
The plot dialog box in V5.5 is non-modal and could be present on
the screen (using the plotStat variable) when this command is
executed. This command must not deallocate the memory which
was allocated by MicroStation's plotting application.
+------------------------------------------------------------------*/
holdPlotStat = plotStat;
/* allocate memory for plot static structure (make sure there is
no way to exit without freeing this memory) */
plotStat = (PlotStatic *) malloc (sizeof(PlotStatic));
/* generate the plot */
doAutoPlot ();
/* free plot static structure */
free (plotStat);
/* restore the original pointer to plotStat global variable */
plotStat = holdPlotStat;
}
/*----------------------------------------------------------------------+
| |
| name main |
| |
| author BSI 6/91 |
| |
+----------------------------------------------------------------------*/
Public int main
(
void
)
{
RscFileHandle rfHandle;
/* Open our file for access to command table and dialog */
mdlResource_openFile (&rfHandle, NULL, FALSE);
/* Load the command table */
if (mdlParse_loadCommandTable (NULL) == NULL)
mdlOutput_rscPrintf (MSG_ERROR, NULL, MESSAGELISTID_Messages,
ERRID_CommandTable);
return 0;
}