home *** CD-ROM | disk | FTP | other *** search
/ Chip 1997 January / Chip_1997-01_cd.bin / ms95 / disk21 / dir03 / f016570.re_ / f016570.re
Text File  |  1996-04-02  |  18KB  |  607 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. |   $Workfile:   autoplot.mc  $
  18. |   $Revision:   1.6  $
  19. |       $Date:   09 Aug 1995 11:55:40  $
  20. |                                    |
  21. +----------------------------------------------------------------------*/
  22. /*----------------------------------------------------------------------+
  23. |                                    |
  24. |   Function -                                |
  25. |                                    |
  26. |   autoplot.mc - example to illustrate the technique for generating a    |
  27. |            plot without using the MicroStation plot dialog    |
  28. |                                    |
  29. |    - - - - - - - - - - - - - - - - - - - - - - - - - - - - -    |
  30. |                                    |
  31. |   Public Routine Summary -                        |
  32. |                                    |
  33. |                                    |
  34. +----------------------------------------------------------------------*/
  35. /*----------------------------------------------------------------------+
  36. |                                    |
  37. |   Include Files                               |
  38. |                                    |
  39. +----------------------------------------------------------------------*/
  40. #include    <mdl.h>
  41. #include    <msdefs.h>
  42. #include    <tcb.h>
  43. #include    <rscdefs.h>
  44. #include    <pltstrct.h>
  45. #include    <string.h>
  46. #include    <stdlib.h>
  47.  
  48. #include    "autoplot.h"
  49. #include    "aplotcmd.h"
  50.  
  51. #include    <msrsrc.fdf>
  52. #include    <msfile.fdf>
  53. #include    <msdialog.fdf>
  54. #include    <msoutput.fdf>
  55. #include    <msview.fdf>
  56. #include    <msparse.fdf>
  57. #include    <msplot.fdf>
  58. #include    <mstmatrx.fdf>
  59. #include    <msrmatrx.fdf>
  60. #include    <mscnv.fdf>
  61.  
  62. /*----------------------------------------------------------------------+
  63. |                                    |
  64. |   Local defines                            |
  65. |                                    |
  66. +----------------------------------------------------------------------*/
  67. #define    USE_DEFAULT_SIZE    0
  68. #define    USE_SCALE        1
  69. #define USE_X_SIZE        2
  70. #define USE_Y_SIZE        3
  71. #define    USE_MAXIMUM_SIZE    4
  72.  
  73. #define CCW_ROTATE        0
  74. #define CW_ROTATE        1
  75. #define NO_ROTATE        2
  76.  
  77. #define ERROR_BAD_PLTCFG        1
  78. #define    ERROR_BAD_PAPERSIZE        2
  79. #define ERROR_INVALID_VIEW_PARAMS   3
  80. #define    ERROR_INVALID_PAPER_PARAMS  4
  81.  
  82. /*----------------------------------------------------------------------+
  83. |                                    |
  84. | name        cvtUpoint3dToDpoint3d                    |
  85. |                                    |
  86. | author    BSI                     6/91        |
  87. |                                    |
  88. +----------------------------------------------------------------------*/
  89. Private void    cvtUpoint3dToDpoint3d
  90. (
  91. Dpoint3d    *dPnt,            /* <= */
  92. Upoint3d    *uPnt            /* => */
  93. )
  94.     {
  95.     dPnt->x = (double) uPnt->x;
  96.     dPnt->y = (double) uPnt->y;
  97.     dPnt->z = (double) uPnt->z;
  98.     }
  99.  
  100. /*----------------------------------------------------------------------+
  101. |                                    |
  102. | name        swapDoubles                        |
  103. |                                    |
  104. | author    BSI                     6/91        |
  105. |                                    |
  106. +----------------------------------------------------------------------*/
  107. Private void    swapDoubles
  108. (
  109. double        *a,
  110. double        *b
  111. )
  112.     {
  113.     double  temp;
  114.  
  115.     temp    = *a;
  116.     *a        = *b;
  117.     *b        = temp;
  118.     }
  119.  
  120. /*----------------------------------------------------------------------+
  121. |                                    |
  122. | name        findPaperSize                        |
  123. |                                    |
  124. | author    BSI                     6/91        |
  125. |                                    |
  126. +----------------------------------------------------------------------*/
  127. Private int    findPaperSize
  128. (
  129. char        *pageName
  130. )
  131.     {
  132.     int        i;
  133.     Plot_spec    *pSpec = &plotStat->plotSpec;
  134.  
  135.     strupr (pageName);
  136.  
  137.     for (i=0; i < plotStat->plotter.num_papsz; i++)
  138.     {
  139.     if (strcmp (pageName, plotStat->plotter.size[i].name) == 0)
  140.         {
  141.         pSpec->paper_num     = i;
  142.         pSpec->paper_size     = plotStat->plotter.size[i].num;
  143.         pSpec->manual_origin = plotStat->plotter.size[i].manual_origin;
  144.         return  SUCCESS;
  145.         }
  146.     }
  147.  
  148.     return  ERROR;
  149.     }
  150.  
  151. /*----------------------------------------------------------------------+
  152. |                                    |
  153. | name        calculateFenceBounds                    |
  154. |                                    |
  155. | author    BSI                     6/91        |
  156. |                                    |
  157. +----------------------------------------------------------------------*/
  158. Private int    calculateFenceBounds
  159. (
  160. Point3d        *origin,
  161. Dpoint3d    *delta
  162. )
  163.     {
  164.     int        i;
  165.     double    activeZ;
  166.     Dpoint3d    viewOrigin, viewDelta, fenpts[101], fencelow, fencehigh;
  167.     RotMatrix    rMatrix;
  168.  
  169.     if (tcb->fence == 0)
  170.     return    ERROR;
  171.  
  172.     plotStat->plotView    = tcb->fenvw;
  173.     mdlView_getParameters (&viewOrigin, NULL, &viewDelta, &rMatrix, &activeZ,
  174.                 tcb->fenvw);
  175.     mdlRMatrix_rotatePoint (&viewOrigin, &rMatrix);
  176.  
  177.     for (i = 0; i < tcb->fence; i++)
  178.     {
  179.     if (tcb->ndices == 3)
  180.         {
  181.         fenpts[i].x = (double) tcb->fenpts[i].x + viewOrigin.x;
  182.         fenpts[i].y = (double) tcb->fenpts[i].y + viewOrigin.y;
  183.         fenpts[i].z = activeZ;
  184.         }
  185.         else
  186.         {
  187.         fenpts[i].x = (double) tcb->fenpts[i].x;
  188.         fenpts[i].y = (double) tcb->fenpts[i].y;
  189.         fenpts[i].z = fc_zero;
  190.         mdlRMatrix_rotatePoint (&fenpts[i], &rMatrix);
  191.         }
  192.     }
  193.  
  194.     /* find the extents (highest and lowest coordinates) of the fence */
  195.     fencelow = fencehigh = fenpts[0];
  196.     for (i = 1; i < tcb->fence; i++)
  197.     {
  198.     if (fenpts[i].x < fencelow.x)
  199.         fencelow.x = fenpts[i].x;
  200.     if (fenpts[i].y < fencelow.y)
  201.         fencelow.y = fenpts[i].y;
  202.     if (fenpts[i].x > fencehigh.x)
  203.         fencehigh.x = fenpts[i].x;
  204.     if (fenpts[i].y > fencehigh.y)
  205.         fencehigh.y = fenpts[i].y;
  206.     }
  207.  
  208.     /* set the extents */
  209.     delta->x = fencehigh.x - fencelow.x;
  210.     delta->y = fencehigh.y - fencelow.y;
  211.     delta->z = viewDelta.z;
  212.  
  213.     /* set the origin */
  214.     fencelow.z = viewOrigin.z;
  215.     mdlRMatrix_unrotatePoint (&fencelow, &rMatrix);
  216.     mdlCnv_DPointToIPoint (origin, &fencelow);
  217.  
  218.     return  SUCCESS;
  219.     }
  220.  
  221. /*----------------------------------------------------------------------+
  222. |                                    |
  223. | name        setPlotViewParameters                    |
  224. |                                    |
  225. | author    BSI                     6/91        |
  226. |                                    |
  227. +----------------------------------------------------------------------*/
  228. Private int    setPlotViewParameters
  229. (
  230. Plot_spec   *pSpec,
  231. int        viewNumber,
  232. int        useFence
  233. )
  234.     {
  235.     if (useFence)
  236.     {
  237.     if (calculateFenceBounds (&pSpec->origin, &pSpec->delta) != SUCCESS)
  238.         return  ERROR;
  239.     }
  240.     else
  241.     {
  242.     plotStat->plotView  = viewNumber;
  243.     pSpec->origin        = tcb->view[viewNumber].origin;
  244.     cvtUpoint3dToDpoint3d (&pSpec->delta, &tcb->view[viewNumber].delta);
  245.     }
  246.  
  247.     return  SUCCESS;
  248.     }
  249.  
  250. /*----------------------------------------------------------------------+
  251. |                                    |
  252. | name        setPlotPaperParameters                    |
  253. |                                    |
  254. | author    BSI                     6/91        |
  255. |                                    |
  256. +----------------------------------------------------------------------*/
  257. Private int    setPlotPaperParameters
  258. (
  259. Plot_spec   *pSpec,
  260. double        param,
  261. int        useFlag
  262. )
  263.     {
  264.     double        maxScale, uorsPerMast, h_center, v_center;
  265.     double        point_000001 = .000001, point_00005 = .00005;
  266.     Dpaper_pnt        paperMax, paperSize, plotSize, plotMin;
  267.     Dpoint2d        maxSize;
  268.     Pltr_papsz        *currSize;
  269.  
  270.     /* get # of UORS per master unit */
  271.     uorsPerMast = tcb->subpermast * tcb->uorpersub;
  272.  
  273.     /* If manual origin or maximizing, eliminate user offsets */
  274.     if (useFlag == USE_DEFAULT_SIZE || pSpec->manual_origin)
  275.         {
  276.         pSpec->user_off.h = fc_zero;
  277.         pSpec->user_off.v = fc_zero;
  278.         }
  279.  
  280.     currSize = &plotStat->plotter.size[pSpec->paper_num];
  281.     paperMax.h = (currSize->bound.h + currSize->offset.h) /
  282.             plotStat->plotter.resolution.h;
  283.     paperMax.v = (currSize->bound.v + currSize->offset.v) /
  284.             plotStat->plotter.resolution.v;
  285.  
  286.     paperSize.h = currSize->bound.h / plotStat->plotter.resolution.h;
  287.     paperSize.v = currSize->bound.v / plotStat->plotter.resolution.v;
  288.  
  289.     /* Calculate the absolute maximums for the paper size */
  290.     maxSize.x = currSize->bound.h;
  291.     maxSize.y = currSize->bound.v;
  292.  
  293.     /* See if we should rotate the plot */
  294.     if (useFlag == USE_DEFAULT_SIZE && !pSpec->rotate &&
  295.             (plotStat->plotter.rotate_direction != NO_ROTATE))
  296.         {
  297.         if ((pSpec->delta.x < pSpec->delta.y) ^ (paperSize.h < paperSize.v))
  298.             pSpec->rotate = TRUE;
  299.         else
  300.             pSpec->rotate = FALSE;
  301.         }
  302.  
  303.     /* If the image is to be rotated, rotate the extents */
  304.     if (pSpec->rotate)
  305.     swapDoubles (&pSpec->delta.x, &pSpec->delta.y);
  306.  
  307.     if (pSpec->delta.x / maxSize.x > pSpec->delta.y / maxSize.y)
  308.     maxSize.y = pSpec->delta.y * (maxSize.x / pSpec->delta.x);
  309.     else
  310.     maxSize.x = pSpec->delta.x * (maxSize.y / pSpec->delta.y);
  311.  
  312.     maxScale  = ((pSpec->delta.x / uorsPerMast) / maxSize.x);
  313.     switch (useFlag)
  314.         {
  315.         case USE_DEFAULT_SIZE:
  316.         if (plotStat->plotter.def_scale &&
  317.             (plotStat->plotter.scalefctr > (maxScale - point_00005)))
  318.         {
  319.         pSpec->scale = plotStat->plotter.scalefctr;
  320.         break;
  321.         }
  322.  
  323.     case USE_MAXIMUM_SIZE:
  324.         pSpec->scale = maxScale;
  325.             break;
  326.  
  327.         case USE_SCALE:
  328.         pSpec->scale = param;
  329.             if (pSpec->scale < maxScale - point_00005)
  330.         return    ERROR;
  331.             if (pSpec->scale < maxScale)
  332.         pSpec->scale = maxScale;
  333.             if (pSpec->scale * uorsPerMast < point_000001)
  334.         return    ERROR;
  335.             break;
  336.  
  337.         case USE_X_SIZE:
  338.         pSpec->size.x = param;
  339.             if (pSpec->size.x > maxSize.x + point_00005)
  340.         return    ERROR;
  341.             if (pSpec->size.x > maxSize.x)
  342.         pSpec->size.x = maxSize.x;
  343.         pSpec->scale = (pSpec->delta.x / uorsPerMast) / pSpec->size.x;
  344.         break;
  345.  
  346.         case USE_Y_SIZE:
  347.         pSpec->size.y = param;
  348.             if (pSpec->size.y > maxSize.y + point_00005)
  349.         return    ERROR;
  350.             if (pSpec->size.y > maxSize.y)
  351.         pSpec->size.y = maxSize.y;
  352.         pSpec->scale = (pSpec->delta.y / uorsPerMast) / pSpec->size.y;
  353.         break;
  354.         }
  355.  
  356.     /* Calculate the size of the plot */
  357.     pSpec->size.x = (pSpec->delta.x / uorsPerMast) / pSpec->scale;
  358.     pSpec->size.y = (pSpec->delta.y / uorsPerMast) / pSpec->scale;
  359.  
  360.     /* Get the size of the plot in each direction */
  361.     plotSize.h = pSpec->size.x / plotStat->plotter.resolution.h;
  362.     plotSize.v = pSpec->size.y / plotStat->plotter.resolution.v;
  363.  
  364.     /* Should we "auto-center" */
  365.     if ((useFlag == USE_DEFAULT_SIZE || useFlag == USE_MAXIMUM_SIZE)
  366.         && plotStat->plotter.auto_center && !pSpec->manual_origin)
  367.         {
  368.     h_center = (paperSize.h - plotSize.h) / fc_2;
  369.         v_center = (paperSize.v - plotSize.v) / fc_2;
  370.     if (h_center < fc_zero)
  371.         h_center = fc_zero;
  372.     if (v_center < fc_zero)
  373.         v_center = fc_zero;
  374.  
  375.         pSpec->user_off.h = (h_center * plotStat->plotter.resolution.h);
  376.         pSpec->user_off.v = (v_center * plotStat->plotter.resolution.v);
  377.         }
  378.  
  379.     plotMin.h = (currSize->offset.h + pSpec->user_off.h) /
  380.             plotStat->plotter.resolution.h;
  381.     plotMin.v = (currSize->offset.v + pSpec->user_off.v) /
  382.             plotStat->plotter.resolution.v;
  383.  
  384.     /*
  385.     *    It's necessary to truncate here instead of rounding, since
  386.     *    we sometimes exceed the p1 and p2 pts set for the plotter's range.
  387.     */
  388.     pSpec->p1.h = (long) plotMin.h;
  389.     pSpec->p2.h = (long) (plotMin.h + plotSize.h);
  390.     pSpec->p1.v = (long) plotMin.v;
  391.     pSpec->p2.v = (long) (plotMin.v + plotSize.v);
  392.  
  393.     if ((pSpec->p2.h > mdlCnv_roundDoubleToLong (paperMax.h + fc_p001)) ||
  394.     (pSpec->p2.v > mdlCnv_roundDoubleToLong (paperMax.v + fc_p001)))
  395.     return    ERROR;
  396.  
  397.     if (pSpec->size.x <= fc_zero || pSpec->size.y <= fc_zero)
  398.     return    ERROR;
  399.  
  400.     /*    Calculate the paper coordinates for the lower left and
  401.     upper right corners of the area being plotted. */
  402.     pSpec->ll = pSpec->p1;
  403.     pSpec->ur = pSpec->p2;
  404.  
  405.     mdlTMatrix_getIdentity (&pSpec->trans);
  406.     if (pSpec->rotate)
  407.     {
  408.     double        angle;
  409.     Dpoint3d    offset;
  410.  
  411.     pSpec->ll.h = pSpec->p1.v;
  412.     pSpec->ll.v = pSpec->p1.h;
  413.     pSpec->ur.h = pSpec->p2.v;
  414.     pSpec->ur.v = pSpec->p2.h;
  415.  
  416.     memset (&offset, 0, sizeof(offset));
  417.     if (plotStat->plotter.rotate_direction == CCW_ROTATE)
  418.         {
  419.         angle    = fc_piover2;
  420.         offset.x    = 2*pSpec->p1.h + plotSize.h;
  421.         }
  422.     else
  423.         {
  424.         angle    = -fc_piover2;
  425.         offset.y    = 2*pSpec->p1.v + plotSize.v;
  426.         }
  427.  
  428.     mdlTMatrix_rotateByAngles (&pSpec->trans, NULL, fc_zero, fc_zero,
  429.                 angle);
  430.     mdlTMatrix_setTranslation (&pSpec->trans, &offset);
  431.     }
  432.  
  433.     return  SUCCESS;
  434.     }
  435.  
  436. /*----------------------------------------------------------------------+
  437. |                                    |
  438. | name        setPlotParameters                    |
  439. |                                    |
  440. | author    BSI                     6/91        |
  441. |                                    |
  442. +----------------------------------------------------------------------*/
  443. Private int    setPlotParameters
  444. (
  445. char        *pageName,
  446. char        *plotFileName,
  447. int        viewNumber,
  448. int        rotate,
  449. int        useFence,
  450. int        useFlag,
  451. double        param
  452. )
  453.     {
  454.     Plot_spec    *pSpec = &plotStat->plotSpec;
  455.  
  456.     /* first find the paper size by name */
  457.     if (findPaperSize (pageName) != SUCCESS)
  458.     return    ERROR_BAD_PAPERSIZE;
  459.  
  460.     pSpec->pf_fence    = useFence;
  461.     pSpec->rotate    = rotate;
  462.  
  463.     /* set viewing extents */
  464.     if (setPlotViewParameters (pSpec, viewNumber, useFence) != SUCCESS)
  465.     return    ERROR_INVALID_VIEW_PARAMS;
  466.  
  467.     /* set values that relate to size and location of the plot on the page */
  468.     if (setPlotPaperParameters (pSpec, param, useFlag) != SUCCESS)
  469.     return    ERROR_INVALID_PAPER_PARAMS;
  470.  
  471.     /* set plotfile name */
  472.     mdlFile_find (plotStat->plotSpec.file_name, plotFileName,
  473.             "MS_PLTFILES", plotStat->plotter.defExtension);
  474.  
  475.     return  SUCCESS;
  476.     }
  477.  
  478. /*----------------------------------------------------------------------+
  479. |                                    |
  480. | name        doAutoPlot                        |
  481. |                                    |
  482. | author    BSI                     6/91        |
  483. |                                    |
  484. +----------------------------------------------------------------------*/
  485. Private void    doAutoPlot
  486. (
  487. void
  488. )
  489.     {
  490.     char    configName[MAXFILELENGTH], plotFileName[MAXFILELENGTH];
  491.     char    pageName[128];
  492.     int        viewNumber, rotate, useFence, useFlag, status;
  493.     double    param;
  494.     Plot_spec    *pSpec;
  495.  
  496.     /* read the current plotter configuration file */
  497.     configName[0] = '\0';
  498.     if (mdlPlot_getInfo (plotStat, configName) != SUCCESS)
  499.     {
  500.     mdlOutput_rscPrintf (MSG_ERROR, NULL, MESSAGELISTID_Messages,
  501.                  ERRID_ConfigFile);
  502.     tcb->relerr = ERROR_BAD_PLTCFG;
  503.     return;
  504.     }
  505.  
  506.     /* get the parameters from the user command */
  507.     viewNumber    = tcb->uc_r[0];
  508.     rotate    = tcb->uc_r[1];
  509.     useFence    = tcb->uc_r[2];
  510.     useFlag    = tcb->uc_r[3];
  511.     param    = tcb->uc_a[0];
  512.  
  513.     /* get the page name from C0 */
  514.     memset (pageName, 0, sizeof(pageName));
  515.     strncpy (pageName, tcb->uc_c[0].c, tcb->uc_c[0].len);
  516.  
  517.     /* get the border comment from C1 */
  518.     pSpec = &plotStat->plotSpec;
  519.     memset (pSpec->bdr_comment, 0, sizeof(pSpec->bdr_comment));
  520.     strncpy (pSpec->bdr_comment, tcb->uc_c[1].c, tcb->uc_c[1].len);
  521.  
  522.     /* get name of plot file from C2 */
  523.     memset (plotFileName, 0, sizeof(plotFileName));
  524.     strncpy (plotFileName, tcb->uc_c[2].c, tcb->uc_c[2].len);
  525.  
  526.     /* fill in the plotStat structure */
  527.     if ((status = setPlotParameters (pageName, plotFileName, viewNumber,
  528.             rotate, useFence, useFlag, param)) != SUCCESS)
  529.     {
  530.     /* something bad happened, tell user command */
  531.     tcb->relerr = status;
  532.     return;
  533.     }
  534.  
  535.     /* generate the actual plot */
  536.     mdlPlot_execute ();
  537.  
  538.     /* indicate successful plot */
  539.     tcb->relerr = 0;
  540.     }
  541.  
  542. /*----------------------------------------------------------------------+
  543. |                                    |
  544. | name        autoPlot                        |
  545. |                                    |
  546. | author    BSI                     6/91        |
  547. |                                    |
  548. +----------------------------------------------------------------------*/
  549. Private void    autoPlot
  550. (
  551. void
  552. ) cmdNumber CMD_AUTOPLOT
  553.     {
  554.     char        configName[MAXFILELENGTH];
  555.     PlotStatic *holdPlotStat;
  556.  
  557.     /*------------------------------------------------------------------+ 
  558.         Due to V5.5 plotting changes, the memory for MicroStation's
  559.          plotStat global variable may be allocated prior to this command
  560.     running.  Therefore, we must save the pointer to this memory
  561.     area, and restore the pointer when we are finished processing.
  562.     The plot dialog box in V5.5 is non-modal and could be present on
  563.     the screen (using the plotStat variable) when this command is
  564.     executed.  This command must not deallocate the memory which
  565.     was allocated by MicroStation's plotting application.
  566.     +------------------------------------------------------------------*/
  567.     holdPlotStat = plotStat;
  568.  
  569.     /* allocate memory for plot static structure (make sure there is
  570.         no way to exit without freeing this memory) */
  571.     plotStat = (PlotStatic *) malloc (sizeof(PlotStatic));
  572.  
  573.     /* generate the plot */
  574.     doAutoPlot ();
  575.  
  576.     /* free plot static structure */
  577.     free (plotStat);
  578.  
  579.     /* restore the original pointer to plotStat global variable */
  580.     plotStat = holdPlotStat;
  581.     }
  582.  
  583. /*----------------------------------------------------------------------+
  584. |                                    |
  585. | name        main                            |
  586. |                                    |
  587. | author    BSI                     6/91        |
  588. |                                    |
  589. +----------------------------------------------------------------------*/
  590. Public    int    main
  591. (
  592. void
  593. )
  594.     {
  595.     RscFileHandle   rfHandle;
  596.  
  597.     /* Open our file for access to command table and dialog */
  598.     mdlResource_openFile (&rfHandle, NULL, FALSE);
  599.  
  600.     /* Load the command table */
  601.     if (mdlParse_loadCommandTable (NULL) == NULL)
  602.     mdlOutput_rscPrintf (MSG_ERROR, NULL, MESSAGELISTID_Messages,
  603.                  ERRID_CommandTable);
  604.  
  605.     return  0;
  606.     }
  607.