home *** CD-ROM | disk | FTP | other *** search
/ Chip 1997 January / Chip_1997-01_cd.bin / ms95 / disk21 / dir03 / f014320.re_ / f014320.re
Text File  |  1996-04-02  |  15KB  |  436 lines

  1. /*----------------------------------------------------------------------+
  2. |                                    |
  3. |  Copyright (1995) Bentley Systems, Inc., All rights reserved.        |
  4. |                                    |
  5. |  "MicroStation" is a registered trademark and "MDL" and "MicroCSL"    |
  6. |  are trademarks of Bentley Systems, Inc.                    |
  7. |                                    |
  8. |  Limited permission is hereby granted to reproduce and modify this    |
  9. |  copyrighted material provided that the resulting code is used only     |
  10. |  in conjunction with Bentley Systems products under the terms of the    |
  11. |  license agreement provided therein, and that this notice is retained    |
  12. |  in its entirety in any such reproduction or modification.        |
  13. |                                    |
  14. +----------------------------------------------------------------------*/
  15. /*----------------------------------------------------------------------+
  16. |                                    |
  17. |    $Logfile:   J:/mdl/examples/doc/dynamic.mcv  $
  18. |   $Workfile:   dynamic.mc  $
  19. |   $Revision:   5.3  $
  20. |       $Date:   20 Jun 1995 08:49:56  $
  21. |                                    |
  22. +----------------------------------------------------------------------*/
  23. /*----------------------------------------------------------------------+
  24. |                                    |
  25. |  dynamic.mc                                |
  26. |                                    |
  27. |  Example program that contains a few MDL commands that illustrate    |
  28. |  various techniques to use the concept of "simple dynamics".        |
  29. |  These are not intended to be true application commands (since they    |
  30. |  have no resource files associated with them and they really do not    |
  31. |  do sufficient prompting or error checking and reporting). Rather,    |
  32. |  they are intended to show various aspects of MicroStation's        |
  33. |  dynamics and how MDL primitive functions interact with same.        |
  34. |                                    |
  35. +----------------------------------------------------------------------*/
  36. /*----------------------------------------------------------------------+
  37. |                                    |
  38. |   Include Files                               |
  39. |                                    |
  40. +----------------------------------------------------------------------*/
  41. #include    <mselems.h>
  42. #include    <global.h>
  43. #include    <mdl.h>
  44. #include    <tcb.h>
  45. #include    <userfnc.h>
  46.     
  47. /*----------------------------------------------------------------------+
  48. |                                    |
  49. |   Private function declarations                    |
  50. |                                    |
  51. +----------------------------------------------------------------------*/
  52. void    moveAnElement();
  53. void    placeACell();
  54.  
  55. /*----------------------------------------------------------------------+
  56. |                                    |
  57. |    MOVE EXISTING ELEMENT example                    |
  58. |                                    |
  59. +----------------------------------------------------------------------*/
  60. /*----------------------------------------------------------------------+
  61. |                                    |
  62. | name        getMoveDistance    - get distance from anchor point to     |
  63. |            current point.                    |
  64. |                                    |
  65. | author    BSI                     10/90        |
  66. |                                    |
  67. +----------------------------------------------------------------------*/
  68. Private void    getMoveDistance
  69. (
  70. Dpoint3d    *distance,        /* <= distance from anchor */
  71. Dpoint3d    *pt            /* => current point */
  72. )
  73.     {
  74.     Dpoint3d    anchor;
  75.  
  76.     /*----------------------------------------------------------------------
  77.       The element location logic stores the point where the user located the
  78.       element in the global variable "statedata.pointstack[0]". We use that 
  79.       point for our anchor point. Since it is stored in integer world 
  80.       coordinates we need to convert it to Dpoint3d first.
  81.       ----------------------------------------------------------------------*/
  82.     mdlCnv_IPointToDPoint (&anchor, statedata.pointstack);
  83.     
  84.     /* subtract anchor point from current point to get the distance */
  85.     mdlVec_subtractPoint (distance, pt, &anchor);
  86.     }
  87.  
  88. /*----------------------------------------------------------------------+
  89. |                                    |
  90. | name        offsetElement - dynamic function for "moveAnElement".   |
  91. |                                    |
  92. | author    BSI                     10/90        |
  93. |                                    |
  94. +----------------------------------------------------------------------*/
  95. Private void    offsetElement
  96. (   
  97. Dpoint3d    *pt        /* => current location of cursor */
  98. )
  99.     {
  100.     Dpoint3d    distance;
  101.     
  102.     getMoveDistance (&distance, pt);
  103.     mdlElement_offset (dgnBuf, dgnBuf, &distance);
  104.     }
  105.     
  106. /*----------------------------------------------------------------------+
  107. |                                    |
  108. | name        elementModify_move - called indirectly for each element    |
  109. |               to be moved by mdlModify_elementMulti.        |
  110. |                                    |
  111. | author    BSI                     10/90        |
  112. |                                    |
  113. +----------------------------------------------------------------------*/
  114. Private int    elementModify_move
  115. (
  116. MSElementUnion    *el,        /* <> element to be modified */
  117. Dpoint3d    *distance    /* => from params in mdlModify_element... */
  118. )
  119.     {
  120.     /* offset the element by specified distance */
  121.     if (mdlElement_offset (el, el, distance))
  122.     return    MODIFY_STATUS_ERROR;
  123.     
  124.     /* indicate that we did something to the element */
  125.     return  MODIFY_STATUS_REPLACE;
  126.     }
  127.     
  128. /*----------------------------------------------------------------------+
  129. |                                    |
  130. | name        moveElement_accept - data point function for        |
  131. |               "moveAnElement" example.            |
  132. |                                    |
  133. | author    BSI                     10/90        |
  134. |                                    |
  135. +----------------------------------------------------------------------*/
  136. Private void    moveElement_accept
  137. (
  138. Dpoint3d    *pt        /* => final point for move element */
  139. )
  140.     {
  141.     Dpoint3d    distance;
  142.     int        fileNum, modifyFlags = MODIFY_ORIG;
  143.     ULong    filePos;
  144.  
  145.     /* Get the distance by which to move each element. */
  146.     getMoveDistance (&distance, pt);
  147.  
  148.     /* Get the file position and file number of the element to move. */
  149.     filePos = mdlElement_getFilePos (FILEPOS_CURRENT, &fileNum);
  150.  
  151.     /*----------------------------------------------------------------------
  152.       If we are using a selection set we want to draw the element(s) in 
  153.       their new location in their normal color. If we are moving a single
  154.       element, we want to draw them in the hilite color.
  155.       ----------------------------------------------------------------------*/
  156.     if (!mdlSelect_isActive())
  157.     modifyFlags |= MODIFY_DRAWINHILITE;
  158.  
  159.     /* Now move each element the user accepted. */
  160.     mdlModify_elementMulti (fileNum, filePos, MODIFY_REQUEST_HEADERS,
  161.                 modifyFlags, elementModify_move, &distance, 1);
  162.  
  163.     /* Save new anchor point (the current acceptance point) */
  164.     mdlCnv_DPointToIPoint (statedata.pointstack, pt);
  165.  
  166.     /* Reload the dynamic buffer with the new element. */
  167.     mdlDynamic_loadElement (NULL, fileNum, filePos);
  168.     
  169.     /* Change the reset function to restart the whole command rather than to
  170.        continue to look for additional element about the last data point. */
  171.     mdlState_setFunction (STATE_RESET, moveAnElement);
  172.     
  173.     /* See if we were single-shotted, or if we acted upon a selection set 
  174.        (in which case we don't want to keep performing the same action). */
  175.     mdlState_checkSingleShot ();
  176.     }
  177.  
  178. /*----------------------------------------------------------------------+
  179. |                                    |
  180. | name        moveAnElement - emulate (almost) the MicroStation    |
  181. |               "MOVE ELEMENT" commmand.                |
  182. |                                    |
  183. | author    BSI                     10/90        |
  184. |                                    |
  185. +----------------------------------------------------------------------*/
  186. cmdName    void    moveAnElement
  187. (
  188. void
  189. )
  190.     {
  191.     /*----------------------------------------------------------------------
  192.       Start a "modification" command. This command will use groups 
  193.       (either selection sets or graphic groups), and requires 2
  194.       data points to complete.
  195.       ----------------------------------------------------------------------*/
  196.     mdlState_startModifyCommand (moveAnElement, moveElement_accept, 
  197.         offsetElement, NULL, NULL, 0, 0, TRUE, 2);
  198.  
  199.     /* initialize the element location logic so that it starts at the
  200.        beginning of the file finding all displayable element types */
  201.     mdlLocate_init();
  202.     }
  203.  
  204.  
  205. /*----------------------------------------------------------------------+
  206. |                                    |
  207. |    CELL PLACEMENT example                      |
  208. |                                    |
  209. +----------------------------------------------------------------------*/
  210.  
  211. Dpoint3d    cellOrigin;    /* origin of cell to be placed, 
  212.                     set by first data point. */
  213. int        cellView;    /* view of cell to be placed,
  214.                     set by first data point. */
  215.  
  216. /*----------------------------------------------------------------------+
  217. |                                    |
  218. | name        getCellTransform - return transformation matrix based   |
  219. |               on the current view and active scales.        |
  220. |                                    |
  221. | author    BSI                     10/90        |
  222. |                                    |
  223. +----------------------------------------------------------------------*/
  224. Private void    getCellTransform
  225. (
  226. Transform   *cellTrans,        /* <= transformation to be set */
  227. int        view        /* => view in which to draw cell */
  228. )
  229.     {
  230.     RotMatrix    rMatrix;
  231.  
  232.     /* get the inverse of the rotation matrix for the given view */
  233.     mdlRMatrix_fromView (&rMatrix, view, FALSE);
  234.     mdlRMatrix_invert (&rMatrix, &rMatrix);
  235.     
  236.     /* convert to a transformation matrix and scale the columns */
  237.     mdlTMatrix_fromRMatrix (cellTrans, &rMatrix);
  238.     mdlTMatrix_scale (cellTrans, cellTrans, tcb->xactscle, tcb->yactscle,
  239.         tcb->zactscle);
  240.     }
  241.     
  242. /*----------------------------------------------------------------------+
  243. |                                    |
  244. | name        getCursorAngle - find the angle to rotate the cell    |
  245. |            for the "placeACell" command.            |
  246. |                                    |
  247. | author    BSI                     8/91        |
  248. |                                    |
  249. +----------------------------------------------------------------------*/
  250. Private double    getCursorAngle
  251. (
  252. Dpoint3d    *pt        /* => current location of cursor */
  253. )
  254.     {
  255.     double  zRotation;
  256.     
  257.     if (pt->x - cellOrigin.x == 0)
  258.     zRotation = fc_piover2;
  259.     else
  260.     zRotation = atan ((pt->y - cellOrigin.y) / (pt->x - cellOrigin.x));
  261.                 
  262.     if (pt->x - cellOrigin.x < 0)
  263.     zRotation += fc_pi;
  264.     
  265.     return (zRotation);
  266.     }
  267.     
  268. /*----------------------------------------------------------------------+
  269. |                                    |
  270. | name        drawRotatingCell - dynamic function for rotating the    |
  271. |            cell for the "placeACell" command.        |
  272. |                                    |
  273. | author    BSI                     8/91        |
  274. |                                    |
  275. +----------------------------------------------------------------------*/
  276. Private int    drawRotatingCell
  277. (
  278. Dpoint3d    *pt,        /* => current location of cursor */
  279. int        view        /* => current view */
  280. )
  281.     {
  282.     Transform    tMatrix;
  283.  
  284.     getCellTransform (&tMatrix, cellView);
  285.  
  286.     /* rotate the transformation matrix to current cursor position. */
  287.     mdlTMatrix_rotateByAngles (&tMatrix, &tMatrix, fc_zero, fc_zero, 
  288.                 getCursorAngle (pt));
  289.  
  290.     mdlTMatrix_setTranslation (&tMatrix, &cellOrigin);
  291.     mdlElement_transform (dgnBuf, dgnBuf, &tMatrix);
  292.     }
  293.     
  294. /*----------------------------------------------------------------------+
  295. |                                    |
  296. | name        drawCell - dynamic function for the "placeACell"    |
  297. |            command.                    |
  298. |                                    |
  299. | author    BSI                     10/90        |
  300. |                                    |
  301. +----------------------------------------------------------------------*/
  302. Private int    drawCell
  303. (
  304. Dpoint3d    *pt,        /* => current location of cursor */
  305. int        view        /* => current view */
  306. )
  307.     {
  308.     Transform    tMatrix;
  309.  
  310.     getCellTransform (&tMatrix, view);
  311.  
  312.     /* rotate the transformation matrix by the active angle */
  313.     mdlTMatrix_rotateByAngles (&tMatrix, &tMatrix, fc_zero, fc_zero, 
  314.         tcb->actangle * fc_piover180);
  315.  
  316.     mdlTMatrix_setTranslation (&tMatrix, pt);
  317.     mdlElement_transform (dgnBuf, dgnBuf, &tMatrix);
  318.     }
  319.     
  320. /*----------------------------------------------------------------------+
  321. |                                    |
  322. | name        acceptPlaceCell - second data point function for    |
  323. |            "placeACell".                    |
  324. |                                    |
  325. | author    BSI                     10/90        |
  326. |                                    |
  327. +----------------------------------------------------------------------*/
  328. Private void    acceptPlaceCell
  329. (
  330. Dpoint3d    *pt,        /* => final data point */
  331. int        view        /* => view for same */
  332. )
  333.     {
  334.     char    activeCell[10];
  335.     Transform    tMatrix;
  336.     RotMatrix    rMatrix;
  337.     
  338.     getCellTransform (&tMatrix, cellView);
  339.  
  340.     /* rotate the transformation matrix to current cursor position. */
  341.     mdlTMatrix_rotateByAngles (&tMatrix, &tMatrix, fc_zero, fc_zero, 
  342.                 getCursorAngle (pt));
  343.  
  344.     mdlRMatrix_fromTMatrix (&rMatrix, &tMatrix);
  345.     
  346.     mdlParams_getActive (activeCell, ACTIVEPARAM_CELLNAME);
  347.     mdlCell_placeCell (0L, &cellOrigin, NULL, &rMatrix, NULL, 0, FALSE, 0,
  348.         tcb->ext_locks.sharedCells, activeCell);
  349.     
  350.     mdlState_restartCurrentCommand();
  351.     }
  352.     
  353. /*----------------------------------------------------------------------+
  354. |                                    |
  355. | name        placeACellPt1 - first data point function for        |
  356. |            "placeACell".                    |
  357. |                                    |
  358. | author    BSI                     8/91        |
  359. |                                    |
  360. +----------------------------------------------------------------------*/
  361. Private void    placeACellPt1
  362. (
  363. Dpoint3d    *pt,        /* => first data point */
  364. int        view        /* => view for same */
  365. )
  366.     {
  367.     /* Set the cell origin and view */
  368.     cellOrigin = *pt;
  369.     cellView = view;
  370.     
  371.     /* Set function to use second data point */
  372.     mdlState_setFunction (STATE_DATAPOINT, acceptPlaceCell);
  373.     
  374.     /* establish a new "simple dynamics" function to rotate the cell during
  375.     cursor    movement */
  376.     mdlState_dynamicUpdate (drawRotatingCell, TRUE);
  377.     }
  378.     
  379. /*----------------------------------------------------------------------+
  380. |                                    |
  381. | name        restartDefault                        |
  382. |                                    |
  383. | author    BSI                     10/90        |
  384. |                                    |
  385. +----------------------------------------------------------------------*/
  386. Private void    restartDefault
  387. (
  388. void    
  389. )
  390.     {
  391.     mdlState_startDefaultCommand();
  392.     }
  393.     
  394. /*----------------------------------------------------------------------+
  395. |                                    |
  396. | name      placeACell - simple example of how an MDL application can    |
  397. |                emulate the MicroStation "PLACE CELL ABSOLUTE"    |
  398. |                command.                    |
  399. |                                    |
  400. | author    BSI                    10/90            |
  401. |                                    |
  402. +----------------------------------------------------------------------*/
  403. cmdName    void    placeACell
  404. (
  405. void 
  406. )
  407.     {
  408.     MSElementDescr  *cellDscrP;
  409.     char        activeCell[10];
  410.  
  411.     mdlState_startPrimitive (placeACellPt1, placeACell, 0, 0);
  412.     mdlState_setFunction (STATE_RESET, restartDefault);
  413.     
  414.     /* first get the name of the active cell */
  415.     mdlParams_getActive (activeCell, ACTIVEPARAM_CELLNAME);
  416.     
  417.     /* get an element descriptor to hold the active cell (for use with 
  418.         the dynamic function) */
  419.     mdlCell_getElmDscr (&cellDscrP, NULL, 0L, NULL, NULL, NULL, NULL, 0,
  420.             tcb->ext_locks.sharedCells, activeCell);
  421.     
  422.     /*----------------------------------------------------------------------
  423.       Load the element descriptor into MicroStation's dynamic buffer. 
  424.       This is the only place in MDL where an application creates an element 
  425.       descriptor and does not have to free it. Once an element descriptor 
  426.       is passed to mdlDynamic_setElmDescr, MicroStation owns the descriptor 
  427.       and will free it when finished with it.
  428.       ----------------------------------------------------------------------*/
  429.     mdlDynamic_setElmDescr (cellDscrP);
  430.     
  431.     /* establish a "simple dynamics" function to draw the cell during cursor
  432.     movement */
  433.     mdlState_dynamicUpdate (drawCell, TRUE);
  434.     }
  435.  
  436.