Here are answers to questions about MicroStation® MDL that are posted from time to time on the Bentley Discussion Groups. This question appeared on the MDL discussion group.

Q Sometimes you want to convert a curved element to a line string, or an ellipse to a polygon. Perhaps you have a complex shape, composed of linear and curved elements, that you want to simplify to a polygon. The term used to describe the process of converting or simplifying a set of curves to a polygon or line string is stroking.

A The process of stroking is used to simplify or convert one geometry to a simpler geometry, where the result is a set of vertices that can be displayed as a line string or a closed polygon.

MDL provides at least two functions for stroking an element descriptor …

Open or Closed?

The curve or shape you want to simplify may be open or closed. The MDL functions described below may require you to specify whether or not the original element is closed. In some cases, that's obvious: simply test the element's type …

BoolInt         IsClosed (MSElement const* el)
{
  BoolInt       closed  = FALSE;
  int elemType = mdlElement_getType (el);
  switch (elemType)
  {
    case SHAPE_ELM:
    case CMPLX_SHAPE_ELM:
    case ELLIPSE_ELM:
    	closed = TRUE;
    	break;
  }
  return closed;
}

In other cases, it's not so obvious; but you can test the element's closure like this …

BoolInt         IsClosed (MSElementDescr const* el)
{
  BoolInt       closed  = mdlElmdscr_isClosed (el);
  return closed;
}

mdlElmdscr_stroke

MDL function mdlElmdscr_stroke strokes an element to a set of vectors that approximate the original. The maximum distance from each vector to the original curve is the tolerance. You specify the tolerance that is used by this function. If you're stroking curved elements, the number of points you obtain is determined by that tolerance. The smaller the tolerance, the more points are created to approximate the original curve. With a coarser tolerance, the line string looks less like the original curve.

Of course, if you're stroking a complex shape composed entirely of vectors, no approximation is needed.

You don't know the number of points in the array until mdlElmdscr_stroke completes its work and tells you how many points it has created. To use this function, you need to do something like this …

  DPoint3d*     points   = NULL;
  int           nPoints  = 0;
  if (SUCCESS == mdlElmdscr_stroke (&points, &nPoints, pElm, mdlModelRef_getUorPerMaster (ACTIVEMODEL)))
  {
    //  Do something with array of points.  For example:
    MSElementDescr*	pStroked	= NULL;
    if (SUCCESS == mdlElmdscr_createFromVertices (&pStroked, NULL, points, size, FALSE, -1))
    {
      mdlElmdscr_add (pStroked);
      mdlElmdscr_display (pStroked, ACTIVEMODEL, NORMALDRAW);
      mdlElmdscr_freeAll (&pStroked);
    }
    //	Cleanup
    free (points);
  }

mdlElmdscr_strokeToNumPoints

MDL function mdlElmdscr_strokeToNumPoints strokes an element to a fixed number of points. You specify the point count. This function appears to work only with closed shapes, although the MDL documentation omits to mention that restriction.

Because no tolerance is specified, mdlElmdscr_strokeToNumPoints may have unexpected results. That is, the resulting shape may be only a loose approximation to the original. To use this function, you need to do something like this …

  enum ArrayControl	{	PointCount	= 100,	};
  DPoint3d	points	[PointCount];
  memset (points, 0x00, sizeof (points));
  if (SUCCESS == mdlElmdscr_strokeToNumPoints (points, PointCount, el))
  {
    //  Do something with array of points.  For example:
    MSElementDescr*	pStroked	= NULL;
    if (SUCCESS == mdlElmdscr_createFromVertices (&pStroked, NULL, points, PointCount, FALSE, -1))
    {
      mdlElmdscr_add (pStroked);
      mdlElmdscr_display (pStroked, ACTIVEMODEL, NORMALDRAW);
      //	Cleanup
      mdlElmdscr_freeAll (&pStroked);
    }
  }

Stroke a B-Spline Curve

There are several ways to extract information from a B-Spline curve using MDL …

If you're interested in reading more about B-Spline curves here, let us know! Use the enquiry form with your comments about this page and hints about B-Splines that you would like to see here.

Sample Code

Download

You can download some sample code. This ZIP archive includes the source code of a working implementation of the examples above.

Return to MDL articles index.