home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Chip 1997 January
/
Chip_1997-01_cd.bin
/
ms95
/
disk21
/
dir03
/
f014320.re_
/
f014320.re
Wrap
Text File
|
1996-04-02
|
15KB
|
436 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. |
| |
+----------------------------------------------------------------------*/
/*----------------------------------------------------------------------+
| |
| $Logfile: J:/mdl/examples/doc/dynamic.mcv $
| $Workfile: dynamic.mc $
| $Revision: 5.3 $
| $Date: 20 Jun 1995 08:49:56 $
| |
+----------------------------------------------------------------------*/
/*----------------------------------------------------------------------+
| |
| dynamic.mc |
| |
| Example program that contains a few MDL commands that illustrate |
| various techniques to use the concept of "simple dynamics". |
| These are not intended to be true application commands (since they |
| have no resource files associated with them and they really do not |
| do sufficient prompting or error checking and reporting). Rather, |
| they are intended to show various aspects of MicroStation's |
| dynamics and how MDL primitive functions interact with same. |
| |
+----------------------------------------------------------------------*/
/*----------------------------------------------------------------------+
| |
| Include Files |
| |
+----------------------------------------------------------------------*/
#include <mselems.h>
#include <global.h>
#include <mdl.h>
#include <tcb.h>
#include <userfnc.h>
/*----------------------------------------------------------------------+
| |
| Private function declarations |
| |
+----------------------------------------------------------------------*/
void moveAnElement();
void placeACell();
/*----------------------------------------------------------------------+
| |
| MOVE EXISTING ELEMENT example |
| |
+----------------------------------------------------------------------*/
/*----------------------------------------------------------------------+
| |
| name getMoveDistance - get distance from anchor point to |
| current point. |
| |
| author BSI 10/90 |
| |
+----------------------------------------------------------------------*/
Private void getMoveDistance
(
Dpoint3d *distance, /* <= distance from anchor */
Dpoint3d *pt /* => current point */
)
{
Dpoint3d anchor;
/*----------------------------------------------------------------------
The element location logic stores the point where the user located the
element in the global variable "statedata.pointstack[0]". We use that
point for our anchor point. Since it is stored in integer world
coordinates we need to convert it to Dpoint3d first.
----------------------------------------------------------------------*/
mdlCnv_IPointToDPoint (&anchor, statedata.pointstack);
/* subtract anchor point from current point to get the distance */
mdlVec_subtractPoint (distance, pt, &anchor);
}
/*----------------------------------------------------------------------+
| |
| name offsetElement - dynamic function for "moveAnElement". |
| |
| author BSI 10/90 |
| |
+----------------------------------------------------------------------*/
Private void offsetElement
(
Dpoint3d *pt /* => current location of cursor */
)
{
Dpoint3d distance;
getMoveDistance (&distance, pt);
mdlElement_offset (dgnBuf, dgnBuf, &distance);
}
/*----------------------------------------------------------------------+
| |
| name elementModify_move - called indirectly for each element |
| to be moved by mdlModify_elementMulti. |
| |
| author BSI 10/90 |
| |
+----------------------------------------------------------------------*/
Private int elementModify_move
(
MSElementUnion *el, /* <> element to be modified */
Dpoint3d *distance /* => from params in mdlModify_element... */
)
{
/* offset the element by specified distance */
if (mdlElement_offset (el, el, distance))
return MODIFY_STATUS_ERROR;
/* indicate that we did something to the element */
return MODIFY_STATUS_REPLACE;
}
/*----------------------------------------------------------------------+
| |
| name moveElement_accept - data point function for |
| "moveAnElement" example. |
| |
| author BSI 10/90 |
| |
+----------------------------------------------------------------------*/
Private void moveElement_accept
(
Dpoint3d *pt /* => final point for move element */
)
{
Dpoint3d distance;
int fileNum, modifyFlags = MODIFY_ORIG;
ULong filePos;
/* Get the distance by which to move each element. */
getMoveDistance (&distance, pt);
/* Get the file position and file number of the element to move. */
filePos = mdlElement_getFilePos (FILEPOS_CURRENT, &fileNum);
/*----------------------------------------------------------------------
If we are using a selection set we want to draw the element(s) in
their new location in their normal color. If we are moving a single
element, we want to draw them in the hilite color.
----------------------------------------------------------------------*/
if (!mdlSelect_isActive())
modifyFlags |= MODIFY_DRAWINHILITE;
/* Now move each element the user accepted. */
mdlModify_elementMulti (fileNum, filePos, MODIFY_REQUEST_HEADERS,
modifyFlags, elementModify_move, &distance, 1);
/* Save new anchor point (the current acceptance point) */
mdlCnv_DPointToIPoint (statedata.pointstack, pt);
/* Reload the dynamic buffer with the new element. */
mdlDynamic_loadElement (NULL, fileNum, filePos);
/* Change the reset function to restart the whole command rather than to
continue to look for additional element about the last data point. */
mdlState_setFunction (STATE_RESET, moveAnElement);
/* See if we were single-shotted, or if we acted upon a selection set
(in which case we don't want to keep performing the same action). */
mdlState_checkSingleShot ();
}
/*----------------------------------------------------------------------+
| |
| name moveAnElement - emulate (almost) the MicroStation |
| "MOVE ELEMENT" commmand. |
| |
| author BSI 10/90 |
| |
+----------------------------------------------------------------------*/
cmdName void moveAnElement
(
void
)
{
/*----------------------------------------------------------------------
Start a "modification" command. This command will use groups
(either selection sets or graphic groups), and requires 2
data points to complete.
----------------------------------------------------------------------*/
mdlState_startModifyCommand (moveAnElement, moveElement_accept,
offsetElement, NULL, NULL, 0, 0, TRUE, 2);
/* initialize the element location logic so that it starts at the
beginning of the file finding all displayable element types */
mdlLocate_init();
}
/*----------------------------------------------------------------------+
| |
| CELL PLACEMENT example |
| |
+----------------------------------------------------------------------*/
Dpoint3d cellOrigin; /* origin of cell to be placed,
set by first data point. */
int cellView; /* view of cell to be placed,
set by first data point. */
/*----------------------------------------------------------------------+
| |
| name getCellTransform - return transformation matrix based |
| on the current view and active scales. |
| |
| author BSI 10/90 |
| |
+----------------------------------------------------------------------*/
Private void getCellTransform
(
Transform *cellTrans, /* <= transformation to be set */
int view /* => view in which to draw cell */
)
{
RotMatrix rMatrix;
/* get the inverse of the rotation matrix for the given view */
mdlRMatrix_fromView (&rMatrix, view, FALSE);
mdlRMatrix_invert (&rMatrix, &rMatrix);
/* convert to a transformation matrix and scale the columns */
mdlTMatrix_fromRMatrix (cellTrans, &rMatrix);
mdlTMatrix_scale (cellTrans, cellTrans, tcb->xactscle, tcb->yactscle,
tcb->zactscle);
}
/*----------------------------------------------------------------------+
| |
| name getCursorAngle - find the angle to rotate the cell |
| for the "placeACell" command. |
| |
| author BSI 8/91 |
| |
+----------------------------------------------------------------------*/
Private double getCursorAngle
(
Dpoint3d *pt /* => current location of cursor */
)
{
double zRotation;
if (pt->x - cellOrigin.x == 0)
zRotation = fc_piover2;
else
zRotation = atan ((pt->y - cellOrigin.y) / (pt->x - cellOrigin.x));
if (pt->x - cellOrigin.x < 0)
zRotation += fc_pi;
return (zRotation);
}
/*----------------------------------------------------------------------+
| |
| name drawRotatingCell - dynamic function for rotating the |
| cell for the "placeACell" command. |
| |
| author BSI 8/91 |
| |
+----------------------------------------------------------------------*/
Private int drawRotatingCell
(
Dpoint3d *pt, /* => current location of cursor */
int view /* => current view */
)
{
Transform tMatrix;
getCellTransform (&tMatrix, cellView);
/* rotate the transformation matrix to current cursor position. */
mdlTMatrix_rotateByAngles (&tMatrix, &tMatrix, fc_zero, fc_zero,
getCursorAngle (pt));
mdlTMatrix_setTranslation (&tMatrix, &cellOrigin);
mdlElement_transform (dgnBuf, dgnBuf, &tMatrix);
}
/*----------------------------------------------------------------------+
| |
| name drawCell - dynamic function for the "placeACell" |
| command. |
| |
| author BSI 10/90 |
| |
+----------------------------------------------------------------------*/
Private int drawCell
(
Dpoint3d *pt, /* => current location of cursor */
int view /* => current view */
)
{
Transform tMatrix;
getCellTransform (&tMatrix, view);
/* rotate the transformation matrix by the active angle */
mdlTMatrix_rotateByAngles (&tMatrix, &tMatrix, fc_zero, fc_zero,
tcb->actangle * fc_piover180);
mdlTMatrix_setTranslation (&tMatrix, pt);
mdlElement_transform (dgnBuf, dgnBuf, &tMatrix);
}
/*----------------------------------------------------------------------+
| |
| name acceptPlaceCell - second data point function for |
| "placeACell". |
| |
| author BSI 10/90 |
| |
+----------------------------------------------------------------------*/
Private void acceptPlaceCell
(
Dpoint3d *pt, /* => final data point */
int view /* => view for same */
)
{
char activeCell[10];
Transform tMatrix;
RotMatrix rMatrix;
getCellTransform (&tMatrix, cellView);
/* rotate the transformation matrix to current cursor position. */
mdlTMatrix_rotateByAngles (&tMatrix, &tMatrix, fc_zero, fc_zero,
getCursorAngle (pt));
mdlRMatrix_fromTMatrix (&rMatrix, &tMatrix);
mdlParams_getActive (activeCell, ACTIVEPARAM_CELLNAME);
mdlCell_placeCell (0L, &cellOrigin, NULL, &rMatrix, NULL, 0, FALSE, 0,
tcb->ext_locks.sharedCells, activeCell);
mdlState_restartCurrentCommand();
}
/*----------------------------------------------------------------------+
| |
| name placeACellPt1 - first data point function for |
| "placeACell". |
| |
| author BSI 8/91 |
| |
+----------------------------------------------------------------------*/
Private void placeACellPt1
(
Dpoint3d *pt, /* => first data point */
int view /* => view for same */
)
{
/* Set the cell origin and view */
cellOrigin = *pt;
cellView = view;
/* Set function to use second data point */
mdlState_setFunction (STATE_DATAPOINT, acceptPlaceCell);
/* establish a new "simple dynamics" function to rotate the cell during
cursor movement */
mdlState_dynamicUpdate (drawRotatingCell, TRUE);
}
/*----------------------------------------------------------------------+
| |
| name restartDefault |
| |
| author BSI 10/90 |
| |
+----------------------------------------------------------------------*/
Private void restartDefault
(
void
)
{
mdlState_startDefaultCommand();
}
/*----------------------------------------------------------------------+
| |
| name placeACell - simple example of how an MDL application can |
| emulate the MicroStation "PLACE CELL ABSOLUTE" |
| command. |
| |
| author BSI 10/90 |
| |
+----------------------------------------------------------------------*/
cmdName void placeACell
(
void
)
{
MSElementDescr *cellDscrP;
char activeCell[10];
mdlState_startPrimitive (placeACellPt1, placeACell, 0, 0);
mdlState_setFunction (STATE_RESET, restartDefault);
/* first get the name of the active cell */
mdlParams_getActive (activeCell, ACTIVEPARAM_CELLNAME);
/* get an element descriptor to hold the active cell (for use with
the dynamic function) */
mdlCell_getElmDscr (&cellDscrP, NULL, 0L, NULL, NULL, NULL, NULL, 0,
tcb->ext_locks.sharedCells, activeCell);
/*----------------------------------------------------------------------
Load the element descriptor into MicroStation's dynamic buffer.
This is the only place in MDL where an application creates an element
descriptor and does not have to free it. Once an element descriptor
is passed to mdlDynamic_setElmDescr, MicroStation owns the descriptor
and will free it when finished with it.
----------------------------------------------------------------------*/
mdlDynamic_setElmDescr (cellDscrP);
/* establish a "simple dynamics" function to draw the cell during cursor
movement */
mdlState_dynamicUpdate (drawCell, TRUE);
}