Calculating the range of Rotated Cells


  
 Applies To 
  
 Product(s):MicroStation
 Version(s):08.11.09.578
 Environment: Windows 7 32 bit,Windows 7 64 bit
 Area: Programming
 Subarea: VBA
 Original Author:Tristan Anderson, Bentley Technical Support Group
  

 Background Information

To calculate the size of a cell (also referred to as range), you can use the VBA property Range.
The datatype Range includes two points, typically the lower left and top right corners of the smallest rectangle enclosing the cell.
This range can also be calculated in 3D analog. Although the following examples can also work in 3D, I have shown everything in 2D for illustrative purposes.
Be aware that the range box of a given element is always orthogonal to the identify view and a rotated view will always show/calculate a rotated range block that will differ from the identity.

Steps

To demonstrate the problem, this example will show a simple procedure for non-rotated cells. Consider the following example with two cells with the names CellA and CellB:

To determine the size of these cells, you can use the Range property in a cell, as shown in an example below:

Sub range_simple()
    Dim rangeBox As Range3d
    Dim Ee As ElementEnumerator
    Set Ee = ActiveModelReference.GraphicalElementCache.Scan
    Do While Ee.MoveNext
        If Ee.Current.Type = msdElementTypeCellHeader Then
            Debug.Print "Name of Cell: " & Ee.Current.AsCellElement.Name
            rangeBox = Ee.Current.AsCellElement.range
            Debug.Print "Width and Height: ", rangeBox.High.X - rangeBox.Low.X, rangeBox.High.Y - rangeBox.Low.Y
        End If
    Loop
End Sub

The issue is not shown here, as the two cells currently have identical dimensions:

If, however, one cell is rotated as shown below:

The results of the calculation will be changed:

The rotated cell now shows a different size from the Range property. The reason, however, in the range calculation is shown below

by the Keying "set range;Update1":

To compensate for this error, you can simply turn the rotated cell back to its original position to calculate the size correctly.
For this, I used the following example:

Sub range_untwisted()
    Dim rangeBox As Range3d
    Dim Rotate As Matrix3d
    Dim transForm As Transform3d
    Dim Ee As ElementEnumerator
    Set Ee = ActiveModelReference.GraphicalElementCache.Scan
    Do While Ee.MoveNext
        If Ee.Current.Type = msdElementTypeCellHeader Then
            Debug.Print "Name of Cell: " & Ee.Current.AsCellElement.Name
             
            'Cell untwisted examine:
            Rotate = Ee.Current.AsCellElement.Rotation
            Rooted = Matrix3dInverse(Roooted)
            transForm = Transform3dFromMatrix3dAndFixedPoint3d(Rotat, Ee.Current.AsCellElement.Origin)
            Ee.Current.AsCellElement.transForm transForm
             
            rangeBox = Ee.Current.AsCellElement.range
            Debug.Print "Width and Height: ", rangeBox.High.X - rangeBox.Low.X, rangeBox.High.Y - rangeBox.Low.Y
        End If
Loop
End Sub

First, the current rotation of the cell is read (.rotation), and the inverse matrix (Matrix3dInverse) is calculated to reverse the rotation.
From the inverse matrix, we create a transformation (Transform3dFromMatrix3dAndFixedPoint3d) to use on the cell (.transform).
When executing again, we get the same results as the first time:

Interestingly, this has not changed the drawing itself, because the rotation of the cells was only carried out in memory.

See Also

MVBA-FAQ