home *** CD-ROM | disk | FTP | other *** search
/ Chip 1997 January / Chip_1997-01_cd.bin / ms95 / disk21 / dir01 / f014270.re_ / f014270.re
Text File  |  1996-04-02  |  33KB  |  1,184 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/bspline.mcv  $
  18. |   $Workfile:   bspline.mc  $
  19. |   $Revision:   5.3  $
  20. |       $Date:   20 Jun 1995 08:49:42  $
  21. |                                    |
  22. +----------------------------------------------------------------------*/
  23. /*----------------------------------------------------------------------+
  24. |                                    |
  25. |   bspline.mc - examples for the mdlBspline_ functions.        |
  26. |                                    |
  27. |   This file is intended as an adjunct to the MDL manual to        |
  28. |   illustrate MDL built-in function calling conventions and parameter    |
  29. |   values. While it can be compiled, it does NOT, on its own,        |
  30. |   constitute a workable MDL example.                    |
  31. |                                    |
  32. +----------------------------------------------------------------------*/
  33. /*----------------------------------------------------------------------+
  34. |                                    |
  35. |   Include Files                               |
  36. |                                    |
  37. +----------------------------------------------------------------------*/
  38. #include    <mdl.h>        /* system include files */
  39. #include    <global.h>
  40. #include    <mselems.h>
  41. #include    <mdlbspln.h>
  42.  
  43. /*----------------------------------------------------------------------+
  44. |                                    |
  45. | name      defineACurve                        |
  46. |                                    |
  47. | author    BSI                        1/91        |
  48. |                                    |
  49. +----------------------------------------------------------------------*/
  50. Private int defineACurve
  51. (
  52. MSBsplineCurve        *curve
  53. )
  54.     {
  55.     int                status;
  56.     MSElementDescr  *edP;
  57.  
  58.     memset (curve, 0, sizeof (*curve));
  59.  
  60.     curve->params.order      = 3;
  61.     curve->params.numPoles = 5;
  62.  
  63.     if ((status = mdlBspline_allocateCurve (&curve)) != SUCCESS)
  64.     return (status);
  65.     
  66.     curve->poles[0].x =  0.0;
  67.     curve->poles[0].y = 10.0;
  68.     curve->poles[0].z =  5.0;
  69.     curve->poles[1].x =  1.0;
  70.     curve->poles[1].y = 10.0;
  71.     curve->poles[1].z = 10.0;
  72.     curve->poles[2].x =  2.0;
  73.     curve->poles[2].y = 10.0;
  74.     curve->poles[2].z = 15.0;
  75.     curve->poles[3].x =  3.0;
  76.     curve->poles[3].y = 10.0;
  77.     curve->poles[3].z = 20.0;
  78.     curve->poles[4].x =  4.0;
  79.     curve->poles[4].y = 10.0;
  80.     curve->poles[4].z = 25.0;
  81.  
  82.     mdlBspline_computeKnotVector (curve->knots, &curve->params, NULL);
  83.  
  84.     if ((status = mdlBspline_createCurve (&edP, NULL, curve)) == SUCCESS)
  85.     {
  86.     mdlElmdscr_display (edP, 0, NORMALDRAW);
  87.     mdlElmdscr_add (edP);
  88.         mdlElmdscr_freeAll (&edP);
  89.     }
  90.  
  91.     return (SUCCESS);
  92.     }
  93.  
  94. /*----------------------------------------------------------------------+
  95. |                                    |
  96. | name      defineASurface                        |
  97. |                                    |
  98. | author    BSI                        1/91        |
  99. |                                    |
  100. +----------------------------------------------------------------------*/
  101. Private int defineASurface
  102. (
  103. MSBsplineSurface    *surface
  104. )
  105.     {
  106.     int                status;
  107.     MSElementDescr    *edP;
  108.  
  109.     memset (surface, 0, sizeof (*surface));
  110.  
  111.     surface->uParams.order    = 3;
  112.     surface->uParams.numPoles = 4;
  113.     surface->vParams.order    = 2;
  114.     surface->vParams.numPoles = 2;
  115.  
  116.     if ((status = mdlBspline_allocateSurface (&surface)) != SUCCESS)
  117.     return (status);
  118.     
  119.     surface->poles[0].x =  0.0;
  120.     surface->poles[0].y = 10.0;
  121.     surface->poles[0].z =  5.0;
  122.     surface->poles[1].x =  1.0;
  123.     surface->poles[1].y = 10.0;
  124.     surface->poles[1].z = 10.0;
  125.     surface->poles[2].x =  2.0;
  126.     surface->poles[2].y = 10.0;
  127.     surface->poles[2].z = 15.0;
  128.     surface->poles[3].x =  3.0;
  129.     surface->poles[3].y = 10.0;
  130.     surface->poles[3].z = 20.0;
  131.     surface->poles[4].x =  0.0;
  132.     surface->poles[4].y = 30.0;
  133.     surface->poles[4].z = 25.0;
  134.     surface->poles[5].x =  1.0;
  135.     surface->poles[5].y = 30.0;
  136.     surface->poles[5].z = 25.0;
  137.     surface->poles[6].x =  2.0;
  138.     surface->poles[6].y = 30.0;
  139.     surface->poles[6].z = 25.0;
  140.     surface->poles[7].x =  3.0;
  141.     surface->poles[7].y = 30.0;
  142.     surface->poles[7].z = 25.0;
  143.  
  144.     mdlBspline_computeKnotVector (surface->uKnots, &surface->uParams, NULL);
  145.     mdlBspline_computeKnotVector (surface->vKnots, &surface->vParams, NULL);
  146.  
  147.     if ((status = mdlBspline_createSurface (&edP, NULL, surface)) == SUCCESS)
  148.     {
  149.     mdlElmdscr_display (edP, 0, NORMALDRAW);
  150.     mdlElmdscr_add (edP);
  151.         mdlElmdscr_freeAll (&edP);
  152.     }
  153.  
  154.     return (SUCCESS);
  155.     }
  156.  
  157. /*----------------------------------------------------------------------+
  158. |                                    |
  159. | name      createASpiral                        |
  160. |                                    |
  161. | author    BSI                        1/91        |
  162. |                                    |
  163. +----------------------------------------------------------------------*/
  164. Public void createASpiral
  165. (
  166. void
  167. )
  168.     {
  169.     int                status;
  170.     double        initialRadius, finalRadius, sweepAngle;
  171.     Dpoint3d        startPt, tangentPt, directionPt;
  172.     MSBsplineCurve  curve;
  173.     MSElementDescr  *edP;
  174.  
  175.     memset (&curve, 0, sizeof(curve));
  176.  
  177.     initialRadius = 1000.0;
  178.     finalRadius   = 100.0;
  179.     sweepAngle       = fc_pi;
  180.     startPt.x       =  0.0;
  181.     startPt.y      =  0.0;
  182.     startPt.z       =  0.0;
  183.     tangentPt.x      = 10.0;
  184.     tangentPt.y      = 10.0;
  185.     tangentPt.z      =  0.0;
  186.     directionPt.x = 10.0;
  187.     directionPt.y = 20.0;
  188.     directionPt.z =  0.0;
  189.  
  190.     if (status = mdlBspline_spiral (&curve, initialRadius, finalRadius,
  191.                                 sweepAngle, &startPt, &tangentPt,
  192.                     &directionPt))
  193.     {
  194.     mdlOutput_printf (MSG_ERROR, "ERROR : # %d", status);
  195.     return;
  196.     }
  197.     
  198.     if (status = mdlBspline_createCurve (&edP, NULL, &curve))
  199.     {
  200.     mdlOutput_printf (MSG_ERROR, "ERROR : # %d", status);
  201.         mdlBspline_freeCurve (&curve);
  202.     return;
  203.     }
  204.  
  205.     mdlElmdscr_display (edP, 0, NORMALDRAW);
  206.     mdlElmdscr_add (edP);
  207.     mdlElmdscr_freeAll (&edP);
  208.  
  209.     mdlBspline_freeCurve (&curve);
  210.     }
  211.  
  212. /*----------------------------------------------------------------------+
  213. |                                    |
  214. | name      createAHelix                        |
  215. |                                    |
  216. | author    BSI                        1/91        |
  217. |                                    |
  218. +----------------------------------------------------------------------*/
  219. Public void createAHelix
  220. (
  221. void
  222. )
  223.     {
  224.     int                status;
  225.     double        initialRadius, finalRadius, pitchHeight;
  226.     Dpoint3d        startPt, axis1Pt, axis2Pt;
  227.     MSBsplineCurve  curve;
  228.     MSElementDescr  *edP;
  229.  
  230.     memset (&curve, 0, sizeof(curve));
  231.  
  232.     initialRadius = 1000.0;
  233.     finalRadius   = 500.0;
  234.     pitchHeight      = 10.0;
  235.  
  236.     startPt.x       =  1000.0;
  237.     startPt.y      =  0.0;
  238.     startPt.z       =  0.0;
  239.     axis1Pt.x      =  0.0;
  240.     axis1Pt.y      =  0.0;
  241.     axis1Pt.z      =  0.0;
  242.     axis2Pt.x       =  0.0;
  243.     axis2Pt.y       = 10.0;
  244.     axis2Pt.z       =  0.0;
  245.  
  246.     if (status = mdlBspline_helix (&curve, initialRadius, finalRadius,
  247.                                pitchHeight, &startPt,
  248.                    &axis1Pt, &axis2Pt, TRUE))
  249.     {
  250.     mdlOutput_printf (MSG_ERROR, "ERROR : # %d", status);
  251.     return;
  252.     }
  253.     
  254.     if (status = mdlBspline_createCurve (&edP, NULL, &curve))
  255.     {
  256.     mdlOutput_printf (MSG_ERROR, "ERROR : # %d", status);
  257.         mdlBspline_freeCurve (&curve);
  258.     return;
  259.     }
  260.  
  261.     mdlElmdscr_display (edP, 0, NORMALDRAW);
  262.     mdlElmdscr_add (edP);
  263.     mdlElmdscr_freeAll (&edP);
  264.  
  265.     mdlBspline_freeCurve (&curve);
  266.     }
  267.  
  268. /*----------------------------------------------------------------------+
  269. |                                    |
  270. | name      displayKnotInfo                        |
  271. |                                    |
  272. | author    BSI                        1/91        |
  273. |                                    |
  274. +----------------------------------------------------------------------*/
  275. Public void displayKnotInfo
  276. (
  277. MSBsplineCurve        *curve,
  278. double                parameter
  279. )
  280.     {
  281.     int            i, status, index, totalKnots, numDistinct,
  282.             multiplicities[MAX_KNOTS], numInflects;
  283.     double        knotTolerance, distinctKnots[MAX_KNOTS], greville[MAX_POLES];
  284.  
  285.     knotTolerance = mdlBspline_knotTolerance (curve);
  286.  
  287.     totalKnots = curve->params.closed ?
  288.              curve->params.numPoles + 2 * curve->params.order - 1 :
  289.          curve->params.numPoles + curve->params.order;
  290.     if (totalKnots > MAX_KNOTS)
  291.     return;
  292.  
  293.     mdlBspline_getKnotMultiplicity (distinctKnots, multiplicities,
  294.                                 &numDistinct,
  295.                                 curve->knots, curve->params.numPoles,
  296.                     curve->params.order, curve->params.closed,
  297.                     knotTolerance);
  298.  
  299.     for (i=0; i < numDistinct; i++)
  300.         printf ("Knot [#i] = %3.4f\n", i, distinctKnots[i]);
  301.  
  302.     mdlBspline_computeGrevilleAbscissa (greville, curve->knots,
  303.                                     curve->params.numPoles,
  304.                                     curve->params.order,
  305.                                     curve->params.closed,
  306.                     knotTolerance);
  307.  
  308.     for (i=0; i < curve->params.numPoles; i++)
  309.         printf ("Greville Abscissa [#d] = %3.4f\n", i, greville[i]);
  310.  
  311.     mdlBspline_findSpan (&index, curve->knots, curve->params.numPoles,
  312.                      curve->params.order, curve->params.closed,
  313.              parameter);
  314.     printf ("Parameter value %3.4f is in span %d\n", parameter, index);
  315.  
  316.     mdlBspline_inflectionPoints (NULL, NULL, &numInflects, curve, NULL);
  317.     printf ("The curve contains %d inflection points \n", numInflects);
  318.     }
  319.  
  320. /*----------------------------------------------------------------------+
  321. |                                    |
  322. | name      convertElementDescr                        |
  323. |                                    |
  324. | author    BSI                        1/91        |
  325. |                                    |
  326. +----------------------------------------------------------------------*/
  327. Private int convertElementDescr
  328. (
  329. MSElementDescr    **newEdP,
  330. MSElementDescr    *edP
  331. )
  332.     {
  333.     int               status;
  334.     MSBsplineCurve    curve;
  335.     MSBsplineSurface  surface;
  336.     MSElementDescr    *endCaps;
  337.  
  338.     if ((edP->el.ehdr.type == LINE_ELM) ||
  339.         (edP->el.ehdr.type == LINE_STRING_ELM) ||
  340.         (edP->el.ehdr.type == SHAPE_ELM) ||
  341.         (edP->el.ehdr.type == CURVE_ELM) ||
  342.         (edP->el.ehdr.type == CMPLX_STRING_ELM) ||
  343.         (edP->el.ehdr.type == CMPLX_SHAPE_ELM) ||
  344.         (edP->el.ehdr.type == ELLIPSE_ELM) ||
  345.         (edP->el.ehdr.type == ARC_ELM))
  346.     {
  347.     if ((status = mdlBspline_convertToCurve (&curve, edP)) ||
  348.         (status = mdlBspline_createCurve (newEdP, NULL, &curve)))
  349.         return (status);
  350.     mdlBspline_freeCurve (&curve);
  351.     }
  352.     else if ((edP->el.ehdr.type == SURFACE_ELM) ||
  353.              (edP->el.ehdr.type == CONE_ELM) ||
  354.              (edP->el.ehdr.type == SOLID_ELM))
  355.     {
  356.     if ((status = mdlBspline_convertToSurface (&surface, edP)) ||
  357.         (status = mdlBspline_createSurface (newEdP, NULL, &surface)))
  358.         return (status);
  359.     mdlBspline_freeSurface (&surface);
  360.  
  361.         if (edP->el.ehdr.type == SOLID_ELM ||
  362.            (edP->el.ehdr.type == CONE_ELM && ! edP->el.cone_3d.b.surf))
  363.         {
  364.         if (status = mdlBspline_convertToEndcaps (&endCaps, edP))
  365.             return (status);
  366.         mdlElmdscr_addToChain (*newEdP, endCaps);
  367.         }
  368.     }
  369.     return (SUCCESS);
  370.     }
  371.  
  372. /*----------------------------------------------------------------------+
  373. |                                    |
  374. | name      sampleCurvePoints                        |
  375. |                                    |
  376. | author    BSI                        1/91        |
  377. |                                    |
  378. +----------------------------------------------------------------------*/
  379. Private void sampleCurvePoints
  380. (
  381. void
  382. )
  383.     {
  384.     int                  i, status, numPoints;
  385.     Dpoint3d          *points, line[2];
  386.     MSBsplineCurve    curve;
  387.     MSElementUnion    u;
  388.  
  389.     if (status = defineACurve (&curve))
  390.     {
  391.     mdlOutput_printf (MSG_ERROR, "ERROR : # %d", status);
  392.     return;
  393.     }
  394.  
  395.     numPoints = 50;
  396.     points = NULL;
  397.  
  398.     if ((status = mdlBspline_evaluateCurve (&points, NULL, &numPoints, &curve))
  399.             != SUCCESS)
  400.     {
  401.     mdlOutput_printf (MSG_ERROR, "ERROR : # %d", status);
  402.     return;
  403.     }
  404.  
  405.     for (i = 0; i < numPoints; i++)
  406.     {
  407.     line[0] = line[1] = points[i];
  408.     mdlLine_create (&u, NULL, line);
  409.     u.line_3d.dhdr.symb.b.weight = 5;
  410.     mdlElement_display (&u, NORMALDRAW);
  411.     }
  412.  
  413.     /* Free the memory allocated by mdlBspline_evaluateCurve */
  414.     free (points);
  415.     mdlBspline_freeCurve (&curve);
  416.     }
  417.  
  418. /*----------------------------------------------------------------------+
  419. |                                    |
  420. | name      sampleSurfacePoints                        |
  421. |                                    |
  422. | author    BSI                        1/91        |
  423. |                                    |
  424. +----------------------------------------------------------------------*/
  425. Private void sampleSurfacePoints
  426. (
  427. void
  428. )
  429.     {
  430.     int                  i, status, numPoints[2];
  431.     Dpoint3d          *points, line[2];
  432.     MSBsplineSurface  surface;
  433.     MSElementUnion    u;
  434.  
  435.     if (status = defineASurface (&surface))
  436.     {
  437.     mdlOutput_printf (MSG_ERROR, "ERROR : # %d", status);
  438.     return;
  439.     }
  440.  
  441.     numPoints[0] = 50;
  442.     numPoints[1] = 100;
  443.     points = NULL;
  444.  
  445.     if ((status = mdlBspline_evaluateSurface (&points, NULL, numPoints,
  446.                                           &surface))
  447.             != SUCCESS)
  448.     {
  449.     mdlOutput_printf (MSG_ERROR, "ERROR : # %d", status);
  450.     return;
  451.     }
  452.  
  453.     for (i = 0; i < numPoints[0]*numPoints[1]; i++)
  454.     {
  455.     line[0] = line[1] = points[i];
  456.     mdlLine_create (&u, NULL, line);
  457.     u.line_3d.dhdr.symb.b.weight = 5;
  458.     mdlElement_display (&u, NORMALDRAW);
  459.     }
  460.  
  461.     /* Free the memory allocated by mdlBspline_evaluateSurface */
  462.     free (points);
  463.  
  464.     mdlBspline_freeSurface (&surface);
  465.     }
  466.  
  467. /*----------------------------------------------------------------------+
  468. |                                    |
  469. | name      modifyBsplineCurve                        |
  470. |                                    |
  471. | author    BSI                        1/91        |
  472. |                                    |
  473. +----------------------------------------------------------------------*/
  474. Private void modifyBsplineCurve
  475. (
  476. void
  477. )
  478.     {
  479.     int            i, status, action, intValue, numKnots;
  480.     double                doubleValue, knotTolerance;
  481.     MSBsplineCurve    curve, result;
  482.     MSElementDescr        *edP=NULL;
  483.     
  484.     memset (&result, 0, sizeof (result));
  485.     if (status = defineACurve (&curve))
  486.     {
  487.     mdlOutput_printf (MSG_ERROR, "ERROR : # %d", status);
  488.     return;
  489.     }
  490.  
  491.     action = 0;
  492.     switch (action)
  493.     {
  494.     /* Reverse direction of curve */
  495.     case 0:
  496.         status = mdlBspline_reverseCurve (&result, &curve);
  497.         break;
  498.  
  499.     /* Make into a multiple segment Bezier curve */
  500.     case 1:
  501.         status = mdlBspline_makeBezier (&result, &curve);
  502.         break;
  503.  
  504.     /* Close curve */
  505.     case 2:
  506.         status = mdlBspline_closeCurve (&result, &curve);
  507.         break;
  508.  
  509.     /* Open curve */
  510.     case 3:
  511.         doubleValue = fc_zero;
  512.         status = mdlBspline_openCurve (&result, &curve, doubleValue);
  513.         break;
  514.  
  515.     /* Elevate the degree of the curve */
  516.     case 4:
  517.         intValue = 4;
  518.         status = mdlBspline_elevateDegree (&result, &curve, intValue);
  519.         break;
  520.  
  521.     /* Add a knot to the knot vector of the curve */
  522.     case 5:
  523.             doubleValue = fc_onehalf;
  524.         status = mdlBspline_copyCurve (&result, &curve);
  525.         if (status == SUCCESS)
  526.         {
  527.         knotTolerance = mdlBspline_knotTolerance (&result);
  528.         status = mdlBspline_addKnot (&result, doubleValue,
  529.                                      knotTolerance,
  530.                                      intValue, TRUE);
  531.         }
  532.         break;
  533.  
  534.     /* Change the weights of the curve */
  535.     case 6:
  536.             doubleValue = fc_onehalf;
  537.         status = mdlBspline_makeRational (&result, &curve);
  538.         if (status == SUCCESS)
  539.         {
  540.         mdlBspline_unWeightPoles (result.poles, result.poles,
  541.                            result.weights, result.params.numPoles);
  542.                 for (i=0; i < result.params.numPoles; i++)
  543.                 result.weights[i] *= doubleValue;
  544.         mdlBspline_weightPoles (result.poles, result.poles,
  545.                          result.weights, result.params.numPoles);
  546.         }
  547.         break;
  548.  
  549.     /* Partially delete the curve */
  550.     case 7:
  551.             doubleValue = fc_onehalf;
  552.         status = mdlBspline_segmentCurve (&result, &curve,
  553.                                       fc_zero, doubleValue);
  554.         break;
  555.  
  556.     /* Change the parameterization of the curve */
  557.     case 8:
  558.             status = mdlBspline_copyCurve (&result, &curve);
  559.         if (status == SUCCESS)
  560.         {
  561.                 numKnots = result.params.closed ?
  562.                         result.params.numPoles + 2 * result.params.order-1:
  563.                     result.params.numPoles + result.params.order;
  564.  
  565.                 for (i=0; i < numKnots; i++)
  566.                 result.knots[i] *= doubleValue;
  567.  
  568.                 mdlBspline_normalizeKnotVector (result.knots,
  569.                                             result.params.numPoles,
  570.                                               result.params.order,
  571.                                 result.params.closed);
  572.         }
  573.         break;
  574.  
  575.     }
  576.  
  577.     if (status)
  578.     mdlOutput_printf (MSG_ERROR, "ERROR : # %d", status);
  579.     else
  580.     {
  581.     mdlBspline_createCurve (&edP, NULL, &result);
  582.     mdlElmdscr_display (edP, 0, NORMALDRAW);
  583.     }
  584.  
  585.     mdlBspline_freeCurve (&result);
  586.     mdlBspline_freeCurve (&curve);
  587.     mdlElmdscr_freeAll (&edP);
  588.     }
  589.  
  590. /*----------------------------------------------------------------------+
  591. |                                    |
  592. | name      modifyBsplineSurface                    |
  593. |                                    |
  594. | author    BSI                        1/91        |
  595. |                                    |
  596. +----------------------------------------------------------------------*/
  597. Private void modifyBsplineSurface
  598. (
  599. void
  600. )
  601.     {
  602.     int            i, status, action, intValue;
  603.     double                doubleValue;
  604.     Dpoint2d            start, finish;
  605.     MSBsplineSurface    surface, result;
  606.     MSElementDescr        *edP=NULL;
  607.     
  608.     memset (&result, 0, sizeof (result));
  609.     if (status = defineASurface (&surface))
  610.     {
  611.     mdlOutput_printf (MSG_ERROR, "ERROR : # %d", status);
  612.     return;
  613.     }
  614.     
  615.     action = 0;
  616.     switch (action)
  617.     {
  618.     /* Make into a multiple patch Bezier surface */
  619.     case 0:
  620.         status = mdlBspline_makeBezierSurface (&result, &surface);
  621.         break;
  622.  
  623.     /* Open surface in U direction */
  624.     case 1:
  625.         doubleValue = fc_zero;
  626.         status = mdlBspline_openSurface (&result, &surface,
  627.                                      doubleValue, BSSURF_U);
  628.         break;
  629.  
  630.     /* Elevate the degree of the surface in V direction */
  631.     case 2:
  632.         intValue = 4;
  633.         status = mdlBspline_elevateDegreeSurface (&result, &surface,
  634.                                               intValue, BSSURF_V);
  635.         break;
  636.  
  637.     /* Partially delete the surface */
  638.     case 3:
  639.             start.x = 0.2;
  640.             start.y = 0.0;
  641.         finish.x = 0.8;
  642.         finish.y = 0.8;
  643.         status = mdlBspline_segmentSurface (&result, &surface,
  644.                                         &start, &finish);
  645.         break;
  646.  
  647.     }
  648.  
  649.     if (status)
  650.     mdlOutput_printf (MSG_ERROR, "ERROR : # %d", status);
  651.     else
  652.     {
  653.     mdlBspline_createSurface (&edP, NULL, &result);
  654.     mdlElmdscr_display (edP, 0, NORMALDRAW);
  655.     }
  656.  
  657.     mdlBspline_freeSurface (&result);
  658.     mdlBspline_freeSurface (&surface);
  659.     mdlElmdscr_freeAll (&edP);
  660.     }
  661.  
  662. /*----------------------------------------------------------------------+
  663. |                                    |
  664. | name      makeDerivedSurface                        |
  665. |                                    |
  666. | author    BSI                        1/91        |
  667. |                                    |
  668. +----------------------------------------------------------------------*/
  669. Private void makeDerivedSurface
  670. (
  671. MSBsplineCurve    *curve1,
  672. MSBsplineCurve    *curve2,
  673. MSBsplineCurve    *curve3,
  674. MSBsplineCurve    *curve4,
  675. int                surfaceType
  676. )
  677.     {
  678.     int                    i, status;
  679.     double                start, sweep;
  680.     Dpoint3d            center, axis, delta;
  681.     Dvector3d            orientation1, orientation2;
  682.     MSBsplineCurve        curves[4];
  683.     MSBsplineSurface    surface;
  684.     MSElementDescr        *edP=NULL;
  685.  
  686.     memset (&surface, 0, sizeof(surface));
  687.     memset (curves, 0, sizeof(curves));
  688.  
  689.     switch (surfaceType)
  690.     {
  691.     case 0:
  692.         status = mdlBspline_ruledSurface (&surface, curve1, curve2);
  693.         break;
  694.  
  695.     case 1:
  696.         if (!(status = mdlBspline_copyCurve (&curves[0], curve1)) ||
  697.              (status = mdlBspline_copyCurve (&curves[1], curve2)) ||
  698.              (status = mdlBspline_copyCurve (&curves[2], curve3)) ||
  699.              (status = mdlBspline_copyCurve (&curves[3], curve4)))
  700.         {
  701.         status = mdlBspline_coonsPatch (&surface, curves);
  702.         }
  703.         for (i=0; i < 4; i++)
  704.         mdlBspline_freeCurve (&curves[i]);
  705.         break;
  706.  
  707.     case 2:
  708.         center.x = 0.0;
  709.         center.y = 0.0;
  710.         center.z = 0.0;
  711.         axis.x =   0.0;
  712.         axis.y =   0.0;
  713.         axis.z = 100.0;
  714.  
  715.         start = fc_zero;
  716.         sweep = fc_pi;
  717.  
  718.         status = mdlBspline_surfaceOfRevolution (&surface, curve1,
  719.                         ¢er, &axis, start, sweep);
  720.         break;
  721.  
  722.     case 3:
  723.         delta.x =   0.0;
  724.         delta.y =   0.0;
  725.         delta.z = 100.0;
  726.  
  727.         start = fc_zero;
  728.         sweep = fc_pi;
  729.  
  730.         status = mdlBspline_surfaceOfProjection (&surface, curve1, &delta);
  731.         break;
  732.  
  733.     case 4:
  734.         orientation1.org.x = 0.0;        orientation1.org.x = 0.0;
  735.         orientation1.org.y = 0.0;        orientation1.org.y = 1.0;
  736.         orientation1.org.z = 0.0;        orientation1.org.z = 0.0;
  737.  
  738.         orientation2.org.x = 0.0;        orientation2.org.x = 1.0;
  739.         orientation2.org.y = 0.0;        orientation2.org.y = 0.0;
  740.         orientation2.org.z = 0.0;        orientation2.org.z = 0.0;
  741.  
  742.         status = mdlBspline_skinPatch (&surface, curve1, curve2, curve3,
  743.                                    &orientation1, &orientation2,
  744.                        TRUE);
  745.         break;
  746.     }
  747.  
  748.     if (status)
  749.     mdlOutput_printf (MSG_ERROR, "ERROR : # %d", status);
  750.     else
  751.     {
  752.     mdlBspline_createSurface (&edP, NULL, &surface);
  753.     mdlElmdscr_display (edP, 0, NORMALDRAW);
  754.     }
  755.  
  756.     mdlBspline_freeSurface (&surface);
  757.     mdlElmdscr_freeAll (&edP);
  758.     }
  759.  
  760. /*----------------------------------------------------------------------+
  761. |                                    |
  762. | name      makeCompatible                        |
  763. |                                    |
  764. | author    BSI                        1/91        |
  765. |                                    |
  766. +----------------------------------------------------------------------*/
  767. Private int makeCompaible
  768. (
  769. MSBsplineCurve    *curve1,
  770. MSBsplineCurve    *curve2,
  771. MSBsplineCurve    *curve3,
  772. MSBsplineCurve    *curve4,
  773. int                numberOfCurves
  774. )
  775.     {
  776.     int                    i, status;
  777.     MSBsplineCurve        *inputPtr[4], *compatiblePtr[4], compatibleCurves[4];
  778.  
  779.     if (numberOfCurves > 4)
  780.     return (ERROR);
  781.     if (numberOfCurves == 1)
  782.     return (SUCCESS);
  783.  
  784.     memset (compatibleCurves, 0, sizeof(compatibleCurves));
  785.  
  786.     if (numberOfCurves == 2)
  787.     return mdlBspline_make2CurvesCompatible (curve1, curve2);
  788.  
  789.     inputPtr[0] = curve1;    inputPtr[1] = curve2;
  790.     inputPtr[2] = curve3;    inputPtr[3] = curve4;
  791.  
  792.     for (i=0; i < numberOfCurves; i++)
  793.     compatiblePtr[i] = &compatibleCurves[i];
  794.  
  795.     if (status = mdlBspline_makeCurvesCompatible (compatiblePtr, inputPtr,
  796.                                               numberOfCurves))
  797.     return (status);
  798.  
  799.     for (i=0; i < numberOfCurves; i++)
  800.     {
  801.     mdlBspline_freeCurve (inputPtr[i]);
  802.     *inputPtr[i] = *compatiblePtr[i];
  803.     }
  804.  
  805.     return (SUCCESS);
  806.     }
  807.  
  808. /*----------------------------------------------------------------------+
  809. |                                    |
  810. | name      imposeBoundary                        |
  811. |                                    |
  812. | author    BSI                        1/91        |
  813. |                                    |
  814. +----------------------------------------------------------------------*/
  815. Private int imposeBoundary
  816. (
  817. MSBsplineSurface    *surface,
  818. MSBsplineCurve        *boundary
  819. )
  820.     {
  821.     int            i, status, numPts;
  822.     double                tolerance;
  823.     Dpoint3d            *points=NULL, *pP;
  824.     Dvector3d            direction;
  825.     MSElementUnion        u;
  826.     MSElementDescr        *edP=NULL;
  827.     
  828.     tolerance = fc_10000;
  829.  
  830.     if (status = mdlBspline_createCurve (&edP, NULL, boundary))
  831.     return (status);
  832.     else
  833.     {
  834.         mdlElmdscr_extractNormal (&direction.end, &direction.org, edP, NULL);
  835.     mdlElmdscr_freeAll (&edP);
  836.     }
  837.  
  838.     if (status = mdlBspline_imposeBoundary (surface, boundary, tolerance,
  839.                                         &direction, &points, &numPts))
  840.     return (status);
  841.  
  842.     for (i=0, pP=points; i < numPts; i++, pP++)
  843.     {
  844.     mdlLine_create (&u, NULL, pP);
  845.     u.line_3d.dhdr.symb.b.weight = 5;
  846.     mdlElement_display (&u, NORMALDRAW);
  847.     }
  848.  
  849.     /* Free memory allocated in mdlBspline_imposeBoundary */
  850.     free (points);
  851.  
  852.     if (status = mdlBspline_extractBoundary (&edP, surface, tolerance))
  853.     return (status);
  854.  
  855.     mdlElmdscr_display (edP, 0, NORMALDRAW);
  856.     mdlElmdscr_freeAll (&edP);
  857.     }
  858.  
  859. /*----------------------------------------------------------------------+
  860. |                                    |
  861. | name      extractSurfaceCurves                    |
  862. |                                    |
  863. | author    BSI                        1/91        |
  864. |                                    |
  865. +----------------------------------------------------------------------*/
  866. Private int extractSurfaceCurves
  867. (
  868. MSBsplineSurface    *surface,
  869. Dpoint3d            *pt
  870. )
  871.     {
  872.     int            i, status;
  873.     double              distance;
  874.     Dpoint2d            parameter;
  875.     Dpoint3d            closestPt;
  876.     MSBsplineCurve        curve;
  877.     MSElementDescr        *edP=NULL;
  878.  
  879.     if (status = mdlBspline_minimumDistanceToSurface (&distance, &closestPt,
  880.                                                   ¶meter, pt, surface))
  881.     return (status);
  882.     
  883.     if (status = mdlBspline_extractIsoCurve (&edP, surface,
  884.                                          parameter.x, BSSURF_U))
  885.     return (status);
  886.     else
  887.     {
  888.     mdlElmdscr_display (edP, 0, NORMALDRAW);
  889.         mdlElmdscr_freeAll (&edP);
  890.     }
  891.  
  892.     if (status = mdlBspline_extractIsoCurve (&edP, surface,
  893.                                          parameter.y, BSSURF_V))
  894.     return (status);
  895.     else
  896.     {
  897.     mdlElmdscr_display (edP, 0, NORMALDRAW);
  898.         mdlElmdscr_freeAll (&edP);
  899.     }
  900.  
  901.     memset (&curve, 0, sizeof (curve));
  902.     if (status = mdlBspline_extractProfile (&curve, surface))
  903.     return (status);
  904.     else
  905.     {
  906.     mdlElmdscr_display (edP, 0, NORMALDRAW);
  907.         mdlElmdscr_freeAll (&edP);
  908.     }
  909.  
  910.     return (SUCCESS);
  911.     }
  912.  
  913.  
  914. /*----------------------------------------------------------------------+
  915. |                                    |
  916. | name      curveInfo                            |
  917. |                                    |
  918. | author    BSI                        1/91        |
  919. |                                    |
  920. +----------------------------------------------------------------------*/
  921. Private int curveInfo
  922. (
  923. MSBsplineCurve        *curve,
  924. Dpoint3d            *pt
  925. )
  926.     {
  927.     int                  i, status;
  928.     double            distance, parameter, wtDerv[3], curvature, torsion;
  929.     Dpoint3d          closestPt, frame[3], line[2];
  930.     MSElementUnion    u;
  931.  
  932.     if (status = mdlBspline_minimumDistanceToCurve (&distance, &closestPt,
  933.                                                 ¶meter, pt, curve))
  934.     return (status);
  935.  
  936.     if (status = mdlBspline_computeDerivatives (frame, wtDerv, curve, 2,
  937.                                             ¶meter))
  938.     return (status);
  939.  
  940.     if (status = mdlBspline_frenetFrame (frame, line, &curvature, &torsion,
  941.                                      curve, parameter))
  942.     return (status);
  943.  
  944.     for (i=0; i < 3; i++)
  945.     {
  946.     mdlVec_projectPoint (line+1, line, frame+i, fc_10000);
  947.     mdlLine_create (&u, NULL, line);
  948.     mdlElement_display (&u, NORMALDRAW);
  949.     }
  950.  
  951.     return (SUCCESS);
  952.     }
  953.  
  954. /*----------------------------------------------------------------------+
  955. |                                    |
  956. | name      leastSquaresCurve                        |
  957. |                                    |
  958. | author    BSI                        1/91        |
  959. |                                    |
  960. +----------------------------------------------------------------------*/
  961. Private void leastSquaresCurve
  962. (
  963. Dpoint3d        *data,
  964. int                numDataPoints
  965. )
  966.     {
  967.     int                    status;
  968.     MSBsplineCurve    curve;
  969.     MSElementDescr        *edP=NULL;
  970.  
  971.     memset (&curve, 0, sizeof (curve));
  972.  
  973.     curve.params.order    = 3;
  974.     curve.params.numPoles = 5;
  975.  
  976.     if (status = mdlBspline_leastSquaresToCurve (&curve, NULL, NULL, data,
  977.                                              NULL, numDataPoints))
  978.         {
  979.     mdlOutput_printf (MSG_ERROR, "ERROR : # %d", status);
  980.     return;
  981.     }
  982.  
  983.     mdlBspline_createCurve (&edP, NULL, &curve);
  984.     mdlElmdscr_display (edP, 0, NORMALDRAW);
  985.     mdlElmdscr_freeAll (&edP);
  986.  
  987.     mdlBspline_freeCurve (&curve);
  988.     }
  989.  
  990. /*----------------------------------------------------------------------+
  991. |                                    |
  992. | name      leastSquaresSurface                        |
  993. |                                    |
  994. | author    BSI                        1/91        |
  995. |                                    |
  996. +----------------------------------------------------------------------*/
  997. Private void leastSquaresSurface
  998. (
  999. Dpoint3d        *data,
  1000. int                *numPointsInEachRow,
  1001. int                numberOfRows
  1002. )
  1003.     {
  1004.     int                    status;
  1005.     MSBsplineSurface    surface;
  1006.     MSElementDescr        *edP=NULL;
  1007.  
  1008.     memset (&surface, 0, sizeof (surface));
  1009.  
  1010.     surface.uParams.order    = 3;
  1011.     surface.uParams.numPoles = 5;
  1012.     surface.vParams.order    = 2;
  1013.     surface.vParams.numPoles = 4;
  1014.  
  1015.     if (status = mdlBspline_leastSquaresToSurface (&surface, NULL, NULL,
  1016.                                                data, NULL,
  1017.                            numPointsInEachRow,
  1018.                            numberOfRows))
  1019.         {
  1020.     mdlOutput_printf (MSG_ERROR, "ERROR : # %d", status);
  1021.     return;
  1022.     }
  1023.  
  1024.     mdlBspline_createSurface (&edP, NULL, &surface);
  1025.     mdlElmdscr_display (edP, 0, NORMALDRAW);
  1026.     mdlElmdscr_freeAll (&edP);
  1027.  
  1028.     mdlBspline_freeSurface (&surface);
  1029.     }
  1030.  
  1031. /*----------------------------------------------------------------------+
  1032. |                                    |
  1033. | name      convertBackToNonBspline                    |
  1034. |                                    |
  1035. | author    BSI                        1/91        |
  1036. |                                    |
  1037. +----------------------------------------------------------------------*/
  1038. Private int convertBackToNonBspline
  1039. (
  1040. MSElementDescr        **out,
  1041. MSElementDescr        *in
  1042. )
  1043.     {
  1044.     int                    status;
  1045.     MSBsplineCurve        curve;
  1046.     MSBsplineSurface       surface;
  1047.  
  1048.     if ((status = mdlBspline_convertToCurve (&curve, in)) == SUCCESS)
  1049.     {
  1050.     status = mdlBspline_extractFromCurve (out, &curve);
  1051.     mdlBspline_freeCurve (&curve);
  1052.     return (status);
  1053.     }
  1054.     else if ((status = mdlBspline_convertToSurface (&surface, in)) == SUCCESS)
  1055.     {
  1056.     status = mdlBspline_extractFromSurface (out, &surface);
  1057.     mdlBspline_freeSurface (&surface);
  1058.     return (status);
  1059.     }
  1060.     else
  1061.     return (status);
  1062.     }
  1063.  
  1064. /*----------------------------------------------------------------------+
  1065. |                                    |
  1066. | name      extractCurveInfo                        |
  1067. |                                    |
  1068. | author    BSI                        1/91        |
  1069. |                                    |
  1070. +----------------------------------------------------------------------*/
  1071. Private void extractCurveInfo
  1072. (
  1073. MSElementDescr        *in
  1074. )
  1075.     {
  1076.     int                  type, rational;
  1077.     double              *weights, *knots;
  1078.     Dpoint3d          *poles;
  1079.     BsplineParam      params;
  1080.     MSElementUnion    header;
  1081.  
  1082.     poles = (Dpoint3d *) 0;
  1083.     knots = weights = (double *) 0;
  1084.  
  1085.     mdlBspline_extractCurve (&header, &type, &rational, NULL, ¶ms,
  1086.                          &poles, &knots, &weights, in);
  1087.  
  1088.     if (poles)        free (poles);
  1089.     if (knots)        free (knots);
  1090.     if (weights)        free (weights);
  1091.     }
  1092.  
  1093. /*----------------------------------------------------------------------+
  1094. |                                    |
  1095. | name      extractSurfaceInfo                        |
  1096. |                                    |
  1097. | author    BSI                        1/91        |
  1098. |                                    |
  1099. +----------------------------------------------------------------------*/
  1100. Private void extractSurfaceInfo
  1101. (
  1102. MSElementDescr        *in
  1103. )
  1104.     {
  1105.     int                  type, rational, numBounds, holeOrigin;
  1106.     double              *weights, *uKnots, *vKnots;
  1107.     Dpoint3d          *poles;
  1108.     BsplineParam      uParams, vParams;
  1109.     MSElementUnion    header;
  1110.  
  1111.     poles = (Dpoint3d *) 0;
  1112.     uKnots = vKnots = weights = (double *) 0;
  1113.  
  1114.     mdlBspline_extractSurface (&header, &type, &rational, NULL, &uParams,
  1115.                            &vParams, &poles, &uKnots, &vKnots, &weights,
  1116.                    &holeOrigin, &numBounds, NULL, in);
  1117.  
  1118.     if (poles)        free (poles);
  1119.     if (uKnots)        free (uKnots);
  1120.     if (vKnots)        free (vKnots);
  1121.     if (weights)    free (weights);
  1122.     }
  1123.  
  1124.  
  1125. /*----------------------------------------------------------------------+
  1126. |                                    |
  1127. | name      appendCurves                        |
  1128. |                                    |
  1129. | author    BSI                        1/91        |
  1130. |                                    |
  1131. +----------------------------------------------------------------------*/
  1132. Private int appendCurve
  1133. (
  1134. MSBsplineCurve        *curve1,
  1135. MSBsplineCurve        *curve2
  1136. )
  1137.     {
  1138.     int                    status;
  1139.     MSBsplineCurve      result;
  1140.     MSElementDescr        *edP=NULL;
  1141.  
  1142.     if (status =  mdlBspline_appendCurves (&result, curve1, curve2))
  1143.     return (status);
  1144.  
  1145.     mdlBspline_createCurve (&edP, NULL, &result);
  1146.     mdlElmdscr_display (edP, 0, NORMALDRAW);
  1147.  
  1148.     mdlElmdscr_freeAll (&edP);
  1149.     mdlBspline_freeCurve (&result);
  1150.  
  1151.     return (SUCCESS);
  1152.     }
  1153.  
  1154. /*----------------------------------------------------------------------+
  1155. |                                    |
  1156. | name      appendSurfaces                        |
  1157. |                                    |
  1158. | author    BSI                        1/91        |
  1159. |                                    |
  1160. +----------------------------------------------------------------------*/
  1161. Private int appendSurface
  1162. (
  1163. MSBsplineSurface        *surface1,
  1164. MSBsplineSurface        *surface2
  1165. )
  1166.     {
  1167.     int                    status;
  1168.     MSBsplineSurface    result;
  1169.     MSElementDescr        *edP=NULL;
  1170.  
  1171.     if (status =  mdlBspline_appendSurfaces (&result, surface1, surface2,
  1172.                                          BSSURF_U))
  1173.     return (status);
  1174.  
  1175.     mdlBspline_createSurface (&edP, NULL, &result);
  1176.     mdlElmdscr_display (edP, 0, NORMALDRAW);
  1177.  
  1178.     mdlElmdscr_freeAll (&edP);
  1179.     mdlBspline_freeSurface (&result);
  1180.  
  1181.     return (SUCCESS);
  1182.     }
  1183.  
  1184.