Viewport width in mm?

I’m trying to set a dimension styles text height as a percentage of the width in mm of a view or viewport so that apparent text size is independent of how zoomed in the user is when the dimensions are added. I thought I had found what I was looking for when I cam across doc.Views.ActiveView.ScreenRectangle.Width. But this seems to look at the width in pixels of the view? Is there something similar but for mm? Or maybe someone has another suggestion on how to add dimensions to the document such that they appear identical in size regardless of how zoomed in the user is.

Thanks,
Sam

Hi Sam - presumably you’ll need to get the display density, pixels per inch or pixels per mm, per display, in order for this to work.

-Pascal

If Dots could display Text Fields, you’d have a solution. But I’ve just tried it, and it doesn’t work :disappointed:

Hi Pascal,

Say I have a circle in the xy plane with diameter 100mm and I press zoom extents. The visible height of the viewport showing the top view will be 100mm, maybe a bit more. I am looking for a function that will tell me this 100mm so I can skip this path of logic. I’ll be using this en route to ensuring dimension style text height takes up a certain percentage of the viewport at its current zoomed position when added to the document.

Hope this is a bit more clear,
Thanks,
Sam

Hi Sam - it is clear enough, but I do not see how you can proceed without knowing the density of the current display so that you can work out how large the viewports are.

-Pascal

Perhaps you are understanding me correctly and I’m just off the ball today, I might have to sleep on this one…

What I’m looking for is a function that returns how zoomed in the viewport is on the model. When zoomed extents on a 100mm diameter circle for example, the function should report 100mm. When the user zooms out by x2, the function should return 200mm. I don’t think monitor resolution should come into play for this as I’m not concerned with dimensions as seen on a monitor, just as a percentage of the viewport.

The workaround I’ve got going now is to zoom extents, get a bounding box of all objects in the current plane, and then set text height to a percentage of the largest bounding box dimension (after adjusting for veiwport aspect ratio). This works OK but seems a roundabout… If you have any thoughts, please let me know, otherwise I’ll stick with this workaround.

Thanks,
Sam

OK, so mm in the model, not the screen - got it. You might be able to use the viewport view corners to help with this -

view.ActiveViewport.GetNearRect()

but anyway, probably a question for the devloper or scripting forum, I’ll move it over there.

-Pascal

Hi Sam, I don’t know if this is an option for you, but if you do the dimensions in a detail on a layout page, then the size will always look the same (relative to the Layout). Just an idea…

I thought I had posted to the developer area, whoops…

I tried view.ActiveViewport.GetNearRect() and get some curious results. I think it is telling me how much of the viewport is providing a view of an object with respect to the global coordinate system. For example, if I run the following witht the right view active, it will return 0.

Dim width = doc.Views.ActiveView.ActiveViewport.GetNearRect(1).X - doc.Views.ActiveView.ActiveViewport.GetNearRect(0).X
MsgBox(CStr(width))

This function is close to what I need, but I need to be able to make it relative to the current CPlane coordinate system. Any suggestions?

Thanks,
Sam

I see this thread has been moved to the developers area now, anyone here have any thoughts?

Thanks,
Sam

How about this:

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

  var rect = view.ScreenRectangle;
  var width_in_pixels = rect.Width;
  var height_in_pixels = rect.Height;

  var graphics = System.Drawing.Graphics.FromHwnd(IntPtr.Zero);
  var pixels_per_inch_x = graphics.DpiX;
  var pixels_per_inch_y = graphics.DpiY;

  var width_in_inches = width_in_pixels/pixels_per_inch_x;
  var height_in_inches = height_in_pixels / pixels_per_inch_y;

  const double mm_per_inch = 25.4;
  var width_in_mm = width_in_inches * mm_per_inch;
  var height_in_mm = height_in_inches * mm_per_inch;

  var name = view.ActiveViewport.Name;
  RhinoApp.WriteLine(string.Format("{0} view width: {1} mm", name, width_in_mm));
  RhinoApp.WriteLine(string.Format("{0} view height: {1} mm", name, height_in_mm));

  return Result.Success;
}
1 Like

Hi Dale,

What I’m trying to get should be a function of how zoomed in the viewport is, not resolution etc. If, for example, a 100mm diameter sphere is the only object in the document and the user presses zoom extents, then the height of model space that is visible by the viewport becomes 100mm and that is what the function should return. Now if the user zooms out x2, the new model space height that is visible in the viewport becomes 200mm. You see what I’m after?

The reason why I’m trying to get this is so that I can set the height of dimensions before adding them such that they take up a percentage of the viewport at the current zoom level. Maybe there is a better way to achieve this objective…

Thanks,
Sam

You see what I’m after?

No, not really.

Rhino does not have a function that returns how zoomed in or out a viewport is. RhinoScript cooks up a value based on the viewport’s frustum.

Rhino.ViewRadius

This is the code, essentially.

var view = doc.Views.ActiveView;
if (null != view && view.ActiveViewport.IsParallelProjection)
{
  double left, right, top, bottom, far, near;
  view.ActiveViewport.GetFrustum(out left, out right, out bottom, out top, out near, out far);
  var radius = Math.Min(right, top);
  RhinoApp.WriteLine("View radius = {0}", radius);
}

Are you adding dimensions to the document? Or are you drawing them in a conduit? If, after “drawing” the dimension, if you zoom in or out, do you expect the dimension text to remain the same size?

Sorry I’m dense…

Hi Pascal,

GetFrustrum is exactly what I needed. I had noticed it before but sadly overlooked it, probably because I had never heard the word frustrum before.

I’m adding dimensions to the document at a specific zoom level and I don’t expect the dimensions to scale when the user zoom in or out, so this method works just fine for me.

One quick and somewhat related question: I’ve been moving to parallel projection mode by scripting the rhino command:
RhinoApp.RunScript("_-ViewportProperties Projection Parallel _enter ", True)

Is there a Rhinocommon version of this?

Thanks,
Sam

The term is Frustum, not Frustrum. :wink:

Try the following:

protected override Result RunCommand(RhinoDoc doc, RunMode mode)
{
  var view = doc.Views.ActiveView;
  if (null != view && !view.ActiveViewport.IsParallelProjection)
  {
    view.ActiveViewport.ChangeToParallelProjection(true);
    view.Redraw();
  }
  return Result.Success;
}

Works great, thanks Dale.

Sam

@dale
Hi, thanks for this!
What does IntPtr.Zero mean in the context of Rhinocommon? Can I substitute it for something or bring it in as a default from a System library?

An IntPtr is a value type large enough to store a memory address as used in native or unsafe code. IntPtr.Zero is the C/C++ equivalent of nullptr.

Sorry, I don’t understand this question. I’ll need some additional information or background.

– Dale

Hi Dale, thanks for the reply :slight_smile:

When running the line
graphics = System.Drawing.Graphics.FromHwnd(IntPtr.Zero)

I’m getting the error:

Runtime error (UnboundNameException): global name ‘IntPtr’ is not defined
Traceback:
line 11, in test_view_capture, “”
line 27, in script

So I wonder how you defined IntPtr or where exactly it gets initialized? Is it a import System variable or something that I have to define previously in the script? I don’t see that definition in your example.

Specifically I’m writing in Python so I’m trying to find an alternative to this line which will do the same thing.

Hi @Yafim_Simanovsky,

IntPtr is in the System namespace. So either do this:

var graphics = System.Drawing.Graphics.FromHwnd(System.IntPtr.Zero);

or

using System;

...

var graphics = System.Drawing.Graphics.FromHwnd(IntPtr.Zero);

– Dale

1 Like