LinearDimension.GetTextRectangle beeing weird on generated dims

It seems that GetTextRectangle behaves differently with “generated” dimensions than with the ones “selected” from the model.

The third test (“spooked”) kind of “refresh” the object table (I guess). How could I emulate that without user interaction ?

Tested on Rhino 6 SR35 & 7 SR28

import rhinoscriptsyntax as rs 
import Rhino 
import scriptcontext 
from scriptcontext import doc 
import Rhino.Geometry as rg 


def main() : 
    
    generated()
    selected()
    spooked()

def FindAndGet(dimId, mode):
    dimObj = doc.Objects.Find(dimId).Geometry
    print(mode, dimObj.GetTextRectangle())


def generated():
    dim = rg.LinearDimension(rg.Plane.WorldXY, rg.Point2d(0,0), rg.Point2d(100,0), rg.Point2d(50,0))
    dimId = doc.Objects.Add(dim)
    
    FindAndGet(dimId, "generated")


def selected():
    dimId = rs.GetObject()
    
    FindAndGet(dimId, "selected")

def spooked():
    dim = rg.LinearDimension(rg.Plane.WorldXY, rg.Point2d(0,0), rg.Point2d(100,0), rg.Point2d(50,0))
    dimId = doc.Objects.Add(dim)
    rs.GetObject("don't, just press escape")
    
    FindAndGet(dimId, "spooked")
    
main()

result :

Cheers !
Sylvain

… Huuuum, seems like the success flag is False on the first one ! but the documentation is a bit cryptic :

calling Rhino.RhinoDoc.ActiveDoc.Views.ActiveView.ActiveViewport.ZoomExtents() instead of a cancelled GetObjects also solves it, but Rhino.RhinoDoc.ActiveDoc.Views.ActiveView.Redraw() doesn’t … I hope someone has a cleaner solution.

Hi @_Sylvain,

Rhino doesn’t generate annotation text until it needs to - usually when the scene is redrawn.

If you don’t want to redraw, then just ask for the annotation’s bounding box. This will trigger text generation.

def FindAndGet(dimId, mode):
    print("Mode: {0}".format(mode))
    dimObj = doc.Objects.Find(dimId).Geometry
    rc, corners = dimObj.GetTextRectangle()
    if not rc:
        # Force text update
        dimObj.GetBoundingBox(True)
        rc, corners = dimObj.GetTextRectangle()
    if rc:
        for i in range(len(corners)):
            print("  {0}: {1}".format(i, corners[i].ToString()))
    else:
        print("  GetTextRectangle failed")

– Dale

1 Like

Hi Dale,
Thanks a ton, I’ll try that !
Sylvain

The plot thickens ! Thanks Dale for the fix, forcing an update with a bounding box call solves the issue on python. The issue remains if I do the same from a C# plugin.

Here’s the command

               protected override Result RunCommand(RhinoDoc doc, RunMode mode)
        {
            // create a dimension 
            var dim1 = new Rhino.Geometry.LinearDimension(Plane.WorldXY, new Point2d(0, 0), new Point2d(100, 0), new Point2d(50, 0));
            Guid dimId = doc.Objects.Add(dim1);
            Rhino.Geometry.LinearDimension dimObj = (Rhino.Geometry.LinearDimension)Rhino.RhinoDoc.ActiveDoc.Objects.FindId(dimId).Geometry;

            // get the text corners and plane 
            bool foundRect = dimObj.GetTextRectangle(out var cornerPoints);
            if (!foundRect)
            {
                // Force text update
                var bbox = dimObj.GetBoundingBox(true);
                foundRect = dimObj.GetTextRectangle(out cornerPoints);

                if (!foundRect)
                {
                    Rhino.RhinoApp.WriteLine("CCC_SolveDimensionCollisions : failed to retrieve rect corners");
                    return Result.Failure;
                }
            }
            return Result.Success;
        }

Hi @_Sylvain,

Give this a try:

protected override Result RunCommand(RhinoDoc doc, RunMode mode)
{
  var view = doc.Views.ActiveView;
  if (null == view)
    return Result.Failure;

  var dim = new LinearDimension(Plane.WorldXY, new Point2d(0, 0), new Point2d(100, 0), new Point2d(50, 0));
  var dimId = doc.Objects.Add(dim);

  var dimObj = doc.Objects.FindId(dimId) as LinearDimensionObject;
  if (null == dimObj)
    return Result.Failure;

  dim = dimObj.LinearDimensionGeometry;
  if (null == dim)
    return Result.Failure;

  var rc = dim.GetTextRectangle(out var corners);
  if (!rc)
  {
    dim.GetBoundingBox(true);
    rc = dim.GetTextRectangle(out corners);
  }

  if (rc)
  {
    var style = dimObj.DimensionStyle;
    var scale = style.DimensionScale;
    var drawForward = style.DrawForward;
    var vp = new ViewportInfo(view.ActiveViewport);
    var xform = dim.GetTextTransform(vp, style, scale, drawForward);
    foreach (var p in corners)
    {
      p.Transform(xform);
      doc.Objects.AddPoint(p);
    }
  }
  else
  {
    Rhino.RhinoApp.WriteLine("Failed to retrieve rect corners");
  }

  doc.Views.Redraw();

  return Result.Success;
}

– Dale

Hi @dale it works, thanks a lot !!
I also realized that the first solution you gave runs on rhino 7 and I just tested it on 6, so i’ll mark this one as accepted.

Hi @dale

Im kind of running with the same issue for ordinate dimensions here, I’m working in a grasshopper script to test it and is returning false even if I call for the bounding box, the corners are all zero points. Any help here?

private void RunScript(Point3d x, ref object A)
  {
    OrdinateDimension ord = OrdinateDimension.Create(RhinoDoc.ActiveDoc.DimStyles.Current, Plane.WorldXY, OrdinateDimension.MeasuredDirection.Xaxis, Point3d.Origin, x, x + Vector3d.ZAxis, 2, 2);
    Point3d[] corners;
    if (!ord.GetTextRectangle(out corners)){
      ord.GetBoundingBox(true);
      ord.GetTextRectangle(out corners);
    }
    A = corners;
  }

Hi @Marcio_Souza,

It is currently not possible to get text rectangle of dimension without it being added to the document. You can read more about this by reviewing the issue below.

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

– Dale

I see thanks! I managed to have a workaround by adding to the document, grabing the corners and then deleting the object.

However I’m struggling to make this work for Leaders. They don’t have the GetTextRectangle method and their GetBoundingBox seems to only deliver the BBox of the leader lines, not the text. I tried to recreate a BBox by using the TextHeight and TextModelSpaceWidth properties but it seems the width is way larger than it is supposed to be.

Im almost going to the ultimate hacky solution of adding the leader to the doc, selecting it, call a branch script for the explode command, retrieve the TextEntity and then erase the remains. However I would be grateful for any idea on making this work avoiding this.

The BoundingBox command works on leaders added to the document.

Can you provide a sample that isn’t working for you?

Thanks,

– Dale

RH-76380 is fixed in Rhino 7 Service Release 34 Release Candidate

1 Like