Questions similar to this appear on the Bentley Discussion Groups. These questions, or something like them, appeared in the MDL discussion group.

Q Questions about metrics measurement with MDL pop up occasionally …

A The answers to those questions are simple, but confused because of the MDL API function names and that some functions operate on an MSElementUnion (same as MSElement) and others operate on MSElementDescrs. Here are some hints to guide you through the maze …

Area & Volume Measurement Functions in MicroStation XM
Function Measures Constraint Accepts Element Types
mdlMeasure_elmDscrArea surface area planar shapes only shapes, ellipses, complex shapes and closed B-spline curves
mdlMeasure_areaProperties surface area planar shapes and SmartSurfaces1
mdlMeasure_areaPropertiesXY surface area ignores Z component planar shapes only
mdlMeasure_surfaceProperties surface area planar and non-planar shapes including SmartSurfaces1
mdlMeasure_polygonArea area of polygon array of points that define a polygon (not an element)
mdlMeasure_volumeProperties volume type 19 and SmartSolids1

1 For versions of MicroStation prior to XM, the measurement functions do not work with SmartSurfaces or SmartSolids. If you are writing code for MicroStation V8.5 or earlier, you need to use the mdlKISolid_xxx function family to measure SmartSurfaces and SmartSolids.


mdlLinear_extract

This function extracts a list of vertices from a linear element.

BoolInt             example_getVertexList
(
ULong               filePos,  //  =>  File position of element to measure
DgnModelRefP        modelRef  //  =>  Model reference of element
)
{
  BoolInt           rc        = FALSE;
  MSElement         object;

  if (SUCCESS == mdlElement_read (&object, modelRef, filePos))
  {
    int             nPoints = mdlLinear_getPointCount (&object);
    DPoint3d*       points  = (DPoint3d*)calloc (nPoints, sizeof (DPoint3d));

    if (NULL != points
       &&
       SUCCESS == mdlLinear_extract (points, &nPoints, object, modelRef))
    {
      if (2 == nPoints)
      {
        printf ("Length=%.2lf\n", mdlVec_distance ((1 + points), (0 + points));
      }
      else if (2 < nPoints)
      {
        double total = 0.0;
        int    i;
        for (i = 1; i < nPoints; ++i)
        {
          total += mdlVec_distance ((i + points), (i - 1 + points));
        }
        printf ("Total length=%.2lf\n", total);
      }
      rc = TRUE;
      free (points);
    }
  }

  return rc;
}

mdlElmdscr_extractEndPoints

This function gets the coordinate of the start and end point of a linear element. You can also ask for the corresponding tangents (slope or angle) of each end point.

BoolInt             example_measureLengthFromEndPoints
(
ULong               filePos,  //  =>  File position of shape element to measure
DgnModelRefP        modelRef  //  =>  Model reference of shape element
)
{
  BoolInt           rc        = FALSE;
  DPoint3d          startPoint;
  DPoint3d          endPoint;
  MSElementDescr*   pObject   = NULL;

  if (0 < mdlElmdscr_readToMaster (&pObject, filePos, modelRef, FALSE, NULL))
  {
    if (SUCCESS == mdlElmdscr_extractEndPoints (&startPoint, NULL, &endPoint, NULL, pObject))
    {
      printf ("Length=%.2lf\n", mdlVec_distance (&endPoint, &startPoint));
      rc = TRUE;
    }

    mdlElmdscr_freeAll (&pObject);
  }

  return rc;
}

mdlMeasure_linearProperties

This function analyses a linear or area element and extracts mechanical properties such as length (or perimeter of a shape), centroid, and various moments.

BoolInt             example_measureLinear
(
ULong               filePos,  //  =>  File position of element to measure
DgnModelRefP        modelRef  //  =>  Model reference of element
)
{
  BoolInt          	rc        = FALSE;
  double           	length    = 0.0;
  const double     	tolerance = 0.01;
  MSElementDescr*  	pLinear   = NULL;

  if (0 < mdlElmdscr_readToMaster (&pLinear, filePos, modelRef, FALSE, NULL))
  {
    if (SUCCESS == mdlMeasure_linearProperties (&perimeter, &area, NULL, NULL, NULL, NULL, NULL, NULL, NULL, pLinear, tolerance))
    {
      printf ("Length=%.2lf\n", length);
      rc = TRUE;
    }

    mdlElmdscr_freeAll (&pLinear);
  }

  return rc;
}

mdlMeasure_areaProperties

This function analyses an area element and extracts mechanical properties such as area, perimeter, centroid, and various moments. If you want just the area of an element, then mdlMeasure_elmDscrArea () may be simpler to use.

mdlMeasure_polygonArea () calculates the area and perimeter of a closed shape expressed as a list of DPoint3d vertices.

BoolInt             example_measureArea
(
ULong               filePos,  //  =>  File position of shape element to measure
DgnModelRefP        modelRef  //  =>  Model reference of shape element
)
{
  BoolInt          	rc        = FALSE;
  double           	area      = 0.0;
  double           	perimeter = 0.0;
  const double     	tolerance = 0.01;
  MSElementDescr*  	pShape    = NULL;

  if (0 < mdlElmdscr_readToMaster (&pShape, filePos, modelRef, FALSE, NULL))
  {
    if (SUCCESS == mdlMeasure_areaProperties (&perimeter, &area, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, pShape, tolerance))
    {
      printf ("Area=%.2lf Perimeter=%.2lf\n", area, perimeter);
      rc = TRUE;
    }

    mdlElmdscr_freeAll (&pShape);
  }

  return rc;
}

mdlMeasure_volumeProperties

This function analyses an solid element and extracts mechanical properties such as the principal moments, and the principal axes of an element.

Depending on your version of MicroStation, this function may or may not work with SmartSolid elements.


Return to MDL articles index.