TextEntity.GetBoundingBox() returns incorrect BoundingBox

Hi,
This bug was supposed to be fixed since rhino6 SR8, but I still have the issue with Rhino6 SR9:
https://mcneel.myjetbrains.com/youtrack/issue/RH-44507

Set up a TextEntity with, or without a dimstyle with a TextHeight other than 1 and try to get the BoundingBox via .GetBoundingBox(). The result will be a bounding box with a height of 1.

Also, that is not only the text’s height that is wrong, but also the text’s alignement:
image

Hi @Matthieu_from_NAVINN,

Can you post a model and/or source code that isn’t working for you?

Thanks,

– Dale

Hi, I did a few more tests, and the text alignment issue was from my code.

Here is a code sample showing the boundingbox drawn with a height of 1 when the text’s height is 12:

    Protected Overrides Function RunCommand(ByVal doc As RhinoDoc, ByVal mode As RunMode) As Result

        'Creates/updates the DimStyle
        Dim NewDimStyleSettings = New Rhino.DocObjects.DimensionStyle()
        NewDimStyleSettings.TextHeight = 12
        NewDimStyleSettings.TextHorizontalAlignment = TextHorizontalAlignment.Center
        NewDimStyleSettings.LeaderTextVerticalAlignment = TextVerticalAlignment.Bottom
        NewDimStyleSettings.Name = "TestDimStyle"
        NewDimStyleSettings.DimensionScale = 1
        DimStyle = doc.DimStyles.FindName("TestDimStyle")
        Dim DimStyleIndex As Integer = -1
        If DimStyle Is Nothing Then
            DimStyleIndex = doc.DimStyles.Add("TestDimStyle")
            DimStyle = doc.DimStyles.FindIndex(DimStyleIndex)
        Else
            DimStyleIndex = DimStyle.Index
        End If
        doc.DimStyles.Modify(NewDimStyleSettings, DimStyleIndex, True)


        'Pick a point
        Dim pt1 As Point3d
        Using getPointAction As New GetPoint()
            getPointAction.SetCommandPrompt("Please select the point")
            AddHandler getPointAction.DynamicDraw, AddressOf DynamicD
            If getPointAction.[Get]() <> GetResult.Point Then
                RhinoApp.WriteLine("No end point was selected.")
                Return getPointAction.CommandResult()
            End If
            pt1 = getPointAction.Point()
        End Using


        'Draw the result
        doc.Objects.AddText(RsltTextEntity)
        doc.Views.Redraw()

        Return Result.Success
    End Function

    Private Sub DynamicD(sender As Object, e As GetPointDrawEventArgs)

        CreateTextEntity(e.CurrentPoint)

        e.Display.DrawAnnotation(RsltTextEntity, Color.Blue)

        'draw the boundingbox
        For Each tp In RsltTextEntity.GetBoundingBox(RsltTextEntity.Plane).GetEdges
            tp.Transform(RsltTextEntity.GetTextTransform(1, DimStyle))
            e.Display.DrawLine(tp, Color.Red)
        Next

    End Sub

    Private RsltTextEntity As TextEntity = Nothing

    Private Sub CreateTextEntity(ByVal location As Point3d)
        Dim doc As RhinoDoc = RhinoDoc.ActiveDoc

        'Creates the TextEntity
        RsltTextEntity = New TextEntity
        RsltTextEntity.PlainText = "Hello World"
        Dim p As Plane = Plane.WorldXY
        p.Origin = location
        RsltTextEntity.Plane = p
        RsltTextEntity.TextHeight = 1
        RsltTextEntity.Font = DimStyle.Font
        RsltTextEntity.Justification = TextJustification.Center
        RsltTextEntity.DimensionStyleId = DimStyle.Id
    End Sub

End Class

Does anyone has a workaround for this?

Hi @Matthieu_from_NAVINN,

This sample seems to work correctly.

https://github.com/mcneel/rhino-developer-samples/blob/6/rhinocommon/cs/SampleCsCommands/SampleCsBoundingBox.cs

What am I missing?

– Dale

Could it be because your text is in the model while mine isn’t? Although it would be weird, because, in my case the bounding box is really calculated, but with the wrong text height.

Have you tried my sample?

Hi @Matthieu_from_NAVINN,

I’ve reported this as a bug.

https://mcneel.myjetbrains.com/youtrack/issue/RH-48756

– Dale

Thanks @dale

Hi @dale,
Sorry to reopen this old topic but I see that your bug report has been closed and it seems to me that it’s far to be solved.
It I use your code sample but with a different definition plane for the TextEntity this is what I get:
image

Full code
 Protected Overrides Function RunCommand(ByVal doc As RhinoDoc, ByVal mode As RunMode) As Result
        Dim view = doc.Views.ActiveView
        If view Is Nothing Then Return Result.Failure
        Dim plane = view.ActiveViewport.ConstructionPlane()
        plane.Rotate(RhinoMath.ToRadians(30), view.ActiveViewport.ConstructionPlane.Normal)
        Dim dimstyle = doc.DimStyles.FindName("TestDimStyle")

        If dimstyle Is Nothing Then
            dimstyle = New DimensionStyle With {
                .TextHeight = 2,
                .TextHorizontalAlignment = TextHorizontalAlignment.Center,
                .LeaderTextVerticalAlignment = TextVerticalAlignment.Bottom,
                .Name = "TestDimStyle",
                .DimensionScale = 1,
                .Font = New Rhino.DocObjects.Font("Book Antiqua")
            }
            Dim dimstyle_index = doc.DimStyles.Add(dimstyle, False)

            If dimstyle_index >= 0 AndAlso dimstyle_index < doc.DimStyles.Count Then
                dimstyle = doc.DimStyles(dimstyle_index)
            Else
                Return Result.Failure
            End If
        End If

        Dim text_entity = TextEntity.Create("Hello Rhino!", plane, dimstyle, False, 0, 0)
        Dim box = Nothing
        Dim bbox = text_entity.GetBoundingBox(text_entity.Plane, box)
        Dim corners = box.GetCorners()
        Dim points = New Point3d() {corners(0), corners(1), corners(2), corners(3), corners(0)}
        doc.Objects.AddPolyline(points)
        Dim log = Nothing
        text_entity.IsValidWithLog(log)
        doc.Objects.AddText(text_entity)
        doc.Views.Redraw()
        Return Result.Success
    End Function

Hi Arnold
I have also encountered this problem.My solution is to create a TextBoundingBox method.like this.

private Rectangle3d TextBoundingBox(Rhino.DocObjects.TextObject text)
{
BoundingBox empty = BoundingBox.Empty;
var textPlane = text.TextGeometry.Plane;
Transform transform = Transform.ChangeBasis(Plane.WorldXY, textPlane);
var curves = text.TextGeometry.Explode();
foreach(var curve in curves)
{
BoundingBox bbox = curve.GetBoundingBox(transform);
empty.Union(bbox);
}
return new Rhino.Geometry.Rectangle3d(textPlane, new Interval(empty.Min.X, empty.Max.X), new Interval(empty.Min.Y, empty.Max.Y));

}

I hope this help you.

Hi @Matthieu_from_NAVINN,

It appears this is still an open issue. The only workaround I can suggest at the moment is to make a copy of the object, transform it to the world-xy plane, do the bounding box calculation, and then transom the box corner points back to the text’s plane.

– Dale

Thanks @dale,

I think this is the best temporary solution and I’ve finally managed to make this work properly.
I’ve found another related bug: if I try to duplicate the TextEntity (text_entity.Duplicate) the result always goes wrong.

For information if anyone else is interested, this is my workaround code, it works quite well:

  Public Function GetTextEntityRectangle(ByRef text_entity As TextEntity) As PolylineCurve
        Dim TE_P As Plane = text_entity.Plane
        text_entity.Plane = Plane.WorldXY

        Dim _box As Box = Nothing
        Dim bbox As BoundingBox = text_entity.GetBoundingBox(text_entity.Plane, _box)
        Dim corners As Point3d() = _box.GetCorners()
        Dim points As New Rhino.Collections.Point3dList({corners(0), corners(1), corners(2), corners(3), corners(0)})
        points.Transform(Transform.ChangeBasis(TE_P, Plane.WorldXY))
        text_entity.Plane = TE_P
        Return (New Polyline(points)).ToPolylineCurve

    End Function

@603419608 (Naruto) Thanks for your solution, I used this as a temporary fix on another project but it is really slow when I need hundreds of TextEntities’ bounding boxes.